http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90710

Revision: 90710
Author:   nad
Date:     2011-06-24 10:54:37 +0000 (Fri, 24 Jun 2011)
Log Message:
-----------
major changes to make it compatible with the new 1.17 LoadBalancer and LBFactory

Modified Paths:
--------------
    trunk/extensions/SimpleSecurity/SimpleSecurity.php
    trunk/extensions/SimpleSecurity/SimpleSecurity_body.php

Modified: trunk/extensions/SimpleSecurity/SimpleSecurity.php
===================================================================
--- trunk/extensions/SimpleSecurity/SimpleSecurity.php  2011-06-24 10:38:51 UTC 
(rev 90709)
+++ trunk/extensions/SimpleSecurity/SimpleSecurity.php  2011-06-24 10:54:37 UTC 
(rev 90710)
@@ -1,29 +1,29 @@
 <?php
+if( !defined( 'MEDIAWIKI' ) ) die( 'Not an entry point.' );
+if( version_compare( $wgVersion, '1.17.0' ) < 0 ) die( 'This version of 
SimpleSecurity is for MediaWiki 1.17 or greater, please install SimpleSecurity 
4.x which can be found at 
http://svn.organicdesign.co.nz/listing.php?repname=extensions' );
 /**
  * SimpleSecurity extension
  * - Extends the MediaWiki article protection to allow restricting viewing of 
article content
  * - Also adds #ifusercan and #ifgroup parser functions for rendering 
restriction-based content
  *
  * See http://www.mediawiki.org/Extension:SimpleSecurity for installation and 
usage details
- * See http://www.organicdesign.co.nz/Extension_talk:SimpleSecurity.php for 
development notes and disucssion
+ * See http://www.organicdesign.co.nz/Extension:SimpleSecurity.php for 
development notes and disucssion
  *
- * Version 4.0 - Oct 2007 - new version for modern MediaWiki's using 
DatabaseFetchHook
+ * Version 4.0 - Oct 2007 - new version for MediaWiki 1.12+ using 
DatabaseFetchHook
  * Version 4.1 - Jun 2008 - development funded for a slimmed down functional 
version
  * Version 4.2 - Aug 2008 - fattened up a bit again - $wgPageRestrictions and 
security info added in again
  * Version 4.3 - Mar 2009 - bug fixes and split out to separate class and i18n 
files
  * Version 4.5 - Sep 2010 - File security started again - by Josh Adams
+ * Version 5.0 - Jun 2011 - major changes to the DB hooking method to handle 
changes in MediaWiki 1.17
  *
  * @file
  * @ingroup Extensions
  * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad]
- * @copyright © 2007 Aran Dunkley
+ * @copyright © 2007-2011 Aran Dunkley
  * @license GNU General Public Licence 2.0 or later
  */
+define( 'SIMPLESECURITY_VERSION', '5.0.0, 2011-06-24' );
 
-if ( !defined( 'MEDIAWIKI' ) )                     die( 'Not an entry point.' 
);
-
-define( 'SIMPLESECURITY_VERSION', '4.5.1, 2010-10-16' );
-
 # Load the SimpleSecurity class and messages
 $dir = dirname( __FILE__ ) . '/';
 $wgExtensionMessagesFiles['SimpleSecurity'] = $dir . 'SimpleSecurity.i18n.php';
@@ -55,10 +55,9 @@
 # protection to apply to all instances of that record type
 $wgSecurityProtectRecords = true;
 
+# Don;t use the DB hook by default since it's voodoo
+if( !isset( $wgSecurityUseDBHook ) ) $wgSecurityUseDBHook = false;
 
-# Put SimpleSecurity's setup function before all others
-array_unshift( $wgExtensionFunctions, 'wfSetupSimpleSecurity' );
-
 $wgHooks['LanguageGetMagic'][] = 'wfSimpleSecurityLanguageGetMagic';
 $wgExtensionCredits['parserhook'][] = array(
        'path'        => __FILE__,
@@ -67,54 +66,16 @@
        'url'         => 
"http://www.mediawiki.org/wiki/Extension:SimpleSecurity";,
        'version'     => SIMPLESECURITY_VERSION,
        'descriptionmsg' => 'security-desc',
-
 );
-
 $wgHooks['MessagesPreLoad'][] = 'wfSimpleSecurityMessagesPreLoad';
 
-# SearchEngine is based on $wgDBtype so must be set before it gets changed to 
DatabaseSimpleSecurity
-# - this may be paranoid now since $wgDBtype is changed back after 
LoadBalancer has initialised
-SimpleSecurity::fixSearchType();
+# Instantiate the SimpleSecurity singleton now that the environment is prepared
+$wgSimpleSecurity = new SimpleSecurity();
 
-# If the database class already exists, add the DB hook now, otherwise wait 
until extension setup
-if ( !isset( $wgSecurityUseDBHook ) ) $wgSecurityUseDBHook = false;
-if ( $wgSecurityUseDBHook && class_exists( 'Database' ) ) 
wfSimpleSecurityDBHook();
+# If using the DBHook, apply it now (must be done from the root scope since it 
creates classes)
+if( $wgSecurityUseDBHook ) SimpleSecurity::applyDatabaseHook();
 
 /**
- * Hook into Database::query and Database::fetchObject of database instances
- * - this can't be executed from within a method because PHP doesn't like 
nested class definitions
- * - it needs an eval because the class statement isn't allowed to contain 
strings
- * - the hooks aren't called if $wgSimpleSecurity doesn't exist yet
- * - hooks are added in a sub-class of the database type specified in 
$wgDBtype called DatabaseSimpleSecurity
- * - $wgDBtype is changed so that new DB instances are based on the sub-class
- * - query method is overriden to ensure that old_id field is returned for all 
queries which read old_text field
- * - only SELECT statements are ever patched
- * - fetchObject method is overridden to validate row content based on old_id
- */
-function wfSimpleSecurityDBHook() {
-       global $wgDBtype, $wgSecurityUseDBHook, $wgOldDBtype;
-       $wgOldDBtype = $wgDBtype;
-       $oldClass = ucfirst( $wgDBtype );
-       $wgDBtype = 'SimpleSecurity';
-       eval( "class Database{$wgDBtype} extends Database{$oldClass}" . ' {
-               public function query($sql, $fname = "", $tempIgnore = false) {
-                       global $wgSimpleSecurity;
-                       $count = false;
-                       if (is_object($wgSimpleSecurity))
-                               $patched = preg_replace_callback("/(?<=SELECT 
).+?(?= FROM)/", array("SimpleSecurity", "patchSQL"), $sql, 1, $count);
-                       return parent::query($count ? $patched : $sql, $fname, 
$tempIgnore);
-               }
-               function fetchObject($res) {
-                       global $wgSimpleSecurity;
-                       $row = parent::fetchObject($res);
-                       if (is_object($wgSimpleSecurity) && 
isset($row->old_text)) $wgSimpleSecurity->validateRow($row);
-                       return $row;
-               }
-       }' );
-       $wgSecurityUseDBHook = false;
-}
-
-/**
  * Register magic words
  */
 function wfSimpleSecurityLanguageGetMagic( &$magicWords, $langCode = 0 ) {
@@ -127,34 +88,34 @@
 function wfSimpleSecurityMessagesPreLoad( $title, &$text ) {
        global $wgSecurityExtraActions, $wgSecurityExtraGroups;
 
-       if ( substr( $title, 0, 12 ) == 'Restriction-' ) {
+       if( substr( $title, 0, 12 ) == 'Restriction-' ) {
                $key = substr( $title, 12 );
-               if ( isset( $wgSecurityExtraActions[$key] ) ) {
+               if( isset( $wgSecurityExtraActions[$key] ) ) {
                        $text = empty( $wgSecurityExtraActions[$key] ) ? 
ucfirst( $key ) : $wgSecurityExtraActions[$key];
                }
                return true;
-       } elseif ( substr( $title, 0, 14 ) == 'Protect-level-' ) {
+       } elseif( substr( $title, 0, 14 ) == 'Protect-level-' ) {
                $key = substr( $title, 14 );
                $type = 'level';
-       } elseif ( substr( $title, 0, 6 ) == 'Right-' ) {
+       } elseif( substr( $title, 0, 6 ) == 'Right-' ) {
                $key = substr( $title, 6 );
                $type = 'right';
        } else {
                return true;
        }
 
-       if ( isset( $wgSecurityExtraGroups[$key] ) ) {
+       if( isset( $wgSecurityExtraGroups[$key] ) ) {
                $name = empty( $wgSecurityExtraGroups[$key] ) ? ucfirst( $key ) 
: $wgSecurityExtraGroups[$key]; 
        } else {
                $lower = array_map( 'strtolower', $wgSecurityExtraGroups );
                $nkey = array_search( strtolower( $key ), $lower, true );
-               if ( !is_numeric( $nkey ) ) {
+               if( !is_numeric( $nkey ) ) {
                        return true;
                }
                $name = ucfirst( $wgSecurityExtraGroups[$nkey] );
        }
 
-       if ( $type == 'level' ) {
+       if( $type == 'level' ) {
                $text = $name;
        } else {
                $text = wfMsg( 'security-restricttogroup', $name );
@@ -163,28 +124,4 @@
        return true;
 }
 
-/**
- * Called from $wgExtensionFunctions array when initialising extensions
- */
-function wfSetupSimpleSecurity() {
-       global $wgSimpleSecurity, $wgSecurityUseDBHook,  $wgLoadBalancer, 
$wgDBtype, $wgOldDBtype;
 
-       # Instantiate the SimpleSecurity singleton now that the environment is 
prepared
-       $wgSimpleSecurity = new SimpleSecurity();
-
-       # If the DB hook couldn't be set up early, do it now
-       # - but now the LoadBalancer exists and must have its DB types changed
-       if ( $wgSecurityUseDBHook ) {
-               wfSimpleSecurityDBHook();
-               if ( function_exists( 'wfGetLBFactory' ) ) 
wfGetLBFactory()->forEachLB( array( 'SimpleSecurity', 'updateLB' ) );
-               elseif ( is_object( $wgLoadBalancer ) ) 
SimpleSecurity::updateLB( $wgLoadBalancer );
-               else die( "Can't hook in to Database class!" );
-       }
-
-       # Request a DB connection to ensure the LoadBalancer is initialised,
-       # then change back to old DBtype since it won't be used for making 
connections again but can affect other operations
-       # such as $wgContLang->stripForSearch which is called by 
SearchMySQL::parseQuery
-       wfGetDB( DB_MASTER );
-       $wgDBtype = $wgOldDBtype;
-}
-

Modified: trunk/extensions/SimpleSecurity/SimpleSecurity_body.php
===================================================================
--- trunk/extensions/SimpleSecurity/SimpleSecurity_body.php     2011-06-24 
10:38:51 UTC (rev 90709)
+++ trunk/extensions/SimpleSecurity/SimpleSecurity_body.php     2011-06-24 
10:54:37 UTC (rev 90710)
@@ -14,6 +14,13 @@
 
 
        function __construct() {
+               global $wgExtensionFunctions;
+
+               # Put SimpleSecurity's setup function before all others
+               array_unshift( $wgExtensionFunctions, array( $this, 'setup' ) );
+       }
+       
+       function setup() {
                global $wgParser, $wgHooks, $wgLogTypes, $wgLogNames, 
$wgLogHeaders, $wgLogActions,
                        $wgSecurityMagicIf, $wgSecurityMagicGroup, 
$wgSecurityExtraActions, $wgSecurityExtraGroups,
                        $wgRestrictionTypes, $wgRestrictionLevels, 
$wgGroupPermissions,
@@ -37,9 +44,7 @@
                $wgLogHeaders['security']      = 'securitylogpagetext';
                $wgLogActions['security/deny'] = 'securitylogentry';
 
-               # Load messages
-               
-
+               # Each extra action is also a restriction type
                foreach ( $wgSecurityExtraActions as $k => $v ) {
                        $wgRestrictionTypes[] = $k;
                }
@@ -68,6 +73,9 @@
                        $wgGroupPermissions[$k][$k] = true;      # members of 
$k must be allowed to perform $k
                        $wgGroupPermissions['sysop'][$k] = true; # sysops must 
be allowed to perform $k as well
                }
+
+               $db = &wfGetDB( DB_SLAVE );
+
        }
 
 
@@ -372,34 +380,103 @@
                }
        }
 
-
        /**
-        * Updates passed LoadBalancer's DB servers to secure class
+        * Add hooks into the database classes query() and fetchObject() methods
         */
-       static function updateLB( &$lb ) {
-               $lb->closeAll();
-               $serverCount = $lb->getServerCount(); 
-               for ( $i = 0; $i < $serverCount; $i++ ) {
-                       $server = $lb->getServerInfo( $i );
-                       $sever['type'] = 'SimpleSecurity';
-                       $lb->setServerInfo ( $i, $server );
+       static function applyDatabaseHook() {
+               global $wgDBtype, $wgLBFactoryConf;
+
+               # Create a new "Database_SimpleSecurity" database class with 
hooks into its query() and fetchObject() methods
+               # - hooks are added in a sub-class of the database type 
specified in $wgDBtype
+               # - query method is overriden to ensure that old_id field is 
returned for all queries which read old_text field
+               # - only SELECT statements are ever patched
+               # - fetchObject method is overridden to validate row content 
based on old_id
+               $oldClass = ucfirst( $wgDBtype );
+               eval( "class Database_SimpleSecurity extends 
Database{$oldClass}" . ' {
+                       public function query( $sql, $fname = "", $tempIgnore = 
false ) {
+                               $patched = preg_replace_callback( "/(?<=SELECT 
).+?(?= FROM)/", array("SimpleSecurity", "patchSQL"), $sql, 1 );
+                               return parent::query( $patched, $fname, 
$tempIgnore );
+                       }
+                       function fetchObject( $res ) {
+                               global $wgSimpleSecurity;
+                               $row = parent::fetchObject( $res );
+                               if( isset( $row->old_text ) ) 
$wgSimpleSecurity->validateRow( $row );
+                               return $row;
+                       }
+               }' );
+
+               # Make sure our new LBFactory is used which in turn uses our 
LoadBalancer and Database classes
+               $wgLBFactoryConf = array( 'class' => 'LBFactory_SimpleSecurity' 
);
+
+       }
+
+}
+
+/**
+ * Create a new class based on LoadBalancer which opens connections to our new 
hooked database class
+ */
+class LoadBalancer_SimpleSecurity extends LoadBalancer {
+
+       function reallyOpenConnection( $server, $dbNameOverride = false ) {
+               if( !is_array( $server ) ) {
+                       throw new MWException( 'You must update your 
load-balancing configuration. See DefaultSettings.php entry for $wgDBservers.' 
);
                }
+               $host = $server['host'];
+               $dbname = $server['dbname'];
+               if ( $dbNameOverride !== false ) {
+                       $server['dbname'] = $dbname = $dbNameOverride;
+               }
+               wfDebug( "Connecting to $host $dbname...\n" );
+               $db = new Database_SimpleSecurity(
+                       isset( $server['host'] ) ? $server['host'] : false,
+                       isset( $server['user'] ) ? $server['user'] : false,
+                       isset( $server['password'] ) ? $server['password'] : 
false,
+                       isset( $server['dbname'] ) ? $server['dbname'] : false,
+                       isset( $server['flags'] ) ? $server['flags'] : 0,
+                       isset( $server['tableprefix'] ) ? 
$server['tableprefix'] : 'get from global'
+               );
+               if ( $db->isOpen() ) {
+                       wfDebug( "Connected to $host $dbname.\n" );
+               } else {
+                       wfDebug( "Connection failed to $host $dbname.\n" );
+               }
+               $db->setLBInfo( $server );
+               if ( isset( $server['fakeSlaveLag'] ) ) {
+                       $db->setFakeSlaveLag( $server['fakeSlaveLag'] );
+               }
+               if ( isset( $server['fakeMaster'] ) ) {
+                       $db->setFakeMaster( true );
+               }
+               return $db;
        }
 
+}
 
-       /**
-        * Hack to ensure proper search class is used
-        * - $wgDBtype determines search class unless already defined in 
$wgSearchType
-        * - just copied method from SearchEngine::create()
-        */
-       static function fixSearchType() {
-               global $wgDBtype, $wgSearchType;
-               if ( $wgSearchType ) return;
-               elseif ( $wgDBtype == 'mysql' )    $wgSearchType = 
'SearchMySQL';
-               elseif ( $wgDBtype == 'postgres' ) $wgSearchType = 
'SearchPostgres';
-               elseif ( $wgDBtype == 'sqlite' )   $wgSearchType = 
'SearchSqlite';
-               elseif ( $wgDBtype == 'oracle' )   $wgSearchType = 
'SearchOracle';
-               elseif ( $wgDBtype == 'ibm_db2' )  $wgSearchType = 
'SearchIBM_DB2';
-               else                               $wgSearchType = 
'SearchEngineDummy';
+/**
+ * Create a new LBFactory class based on LBFactory_Simple which uses our new 
LoadBalancer class
+ */
+class LBFactory_SimpleSecurity extends LBFactory_Simple {
+
+       function newMainLB( $wiki = false ) {
+               global $wgDBservers, $wgMasterWaitTimeout;
+               if ( $wgDBservers ) {
+                       $servers = $wgDBservers;
+               } else {
+                       global $wgDBserver, $wgDBuser, $wgDBpassword, 
$wgDBname, $wgDBtype, $wgDebugDumpSql;
+                       $servers = array(array(
+                               'host' => $wgDBserver,
+                               'user' => $wgDBuser,
+                               'password' => $wgDBpassword,
+                               'dbname' => $wgDBname,
+                               'type' => $wgDBtype,
+                               'load' => 1,
+                               'flags' => ($wgDebugDumpSql ? DBO_DEBUG : 0) | 
DBO_DEFAULT
+                       ));
+               }
+               return new LoadBalancer_SimpleSecurity( array(
+                       'servers' => $servers,
+                       'masterWaitTimeout' => $wgMasterWaitTimeout
+               ));
        }
+
 }


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

Reply via email to