FreedomFighterSparrow has uploaded a new change for review. https://gerrit.wikimedia.org/r/325281
Change subject: Convert to use "Extension Registration" (MW 1.25+) ...................................................................... Convert to use "Extension Registration" (MW 1.25+) https://www.mediawiki.org/wiki/Manual:Extension_registration#Migration_for_extension_developers Change-Id: I1d03c0c07e1094bed1e63c68ea3601f4afa3f626 --- D Lockdown.i18n.php D Lockdown.php A LockdownHooks.php M README A extension.json M install.settings 6 files changed, 257 insertions(+), 260 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Lockdown refs/changes/81/325281/1 diff --git a/Lockdown.i18n.php b/Lockdown.i18n.php deleted file mode 100644 index 816658b..0000000 --- a/Lockdown.i18n.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * This is a backwards-compatibility shim, generated by: - * https://git.wikimedia.org/blob/mediawiki%2Fcore.git/HEAD/maintenance%2FgenerateJsonI18n.php - * - * Beginning with MediaWiki 1.23, translation strings are stored in json files, - * and the EXTENSION.i18n.php file only exists to provide compatibility with - * older releases of MediaWiki. For more information about this migration, see: - * https://www.mediawiki.org/wiki/Requests_for_comment/Localisation_format - * - * This shim maintains compatibility back to MediaWiki 1.17. - */ -$messages = array(); -if ( !function_exists( 'wfJsonI18nShimc61c7aea6122cc77' ) ) { - function wfJsonI18nShimc61c7aea6122cc77( $cache, $code, &$cachedData ) { - $codeSequence = array_merge( array( $code ), $cachedData['fallbackSequence'] ); - foreach ( $codeSequence as $csCode ) { - $fileName = dirname( __FILE__ ) . "/i18n/$csCode.json"; - if ( is_readable( $fileName ) ) { - $data = FormatJson::decode( file_get_contents( $fileName ), true ); - foreach ( array_keys( $data ) as $key ) { - if ( $key === '' || $key[0] === '@' ) { - unset( $data[$key] ); - } - } - $cachedData['messages'] = array_merge( $data, $cachedData['messages'] ); - } - - $cachedData['deps'][] = new FileDependency( $fileName ); - } - return true; - } - - $GLOBALS['wgHooks']['LocalisationCacheRecache'][] = 'wfJsonI18nShimc61c7aea6122cc77'; -} diff --git a/Lockdown.php b/Lockdown.php deleted file mode 100644 index 3632364..0000000 --- a/Lockdown.php +++ /dev/null @@ -1,222 +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'; -$wgExtensionMessagesFiles['Lockdown'] = __DIR__ . '/Lockdown.i18n.php'; -$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/LockdownHooks.php b/LockdownHooks.php new file mode 100644 index 0000000..65064b0 --- /dev/null +++ b/LockdownHooks.php @@ -0,0 +1,217 @@ +<?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 + */ + +class LockdownHooks { + /** + * @param Title $title + * @param User $user + * @param string $action + * @param MessageSpecifier|array|string|bool|null $result + * + * @return bool + */ + public static function onGetUserPermissionsErrors( + 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(); + + // Check if this is a restricted special page + if ( NS_SPECIAL === $ns ) { + foreach ( $wgSpecialPageLockdown as $page => $g ) { + if ( !$title->isSpecial( $page ) ) { + continue; + } + $groups = $g; + break; + } + } else { + // Check for any restriction by action/namspace + + $hasNamespaceLock = isset( $wgNamespacePermissionLockdown[ $ns ] ); + $groups = $hasNamespaceLock ? $wgNamespacePermissionLockdown[ $ns ][ $action ] : null; + if ( $groups === null ) { + $groups = isset( $wgNamespacePermissionLockdown[ '*' ] ) ? $wgNamespacePermissionLockdown[ '*' ][ $action ] : null; + } + if ( $groups === null ) { + $groups = $hasNamespaceLock ? $wgNamespacePermissionLockdown[ $ns ][ '*' ] : null; + } + } + + 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; + } + } + + /** + * @param OutputPage $output + * @param Article $article + * @param Title $title + * @param User $user + * @param WebRequest $request + * @param MediaWiki $wiki + * + * @return bool + * @throws PermissionsError + */ + public static 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( array( 'User', 'makeGroupLinkWiki' ), $groups ); + + $err = array( 'badaccess-groups', $wgLang->commaList( $groupLinks ), count( $groups ) ); + throw new PermissionsError( $request->getVal( 'action' ), array( $err ) ); + } + } + + public static function onSearchableNamespaces( array &$searchableNs ) { + $user = RequestContext::getMain()->getUser(); + $ugroups = $user->getEffectiveGroups(); + + foreach ( $searchableNs as $ns => $name ) { + if ( !self::lockdownNamespace( $ns, $ugroups ) ) { + unset( $searchableNs[ $ns ] ); + } + } + + return true; + } + + /** + * @param $ns + * @param array $ugroups + * + * @return bool + */ + 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. + /** + * @param string $searchterm + * @param Title|null $title + * + * @return bool + */ + function onSearchGetNearMatchComplete( $searchterm, Title $title = null ) { + global $wgUser; + + if ( $title ) { + $ugroups = $wgUser->getEffectiveGroups(); + + return self::lockdownNamespace( $title->getNamespace(), $ugroups ); + } + + return true; + } +} diff --git a/README b/README index e7b7657..f2d58fd 100644 --- a/README +++ b/README @@ -22,7 +22,7 @@ * <http://www.mediawiki.org/wiki/Manual:$wgGroupPermissions> -== WARNING: restricting read access not fully possible == +== WARNING: fully restricting read access is probably impossible == Mediawiki is not designed to be a CMS, or to protect sensitive data. To the contrary, it was designed to be as open as possible. Thus it does @@ -62,7 +62,7 @@ MediaWiki installation. Then add the following lines to your LocalSettings.php file (near the end): - require_once( "$IP/extensions/Lockdown/Lockdown.php" ); + wfLoadExtension( 'Lockdown' ); $wgSpecialPageLockdown['Export'] = array('user'); diff --git a/extension.json b/extension.json new file mode 100644 index 0000000..e5f6f91 --- /dev/null +++ b/extension.json @@ -0,0 +1,37 @@ +{ + "name": "Lockdown", + "author": [ + "Daniel Kinzler", + "Platonides" + ], + "url": "https://mediawiki.org/wiki/Extension:Lockdown", + "descriptionmsg": "lockdown-desc", + "license-name": "GPL-2.0+", + "type": "other", + "MessagesDirs": { + "Lockdown": [ + "i18n" + ] + }, + "AutoloadClasses": { + "LockdownHooks": "LockdownHooks.php" + }, + "Hooks": { + "getUserPermissionsErrors": "LockdownHooks::onGetUserPermissionsErrors", + "MediaWikiPerformAction": "LockdownHooks::onMediawikiPerformAction", + "SearchableNamespaces": "LockdownHooks::onSearchableNamespaces", + "SearchGetNearMatchComplete": "LockdownHooks::onSearchGetNearMatchComplete" + }, + "config": { + "NamespacePermissionLockdown": { + "value": [] + }, + "SpecialPageLockdown": { + "value": [] + }, + "ActionLockdown": { + "value": [] + } + }, + "manifest_version": 2 +} diff --git a/install.settings b/install.settings index a489640..e17272c 100644 --- a/install.settings +++ b/install.settings @@ -1,4 +1,4 @@ -require_once( "{{path}}/Lockdown.php" ); +wfLoadExtension( 'Lockdown' ); # see Lockdown/README for instructions on configuration # -- To view, visit https://gerrit.wikimedia.org/r/325281 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1d03c0c07e1094bed1e63c68ea3601f4afa3f626 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Lockdown Gerrit-Branch: master Gerrit-Owner: FreedomFighterSparrow <freedomfighterspar...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits