Index: includes/SpecialAllpages.php =================================================================== --- includes/SpecialAllpages.php (revision 13537) +++ includes/SpecialAllpages.php (working copy) @@ -19,7 +19,9 @@ $indexPage = new SpecialAllpages(); - if( !in_array($namespace, array_keys($namespaces)) ) + #If namespace does not exist or the user is not allowed to access it + #return him to the main namespace. + if( !in_array($namespace, array_keys($namespaces)) || !$wgUser->canAccessNamespace( $namespace)) $namespace = 0; $wgOut->setPagetitle( $namespace > 0 ? Index: includes/SpecialRecentchangeslinked.php =================================================================== --- includes/SpecialRecentchangeslinked.php (revision 13537) +++ includes/SpecialRecentchangeslinked.php (working copy) @@ -62,6 +62,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(); Index: includes/CategoryPage.php =================================================================== --- includes/CategoryPage.php (revision 13537) +++ includes/CategoryPage.php (working copy) @@ -115,6 +115,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 ) { // Subcategory; strip the 'Category' namespace from the link text. array_push( $children, $sk->makeKnownLinkObj( $title, $wgContLang->convertHtml( $title->getText() ) ) ); Index: includes/User.php =================================================================== --- includes/User.php (revision 13537) +++ includes/User.php (working copy) @@ -1171,18 +1171,159 @@ /** * Check if user is allowed to access a feature / make an action * @param string $action Action to be checked (see $wgAvailableRights in Defines.php for possible actions). + * @param string $title Title of the article (so we can check if it's namespace is restricted to the user). * @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) ) { + $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."]]"."
\n"; + } + } + } + return $titles; + } + + /** * Load a skin if it doesn't exist or return it * @todo FIXME : need to check the old failback system [AV] */ Index: includes/SpecialUserlogin.php =================================================================== --- includes/SpecialUserlogin.php (revision 13537) +++ includes/SpecialUserlogin.php (working copy) @@ -411,6 +411,7 @@ function successfulLogin( $msg, $auto = true ) { global $wgUser; global $wgOut; + global $wgLinkWarn; # Run any hooks; ignore results @@ -420,7 +421,18 @@ $wgOut->setRobotpolicy( 'noindex,nofollow' ); $wgOut->setArticleRelated( false ); $wgOut->addWikiText( $msg ); - $wgOut->returnToMain( $auto ); + + 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').str_replace( '_', ' ',$wgUser->getRMainPages())); + $wgOut->returnToMain(false); + }else{ + $wgOut->returnToMain( $auto ); + } } /** */ Index: includes/SpecialWhatlinkshere.php =================================================================== --- includes/SpecialWhatlinkshere.php (revision 13537) +++ includes/SpecialWhatlinkshere.php (working copy) @@ -199,6 +199,11 @@ $wgOut->addHTML( '