Page MenuHomePhabricator

Restricted read access for subset of wiki
Closed, DeclinedPublic

Assigned To
None
Authored By
bzimport
Apr 19 2005, 2:02 PM
Referenced Files
F1965: mediawiki-1.8.2-restrictednamespaces.patch
Nov 21 2014, 8:21 PM
F1964: RS.patch
Nov 21 2014, 8:20 PM
F1963: rest_ns_1_6_7.diff
Nov 21 2014, 8:20 PM
F1962: 163_and_access_denied_patch
Nov 21 2014, 8:20 PM
F1961: restrict-20060406.diff
Nov 21 2014, 8:20 PM
F1960: restrict_namespace_access-1.5.7.patch
Nov 21 2014, 8:20 PM
F1959: Restrict_access_1.5.5.patch
Nov 21 2014, 8:20 PM
F1958: access-denied.patch
Nov 21 2014, 8:20 PM

Description

Author: maphiwe

Description:
It should be possible to restrict read access for a subset of the wiki pages to
specific users. This might not be necessary for Wikipedia, but is essential for
company wikis.

This enhancement has been brought up before on sourceforge.

References to related requests:
http://bugzilla.wikipedia.org/show_bug.cgi?id=1740
http://sourceforge.net/tracker/index.php?func=detail&aid=979095&group_id=34373&atid=411195
http://sourceforge.net/tracker/index.php?func=detail&aid=1014562&group_id=34373&atid=411195


Version: unspecified
Severity: enhancement
URL: http://meta.wikimedia.org/wiki/Hidden_pages

Details

Reference
bz1924

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

cnchris_98 wrote:

Hello, I used to patch on mediawiki 1.5.2 and it seems to work ok apart from
this error I keep getting:

Warning:in_array() [function.in-array]: Wrong datatype for second argument in
mediawiki/includes/User.php on line 1046

There was also an error about wrong datatype where it assumed a constant, I
fixed that by adding quotes around 'edit' on line 1045 in User.php

Does anyone have any clue on how to solve the issues?

Thanks,
Christian

cnchris_98 wrote:

I think I 'fixed' it already. I had to add the variables to the config file for
it to work :)

jiangxin wrote:

(In reply to comment #45)

I keep getting:Warning:in_array() [function.in-array]:

add $wgRestrictedNamespaces = NULL to config file, warning also exisit there.
Fixed like that:
+ if( is_array( $wgRestrictedNamespaces ))
+ {

if( in_array($ns, $wgRestrictedNamespaces) && $this->canAccessNamespace($ns) ) {
         if( ($action == edit) && (in_array('sedit', $this->mRights)) ) {
                  return true;
         }
}

+ }

torsten.schmidt wrote:

Created an attachment (id=1037) [edit]
Update + addons for 1.5.1

i've installed this patch on 1.5.0 and it works, thanks for this patch Nick.

one question to the message being displayed, if an unauthorized user trys to
access a restricted ns:

i get the following text (translated from the german version):


Login required!
you have to [[Special:UserLogin]] to view other pages.

Back to [[Mainpage]]

this doesn't make so much sense.
how could i change this message to something like:
you don't have the Right to view this page. / you're not allowed to view this page.

Thanks in advance.
Torsten

robchur wrote:

Special:Allmessages

mickflemm wrote:

I found a bug in the implementation of 'sedit' right, it seems that it doesn't work.

To fix that go to includes/User.php line 1047 and change

if( in_array($ns,$wgRestrictedNamespaces) && $this->canAccessNamespace($ns) ) {

to

if( $this->canAccessNamespace($ns) ) {

Also do what JiangXin sugests.

Sorry ppl, i didn't test that feature well :-(

A new patch is almost ready, I' ll release it soon..

Nick

mickflemm wrote:

also change

if( ($action == edit) && (in_array('sedit', $this->mRights)) ) {

to

if( !$title->isProtected() && ($action == edit) && (in_array('sedit',
$this->mRights)) ) {

so that protected pages inside restricted namespaces are not editable

Nick

donn.morrison wrote:

Is it possible with this patch to have a namespace read-only for certain users?
I'd still like to have the namespace restricted for editing, but don't want the
restricted pages hidden from everyone.

cnchris_98 wrote:

I use this patch on 1.5.0 and it works likes a charm.
Now I would like to use a custom authentication scheme using my own extension of
the AuthPlugin interface. However the wiki doesn't seem to respond to any
changes I make to the custom authentication class.
Is it still possible to extend this interface after using this plugin?

filipe wrote:

I'm having a problem with this patch on 1.5.2. This is the setup I have:

$wgExtraNamespaces = array(

100 => 'Code',
101 => 'Skinne',
102 => 'SLF',
103 => 'Content'
);

$wgRestrictedNamespaces = array(

100 => array('coder'),
101 => array('projectskinne'),
102 => array('projectslf'),
103 => array('content')

);

Permissions
"Code" Namespace
$wgGroupPermissions['sysop']['Code'] = true;
$wgGroupPermissions['coder']['Code'] = true;

// "Skinne" Project Namespace
$wgGroupPermissions['sysop']['Skinne'] = true;
$wgGroupPermissions['projectskinne']['Skinne'] = true;

// "SLF" Project Namespace (SportLegsFan.com)
$wgGroupPermissions['sysop']['SLF'] = true;
$wgGroupPermissions['projectslf']['SLF'] = true;

// "Content" namespace
$wgGroupPermissions['sysop']['Content'] = true;
$wgGroupPermissions['content']['Content'] = true;

When I try to access [[Code:Main]] it asks me to login (when I am already logged
in).

When I try to Move a page to Code:Main, it returns an error on the same page
saying "Protected Page"

mickflemm wrote:

Try this...

$wgExtraNamespaces = array(
100 => 'Code',
101 => 'Code_talk',
102 => 'Skinne',
103 => 'Skinne_talk',
104 => 'SLF',
105 => 'SLF_talk',
106 => 'Content'
107 => 'Content_talk'
);

$wgRestrictedNamespaces = array(
100 => 'coder',
102 => 'projectskinne',
104 => 'projectslf',
106 => 'content'
);

Permissions
"Code" Namespace
$wgGroupPermissions['sysop']['coder'] = true;
$wgGroupPermissions['coder']['coder'] = true;

// "Skinne" Project Namespace
$wgGroupPermissions['sysop']['projectskinne'] = true;
$wgGroupPermissions['projectskinne']['projectskinne'] = true;

// "SLF" Project Namespace (SportLegsFan.com)
$wgGroupPermissions['sysop']['projectslf'] = true;
$wgGroupPermissions['projectslf']['projectslf'] = true;

// "Content" namespace
$wgGroupPermissions['sysop']['Content'] = true;
$wgGroupPermissions['content']['content'] = true;

Read the DefaultSettings.php and you 'll find examples there, also read the
previous messages here.

a) You asign a namespace to a right in $wgRestrictedNamespaces
($wgRestrictedNamespaces = array(100=>'coolguy')).
b) You asign the right to a usergroup ($wgGroupPermissions['User_group']
['coolguy'] = true;
c) Always create the talk namespaces because the way you have made your
configuration Skinne is the talk namespace of Code and Content is the talk
namespace of SLF.

Nick

mickflemm wrote:

The new patch for 1.5.2 will probably be ready on Thuesday, it will have a new feature for read
only namespaces (that are not hidden in the logs) and a few bugfixes...

Nick

no-spam wrote:

Sounds great Nick! I just found your patch and it exactly what I need. Thanks
for your effort!

donn.morrison wrote:

Hey Nick, any progress on the latest 1.5.2 patch?

Donn

mickflemm wrote:

Update + addons for 1.5.3

Patch for 1.5.2 also works for 1.5.3.

2 New features...

a) Read-Only Namespaces, now you may put all the namespaces you want to be read
only to an array. Users with the 'roread' right can read them, users with the
'rowrite' right can edit them. These are not locked to usergroups yet (not
specific right per namespace), that means if someone has the 'rowrite' right,
can edit every read only namespace, same goes for 'roread'. Read only
namespaces are not hidden (no log hiding).

b) For those users that have access to restricted namespaces, a list to the
main page of each restricted namespace they have access to is being displayed
after they log in. Each link is formed by the name of the namespace and the
'mainpage' message. Also on top of the list a new 'RNSlist' message is being
displayed, to edit the message go to MediaWiKi:RNSlist.

For more info check out includes/DefaultSettings.php (documentation is there)

Hope it works fine :-)
Nick

P.S. By the way the title of this bug entry is way out of date, I' ll create a
new bug entry sometime.

P.S.2 I also created a patch for changing the logo and the sidebar per
namespace, check it out (4042).

attachment Restrict_access_1.5.3.patch ignored as obsolete

mickflemm wrote:

I forgot to mention i also added a feature to hide User talk stuff from
Special:Recentchanges

Nick

filipe wrote:

I'm still trying to figure out all the code (I've been able to make a couple
edits for my own purposes here-and-there) but I was wondering what I would have
to change to return an "Access Denied" page rather than just sending them to the
"Login" page whenever they try to access a restricted resource.

Or is there something wrong with my installation?

mickflemm wrote:

Check out includes/OutputPage.php and the function returnToMain() whitch is
called in such situations.

Nick

no-spam wrote:

I too wanted to have this so I added a few lines to the function loginToUse() in
includes/OutputPage.php

I ended up with this:

function loginToUse() {
global $wgUser, $wgTitle, $wgContLang;

        $usersNamespaces = $wgUser->getAllowedRNSes();
        $usersNamespacesArray = explode("\n", $usersNamespaces);
        $currentNamespace = Namespace::getCanonicalName($wgTitle->getNamespace());
        
        # If the user tries to access an extra namespace but does not have
        # the correct permissions, display an Access Denied message.
        # You need to define MediaWiki:noaccesstitle and MediaWiki:noaccesstext
        if($wgTitle->getNamespace() >= 100) {
            if(!in_array($currentNamespace, $usersNamespacesArray)) {
                $this->setPageTitle( wfMsg( 'noaccesstitle' ) );
                $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
                $this->setRobotpolicy( 'noindex,nofollow' );
                $this->setArticleFlag( false );
                $this->mBodytext = '';
                $this->addWikiText( wfMsg( 'noaccesstext' ) );
            }
        }
        
        else {        
            $this->setPageTitle( wfMsg( 'loginreqtitle' ) );
            $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) );
            $this->setRobotpolicy( 'noindex,nofollow' );
            $this->setArticleFlag( false );
            $this->mBodytext = '';
            $this->addWikiText( wfMsg( 'loginreqtext' ) );
        }

		# We put a comment in the .html file so a Sysop can diagnose the page the
		# user can't see.
		$this->addHTML( "\n<!--" .
						$wgContLang->getNsText( $wgTitle->getNamespace() ) .
						':' .
						$wgTitle->getDBkey() . '-->' );

        # Do not return to the main page automatically if the user tried to access
        # an extra namespace. Only return if the user tried, but failed to access
        # a system namespace.
        if($wgTitle->getNamespace() < 100) {
            $this->returnToMain();	# Flip back to the main page after 10 seconds.
        }

}

no-spam wrote:

Display Access Denied message when no namespace permission

This patch works after applying the 1.5.3 patch for restricting namespace
access.

Attached:

cgavos wrote:

This is fabulous! I did manage to create Private Namespaces and all. But is
there a way to make the “main” namespace private and then create a public
namespaces?

For example,

Everything posted under the “main” namespace is private

Everything posted under the “Public:” name space is world readable

Everything posted under the “FlexPublic:” name space is readable and writable

Regards,
cgavos

steve wrote:

Will this be making its way into the official code?

No. MediaWiki doesn't target this type of environment, and our
policy is to be open about the fact that we are not built for
that, since security problems in an unmaintained, half-done
approach are likely to crop up constantly.

If you actually need fancy read restrictions to keep some of
your own people from reading each others' writing, MediaWiki is
not the right software for you.

I hadn't realized this bug was actually still open, I'm resolving
it as WONTFIX.

matthew.shepherd wrote:

While I understand what Brion Vibber has said here and elsewhere many times, I
still feel that MediaWiki suits my needs very well aside from the lack of good
Access Control. I'm willing to do what I need to do to ensure that after this
patch is implemented on my wiki, that the wiki remains secure.

I feel that part of the beauty of open source software is that even if the
community that developed it is not interested in a certain aspect or feature,
that feature can be developed, implemented, and maintained by someone 'outside'
of the community so that those who are interested can use it.

I work in a Software Development department at a large ISP. If is possible that
if there is a need we may end up developing further access control ourselves as
we have evaluated many other collaborative documentation repository solutions
and like what MediaWiki has to offer.

MaPhi, will you be continuing to post updates at another location? Since Brion
has made it clear on many occassions that there are no foreseeable plans to
implement something like this, perhaps we should find a forum where this patch
and it's updates can be posted, downloaded, and discussed freely?

ezyang wrote:

You're likely going to have to fork MediaWiki, albeit make it a closely
synchronized fork. MediaWiki, after all, is used for WikiMedia's projects, and
the MediaWiki team has done a great job patching MediaWiki so that it's
deployable on other systems. However, you can only do so much without
implementing ugly hacks or introducing performance problems.

mickflemm wrote:

Brion Vibber is right, MediaWiKi's design is to be open for editing etc and
focuses on other important things. This is a hack for MediaWiKi and it will
remain a hack as long as someone is maintaining it (MaPhi Werner, me, someone
else perhaps). It shouldn't be in the oficial MediaWiKi because MediaWiKi should
be redisigned from scratch and adapt a new user policy etc (that means e.g. new
database scema, different architecture, different session hanlding etc) for this
to work corectly. This hack does not guarantee security etc. I personaly liked
MediaWiKi's interface and features and wanted to mod it for my needs so i used
and maintained this patch. If you want to have a wiki with user managemend in
mind (lot's of permissions to add or remove, more options upon user rights, per
article access control etc), try something else.

mickflemm wrote:

Update + addons for 1.5.5

Lots of bugfixes, tested mostly with 1.5.3 but works for 1.5.5 too...

Some add-ons:

  • Users in Special:Listusers can only see the users in their usergroup (to undo

this overwrite includes/Speciallistusers.php from the main distribution).

  • A new variable {{ns}} added, that gets the name of the current namespace

(this helps with management), especialy with #4042 can be very helpfull in
sidebars.

Attached:

mickflemm wrote:

forgot to mention the above patch can be applied with -p1 instead of -p0...

mickflemm wrote:

I got a report about another bug, users that are not logged in can edit their
user-page (IP), to fix this, go to User.php
in function isallowed, find

// If we are in user's page, allow him to do everything...

if ( $action == 'edit' && ($ns == NS_USER_TALK || $ns == NS_USER)...


if ( $action == 'protect' && ($ns == NS_USER_TALK || $ns ==

NS_USER)...

and change it to...

// If we are in user's page, allow him to do everything...

if ( $this->isLoggedIn() && $action == 'edit' && ($ns ==

NS_USER_TALK || $ns == NS_USER)...

if ( $this->isLoggedIn() && $action == 'protect' && ($ns ==

NS_USER_TALK || $ns == NS_USER)...

gangleri wrote:

(In reply to comment #71)

  • A new variable {{ns}} added, that gets the name of the current namespace

(this helps with management), especialy with #4042 can be very helpfull in
sidebars.

This is the request from
Bug 2162: enhancement request for a new variable GENERICNAMESPACE

greearb wrote:

I'm using mediawiki 1.5.6 with the 1.5.5 patch, and having trouble. I'm new to
wiki, so I could be missing something trivial.

I have added a new group using mysql commands:
mysql> select * from user_groups;
+---------+------------+

ug_userug_group

+---------+------------+

1bureaucrat
1candela
1sysop

+---------+------------+
3 rows in set (0.00 sec)

My local-settings looks like this:

Access restriction settings.

$wgExtraNamespaces = array(
101 => 'Private'
);

$wgRestrictedNamespaces =

array(101 => 'candela'
     );

$wgGroupPermissions['sysop']['candela'] = true;
$wgGroupPermissions['candela']['candela'] = true;

$wgLinkWarn = true;


I'm using this wiki-markup in my main page to try to create a private
link, available only to user 1:

  • [[Private:Private]] Restricted pages, not for public consumption.

I'm logged in as user 1, but when I display the main page, I
see this:

<restrlink> Restricted pages, not for public consumption.

Any ideas what I'm doing wrong?

Thanks,
Ben Greear <greearb@candelatech.com>

oooooooo8 wrote:

(In reply to comment #73)
Hi Nick! Very good work! I thougth it was impossible to do this with MediaWiki
and I was thinking in changing to a different wiki engine! Thanks!

I found two things that maybe you want to change in the patch:

(1) I get a warning:

Warning: substr_count(): Empty substring. in ...\includes\SpecialListusers.php
on line 177

to solve it you can change (near line 177 in SpecialListusers)

if( substr_count($rUsergroups, $tUserGroups[$i]) >0 ){

for

if( strlen($tUserGroups[$i])>0 && substr_count($rUsergroups, $tUserGroups[$i])

(2) If you apply the patch "Diff to restrict the output of groups on the
Special:Listusers page for non-sysops" you still can see the groups because in
Recentchanges you can see things like this (even if you are not in the group
"testgroup")

(Bureaucrat log); 09:42 . . Admin (Discusión) (Changed group membership for
Usuario:TestUser from to testgroup)

I don't care a lot, but maybe is a problem for someone else.

Thanks again!

Octavi

oooooooo8 wrote:

(In reply to comment #75)

Hi Ben! I discovered this patch yesterday so maybe I'm wrong.

You can write
$wgLinkWarn = false;

and the link will show the same way as the others. I didn't like this (I want a
warning AND a link) and changed Parser.php near line 1337 the lines:

$s .=wfMsg( 'restrlink' ). $trail;
continue;

commented something:
$s .=wfMsg( 'restrlink' );. $trail;
continue;

Then you have to create the page MediaWiki:Restrlink and write something you
want to appear before the restricted links. I wanted to appear an image of a
lock so I tried something like [[Image:log.gif]] but doesn't work. If you write
the url like:
http://www.example.com/lock.gif
without any wiki format, it works!

You should create the pages MediaWiki:RNSlist (appears in the login) and
MediaWiki:templatenotincluded (appears if you try to do a template with
restricted pages).

xbelanch wrote:

Hi Octavi,
I have the same problem about <restrlink>. I have this conf in the localsettings.php

$wgGroupPermissions['*' ]['createaccount'] = false;
$wgGroupPermissions['*' ]['read'] = true;
$wgGroupPermissions['*' ]['edit'] = false;
$wgGroupPermissions['sysop' ]['edit'] = true;
$wgGroupPermissions['sysop' ]['read'] = true;
$wgGroupPermissions['sysop' ]['createaccount'] = true;
$wgGroupPermissions['sysop' ]['renameuser'] = true;
$wgGroupPermissions['sysop' ]['userrights'] = true;
$wgGroupPermissions['ninja' ]['read'] = true;
$wgGroupPermissions['ninja' ]['edit'] = true;

#NameSpaces propios de la estructura del curso XTEC
$wgExtraNamespaces = array (

100 => "CURS",
101 => "MODUL",
102 => "PRACTICA",
103 => "EXERCICI",
104 => "GUIA",
105 => "AJUDA"

);
$wgNamespacesWithSubpages = array (

100 => 1, 101=> 1, 102=> 1, 103=> 1, 104=> 1, 105=> 1);

$wgNamespacesToBeSearchDefault = array (100=> 1 , 101=> 1, 102=> 1, 103=> 1,
104=> 1, 105=> 1);

Relación entre los grupos de usuarios y los NameSpaces

$wgGroupPermissions['sysop' ]['cusito'] = true;
$wgGroupPermissions['sysop' ]['modulito'] = true;
$wgGroupPermissions['*' ]['cursito'] = false;
$wgGroupPermissions['*' ]['modulito'] = false;
$wgGroupPermissions['ninja' ]['cursito'] = true;
$wgGroupPermissions['ninja' ]['modulito'] = false;

Afegim als keys dels namespaces els noms dels grups de restricció :=)

$wgRestrictedNamespaces = array(100 => "cursito", 101 => "modulito");

$wgLinkWarn = false;

At this point, when I visit one MODUL or CURS page, it appears something like this:
http://phobos.xtec.net/curslinkat/formacio/index.php/Linkat
Well, I would to know how its the better way to work or solution!

Thanks,
Javier

PD: Octavi, felicitats pel teu projecte de robòtica. Apa, ajuda'm!!!!!

john wrote:

After much tearing out of hair, I did eventually get access restriction to a
namespace, but one thing remains.

What is 'RSNlist' message meant to say? I can't quite understand what it's there
for based on the patch/comments.

john wrote:

[Apologies, I meant RNSlist in comment #79]

In fact, can we have examples of all the messages:

  • restrlink
  • templatenotincluded
  • RNSlist

any others?

xbelanch wrote:

Hey,
Just rules :) I have a problem of permissions! Thanks for your feedbacks :)_

Javier

violendom wrote:

Hi, I had some particular needs :

  • I wanted to view the restricted link if it's allowed and in a different

namespace page.

  • The page must not be cached if a restricted link is present, because the page

is different for differnt user

  • The page can be cached if the restricted link is in the same namespace of the page
  • I need a template to display an open lock near the allowed restricted link

(restrallowedlink)

so I've changed Parser.php to satisfy my needs :

#If the link points to a restricted namespace outside the
#parent namespace warn the user.
global $wgRestrictedNamespaces, $wgLinkWarn, $wgUser;
if( $wgLinkWarn && is_array( $wgRestrictedNamespaces )) {

if( array_key_exists( $ns, $wgRestrictedNamespaces ) ) {			
  if ($this->mTitle->getNamespace() != $ns) {
    #If the restricted link is in a page with a differnt namespace
    #do not cache.
    $this->disableCache();
  }	
  if ( $wgUser->isAllowed($wgRestrictedNamespaces[$ns]) ) {
    $s .=wfMsg( 'restrallowedlink' );
  } else {
    $s .=wfMsg( 'restrlink' ). $trail;
    continue;
  }
}

}

It would be nice with some conf variables to configure the link display behaviour

martinlbg wrote:

hi,
i have running mediawiki 1.5.6. Is it necessary to patch 1.5.6 or is it
necessary to include an extension to enable private and puplic wiki pages?

Which example on this bugzilla-side is running? Or can anybody post me an
running LocalSettings.php.

which convention is correct?
$wgGroupPermissions['Groupname']['restrictedNamespaceName'] = true;
or
$wgGroupPermissions['Groupname']['Right'] = true;

thanks in advanced for "any" answer

martinlbg wrote:

hi,
i have running mediawiki 1.5.6. Is it necessary to patch 1.5.6 or is it
necessary to include an extension to enable private and puplic wiki pages?

Which example on this bugzilla-side is running? Or can anybody post me an
running LocalSettings.php.

which convention is correct?
$wgGroupPermissions['Groupname']['restrictedNamespaceName'] = true;
or
$wgGroupPermissions['Groupname']['Right'] = true;

thanks in advanced for "any" answer

temporaryspamtrap wrote:

Addons for 1.5.7 (based on 1.5.5 addons 1316, munged for 1.5.7)

No updates here. Just munged patch from
[http://bugzilla.wikimedia.org/attachment.cgi?id=1316&action=edit|addons for
1.5.5] to jive with plain 1.5.7 release.

attachment restrict_namespace_access-1.5.7.patch ignored as obsolete

temporaryspamtrap wrote:

Addons for 1.5.7 (based on 1.5.5 addons 1316, munged for 1.5.7)

Sorry, I've been smoking crack and original patch did not, err, patch cleanly.
This one does.

Attached:

ironmann77 wrote:

Is there a simple piece of code that will allow a general user to edit the talk
page and nothing else?

hiram wrote:

Pawel O: Your patch produces the following error when a user not in any
namespace group askes for List Users:<BR>
Warning: substr_count() [<a
href='function.substr-count'>function.substr-count</a>]: Empty substring. in
includes/SpecialListusers.php <BR>
It is from the following section of code:<BR>
<PRE>
+ $incl = false;
+ $rUsergroups = implode(',',$groups);
+ $tUserGroups = $wgUser->getGroups();
+ for( $i = 0; count($tUserGroups) >= $i; $i++) {
+ if( substr_count($rUsergroups, $tUserGroups[$i])

0 ){

+ $incl = true;
+ break;
+ }
+ }
</PRE>

wiki-devel wrote:

Hello,

(first : thanks Nick Kossifidis for this patch, it helps a lot
setting up corporate wikis).

We'd like to also protect uploaded files, i.e. be able to upload
files that could then be retrieved only by a group of users.

Does the patch allow to do this ? For this purpose, it would be nice
if we could use the same restrictions that are set up by the way of
this patch, for "normal" wiki pages !

Thanks in advance ...

alfonsname wrote:

Restricted namespace access on SVN/Head 2006-04-06 + Addons 1452

I updated 1452 to work with recent SVN Code (2006-04-06).

Attached:

i.vighetto wrote:

Applying the patch, doesn't work "preferences". I added $wgUser as global in
function namespacesCheckboxes() in SpecialPreferences.php and works ok.

i.vighetto wrote:

After applying the patch, doesn't work "preferences". I added $wgUser as global
in function namespacesCheckboxes() in SpecialPreferences.php and works ok.

silvia.pfeiffer wrote:

I run mediawiki 1.5.7 and have applied
mediawiki-1.5.7-restriction-patch-beta-0.62.tar.gz . The section that I have
restriced is all pages that contain "Restricted/" in them.

It works, but when I use "search", the restricted pages also come up as search
results.
Try http://www.annodex.org/ and search for "restricted".

I checked the source code, but couldn't find out why. Can anyone help?

majormax wrote:

Addons for 1.6.3 with Display Access Denied message when no namespace permission patch (based SVN/Head 2006-04-06 + Addons 1452)

Hi,

I recently set up a MediaWiki installation and was looking for exactly what
this patch provided! However, it seemed there was no version for 1.6.3, however
I decided to try SVN/Head 2006-04-06 + Addons 1452 with Display Access Denied
message when no namespace permission (had to do some light hacking for the
latter because of some changed code in loginToUse() and there was also a slight
bug in the first in wfSpeciAllpages() since it didn't have global $wgUser).
Anyways, thanks to the writers for the mentioned patches, they did the real
work.

Hopefully, people will keep posting patches to enable this functionality, hope
this helps others.

P.S. I forgot to mention above, that I didn't do any extensive testing, but
after using the wiki for a couple of days it seems to work fine with no side
effects except that little bug in wfSpecialAllpages(). Also it seems the
restricted patches aren't included in Search either unless you have permission
(let me know if I'm wrong).

Attached:

majormax wrote:

(In reply to comment #93)

I run mediawiki 1.5.7 and have applied
mediawiki-1.5.7-restriction-patch-beta-0.62.tar.gz . The section that I have
restriced is all pages that contain "Restricted/" in them.

That file refers to the patch referenced from
http://conseil-recherche-innovation.net/index.php/1974/04 which is different
from the namespace restriction patch on this page. It seems to support
restricting namespaces implicitly by matching the namespace followed by colon
part not explictly like this patch. Also, it only has one group of "authorized"
users, while this patch supports as many restriction groups as you want by
implementing restriction as a user right rather than a user group.

roland wrote:

(In reply to comment #94)

Addons for 1.6.3 with Display Access Denied message when no namespace
permission patch (based SVN/Head 2006-04-06 + Addons 1452)

As far as I can see, this breaks the "what links here" link. The following
patch solves this:

+++ includes/SpecialWhatlinkshere.php Sun Apr 23 20:19:38 2006
@@ -73,7 +73,7 @@

  • @access private */ function showIndirectLinks( $level, $target, $limit, $from = 0, $dir =

'next' ) {

  • global $wgOut;

+ global $wgOut, $wgUser;

$fname = 'WhatLinksHerePage::showIndirectLinks';
 
$dbr =& wfGetDB( DB_READ );

roland wrote:

And another problem with 1.6.3:

  • includes/SpecialPreferences.php.org Sun Apr 23 20:27:10 2006

+++ includes/SpecialPreferences.php Sun Apr 23 20:27:47 2006
@@ -370,7 +370,7 @@

    • @access private */ function namespacesCheckboxes() {
  • global $wgContLang;

+ global $wgContLang, $wgUser;

  1. Determine namespace checkboxes $namespaces = $wgContLang->getNamespaces();

didier.courtaud wrote:

The attachment 1598 does not seem to work with Mediawiki 1.6.5 :

patching file includes/CategoryPage.php
patching file includes/DefaultSettings.php
Hunk #1 succeeded at 1567 (offset 13 lines).
patching file includes/Export.php
patching file includes/OutputPage.php
Hunk #1 FAILED at 748.
1 out of 1 hunk FAILED -- saving rejects to file includes/OutputPage.php.rej
patching file includes/Parser.php
patching file includes/QueryPage.php
patching file includes/SearchEngine.php
patching file includes/SpecialAllpages.php
patching file includes/SpecialContributions.php
patching file includes/SpecialListusers.php
patching file includes/SpecialLog.php
patching file includes/SpecialPreferences.php
patching file includes/SpecialRandompage.php
patching file includes/SpecialRecentchanges.php
patching file includes/SpecialRecentchangeslinked.php
patching file includes/SpecialUserlogin.php
Hunk #1 succeeded at 410 (offset -1 lines).
patching file includes/SpecialWantedpages.php
Hunk #1 succeeded at 71 (offset 3 lines).
patching file includes/SpecialWhatlinkshere.php
patching file includes/Title.php
patching file includes/User.php

cyril.dangerville wrote:

Restricted namespace access for 1.6.5

Based on patch for 1.6.3. Resolved the conflict on includes/OutputPage.php
mentioned by Didier Courteau in last comment to make it compatible with 1.6.5.

attachment ns_restricted_access-1.6.5.patch ignored as obsolete

cyril.dangerville wrote:

Comment on attachment 1714
Restricted namespace access for 1.6.5

Based on attachment #1598.
Do not forget to define MediaWiki:RNSlist, MediaWiki:noaccesstitle and
MediaWiki:noaccesstext.

stephan.braun wrote:

I used this patch for 1.5.7 and everything seems to work fine except for the RSS
feed for recent changes. The feed includes the changes of restriced (hidden)
pages which should not be so. Is there anything to change this behaviour?

Jean-Baptiste.Minchelli wrote:

The patch for 1.6.5 seems to be imcopatible with 1.6.6

Hunk #1 succeeded at 120 with fuzz 2 (offset 5 lines).
patching file includes/DefaultSettings.php
Hunk #1 FAILED at 1554.
1 out of 1 hunk FAILED -- saving rejects to file
includes/DefaultSettings.php.rejpatch

andi wrote:

Restricted namespace access for 1.6.7 (based on 1714)

just updated 1714 to MediaWiki 1.6.7

Attached:

oooooooo8 wrote:

I think I found a possible security hole. If you include a restricted page in a
non restricted page you can see the contents, even if you don't have access to
the restricted namespace.

Try writing {{:RestrictedNS:NameOfThePage}} in a non restricted page
(RestrictedNS is the restricted namespace and NameOfThePage the name of the page).

To solve it, I added an "else" near line 2268 in includes/Parser.php

  1. Articles from restricted namespaces can't be used in templates.
  2. They would appear or disappear based on the rights of the user
  3. that refreshes the cache... if( is_array( $wgRestrictedNamespaces ) ) { if( array_key_exists( $title->getNamespace(), $wgRestrictedNamespaces ) ) { $found = true; $text = $linestart . wfMsg( 'templatenotincluded' ); } }

+ else

if ( $title->getNamespace() == NS_SPECIAL &&

$this->mOptions->getAllowSpecialInclusion() ) {

Anyone can tell me if I'm right? Thanks

Octavi

oooooooo8 wrote:

Never mind my previous post, I introduced the security hole to my wiki some time
ago when I did some changes to the code. All the patches here are ok. Sorry!

Octavi

oooooooo8 wrote:

I've been looking at my changes and the patches and after all maybe my post #104
was right. My wiki has too many changes to know it for sure. Can somebody check
it? Thanks

Octavi

andi wrote:

I certify this bug. In my wiki it also works.
Someone must build a new patch.

oooooooo8 wrote:

In comment #104 there is a mistake and it will prevent to appear any template
(even the ones of non restricted namespaces). To solve it, we have to merge the
two "if" (and leave the "else" after):

  1. Articles from restricted namespaces can't be used in templates.
  2. They would appear or disappear based on the rights of the user
  3. that refreshes the cache...

if( is_array( $wgRestrictedNamespaces ) && array_key_exists(
$title->getNamespace(), $wgRestrictedNamespaces ) ) {

$found = true;
$text = $linestart . wfMsg( 'templatenotincluded' );

}
else if ( $title->getNamespace() == NS_SPECIAL && ...

msspamfang wrote:

(In reply to comment #103)

Created an attachment (id=1933) [edit]
Restricted namespace access for 1.6.7 (based on 1714)

just updated 1714 to MediaWiki 1.6.7

I have some troubles with this patch.
First I often receive a message like "<restrlink>", which I hadn't using version
1.5.3 with that patch. I found out that in "DefaultSettings.php" around line 1424
$wgLinkWarn = false;
has to be set instead of
$wgLinkWarn = true;

also I found some error in SpecialWhatlinkshere.php around line 203: "Fatal
error: Call to a member function canAccessNamespace() on a non-object in
/var/www/html/wiki/includes/SpecialWhatlinkshere.php on line 203"
This can be eliminated by setting
global $wgUser;
around line 78, after function showIndirectLinks() begins.

Another error now occurs in SpecialRecentchangeslinked.php, an syntax error of
the sql statement. "1054: Unknown column 'page_namespace' in 'where clause'
(localhost)" I haven't had a closer look at it by now...

hokie99cpe+wiki wrote:

Adds "your namespaces" to sidebar for 1.6.3.

Makes the restricted namespace patches more useful... shows a user a list of
namespaces to which they have access.

attachment Skin.php.patch ignored as obsolete

hokie99cpe+wiki wrote:

Adds "your namespaces" to sidebar for 1.6.3

Makes the restricted namespace patches more useful by showing the user a list
of
namespaces to which they have access. If the user does not have access to any
restricted namespaces, the sidebar remains the standard.

attachment Skin.php.patch ignored as obsolete

marcor wrote:

(In reply to comment #108)
I've tried your workaround in a 1.5.6 installation and it work fine, but don't
work in a 1.6.7.
What version you are using?

roland wrote:

I found a little but in SpecialRecentchangeslinked: It uses the table
column page_namespace, but table 'page' isn't used in this query so it
fails. Changing this to pl_namespace seems to solve this problem:

  • SpecialRecentchangeslinked.php.old Mon Jul 10 18:32:17 2006

+++ SpecialRecentchangeslinked.php Mon Jul 10 18:38:15 2006
@@ -67,7 +67,7 @@

	if( is_array( $wgRestrictedNamespaces )) {
		foreach( $wgRestrictedNamespaces as $key => $value ) {
			if( ! $wgUser->canAccessNamespace( $key )) {
  • $cmq .= ' AND page_namespace <>' . $key;

+ $cmq .= ' AND pl_namespace <>' . $key;

			}
		}
	}

hokie99cpe+wiki wrote:

Updated for 1.7.1 (includes "your namespaces" in the sidebar)

As not able to include this snippet from a previous version into Parser.php. Do
not really understand it well enough to workout where it should go if it goes
at all.


  • 2527,2532 ****
  • 2537,2546 ----
		if ( !$found ) {
			# Check for NS: (namespace expansion)
			$mwNs = MagicWord::get( MAG_NS );

+ if ( $part1 == 'ns' ) {
+ $text = $linestart . $wgContLang->getNsText(
$this->mTitle->getNamespace() );
+ $found = true;
+ }

			if ( $mwNs->matchStartAndRemove( $part1 ) ) {
				if ( intval( $part1 ) || $part1 == "0" ) {
					$text = $linestart .

$wgContLang->getNsText( intval( $part1 ) );


attachment RS.patch ignored as obsolete

hokie99cpe+wiki wrote:

Updated for 1.7.1 (includes "your namespaces" in the sidebar)

Gah!!! Missed one line (in SpecialPreferences.php).

Attached:

hokie99cpe+wiki wrote:

For v.1.7.1 patches.

Decided to put the sidebar heading into the database:

Create MediaWiki:Yournamespaces with your heading.

Update to includes/Skin.php, line 1494:

  • $heading = 'your namespaces';

+ $heading = wfMsgForContent ('yournamespaces');

Dan

andi wrote:

I modified the restricted link feature. So with this changes it allows links
inside of the namespace group and not only the namespace as it was before.

includes/Parser.php

			if( $wgLinkWarn && is_array( $wgRestrictedNamespaces )) {
  • if( array_key_exists( $ns, $wgRestrictedNamespaces ) &&

($this->mTitle->getNamespace() != $ns)) {
+ if( array_key_exists( $ns, $wgRestrictedNamespaces ) &&
($this->mTitle->getNamespace() != $ns) && ($wgRestrictedNamespaces[$ns] !=
$wgRestrictedNamespaces[$this->mTitle->getNamespace()])) {

					$s .=wfMsg( 'restrlink' ). $trail;
					continue;
				}
			}

hokie99cpe+wiki wrote:

Andreas,

As the code existed prior to your changes, to enable linking into a restricted
namespace, you would set $wgLinkWarn = false; in LocalSettings.php. This would
allow those links.

Dan

andi wrote:

I know. But I would like this feature, but i also want to link to the discussion
pages etc.

Andi

hokie99cpe+wiki wrote:

Anyone else find that after these patches, you can't undelete?

We found the cause in User.php (line 1321). Special:Undelete is protected and
itself includes a call to isAllowed('delete'). Therefore, the updated
isAllowed() function fails. We have updated line 1321 to check for portected
pages other than Special:Undelete.

//If the user wants to delete or undelete a page and it's blocked don't allow

him to do so.

if( ($action == 'delete' || $action == 'undelete') &&
  ( ($title->isProtected() && !$title == "Special:Undelete" ) ||

$this->isBlocked()) ){

     return false;
}

Dan

andi wrote:

In our Wiki follow error occured:
Fatal error: Call to a member function on a non-object in
/webs/phpbb/root/www/phpbb.de/wiki/includes/SpecialWhatlinkshere.php on line 203

To fix this we did follow changes:

Modified: trunk/wiki/includes/SpecialWhatlinkshere.php

  • trunk/wiki/includes/SpecialWhatlinkshere.php (original)

+++ trunk/wiki/includes/SpecialWhatlinkshere.php Mon Jul 17 02:21:18 2006
@@ -73,7 +73,7 @@

    • @access private */ function showIndirectLinks( $level, $target, $limit, $from = 0, $dir = 'next' ) {
  • global $wgOut;

+ global $wgOut, $wgUser;

		$fname = 'WhatLinksHerePage::showIndirectLinks';

		$dbr =& wfGetDB( DB_READ );

andi wrote:

Oh I forgot:
Dan: Your undelete patch worked. The undelete function works now.

jwpolley wrote:

(In reply to comment #03)

You can not access the Special:Preferences page. To do that, I had to remove
the patch at line 377 in SpecialPreferences.php. This is not a problem with the
1.7.1 patch, but I have to use 1.6.x for a bit longer.

oooooooo8 wrote:

(In reply to comment #112)

(In reply to comment #108)
I've tried your workaround in a 1.5.6 installation and it work fine, but don't
work in a 1.6.7.
What version you are using?

I use 1.5.8 (with other patches). I won't upgrade for now because there are too
many changes.
I don't know if (in the patches for 1.6.x and 1.7.x) you can also see the
contents of a restricted page

including it in a non restricted page: {{:RestrictedNS:NameOfThePage}}

Octavi

joe.travaglini wrote:

Octavi -

You will always be able to trans(in)clude a "restricted" page because the page

isn't truly "restricted". These solutions are imperfect hacks. This applies to
1.6.x and 1.7.x and will to 1.8.x as well.

You will have to significantly modify the parser to handle the transclusion.

And even then, there will still be aways around the restriction hacks.

oooooooo8 wrote:

(In reply to comment #125)

Octavi -

You will always be able to trans(in)clude a "restricted" page because the page

isn't truly "restricted". These solutions are imperfect hacks. This applies to
1.6.x and 1.7.x and will to 1.8.x as well.

You will have to significantly modify the parser to handle the transclusion.

And even then, there will still be aways around the restriction hacks.

I don't agree with you. Of course it won't be perfect (all the software has
imperfections), but I think that this patch is near to perfection. And I think
that our purpose is to make it better. I only found this problem and I think
that you won't find any way to see restricted content without the right
permission (at least in version 1.5.x). In case you do, please write it here.
Thanks!

Octavi

didier.courtaud wrote:

The proposed patch does not work with MW 1.8.2 :

patch -p1 < ../RS.patch
patching file includes/CategoryPage.php
Hunk #1 succeeded at 210 with fuzz 2 (offset 103 lines).
patching file includes/DefaultSettings.php
Hunk #1 succeeded at 1747 (offset 54 lines).
patching file includes/Export.php
Hunk #1 succeeded at 256 (offset 19 lines).
Hunk #2 succeeded at 355 (offset 19 lines).
patching file includes/OutputPage.php
Hunk #2 FAILED at 776.
1 out of 2 hunks FAILED -- saving rejects to file includes/OutputPage.php.rej
patching file includes/Parser.php
Hunk #1 FAILED at 1508.
Hunk #2 FAILED at 2826.
2 out of 2 hunks FAILED -- saving rejects to file includes/Parser.php.rej
patching file includes/QueryPage.php
patching file includes/SearchEngine.php
Hunk #1 succeeded at 167 (offset 5 lines).
patching file includes/SpecialAllpages.php
patching file includes/SpecialContributions.php
patching file includes/SpecialLog.php
patching file includes/SpecialPreferences.php
Hunk #2 succeeded at 384 (offset 5 lines).
Hunk #3 FAILED at 394.
1 out of 3 hunks FAILED -- saving rejects to file
includes/SpecialPreferences.php.rej
patching file includes/SpecialRandompage.php
patching file includes/SpecialRecentchanges.php
patching file includes/SpecialRecentchangeslinked.php
patching file includes/SpecialUserlogin.php
Hunk #1 succeeded at 475 (offset 34 lines).
Hunk #2 succeeded at 485 (offset 34 lines).
patching file includes/SpecialWantedpages.php
patching file includes/SpecialWhatlinkshere.php
patching file includes/Title.php
Hunk #1 succeeded at 1026 (offset -4 lines).
Hunk #2 succeeded at 1137 (offset -3 lines).
Hunk #3 succeeded at 1151 (offset -3 lines).
patching file includes/User.php
Hunk #1 FAILED at 1237.
1 out of 1 hunk FAILED -- saving rejects to file includes/User.php.rej
patching file includes/Skin.php
Hunk #1 FAILED at 1445.
Hunk #2 succeeded at 1558 (offset 67 lines).
1 out of 2 hunks FAILED -- saving rejects to file includes/Skin.php.rej

Does anyone can publish a version compatible with MW 1.8.2

Didier

joseph wrote:

Updated for 2082 for 1.8.2

I updated for 1.8.2
I made very few changes

-#if( $this->canAccessNamespace($nsid) && !($nsid %2) ) {
+if( $this->canAccessNamespace($nsid) ) {
all I could see the %2 doing was removing odd numbered namespace ids from the
list. I could not imagine a reason to do that.

  1. altered the formatting of the restricted namespace list on the UserLogin

page.

  1. added a bunch of default rights to the sysop user. I had group user very

limitted and sysop couldn't do anything because it was expecting to inherit
some of its authority from user.

attachment tmp ignored as obsolete

robchur wrote:

Can future patches for this hack be maintained/distributed elsewhere? I ask
because each individual problem/notification clogs up the inboxes of people
who'd rather not receive the emails. In addition, using our bug tracker gives
off the false impressions that (a) this is going to make it into MediaWiki *some
time*, even though it's not, no matter how much Santa Claus begs, and (b) that
we're in some means affiliated with it.

I'm sure someone out there would be willing to host discussion like this for
what amounts to a major fork in aims and scope of MediaWiki.

joseph wrote:

I have fixed one bug and added 2 features to the patch for 1.8.2. Per Rob
Church's request above the current state of my version of the patch can be had at

<a
href="http://wiki.ontoserve.com/index.php/Namespace_Hack">http://wiki.ontoserve.com/index.php/Namespace_Hack</a>

ncante wrote:

Updated for 1.8.2 (two bugs fixed)

Attached:

levittben wrote:

*** Bug 8360 has been marked as a duplicate of this bug. ***

qsheets095 wrote:

Comment on attachment 2838
Updated for 1.8.2 (two bugs fixed)

diff -iEbdu -r ./includes/Article.php ./includes/Article.php

  • ./includes/Article.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/Article.php 2006-12-07 15:30:54.340034100 +0100
@@ -644,7 +644,6 @@

  1. If we got diff and oldid in the query, we want to see a
  2. diff page instead of the article. - if ( !is_null( $diff ) ) { $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );

diff -iEbdu -r ./includes/CategoryPage.php ./includes/CategoryPage.php

  • ./includes/CategoryPage.php 2006-11-21 16:36:14.472026700 +0100

+++ ./includes/CategoryPage.php 2006-12-07 15:22:52.721070900 +0100
@@ -175,6 +175,7 @@

	}

	function doCategoryQuery() {

+ global $wgUser;

		$dbr =& wfGetDB( DB_SLAVE );
		if( $this->from != '' ) {
			$pageCondition = 'cl_sortkey >= ' . $dbr->addQuotes( $this->from );

@@ -210,6 +211,11 @@

			$title = Title::makeTitle( $x->page_namespace, $x->page_title );

+ # If this page is inside a restricted namespace, skip the result...
+ if(!$wgUser->canAccessNamespace($title->getNamespace())) {
+ continue;
+ }
+

			if( $title->getNamespace() == NS_CATEGORY ) {
				$this->addSubcategory( $title, $x->cl_sortkey, $x->page_len );
			} elseif( $title->getNamespace() == NS_IMAGE ) {

diff -iEbdu -r ./includes/DefaultSettings.php ./includes/DefaultSettings.php

  • ./includes/DefaultSettings.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/DefaultSettings.php 2006-12-07 15:30:58.121429300 +0100
@@ -914,6 +914,13 @@
$wgGroupPermissions['bot' ]['autoconfirmed'] = true;

// Most extra permission abilities go to this group
+$wgGroupPermissions['sysop']['createpage'] = true;
+$wgGroupPermissions['sysop']['createtalk'] = true;
+$wgGroupPermissions['sysop']['read'] = true;
+$wgGroupPermissions['sysop']['edit'] = true;
+$wgGroupPermissions['sysop']['minoredit'] = true;
+$wgGroupPermissions['sysop']['roread'] = true;
+$wgGroupPermissions['sysop']['roedit'] = true;
$wgGroupPermissions['sysop']['block'] = true;
$wgGroupPermissions['sysop']['createaccount'] = true;
$wgGroupPermissions['sysop']['delete'] = true;
@@ -1747,6 +1754,96 @@
$wgExtraNamespaces = NULL;

/
+ * Hidden namespaces. If you include a namespace in this array, only users with
+ * the matching priviledges will be able to see and edit pages in this
+ * namespace.
+ *
+ * The form is " namespace => 'priviledge' " e.g.
+ *
+ * $wgRestrictedNamespaces =
+ * array(100 => 'coolguy',
+ * 101 => 'coolguy'
+ * );
+ *
+ * where 100 is the namespace id and 'coolguy' is the priviledge.
+ *
+ * Each priv. is a string in an array, you can add as many as you like
+ * in the $wgGroupPermitions array e.g.
+ *
+ *$wgGroupPermissions['allowed']['coolguy'] = true;
+ *
+ * In this example you asigned the 'coolguy' priviledge to the 'allowed' group.
+ *
+ */
+$wgRestrictedNamespaces = NULL;
+
+/

+ * In case you want only to deny the edit right on a namespace, you may put it
+ * in this array. You also need to asign the 'roread' right to the usergroup you
+ * want to be able to read and the 'roedit' right to the usergroup you want to be
+ * able to edit. Read only namespaces are not hiden (nor their logs etc).
+ *
+ * Example: $wgReadOnlyNSes = array(100,101);
+ *
+ */
+$wgReadOnlyNSes = NULL;
+
+/
+ * In case you have categories of pages located on a restricted namespaces
+ * those categories will appear empty and might be comfusing. Setting this
+ * var to true, (all) categories will be hidden in the Recent changes.
+ */
+$wgHideCategoriesinRC = false;
+
+/

+ * Logs in Recent Changes are treated all the same, so normaly users will be able
+ * to see moves, protects and deletes of pages in restricted namespaces. Setting
+ * this var to true will hide all logs in Recent Changes and only those for restricted
+ * namespaces in Special:Log.
+ */
+$wgHideLogs = false;
+
+/
+ * In case you want to customize what logs the user can see both in Recent Changes
+ * and Special:Log, modify this array to include the log types you want to hide. This is
+ * overriden by $wgHideLogs for Recent Changes and those logs for restricted
+ * namespaces in Special:Log. This feature lets you hide also the 'block' and 'rights'
+ * log types that are namespace independed in Special:Log, or show them in RC while
+ * hiding the rest.
+ *
+ * This example shows how to hide all log types in RC, and (block/rights) in Special:Log
+ * (the others in Special:Log are are filtered based on namespace access rights so they
+ * apply only for restricted namespaces).
+ *
+ *$wgHidenLogs = array('block','protect', 'rights', 'delete','upload', 'move');
+ */
+$wgHidenLogs = NULL;
+
+/

+ * In case some user tries to create a link from some namespace to an other restricted
+ * namespace, while the page gets parsed, instead of the link, a warning message will appear
+ * ('restrlink') to let the user know. If the link is in the same namespace as the edited page,
+ * no check will be done.
+ */
+$wgLinkWarn = true;
+
+/
+ * In case you want to hide logs about User Talk pages (namespace 3) fromnrecent changes
+ * set this to true.
+ *
+ */
+$wgHideUtalk = false;
+
+/

+ * You can use this array to alter wiki's upper left logo depending on the namespace
+ * you are in.
+ *
+ * Example:
+ * $wgNamespaceLogos = array ( 100 => '/url_path_to/logo.gif');
+ /
+$wgNamespaceLogos = NULL;
+
+/

  • Limit images on image description pages to a user-selectable limit. In order
  • to reduce disk usage, limits can only be selected from a list. This is the
  • list of settings the user can choose from:

diff -iEbdu -r ./includes/Export.php ./includes/Export.php

  • ./includes/Export.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/Export.php 2006-12-07 15:30:56.355736500 +0100
@@ -256,7 +256,13 @@

	 */
	function outputStream( $resultset ) {
		$last = null;

+ global $wgUser;

		while( $row = $resultset->fetchObject() ) {

+ #If page is in a secured namespace, skip the row.
+ if(!$wgUser->canAccessNamespace($row->page_namespace) ){
+ continue;
+ }
+

			if( is_null( $last ) ||
				$last->page_namespace != $row->page_namespace ||
				$last->page_title     != $row->page_title ) {

@@ -349,11 +355,14 @@

	}

	function namespaces() {
  • global $wgContLang;
  • $spaces = " <namespaces>\n";

+ global $wgContLang, $wgUser;
+ $spaces = "<namespaces>\n";

		foreach( $wgContLang->getFormattedNamespaces() as $ns => $title ) {

+ if($wgUser->canAccessNamespace($ns))
+ {

			$spaces .= '      ' . wfElement( 'namespace', array( 'key' => $ns ), $title ) . "\n";
		}

+ }

		$spaces .= "    </namespaces>";
		return $spaces;
	}

diff -iEbdu -r ./includes/OutputPage.php ./includes/OutputPage.php

  • ./includes/OutputPage.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/OutputPage.php 2006-12-07 15:30:56.636997300 +0100
@@ -236,7 +236,7 @@

		foreach ( $categories as $category => $arbitrary ) {
			$title = Title::makeTitleSafe( NS_CATEGORY, $category );
			$text = $wgContLang->convertHtml( $title->getText() );
  • $this->mCategoryLinks[] = $sk->makeLinkObj( $title, $text );

+ $this->mCategoryLinks[] = $sk->makeKnownLinkObj( $title, $text );

		}
	}

@@ -723,6 +723,7 @@

		$this->mBodytext = '';

		$groups = array();

+

		foreach( $wgGroupPermissions as $key => $value ) {
			if( isset( $value[$permission] ) && $value[$permission] == true ) {
				$groupName = User::getGroupName( $key );

@@ -777,6 +778,21 @@

		$skin = $wgUser->getSkin();

+ if($wgTitle->getNamespace() >= 100){
+ $usersNamespaces = $wgUser->getAllowedRNSes();
+ $usersNamespacesArray = explode("\n", $usersNamespaces);
+ $currentNamespace = Namespace::getCanonicalName($wgTitle->getNamespace());
+
+ if (!in_array($currentNamespace, $usersNamespacesArray)) {
+ $this->setPageTitle( wfMsg( 'noaccesstitle' ) );
+ $this->setHtmlTitle( wfMsg( 'errorpagetitle' ) );
+ $this->setRobotPolicy( 'noindex,nofollow' );
+ $this->setArticleFlag( false );
+ $this->addHTML( wfMsgHtml( 'noaccesstext') );
+ } else {
+ // Should never reach here.
+ }
+ } else {

		$this->setPageTitle( wfMsg( 'loginreqtitle' ) );
		$this->setHtmlTitle( wfMsg( 'errorpagetitle' ) );
		$this->setRobotPolicy( 'noindex,nofollow' );

@@ -793,6 +809,7 @@

		if( $mainPage->userCanRead() )
			$this->returnToMain( true, $mainPage );
	}

+ }

	/** @obsolete */
	function databaseError( $fname, $sql, $error, $errno ) {

diff -iEbdu -r ./includes/Parser.php ./includes/Parser.php

  • ./includes/Parser.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/Parser.php 2006-12-07 16:39:15.760002900 +0100
@@ -1463,6 +1463,7 @@

	 */
	function replaceInternalLinks( $s ) {
		global $wgContLang;

+ global $wgUser;

		static $fname = 'Parser::replaceInternalLinks' ;

		wfProfileIn( $fname );

@@ -1604,6 +1605,17 @@

			$ns = $nt->getNamespace();
			$iw = $nt->getInterWiki();

+
+ #If the link points to a restricted namespace outside the
+ #parent namespace warn the user.
+ global $wgRestrictedNamespaces, $wgLinkWarn ;
+ if( $wgLinkWarn && is_array( $wgRestrictedNamespaces )) {
+ if( array_key_exists( $ns, $wgRestrictedNamespaces ) && !$wgUser->canAccessNamespace( $ns )) {/*($this->mTitle->getNamespace() != $ns)) {*/
+ $s .=wfMsg( 'restrlink' ). $trail;
+ continue;
+ }
+ }
+

			wfProfileOut( "$fname-title" );
			
			if ($might_be_img) { # if this is actually an invalid link

@@ -2826,7 +2838,7 @@

    • @private */ function braceSubstitution( $piece ) {
  • global $wgContLang, $wgLang, $wgAllowDisplayTitle, $action;

+ global $wgContLang, $wgLang, $wgAllowDisplayTitle, $action, $wgRestrictedNamespaces;

		$fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
		wfProfileIn( $fname );
		wfProfileIn( __METHOD__.'-setup' );

@@ -2994,6 +3006,15 @@

				}

				if ( !$title->isExternal() ) {

+ # Articles from restricted namespaces can't be used in templates.
+ # They would appear or disappear based on the rights of the user
+ # that refreshes the cache...
+ if( is_array( $wgRestrictedNamespaces ) ) {
+ if( array_key_exists( $title->getNamespace(), $wgRestrictedNamespaces ) ) {
+ $found = true;
+ $text = $linestart . wfMsg( 'templatenotincluded' );
+ }
+ }

					if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html'] ) {
						$text = SpecialPage::capturePath( $title );
						if ( is_string( $text ) ) {

diff -iEbdu -r ./includes/QueryPage.php ./includes/QueryPage.php

  • ./includes/QueryPage.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/QueryPage.php 2006-12-07 15:30:58.355813300 +0100
@@ -474,8 +474,14 @@
class PageQueryPage extends QueryPage {

	function formatResult( $skin, $result ) {
  • global $wgContLang;

+ global $wgContLang, $wgUser;

		$nt = Title::makeTitle( $result->namespace, $result->title );

+
+ # Don't show wanted pages in restricted namespaces
+ if( !$wgUser->canAccessNamespace( $nt->getNamespace() ) ) {
+ return "";
+ }
+

		return $skin->makeKnownLinkObj( $nt, htmlspecialchars( $wgContLang->convert( $nt->getPrefixedText() ) ) );
	}

}
diff -iEbdu -r ./includes/SearchEngine.php ./includes/SearchEngine.php

  • ./includes/SearchEngine.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SearchEngine.php 2006-12-07 16:12:19.098684900 +0100
@@ -167,10 +167,10 @@

    • @access public */ function searchableNamespaces() {
  • global $wgContLang;

+ global $wgContLang, $wgUser;

		$arr = array();
		foreach( $wgContLang->getNamespaces() as $ns => $name ) {
  • if( $ns >= NS_MAIN ) {

+ if( $ns >= NS_MAIN && $wgUser->canAccessNamespace($ns)) {

				$arr[$ns] = $name;
			}
		}

diff -iEbdu -r ./includes/Skin.php ./includes/Skin.php

  • ./includes/Skin.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/Skin.php 2006-12-07 15:41:43.918198000 +0100
@@ -121,7 +121,6 @@

		include_once( "{$wgStyleDirectory}/{$skinName}.deps.php" );
		wfRestoreWarnings();
		require_once( "{$wgStyleDirectory}/{$skinName}.php" );
  • Check if we got if not failback to default skin $className = 'Skin'.$skinName; if( !class_exists( $className ) ) {

@@ -1511,11 +1510,22 @@

	 */
	function buildSidebar() {
		global $parserMemc, $wgEnableSidebarCache;
  • global $wgLang, $wgContLang;

+ global $wgLang, $wgContLang, $wgUser, $wgTitle;
+ global $wgExtraNamespaces, $wgRestrictedNamespaces;

		$fname = 'SkinTemplate::buildSidebar';

		wfProfileIn( $fname );

+ $nsname = '';
+ if(is_object($wgTitle))
+ {
+ $nsid = $wgTitle->getNamespace();
+ if(in_array($nsid, array_keys($wgExtraNamespaces)) &&
+ in_array($nsid, array_keys($wgRestrictedNamespaces)))
+ {
+ $nsname = $wgExtraNamespaces[$nsid].":";
+ }
+ }

		$key = wfMemcKey( 'sidebar' );
		$cacheSidebar = $wgEnableSidebarCache &&

@@ -1550,13 +1560,28 @@

					$href = self::makeInternalOrExternalUrl( $link );
					$bar[$heading][] = array(
						'text' => $text,
  • 'href' => $href,

+ 'href' => preg_replace('/Main_Page$/', $nsname."Main_Page", $href),

						'id' => 'n-' . strtr($line[1], ' ', '-'),
						'active' => false
					);
				} else { continue; }
			}
		}

+ $heading = 'your namespaces';
+ $lines = explode( "\n", $wgUser->getAllowedRNSes() );
+ if (count($lines) > 0 && $lines[0] != '') {
+ foreach ($lines as $line) {
+ $bar[$heading][] = array(
+ 'text' => $line,
+ 'href' => $this->makeInternalOrExternalUrl( $line . ':' . wfMsgForContent( 'mainpage' ) ),
+ 'id' => 'n-' . strtr($line, ' ', '-'),
+ 'active' => false
+ );
+ }
+ }
+

		if ($cacheSidebar)
			$cachednotice = $parserMemc->set( $key, $bar, 86400 );
		wfProfileOut( $fname );

diff -iEbdu -r ./includes/SkinTemplate.php ./includes/SkinTemplate.php

  • ./includes/SkinTemplate.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/SkinTemplate.php 2006-12-07 15:41:43.918198000 +0100
@@ -1076,7 +1076,12 @@

	 */

function text( $str ) {

  • echo htmlspecialchars( $this->data[$str] );

+ global $wgTitle, $wgNamespaceLogos;
+ if('logopath'==$str && isset($wgNamespaceLogos[$wgTitle->getNamespace()])) {
+ echo htmlspecialchars( $wgNamespaceLogos[$wgTitle->getNamespace()] );
+ } else {
+ echo htmlspecialchars( $this->data[$str] );
+ }
}

/**

  • @private

diff -iEbdu -r ./includes/SpecialAllpages.php ./includes/SpecialAllpages.php

  • ./includes/SpecialAllpages.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialAllpages.php 2006-12-07 15:21:46.970229300 +0100
@@ -10,17 +10,24 @@

    • @param $specialPage @see SpecialPage object. */ function wfSpecialAllpages( $par=NULL, $specialPage ) {
  • global $wgRequest, $wgOut, $wgContLang;

+ global $wgRequest, $wgOut, $wgContLang, $wgUser;

  1. GET values $from = $wgRequest->getVal( 'from' ); $namespace = $wgRequest->getInt( 'namespace' );

    $namespaces = $wgContLang->getNamespaces();

+ if ( isset($par) ) {
+ foreach ($namespaces as $ns_id => $ns_name) {
+ if ($par == $ns_name) {
+ $namespace = $ns_id;
+ }
+ }
+ }

	$indexPage = new SpecialAllpages();
  • if( !in_array($namespace, array_keys($namespaces)) )

+ if( !in_array($namespace, array_keys($namespaces)) || !$wgUser->canAccessNamespace( $namespace))

		$namespace = 0;

	$wgOut->setPagetitle( $namespace > 0 ?

@@ -28,9 +35,7 @@

		wfMsg( 'allarticles' )
		);
  • if ( isset($par) ) {
  • $indexPage->showChunk( $namespace, $par, $specialPage->including() );
  • } elseif ( isset($from) ) {

+ if ( isset($from) ) {

		$indexPage->showChunk( $namespace, $from, $specialPage->including() );
	} else {
		$indexPage->showToplevel ( $namespace, $specialPage->including() );

diff -iEbdu -r ./includes/SpecialContributions.php ./includes/SpecialContributions.php

  • ./includes/SpecialContributions.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialContributions.php 2006-12-07 15:30:56.136978100 +0100
@@ -16,7 +16,14 @@

	}

	function setNamespace( $ns ) {

+ global $wgUser;
+ # If the namespace asked is restricted return
+ # to the main namespace.
+ if($wgUser->canAccessNamespace($ns)) {

		$this->namespace = $ns;

+ }else{
+ $this->namespace = 0;
+ }

	}

	function setLimit( $limit ) {

@@ -72,15 +79,30 @@

	}

	function getNamespaceCond() {
  • if ( $this->namespace !== false )

+ global $wgUser;
+ # Include the namespace in the querry only if it's not restricted to the user.
+ if (($this->namespace !== false) && ($wgUser->canAccessNamespace($this->namespace))) {

			return ' AND page_namespace = ' . (int)$this->namespace;

+ } else {

		return '';
	}

+ }

	function getPreviousOffsetForPaging() {
		list( $index, $usercond ) = $this->getUserCond();
		$nscond = $this->getNamespaceCond();

+ # Exclude all namespaces that are restricted to this user
+ global $wgRestrictedNamespaces;
+ global $wgUser;
+ if( is_array( $wgRestrictedNamespaces )) {
+ foreach( $wgRestrictedNamespaces as $key => $value ) {
+ if( ! $wgUser->canAccessNamespace( $key )) {
+ $nscond .= ' AND page_namespace <>' . $key;
+ }
+ }
+ }
+

		$use_index = $this->dbr->useIndexClause( $index );
		extract( $this->dbr->tableNames( 'page', 'revision' ) );

@@ -137,6 +159,16 @@

			$offsetQuery = "AND rev_timestamp <= '{$this->offset}'";

		$nscond = $this->getNamespaceCond();

+ # Exclude all namespaces that are restricted to this user
+ global $wgRestrictedNamespaces;
+ global $wgUser;
+ if( is_array( $wgRestrictedNamespaces )) {
+ foreach( $wgRestrictedNamespaces as $key => $value ) {
+ if( ! $wgUser->canAccessNamespace( $key )) {
+ $nscond .= ' AND page_namespace <>' . $key;
+ }
+ }
+ }

		$use_index = $this->dbr->useIndexClause( $index );
		$sql = "SELECT
			page_namespace,page_title,page_is_new,page_latest,

diff -iEbdu -r ./includes/SpecialLog.php ./includes/SpecialLog.php

  • ./includes/SpecialLog.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/SpecialLog.php 2006-12-07 15:30:57.433902900 +0100
@@ -302,11 +302,42 @@

    • @private */ function logLine( $s ) {
  • global $wgLang;

+ global $wgLang, $wgUser;
+ global $wgHideLogs, $wgHidenLogs;

		$title = Title::makeTitle( $s->log_namespace, $s->log_title );
		$user = Title::makeTitleSafe( NS_USER, $s->user_name );
		$time = $wgLang->timeanddate( wfTimestamp(TS_MW, $s->log_timestamp), true );

+ # Hide all logs or the log types in $wgHidenLogs.
+ # Block and rights are namespace independed.
+ if((is_array($wgHidenLogs) &&
+ ((in_array('block', $wgHidenLogs) && $s->log_type =='block' )
+ ||(in_array('rights', $wgHidenLogs) && $s->log_type=='rights'))
+ ||($wgHideLogs && ($s->log_type=='block' ||$s->log_type=='rights')))){
+ return;
+ }
+
+ # Upload namespaces are public.
+ if(is_array($wgHidenLogs) &&
+ (in_array('upload', $wgHidenLogs) && $s->log_type=='upload') ||
+ ($wgHideLogs && $s->log_type=='upload')) {
+ return;
+ }
+
+ # We hide the rest only for the restricted namespaces.
+ if(!$wgUser->canAccessNamespace($s->log_namespace)){
+ if($wgHideLogs){
+ return;
+ }
+ if(is_array($wgHidenLogs)){
+ if((in_array('protect', $wgHidenLogs) && $s->log_type=='protect')
+ ||(in_array('delete', $wgHidenLogs) && $s->log_type=='delete')
+ ||(in_array('move', $wgHidenLogs) && $s->log_type=='move')){
+ return;
+ }
+ }
+ }
+

		// Enter the existence or non-existence of this page into the link cache,
		// for faster makeLinkObj() in LogPage::actionText()
		$linkCache =& LinkCache::singleton();

diff -iEbdu -r ./includes/SpecialPreferences.php ./includes/SpecialPreferences.php

  • ./includes/SpecialPreferences.php 2006-12-07 11:51:17.164600800 +0100

+++ ./includes/SpecialPreferences.php 2006-12-07 15:30:57.730789300 +0100
@@ -88,7 +88,7 @@

		if ( $this->mPosted ) {
			$namespaces = $wgContLang->getNamespaces();
			foreach ( $namespaces as $i => $namespace ) {
  • if ( $i >= 0 ) {

+ if ( $i >= 0 && $wgUser->canAccessNamespace( $i) ) {

					$this->mSearchNs[$i] = $request->getCheck( "wpNs$i" ) ? 1 : 0;
				}
			}

@@ -384,7 +384,7 @@

		$namespaces = $wgContLang->getNamespaces();
		foreach ( $namespaces as $i => $namespace ) {
  • if ( $i >= NS_MAIN ) {

+ if ( $i >= NS_MAIN && $wgUser->canAccessNamespace( $i) ) {

				$this->mSearchNs[$i] = $wgUser->getOption( 'searchNs'.$i );
			}
		}

@@ -394,14 +394,14 @@

    • @access private */ function namespacesCheckboxes() {
  • global $wgContLang;

+ global $wgContLang, $wgUser;

    1. Determine namespace checkboxes $namespaces = $wgContLang->getNamespaces(); $r1 = null;

      foreach ( $namespaces as $i => $name ) {
  • if ($i < 0)

+ if ($i < 0 || !$wgUser->canAccessNamespace( $i) )

				continue;
			$checked = $this->mSearchNs[$i] ? "checked='checked'" : '';
			$name = str_replace( '_', ' ', $namespaces[$i] );

diff -iEbdu -r ./includes/SpecialRandompage.php ./includes/SpecialRandompage.php

  • ./includes/SpecialRandompage.php 2006-10-14 02:06:36.000000000 +0200

+++ ./includes/SpecialRandompage.php 2006-12-07 15:30:59.058965300 +0100
@@ -11,12 +11,15 @@

    • used as e.g. Special:Randompage/Category */ function wfSpecialRandompage( $par = NS_MAIN ) {
  • global $wgOut, $wgExtraRandompageSQL, $wgContLang, $wgLang;

+ global $wgOut, $wgExtraRandompageSQL, $wgContLang, $wgLang, $wgUser;

	$fname = 'wfSpecialRandompage';

	# Determine namespace
	$t = Title::newFromText ( $par . ":Dummy" ) ;
	$namespace = $t->getNamespace () ;

+ if ($namespace === false || $namespace < NS_MAIN || !$wgUser->canAccessNamespace($namespace)) {
+ $namespace = NS_MAIN;
+ }

  1. NOTE! We use a literal constant in the SQL instead of the RAND()
  2. function because RAND() will return a different value for every row

diff -iEbdu -r ./includes/SpecialRecentchanges.php ./includes/SpecialRecentchanges.php

  • ./includes/SpecialRecentchanges.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialRecentchanges.php 2006-12-07 15:30:55.011934900 +0100
@@ -17,6 +17,7 @@

	global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol, $wgDBtype;
	global $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
	global $wgAllowCategorizedRecentChanges ;

+ global $wgRestrictedNamespaces, $wgHideCategoriesinRC, $wgHidenLogs, $wgHideLogs, $wgHideUtalk;

	$fname = 'wfSpecialRecentchanges';

	# Get query parameters

@@ -124,8 +125,9 @@

  1. Get last modified date, for client caching
  2. Don't use this if we are using the patrol feature, patrol changes don't update the timestamp

+ # Don't use it if there are hidden namespaces, as the feed must be different for the users

	$lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, $fname );
  • if ( $feedFormat || !$wgUseRCPatrol ) {

+ if ( !is_array( $wgRestrictedNamespaces ) && ($feedFormat || !$wgUseRCPatrol) ) {

		if( $lastmod && $wgOut->checkLastModified( $lastmod ) ){
			# Client cache fresh and headers sent, nothing more to do.
			return;

@@ -152,6 +154,32 @@

		}
	}

+ # Hide all categories if $wgHideCategoriesinRC is set
+ $hidem .= $wgHideCategoriesinRC ? ' AND rc_namespace <> 14':'';
+ # Hide all User_talk pages if $wgHideUtalk is set
+ $hidem .= $wgHideUtalk ? ' AND rc_namespace <> 3':'';
+ # Hide all logs if $wgHideRCLogs is set
+ $hidem .= $wgHideLogs ? ' AND rc_type <> 3':'';
+ # Hide all logs or the log types in $wgHidenLogs.
+ if(!$wgHideLogs && is_array($wgHidenLogs)){
+ # Block and rights are namespace independed.
+ $hidem .= in_array('block', $wgHidenLogs) ? ' AND rc_title <> "Log/block"':'';
+ $hidem .= in_array('rights', $wgHidenLogs) ? ' AND rc_title <> "Log/rights"':'';
+ # Hide the log types set in $wgHidenLogs
+ $hidem .= in_array('protect', $wgHidenLogs) ? ' AND rc_title <> "Log/protect"':'';
+ $hidem .= in_array('delete', $wgHidenLogs) ? ' AND rc_title <> "Log/delete"':'';
+ $hidem .= in_array('upload', $wgHidenLogs) ? ' AND rc_title <> "Log/upload"':'';
+ $hidem .= in_array('move', $wgHidenLogs) ? ' AND rc_title <> "Log/move"':'';
+ }
+ # Exclude all namespaces that are restricted to this user
+ if( is_array( $wgRestrictedNamespaces )) {
+ foreach( $wgRestrictedNamespaces as $key => $value ) {
+ if( ! $wgUser->canAccessNamespace( $key )) {
+ $hidem .= ' AND rc_namespace <>' . $key;
+ }
+ }
+ }
+

  1. Namespace filtering $hidem .= is_null( $namespace ) ? '' : ' AND rc_namespace' . ($invert ? '!=' : '=') . $namespace;

@@ -349,8 +377,13 @@

  • go ahead and use it even if there have been edits made
  • since it was rendered. This keeps a swarm of requests
  • from being too bad on a super-frequently edited wiki.

+ *
+ * Using restricted namespaces forbids caching the feed,
+ * however, since it must be rendered according to user
+ * rights.

		 */
  • if( time() - wfTimestamp( TS_UNIX, $feedLastmod )

+ if( !is_array( $wgRestrictedNamespaces )
+ && time() - wfTimestamp( TS_UNIX, $feedLastmod )

				< $wgFeedCacheTimeout
			|| wfTimestamp( TS_UNIX, $feedLastmod )
				> wfTimestamp( TS_UNIX, $lastmod ) ) {

diff -iEbdu -r ./includes/SpecialRecentchangeslinked.php ./includes/SpecialRecentchangeslinked.php

  • ./includes/SpecialRecentchangeslinked.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialRecentchangeslinked.php 2006-12-07 15:22:21.173792100 +0100
@@ -67,6 +67,16 @@

		$cmq = 'AND rc_minor=0';
	} else { $cmq = ''; }

+ # Exclude all namespaces that are restricted to this user
+ global $wgRestrictedNamespaces;
+ if( is_array( $wgRestrictedNamespaces )) {
+ foreach( $wgRestrictedNamespaces as $key => $value ) {
+ if( ! $wgUser->canAccessNamespace( $key )) {
+ $cmq .= ' AND page_namespace <>' . $key;
+ }
+ }
+ }
+

	extract( $dbr->tableNames( 'recentchanges', 'categorylinks', 'pagelinks', 'revision', 'page' , "watchlist" ) );

	$uid = $wgUser->getID();

diff -iEbdu -r ./includes/SpecialUserlogin.php ./includes/SpecialUserlogin.php

  • ./includes/SpecialUserlogin.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialUserlogin.php 2006-12-07 15:30:54.574418100 +0100
@@ -475,6 +475,7 @@

	function successfulLogin( $msg, $auto = true ) {
		global $wgUser;
		global $wgOut;

+ global $wgLinkWarn;

  1. Run any hooks; ignore results

@@ -484,12 +485,20 @@

		$wgOut->setRobotpolicy( 'noindex,nofollow' );
		$wgOut->setArticleRelated( false );
		$wgOut->addWikiText( $msg );

+ if($wgUser->getRMainPages() != NULL) {
+ # We are going to put some links to restricted namespaces
+ # that the user has access to, so we disable the warning.
+ $wgLinkWarn = false;
+ $wgOut->addWikiText(wfMsg('RNSlist')."<br>".str_replace( '_', ' ',$wgUser->getRMainPages()));
+ $wgOut->returnToMain(false);
+ } else {

		if ( !empty( $this->mReturnTo ) ) {
			$wgOut->returnToMain( $auto, $this->mReturnTo );
		} else {
			$wgOut->returnToMain( $auto );
		}
	}

+ }

	/** */
	function userNotPrivilegedMessage() {

diff -iEbdu -r ./includes/SpecialWantedpages.php ./includes/SpecialWantedpages.php

  • ./includes/SpecialWantedpages.php 2006-10-14 02:06:36.000000000 +0200

+++ ./includes/SpecialWantedpages.php 2006-12-07 15:30:58.871458100 +0100
@@ -67,10 +67,15 @@

	function formatResult( $skin, $result ) {
  • global $wgLang;

+ global $wgLang, $wgUser;

		$title = Title::makeTitleSafe( $result->namespace, $result->title );

+ # Don't show wanted pages in restricted namespaces
+ if( !$wgUser->canAccessNamespace( $title->getNamespace() ) ) {
+ return "";
+ }
+

		if( $this->isCached() ) {
			# Check existence; which is stored in the link cache
			if( !$title->exists() ) {

diff -iEbdu -r ./includes/SpecialWhatlinkshere.php ./includes/SpecialWhatlinkshere.php

  • ./includes/SpecialWhatlinkshere.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/SpecialWhatlinkshere.php 2006-12-07 15:30:54.761925300 +0100
@@ -73,7 +73,7 @@

    • @private */ function showIndirectLinks( $level, $target, $limit, $from = 0, $dir = 'next' ) {
  • global $wgOut;

+ global $wgOut, $wgUser;

		$fname = 'WhatLinksHerePage::showIndirectLinks';

		$dbr =& wfGetDB( DB_READ );

@@ -199,6 +199,11 @@

		$wgOut->addHTML( '<ul>' );
		foreach ( $rows as $row ) {

+ #If the linking page is located in a secured namespace, skip it.
+ if(!$wgUser->canAccessNamespace($row->page_namespace)) {
+ continue;
+ }
+

			$nt = Title::makeTitle( $row->page_namespace, $row->page_title );

			if ( $row->page_is_redirect ) {

diff -iEbdu -r ./includes/Title.php ./includes/Title.php

  • ./includes/Title.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/Title.php 2006-12-07 17:06:26.249622900 +0100
@@ -1026,6 +1026,10 @@

			wfProfileOut( $fname );
			return false;
		}

+ if( !$wgUser->canAccessNamespace( $this->mNamespace )) {
+ wfProfileOut( $fname );
+ return false;
+ }

		// XXX: This is the code that prevents unprotecting a page in NS_MEDIAWIKI
		// from taking effect -ævar
		if( NS_MEDIAWIKI == $this->mNamespace &&

@@ -1133,7 +1137,7 @@

			return $result;
		}
  • if( $wgUser->isAllowed('read') ) {

+ if( $wgUser->isAllowed('read', $this) ) {

			return true;
		} else {
			global $wgWhitelistRead;

@@ -1147,18 +1151,19 @@

			}

			/** some pages are explicitly allowed */

+ if( is_array( $wgWhitelistRead )) {

			$name = $this->getPrefixedText();
  • if( $wgWhitelistRead && in_array( $name, $wgWhitelistRead ) ) {

+ if( in_array( $name, $wgWhitelistRead ) ) {

				return true;
			}
    1. Compatibility with old settings
  • if( $wgWhitelistRead && $this->getNamespace() == NS_MAIN ) {

+ if( $this->getNamespace() == NS_MAIN ) {

				if( in_array( ':' . $name, $wgWhitelistRead ) ) {
					return true;
				}
			}
		}

+ }

		return false;
	}

diff -iEbdu -r ./includes/User.php ./includes/User.php

  • ./includes/User.php 2006-10-14 02:06:32.000000000 +0200

+++ ./includes/User.php 2006-12-07 15:30:54.011896500 +0100
@@ -871,6 +871,7 @@

			}

			$effectiveGroups = array_merge( $implicitGroups, $this->mGroups );

+

			$this->mRights = $this->getGroupPermissions( $effectiveGroups );
		}

@@ -1348,16 +1349,155 @@

    • @param string $action Action to be checked
    • @return boolean True: action is allowed, False: action should not be allowed */
  • function isAllowed($action='') {

+ function isAllowed($action='', $title=NULL) {
+ global $wgRestrictedNamespaces, $wgReadOnlyNSes;

		if ( $action === '' )
			// In the spirit of DWIM
			return true;

		$this->loadFromDatabase();

+ if( $title == NULL ) {
+ global $wgTitle;
+ $title = $wgTitle;
+ }
+ $ns = $title->getNamespace();
+
+ If user wants to read a page, that page is in a read only namespace
+
and the user has the 'roread' right, allow him to read it. If it has
+ the 'roedit' right allow him to edit it.
+ if( is_array($wgReadOnlyNSes)) {
+ if( $action == 'read' && in_array($ns, $wgReadOnlyNSes) &&
+ in_array('roread', $this->mRights) && !$this->isBlocked() ) {
+ return true;
+ }
+ if( $action == 'edit' && !$title->isProtected() &&
+ in_array($ns, $wgReadOnlyNSes) && in_array('roedit', $this->mRights) && !$this->isBlocked()) {
+ return true;
+ }
+ }
+
+
Prevent access to restricted namespaces if the user does not have all
+ required rights.
+ if( !$this->canAccessNamespace($ns) ) {
+ return false;
+ }
+
+
If we are in user's page, allow him to do everything...
+ if ( $action == 'edit' && ($ns == NS_USER_TALK || $ns == NS_USER) &&
+ $title->getText() == $this->getName() && !$this->isBlocked() && !$title->isProtected() ) {
+ return true;
+ }
+
+ if ( $action == 'protect' && ($ns == NS_USER_TALK || $ns == NS_USER) &&
+ $title->getText() == $this->getName() && !$this->isBlocked() ){
+ return true;
+ }
+
+ If user wants to edit a talk page and has the talk right, allow him to do so...
+ if( $title->isTalkPage() && $action == 'edit' && in_array('talk', $this->mRights) &&
+ !$this->isBlocked() && !$title->isProtected() ){
+ return true;
+ }
+
+
If user wants to leave a mesage on another's user talk page and that page is unprotected, allow him to do so...
+ if( $action == 'edit' && $ns == NS_USER_TALK && !$this->isBlocked() && !$title->isProtected() ){
+ return true;
+ }
+
+ If user has the sedit right, allow him to edit pages in the restricted namespaces
+
he has access.
+ if( is_array($wgRestrictedNamespaces) && array_key_exists($ns, $wgRestrictedNamespaces)
+ && $this->canAccessNamespace($ns) && !$this->isBlocked() ){
+ if( $action == 'edit' && in_array('sedit', $this->mRights) && !$title->isProtected() ) {
+ return true;
+ }
+
+ If user has the sprotect right, allow him to edit pages in the in the restricted namespaces
+
he has access.
+ if(($action == 'protect' || $action == 'unprotect') && in_array('sprotect', $this->mRights)) {
+ return true;
+ }
+
+ If user has the sdelete right, allow him to edit pages in the in the restricted namespaces
+
he has access.
+ if( !$title->isProtected() && ($action == 'delete' || $action == 'undelete') &&
+ (in_array('sdelete', $this->mRights)) ) {
+ return true;
+ }
+ }
+
+ If the user wants to delete or undelete a page and it's blocked don't allow him to do so.
+ if( ($action == 'delete' || $action == 'undelete') && ($title->isProtected() || $this->isBlocked()) ){
+ return false;
+ }
+
+
If the user wants to protect or unprotect a page and it's blocked don't allow him to do so.
+ if( ($action == 'protect' || $action == 'unprotect') && $this->isBlocked() ){
+ return false;
+ }
+

		return in_array( $action , $this->mRights );
	}

	/**

+ * Check if user is allowed to access a given namespace
+ * @param string $namespace ID of the namespace that needs to be checked.
+ * @return boolean True: access is allowed, False: access is denied
+ */
+ function canAccessNamespace( $namespace='' ) {
+ global $wgRestrictedNamespaces;
+ $this->loadFromDatabase();
+ if( is_array( $wgRestrictedNamespaces )) {
+ if( array_key_exists( $namespace, $wgRestrictedNamespaces ) ) {
+ if( in_array($wgRestrictedNamespaces[$namespace], $this->mRights)){
+ return true;
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /
+ * Get the restricted namespaces the user has access to (talk namespaces not included).
+ * @return string with the namespace names seperated by the "\n" character/
+ */
+ function getAllowedRNSes() {
+ global $wgRestrictedNamespaces;
+ $this->loadFromDatabase();
+ $names = NULL;
+ if( is_array( $wgRestrictedNamespaces ) ) {
+ foreach ($wgRestrictedNamespaces as $nsid => $ugroup) {
+ #if( $this->canAccessNamespace($nsid) && !($nsid %2) ) { #huh!?!? what the hell is the mod 2 about?
+ if( $this->canAccessNamespace($nsid) ) {
+ $names .= Namespace::getCanonicalName($nsid)."\n";
+ }
+ }
+ }
+ return $names;
+ }
+
+ /

+ * Get the main page title of each restricted namespace (talk namespaces not included)
+ * the user has access to.
+ * @return string: The titles seperated by the "\n" character.
+ */
+ function getRMainPages() {
+ global $wgRestrictedNamespaces;
+ $titles = NULL;
+ if( is_array( $wgRestrictedNamespaces ) ) {
+ $namespaces = $this->getAllowedRNSes();
+ $nsarray = explode("\n",$namespaces);
+ foreach ($nsarray as $index => $nsname) {
+ if($nsname != ""){
+ $titles .= "[[".$nsname.":".wfMsgForContent( 'mainpage' )."|".$nsname."]]"."<br/>\n";
+ }
+ }
+ }
+ return $titles;
+ }
+
+ /**

  • Load a skin if it doesn't exist or return it
  • @todo FIXME : need to check the old failback system [AV] */

@@ -1370,7 +1510,8 @@

  1. get the user skin $userSkin = $this->getOption( 'skin' ); $userSkin = $wgRequest->getVal('useskin', $userSkin); -

+ ini_set('display_errors', true);
+ ini_set('error_reporting', 2047);

			$this->mSkin =& Skin::newFromKey( $userSkin );
			wfProfileOut( $fname );
		}

diff -iEbdu -r ./includes/Wiki.php ./includes/Wiki.php

  • ./includes/Wiki.php 2006-10-14 02:06:34.000000000 +0200

+++ ./includes/Wiki.php 2006-12-07 15:30:56.855755700 +0100
@@ -331,7 +331,6 @@

			/* No such action; this will switch to the default case */
			$action = 'nosuchaction';
		}
  • switch( $action ) { case 'view': $output->setSquidMaxage( $this->getVal( 'SquidMaxage' ) );

diff -iEbdu -r ./languages/messages/MessagesEn.php ./languages/messages/MessagesEn.php

  • ./languages/messages/MessagesEn.php 2006-10-14 02:07:00.000000000 +0200

+++ ./languages/messages/MessagesEn.php 2006-12-07 15:30:59.512107700 +0100
@@ -1589,6 +1589,7 @@

  1. Namespace form on various pages 'namespace' => 'Namespace:', 'invert' => 'Invert selection',

+'RNSlist' => 'Available Namespaces',

  1. Contributions #

diff -iEbdu -r ./skins/CologneBlue.php ./skins/CologneBlue.php

  • ./skins/CologneBlue.php 2006-10-14 02:06:12.000000000 +0200

+++ ./skins/CologneBlue.php 2006-12-07 15:20:32.734904100 +0100
@@ -183,41 +183,43 @@

		$s .= $this->menuHead( "qbfind" );
		$s .= $this->searchForm();
  • $s .= $this->menuHead( "qbbrowse" );

+ #$s .= $this->menuHead( "qbbrowse" );

  • # Use the first heading from the Monobook sidebar as the "browse" section

+ # Use the first two headings from the Monobook sidebar as the "browse" section

		$bar = $this->buildSidebar();
  • $browseLinks = reset( $bar ); -

+ foreach($bar as $sectionTitle => $browseLinks)
+ {
+ $s .= $this->menuHeadText($sectionTitle);

		foreach ( $browseLinks as $link ) {
			if ( $link['text'] != '-' ) {
				$s .= "<a href=\"{$link['href']}\">" .
					htmlspecialchars( $link['text'] ) . '</a>' . $sep;
			}
		}

+ }

		if ( $wgOut->isArticle() ) {
  • $s .= $this->menuHead( "qbedit" );
  • $s .= "<strong>" . $this->editThisPage() . "</strong>"; -
  • $s .= $sep . $this->makeKnownLink( wfMsgForContent( "edithelppage" ), wfMsg( "edithelp" ) ); -
  • if( $wgUser->isLoggedIn() ) {
  • $s .= $sep . $this->moveThisPage();
  • }
  • if ( $wgUser->isAllowed('delete') ) {
  • $dtp = $this->deleteThisPage();
  • if ( "" != $dtp ) {
  • $s .= $sep . $dtp;
  • }
  • }
  • if ( $wgUser->isAllowed('protect') ) {
  • $ptp = $this->protectThisPage();
  • if ( "" != $ptp ) {
  • $s .= $sep . $ptp;
  • }
  • }
  • $s .= $sep;

+# $s .= $this->menuHead( "qbedit" );
+# $s .= "<strong>" . $this->editThisPage() . "</strong>";
+#
+# $s .= $sep . $this->makeKnownLink( wfMsgForContent( "edithelppage" ), wfMsg( "edithelp" ) );
+#
+# if( $wgUser->isLoggedIn() ) {
+# $s .= $sep . $this->moveThisPage();
+# }
+# if ( $wgUser->isAllowed('delete') ) {
+# $dtp = $this->deleteThisPage();
+# if ( "" != $dtp ) {
+# $s .= $sep . $dtp;
+# }
+# }
+# if ( $wgUser->isAllowed('protect') ) {
+# $ptp = $this->protectThisPage();
+# if ( "" != $ptp ) {
+# $s .= $sep . $ptp;
+# }
+# }
+# $s .= $sep;

			$s .= $this->menuHead( "qbpageoptions" );
			$s .= $this->talkLink()

@@ -295,6 +297,12 @@

		return $s;
	}

+ function menuHeadText( $text )
+ {
+ $s = "\n<h6>" . $text . "</h6>";
+ return $s;
+ }
+

	function searchForm( $label = "" )
	{
		global $wgRequest;

robchur wrote:

Please do *NOT* post future patches here, maintain them elsewhere. The above
comment is particularly irritating because it leaves a large, unwanted email in
the inboxes of people who are trying to monitor other, more important bugs.

qsheets095 wrote:

I'm sorry... I meant for it to attach itself to the last attachment since the
edit was so minor (SkinTemplate.php).

ezyang wrote:

Is there any particular reason why you nuked the CC list?

kristian wrote:

I am sorry for disturbing once again, hopefully it will be the last posting here.

Joseph Southwell and myself have made a SourceForge-project of this patch. It
can be found at

http://sourceforge.net/projects/hiddenwiki/

So far the latest patch only work for MediaWiki 1.8.2, but hopefully it will be
updated soon.

Anyone interested in joining as developers may feel free to send me an e-mail,
and I'll include you as soon as possible.

rotemliss wrote:

*Do not remove people from the CC list.* They will choose whether they would
like to get updates or not. Especially, *do not remove wikibugs-l@wikipedia.org
from the CC list*, as many people use it to get updates from all the bugs.

rotemliss wrote:

Changed Assigned field, sorry for the bug-spam.

jedgar wrote:

Will this mod be updated for MW 1.9? or does the status=closed(wontfix) mean that it's done?

Many thanks.

kristian wrote:

As mentioned in comment #137:

Check out http://sourceforge.net/projects/hiddenwiki/ for updates and new
releases for this patch, or if you want to contribute with the development.

Please post comments and requests there, and NOT here.

jedgar wrote:

My apologies. I didn't see 137. /jte