MarkAHershberger has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/398414 )

Change subject: [WIP] Update for extension registration
......................................................................

[WIP] Update for extension registration

Also fix what look like a couple of bugs

Change-Id: I7e0659872a273fc2026b9bf8d4c4e05f1338c381
---
D Lockdown.php
A extension.json
A src/Hook.php
3 files changed, 279 insertions(+), 223 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Lockdown 
refs/changes/14/398414/1

diff --git a/Lockdown.php b/Lockdown.php
deleted file mode 100644
index 9deef15..0000000
--- a/Lockdown.php
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-
-/**
- * Lockdown extension - implements restrictions on individual namespaces and 
special pages.
- *
- * @file
- * @ingroup Extensions
- * @author Daniel Kinzler, brightbyte.de
- * @copyright © 2007 Daniel Kinzler
- * @license GNU General Public Licence 2.0 or later
- */
-
-/*
-* WARNING: you can use this extension to deny read access to some namespaces. 
Keep in mind that this
-* may be circumvented in several ways. This extension doesn't try to
-* plug such holes. Also note that pages that are not readable will still be 
shown in listings,
-* such as the search page, categories, etc.
-*
-* Known ways to access "hidden" pages:
-* - transcluding as template. can be avoided using $wgNonincludableNamespaces.
-* Some search messages may reveal the page existance by producing links to it 
(MediaWiki:searchsubtitle,
-* MediaWiki:noexactmatch, MediaWiki:searchmenu-exists, 
MediaWiki:searchmenu-new...).
-* - supplying oldid=<revisionfromhiddenpage> may work in some versions of 
mediawiki. Same with diff, etc.
-*
-* NOTE: you cannot GRANT access to things forbidden by $wgGroupPermissions. 
You can only DENY access
-* granted there.
-*/
-
-if ( !defined( 'MEDIAWIKI' ) ) {
-       echo( "This file is an extension to the MediaWiki software and cannot 
be used standalone.\n" );
-       die( 1 );
-}
-
-$wgExtensionCredits['other'][] = array(
-       'path' => __FILE__,
-       'name' => 'Lockdown',
-       'author' => array(
-               'Daniel Kinzler',
-               'Platonides',
-               '...'
-       ),
-       'url' => 'https://mediawiki.org/wiki/Extension:Lockdown',
-       'descriptionmsg' => 'lockdown-desc',
-       'license-name' => 'GPL-2.0+'
-);
-
-$wgMessagesDirs['Lockdown'] = __DIR__ . '/i18n';
-
-$wgNamespacePermissionLockdown = array();
-$wgSpecialPageLockdown = array();
-$wgActionLockdown = array();
-
-$wgHooks['getUserPermissionsErrors'][] = 'lockdownUserPermissionsErrors';
-$wgHooks['MediaWikiPerformAction'][] = 'lockdownMediawikiPerformAction';
-$wgHooks['SearchableNamespaces'][] = 'lockdownSearchableNamespaces';
-$wgHooks['SearchGetNearMatchComplete'][] = 
'lockdownSearchGetNearMatchComplete';
-
-/**
- * @param Title $title
- * @param User $user
- * @param string $action
- * @param MessageSpecifier|array|string|bool|null $result
- * @return bool
- */
-function lockdownUserPermissionsErrors(
-       Title $title,
-       User $user,
-       $action,
-       &$result = null
-) {
-       global $wgNamespacePermissionLockdown, $wgSpecialPageLockdown, 
$wgWhitelistRead, $wgLang;
-
-       $result = null;
-
-       // don't impose extra restrictions on UI pages
-       if ( $title->isCssJsSubpage() ) {
-               return true;
-       }
-
-       if ( $action == 'read' && is_array( $wgWhitelistRead ) ) {
-               // don't impose read restrictions on whitelisted pages
-               if ( in_array( $title->getPrefixedText(), $wgWhitelistRead ) ) {
-                       return true;
-               }
-       }
-
-       $groups = null;
-       $ns = $title->getNamespace();
-       if ( NS_SPECIAL == $ns ) {
-               foreach ( $wgSpecialPageLockdown as $page => $g ) {
-                       if ( !$title->isSpecial( $page ) ) continue;
-                       $groups = $g;
-                       break;
-               }
-       }
-       else {
-               $groups = @$wgNamespacePermissionLockdown[$ns][$action];
-               if ( $groups === null ) {
-                       $groups = @$wgNamespacePermissionLockdown['*'][$action];
-               }
-               if ( $groups === null ) {
-                       $groups = @$wgNamespacePermissionLockdown[$ns]['*'];
-               }
-       }
-
-       if ( $groups === null ) {
-               #no restrictions
-               return true;
-       }
-
-       if ( !$groups ) {
-               #no groups allowed
-
-               $result = array(
-                       'badaccess-group0'
-               );
-
-               return false;
-       }
-
-       $ugroups = $user->getEffectiveGroups();
-
-       $match = array_intersect( $ugroups, $groups );
-
-       if ( $match ) {
-               # group is allowed - keep processing
-               $result = null;
-               return true;
-       } else {
-               # group is denied - abort
-               $groupLinks = array_map( array( 'User', 'makeGroupLinkWiki' ), 
$groups );
-
-               $result = array(
-                       'badaccess-groups',
-                       $wgLang->commaList( $groupLinks ),
-                       count( $groups )
-               );
-
-               return false;
-       }
-}
-
-function lockdownMediawikiPerformAction (
-       OutputPage $output,
-       Article $article,
-       Title $title,
-       User $user,
-       WebRequest $request,
-       MediaWiki $wiki
-) {
-       global $wgActionLockdown, $wgLang;
-
-       $action = $wiki->getAction();
-
-       if ( !isset( $wgActionLockdown[$action] ) ) {
-               return true;
-       }
-
-       $groups = $wgActionLockdown[$action];
-       if ( $groups === null ) {
-               return true;
-       }
-       if ( !$groups ) {
-               return false;
-       }
-
-       $ugroups = $user->getEffectiveGroups();
-       $match = array_intersect( $ugroups, $groups );
-
-       if ( $match ) {
-               return true;
-       } else {
-               $groupLinks = array_map( array( 'User', 'makeGroupLinkWiki' ), 
$groups );
-
-               $err = array( 'badaccess-groups', $wgLang->commaList( 
$groupLinks ), count( $groups ) );
-               throw new PermissionsError( $request->getVal('action'), array( 
$err ) );
-       }
-}
-
-function lockdownSearchableNamespaces( array &$searchableNs ) {
-       $user = RequestContext::getMain()->getUser();
-       $ugroups = $user->getEffectiveGroups();
-
-       foreach ( $searchableNs as $ns => $name ) {
-               if ( !lockdownNamespace( $ns, $ugroups ) ) {
-                       unset( $searchableNs[$ns] );
-               }
-       }
-       return true;
-}
-
-function lockdownNamespace( $ns, array $ugroups ) {
-       global $wgNamespacePermissionLockdown;
-
-       $groups = @$wgNamespacePermissionLockdown[$ns]['read'];
-       if ( $groups === null ) {
-               $groups = @$wgNamespacePermissionLockdown['*']['read'];
-       }
-       if ( $groups === null ) {
-               $groups = @$wgNamespacePermissionLockdown[$ns]['*'];
-       }
-
-       if ( $groups === null ) {
-               return false;
-       }
-
-       if ( !$groups || !array_intersect($ugroups, $groups) ) {
-               $title = null;
-               return false;
-       }
-
-       return true;
-}
-
-#Stop a Go search for a hidden title to send you to the login required page. 
Will show a no such page message instead.
-function lockdownSearchGetNearMatchComplete( $searchterm, Title $title = null 
) {
-       global $wgUser;
-
-       if ( $title ) {
-               $ugroups = $wgUser->getEffectiveGroups();
-               return lockdownNamespace( $title->getNamespace(), $ugroups );
-       }
-}
diff --git a/extension.json b/extension.json
new file mode 100644
index 0000000..6fa24f1
--- /dev/null
+++ b/extension.json
@@ -0,0 +1,36 @@
+{
+       "name": "Lockdown",
+       "author": [
+               "Daniel Kinzler",
+               "Platonides",
+               "Mark A. Hershberger",
+               "..."
+       ],
+       "url": "https://mediawiki.org/wiki/Extension:Lockdown";,
+       "descriptionmsg": "lockdown-desc",
+       "license-name": "GPL-2.0+",
+       "type": "other",
+       "MessagesDirs": {
+               "Lockdown": [
+                       "i18n"
+               ]
+       },
+       "Hooks": {
+               "getUserPermissionsErrors": 
"MediaWiki\\Extensions\\Lockdown\\Hook::onGetUserPermissionsErrors",
+               "MediaWikiPerformAction": 
"MediaWiki\\Extensions\\Lockdown\\Hook::onMediawikiPerformAction",
+               "SearchableNamespaces": 
"MediaWiki\\Extensions\\Lockdown\\Hook::onSearchableNamespaces",
+               "SearchGetNearMatchComplete": 
"MediaWiki\\Extensions\\Lockdown\\Hook::onSearchGetNearMatchComplete"
+       },
+       "config": {
+               "NamespacePermissionLockdown": {
+                       "value": []
+               },
+               "SpecialPageLockdown": {
+                       "value": []
+               },
+               "ActionLockdown": {
+                       "value": []
+               }
+       },
+       "manifest_version": 2
+}
diff --git a/src/Hook.php b/src/Hook.php
new file mode 100644
index 0000000..090bdf5
--- /dev/null
+++ b/src/Hook.php
@@ -0,0 +1,243 @@
+<?php
+/**
+ * Lockdown extension - implements restrictions on individual
+ * namespaces and special pages.
+ *
+ * Copyright (C) 2007, 2016  Daniel Kinzler
+ * Copyright (C) 2017  NicheWork, LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * @file
+ * @ingroup Extensions
+ * @author Daniel Kinzler, brightbyte.de
+ * @author Mark A. Hershberger <[email protected]>
+ * @license GNU General Public Licence 2.0 or later
+ */
+namespace MediaWiki\Extensions\Lockdown;
+
+/**
+ * Holds the hooks for the Lockdown extension.
+ */
+class Hook {
+
+       /**
+        * Fetch an appropriate permission error (or none!)
+        *
+        * @param Title $title being checked
+        * @param User $user whose access is being checked
+        * @param string $action being checked
+        * @param MessageSpecifier|array|string|bool|null &$result User
+        *   permissions error to add. If none, return true. $result can be
+        *   returned as a single error message key (string), or an array of
+        *   error message keys when multiple messages are needed
+        * @return bool
+        * @see 
https://www.mediawiki.org/wiki/Manual:Hooks/getUserPermissionsErrors
+        */
+       public static function onGetUserPermissionsErrors(
+               Title $title, User $user, $action, &$result = null
+       ) {
+               global $wgSpecialPageLockdown, $wgWhitelistRead, $wgLang;
+
+               $result = null;
+
+               // don't impose extra restrictions on UI pages
+               if ( $title->isCssJsSubpage() ) {
+                       return true;
+               }
+
+               if ( $action == 'read' && is_array( $wgWhitelistRead ) ) {
+                       // don't impose read restrictions on whitelisted pages
+                       if ( in_array( $title->getPrefixedText(), 
$wgWhitelistRead ) ) {
+                               return true;
+                       }
+               }
+
+               $groups = null;
+               $ns = $title->getNamespace();
+               if ( NS_SPECIAL == $ns ) {
+                       foreach ( $wgSpecialPageLockdown as $page => $g ) {
+                               if ( !$title->isSpecial( $page ) ) {
+                                       continue;
+                               }
+                               $groups = $g;
+                               break;
+                       }
+               } else {
+                       $groups = self::namespaceGroups( $ns, $action );
+               }
+
+               if ( $groups === null ) {
+                       # no restrictions
+                       return true;
+               }
+
+               if ( !$groups ) {
+                       # no groups allowed
+                       $result = [
+                               'badaccess-group0'
+                       ];
+
+                       return false;
+               }
+
+               $ugroups = $user->getEffectiveGroups();
+
+               $match = array_intersect( $ugroups, $groups );
+
+               if ( $match ) {
+                       # group is allowed - keep processing
+                       $result = null;
+                       return true;
+               } else {
+                       # group is denied - abort
+                       $groupLinks = array_map( [ 'User', 'makeGroupLinkWiki' 
], $groups );
+
+                       $result = [
+                               'badaccess-groups',
+                               $wgLang->commaList( $groupLinks ),
+                               count( $groups )
+                       ];
+
+                       return false;
+               }
+       }
+
+       /**
+        * See if the user is in an allowed group for this action
+        *
+        * @param OutputPage $output to use for output
+        * @param Article $article the article being acted on
+        * @param Title $title the title being acted on
+        * @param User $user who is trying this
+        * @param WebRequest $request to get any input
+        * @param MediaWiki $wiki for other info
+        * @return bool false if permission is denied
+        * @see 
https://www.mediawiki.org/wiki/Manual:Hooks/MediaWikiPerformAction
+        */
+       function onMediawikiPerformAction(
+               OutputPage $output, Article $article, Title $title, User $user, 
WebRequest $request,
+               MediaWiki $wiki
+       ) {
+               global $wgActionLockdown, $wgLang;
+
+               $action = $wiki->getAction();
+
+               if ( !isset( $wgActionLockdown[$action] ) ) {
+                       return true;
+               }
+
+               $groups = $wgActionLockdown[$action];
+               if ( $groups === null ) {
+                       return true;
+               }
+               if ( !$groups ) {
+                       return false;
+               }
+
+               $ugroups = $user->getEffectiveGroups();
+               $match = array_intersect( $ugroups, $groups );
+
+               if ( $match ) {
+                       return true;
+               } else {
+                       $groupLinks = array_map( [ 'User', 'makeGroupLinkWiki' 
], $groups );
+
+                       $err = [
+                               'badaccess-groups', $wgLang->commaList( 
$groupLinks ), count( $groups )
+                       ];
+                       throw new PermissionsError( $request->getVal( 'action' 
), [ $err ] );
+               }
+       }
+
+       /**
+        * Hide the namespaces that this user doesn't have permission to serch
+        *
+        * @param array &$searchableNs from which namespaces will be removed
+        * @see https://www.mediawiki.org/wiki/Manual:Hooks/SearchableNamespaces
+        */
+       public static function onSearchableNamespaces( array &$searchableNs ) {
+               $user = RequestContext::getMain()->getUser();
+               $ugroups = $user->getEffectiveGroups();
+
+               foreach ( $searchableNs as $ns => $name ) {
+                       if ( !self::namespaceCheck( $ns, $ugroups ) ) {
+                               unset( $searchableNs[$ns] );
+                       }
+               }
+       }
+
+       /**
+        * Get groups that this action is restricted to in this namespace.
+        *
+        * @param int $ns to check
+        * @param string $action to check (default: read)
+        * @return null|array of groups
+        */
+       protected static function namespaceGroups( $ns, $action = 'read' ) {
+               global $wgNamespacePermissionLockdown;
+
+               $groups = isset( $wgNamespacePermissionLockdown[$ns][$action] )
+                               ? $wgNamespacePermissionLockdown[$ns][$action]
+                               : null;
+               if ( $groups === null ) {
+                       $groups = isset( 
$wgNamespacePermissionLockdown['*'][$action] )
+                                       ? 
$wgNamespacePermissionLockdown['*'][$action]
+                                       : null;
+               }
+               if ( $groups === null ) {
+                       $groups = isset( 
$wgNamespacePermissionLockdown[$ns]['*'] )
+                                       ? 
$wgNamespacePermissionLockdown[$ns]['*']
+                                       : null;
+               }
+               return $groups;
+       }
+
+       /**
+        * Determine if this the user has the group to read this namespace
+        *
+        * @param int $ns to check
+        * @param array $ugroups that the user is in
+        * @return bool false if the user does not have permission
+        */
+       protected static function namespaceCheck( $ns, array $ugroups ) {
+               $groups = namespaceGroups( $ns );
+               if ( $groups && !array_intersect( $ugroups, $groups ) ) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Stop a Go search for a hidden title to send you to the login
+        * required page. Will show a no such page message instead.
+        *
+        * @param string $searchterm that the user is searching
+        * @param Title $title that the user would end up on
+        * @see 
https://www.mediawiki.org/wiki/Manual:Hooks/SearchGetNearMatchComplete
+        */
+       function onSearchGetNearMatchComplete( $searchterm, Title $title = null 
) {
+               global $wgUser;
+
+               if ( $title ) {
+                       $ugroups = $wgUser->getEffectiveGroups();
+                       if ( self::namespaceCheck( $title->getNamespace(), 
$ugroups ) ) {
+                               $title = null;
+                       }
+               }
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/398414
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I7e0659872a273fc2026b9bf8d4c4e05f1338c381
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Lockdown
Gerrit-Branch: master
Gerrit-Owner: MarkAHershberger <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to