r38292 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r38291‎ | r38292 | r38293 >
Date:14:32, 31 July 2008
Author:vasilievvv
Status:old
Tags:
Comment:
* (bug 14556) Global groups defined for certain sets of wikis. Fixed with all bugs found by Brion + 1 logging bug
* Fix logging: rename 'groupperms2' => 'groupprms2', 'groupperms3' => 'groupprms3' (since log_action is max 10 chars)
Modified paths:
  • /trunk/extensions/CentralAuth/CentralAuth.i18n.php (modified) (history)
  • /trunk/extensions/CentralAuth/CentralAuth.php (modified) (history)
  • /trunk/extensions/CentralAuth/CentralAuthUser.php (modified) (history)
  • /trunk/extensions/CentralAuth/SpecialEditWikiSets.php (added) (history)
  • /trunk/extensions/CentralAuth/SpecialGlobalGroupPermissions.php (modified) (history)
  • /trunk/extensions/CentralAuth/WikiSet.php (added) (history)
  • /trunk/extensions/CentralAuth/central-auth.sql (modified) (history)
  • /trunk/extensions/CentralAuth/db_patches/patch-wikisets.sql (added) (history)

Diff [purge]

Index: trunk/extensions/CentralAuth/central-auth.sql
@@ -134,3 +134,33 @@
135135 KEY (ggp_group),
136136 KEY (ggp_permission)
137137 ) /*$wgDBTableOptions*/;
 138+
 139+-- Sets of wikis (for things like restricting global groups)
 140+-- May be defined in two ways: only specified wikis or all wikis except opt-outed
 141+CREATE TABLE wikiset (
 142+ -- ID of wikiset
 143+ ws_id int auto_increment,
 144+ -- Display name of wikiset
 145+ ws_name varchar(255) not null,
 146+ -- Type of set: opt-in or opt-out
 147+ ws_type enum ('optin', 'optout'),
 148+ -- Wikis in that set. Why isn't it a seperate table?
 149+ -- Because we can just use such simple list, we don't need complicated queries on it
 150+ -- Let's suppose that max length of db name is 31 (32 with ","), then we have space for
 151+ -- 2048 wikis. More than we need
 152+ ws_wikis blob not null,
 153+
 154+ PRIMARY KEY ws_id (ws_id),
 155+ UNIQUE ws_name (ws_name)
 156+) /*$wgDBTableOptions*/;
 157+
 158+-- Allow certain global groups to have their permissions only on certain wikis
 159+CREATE TABLE global_group_restrictions (
 160+ -- Group to restrict
 161+ ggr_group varchar(255) not null,
 162+ -- Wikiset to use
 163+ ggr_set int not null,
 164+
 165+ PRIMARY KEY (ggr_group),
 166+ KEY (ggr_set)
 167+) /*$wgDBTableOptions*/;
Index: trunk/extensions/CentralAuth/db_patches/patch-wikisets.sql
@@ -0,0 +1,29 @@
 2+-- Sets of wikis (for things like restricting global groups)
 3+-- May be defined in two ways: only specified wikis or all wikis except opt-outed
 4+CREATE TABLE wikiset (
 5+ -- ID of wikiset
 6+ ws_id int auto_increment,
 7+ -- Display name of wikiset
 8+ ws_name varchar(255) not null,
 9+ -- Type of set: opt-in or opt-out
 10+ ws_type enum ('optin', 'optout'),
 11+ -- Wikis in that set. Why isn't it a seperate table?
 12+ -- Because we can just use such simple list, we don't need complicated queries on it
 13+ -- Let's suppose that max length of db name is 31 (32 with ","), then we have space for
 14+ -- 2048 wikis. More than we need
 15+ ws_wikis blob not null,
 16+
 17+ PRIMARY KEY ws_id (ws_id),
 18+ UNIQUE ws_name (ws_name)
 19+) /*$wgDBTableOptions*/;
 20+
 21+-- Allow certain global groups to have their permissions only on certain wikis
 22+CREATE TABLE global_group_restrictions (
 23+ -- Group to restrict
 24+ ggr_group varchar(255) not null,
 25+ -- Wikiset to use
 26+ ggr_set int not null,
 27+
 28+ PRIMARY KEY (ggr_group),
 29+ KEY (ggr_set)
 30+) /*$wgDBTableOptions*/;
Index: trunk/extensions/CentralAuth/CentralAuthUser.php
@@ -18,7 +18,7 @@
1919 */
2020 /*private*/ var $mName;
2121 /*private*/ var $mStateDirty = false;
22 - /*private*/ var $mVersion = 1;
 22+ /*private*/ var $mVersion = 2;
2323 /*private*/ var $mDelayInvalidation = 0;
2424
2525 static $mCacheVars = array(
@@ -153,26 +153,40 @@
154154 return;
155155 }
156156 // We need the user id from the database, but this should be checked by the getId accessor.
157 -
 157+
158158 wfDebugLog( 'CentralAuth', "Loading groups for global user {$this->mName}" );
159 -
 159+
160160 $dbr = self::getCentralDB(); // We need the master.
161 -
 161+
162162 $res = $dbr->select(
163163 array( 'global_group_permissions', 'global_user_groups' ),
164164 array( 'ggp_permission', 'ggp_group' ),
165165 array( 'ggp_group=gug_group', 'gug_user' => $this->getId() ),
166 - __METHOD__ );
167 -
 166+ __METHOD__
 167+ );
 168+
 169+ $resSets = $dbr->select(
 170+ array( 'global_user_groups', 'global_group_restrictions', 'wikiset' ),
 171+ array( 'ggr_group', 'ws_id', 'ws_name', 'ws_type', 'ws_wikis' ),
 172+ array( 'ggr_group=gug_group', 'ggr_set=ws_id', 'gug_user' => $this->getId() ),
 173+ __METHOD__
 174+ );
 175+
 176+ $sets = array();
 177+ while( $row = $dbr->fetchObject( $resSets ) ) {
 178+ $sets[$row->ggr_group] = WikiSet::newFromRow( $row );
 179+ }
 180+
168181 // Grab the user's rights/groups.
169182 $rights = array();
170183 $groups = array();
171 -
172 - while ($row = $dbr->fetchObject( $res ) ) {
173 - $rights[] = $row->ggp_permission;
 184+
 185+ while( $row = $dbr->fetchObject( $res ) ) {
 186+ $set = @$sets[$row->ggp_group];
 187+ $rights[] = array( 'right' => $row->ggp_permission, 'set' => $set ? $set->getID() : false );
174188 $groups[$row->ggp_group] = 1;
175189 }
176 -
 190+
177191 $this->mRights = $rights;
178192 $this->mGroups = array_keys($groups);
179193 }
@@ -1620,7 +1634,18 @@
16211635 function getGlobalRights() {
16221636 $this->loadGroups();
16231637
1624 - return $this->mRights;
 1638+ $rights = array();
 1639+ $sets = array();
 1640+ foreach( $this->mRights as $right ) {
 1641+ if( $right['set'] ) {
 1642+ $set = isset( $sets[$right['set']] ) ? $sets[$right['set']] : WikiSet::newFromID( $right['set'] );
 1643+ if( $set->inSet() )
 1644+ $rights[] = $right['right'];
 1645+ } else {
 1646+ $rights[] = $right['right'];
 1647+ }
 1648+ }
 1649+ return $rights;
16251650 }
16261651
16271652 function removeFromGlobalGroups( $groups ) {
Index: trunk/extensions/CentralAuth/SpecialEditWikiSets.php
@@ -0,0 +1,213 @@
 2+<?php
 3+/**
 4+ * Special page to allow managing global groups
 5+ * Prototype for a similar system in core.
 6+ *
 7+ * @addtogroup Extensions
 8+ */
 9+
 10+if ( !defined( 'MEDIAWIKI' ) ) {
 11+ echo "CentralAuth extension\n";
 12+ exit( 1 );
 13+}
 14+
 15+
 16+class SpecialEditWikiSets extends SpecialPage
 17+{
 18+ function __construct() {
 19+ parent::__construct('EditWikiSets', 'globalgrouppermissions');
 20+ wfLoadExtensionMessages('SpecialCentralAuth');
 21+ }
 22+
 23+ function getDescription() {
 24+ return wfMsg( 'centralauth-editset' );
 25+ }
 26+
 27+ function userCanExecute($user) {
 28+ $globalUser = CentralAuthUser::getInstance( $user );
 29+
 30+ ## Should be a global user
 31+ if (!$globalUser->exists() || !$globalUser->isAttached()) {
 32+ return false;
 33+ }
 34+
 35+ ## Permission MUST be gained from global rights.
 36+ return $globalUser->hasGlobalPermission( 'globalgrouppermissions' );
 37+ }
 38+
 39+ function execute( $subpage ) {
 40+ global $wgRequest, $wgOut, $wgUser;
 41+
 42+ if( !$this->userCanExecute( $wgUser ) ) {
 43+ $this->displayRestrictionError();
 44+ return;
 45+ }
 46+
 47+ $this->setHeaders();
 48+
 49+ if( $subpage && !is_numeric( $subpage ) ) {
 50+ $set = WikiSet::newFromName( $subpage );
 51+ if( $set ) {
 52+ $subpage = $set->getID();
 53+ } else {
 54+ $wgOut->setPageTitle( wfMsg( 'error' ) );
 55+ $error = wfMsgExt( 'centralauth-editset-notfound', array( 'escapenoentities' ), $subpage );
 56+ $this->buildMainView( "<strong class='error'>{$error}</strong>" );
 57+ return;
 58+ }
 59+ }
 60+
 61+ if( ( $subpage || $subpage === '0' ) && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
 62+ $this->doSubmit( $subpage );
 63+ } else if( ( $subpage || $subpage === '0' ) && is_numeric( $subpage ) ) {
 64+ $this->buildSetView( $subpage );
 65+ } else {
 66+ $this->buildMainView();
 67+ }
 68+ }
 69+
 70+ function buildMainView( $msg = '' ) {
 71+ global $wgOut, $wgScript, $wgUser;
 72+ $sk = $wgUser->getSkin();
 73+
 74+ $legend = wfMsg( 'centralauth-editset-legend' );
 75+ $wgOut->addHtml( "<fieldset><legend>{$legend}</legend>" );
 76+ if( $msg )
 77+ $wgOut->addHTML( $msg );
 78+ $wgOut->addWikiMsg( 'centralauth-editset-intro' );
 79+ $wgOut->addHTML( '<ul>' );
 80+
 81+ $sets = WikiSet::getAllWikiSets();
 82+ foreach( $sets as $set ) {
 83+ $text = wfMsgExt( 'centralauth-editset-item', array( 'parseinline' ), $set->getName(), $set->getID() );
 84+ $wgOut->addHTML( "<li>{$text}</li>" );
 85+ }
 86+
 87+ $target = SpecialPage::getTitleFor( 'EditWikiSets', '0' );
 88+ $newlink = $sk->makeLinkObj( $target, wfMsgHtml( 'centralauth-editset-new' ) );
 89+ $wgOut->addHTML( "<li>{$newlink}</li>" );
 90+
 91+ $wgOut->addHtml( '</ul></fieldset>' );
 92+ }
 93+
 94+ function buildSetView( $subpage, $error = false, $name = null, $type = null, $wikis = null, $reason = null ) {
 95+ global $wgOut, $wgUser;
 96+
 97+ $set = $subpage ? WikiSet::newFromID( $subpage ) : null;
 98+ if( !$name ) $name = $set ? $set->getName() : '';
 99+ if( !$type ) $type = $set ? $set->getType() : WikiSet::OPTIN;
 100+ if( !$wikis ) $wikis = implode( "\n", $set ? $set->getWikisRaw() : array() );
 101+ else $wikis = implode( "\n", $wikis );
 102+ $url = SpecialPage::getTitleFor( 'EditWikiSets', $subpage )->getLocalUrl();
 103+ $legend = wfMsgHtml( 'centralauth-editset-legend-' . ($set ? 'edit' : 'new'), $name );
 104+
 105+ $wgOut->addHTML( "<fieldset><legend>{$legend}</legend>" );
 106+ if( $error )
 107+ $wgOut->addHTML( "<strong class='error'>{$error}</strong>" );
 108+ $wgOut->addHTML( "<form action='{$url}' method='post'>" );
 109+
 110+ if( $set ) {
 111+ $groups = $set->getRestrictedGroups();
 112+ if ( $groups ) {
 113+ $usage = "<ul>\n";
 114+ foreach( $groups as $group )
 115+ $usage .= "<li>" . wfMsgExt( 'centralauth-editset-grouplink', array('parseinline'), $group ) . "</li>\n";
 116+ $usage .= "</ul>";
 117+ } else {
 118+ $usage = wfMsgWikiHtml('centralauth-editset-nouse');
 119+ }
 120+ } else {
 121+ $usage = '';
 122+ }
 123+
 124+ $form = array();
 125+ $form['centralauth-editset-name'] = Xml::input( 'wpName', false, $name );
 126+ if( $usage )
 127+ $form['centralauth-editset-usage'] = $usage;
 128+ $form['centralauth-editset-type'] = $this->buildTypeSelector( 'wpType', $type );
 129+ $form['centralauth-editset-wikis'] = Xml::textarea( 'wpWikis', $wikis );
 130+ $form['centralauth-editset-reason'] = Xml::input( 'wpReason', false, $reason );
 131+
 132+ $wgOut->addHTML( Xml::buildForm( $form, 'centralauth-editset-submit' ) );
 133+
 134+ $edittoken = Xml::hidden( 'wpEditToken', $wgUser->editToken() );
 135+ $wgOut->addHTML( "<p>{$edittoken}</p></form></fieldset>" );
 136+ }
 137+
 138+ function buildTypeSelector( $name, $value ) {
 139+ $select = new XmlSelect( $name, 'set-type', $value );
 140+ foreach( array( WikiSet::OPTIN, WikiSet::OPTOUT ) as $type )
 141+ $select->addOption( wfMsg( "centralauth-editset-{$type}" ), $type );
 142+ return $select->getHTML();
 143+ }
 144+
 145+ function doSubmit( $id ) {
 146+ global $wgRequest, $wgContLang;
 147+
 148+ $name = $wgContLang->ucfirst( $wgRequest->getVal( 'wpName' ) );
 149+ $type = $wgRequest->getVal( 'wpType' );
 150+ $wikis = array_unique( preg_split( '/(\s+|\s*\W\s*)/', $wgRequest->getVal( 'wpWikis' ), -1, PREG_SPLIT_NO_EMPTY ) );
 151+ $reason = $wgRequest->getVal( 'wpReason' );
 152+
 153+ if( !Title::newFromText( $name ) ) {
 154+ $this->buildSetView( $id, wfMsgHtml( 'centralauth-editset-badname' ), $name, $type, $wikis, $reason );
 155+ return;
 156+ }
 157+ if( WikiSet::newFromName( $name ) ) {
 158+ $this->buildSetView( $id, wfMsgHtml( 'centralauth-editset-setexists' ), $name, $type, $wikis, $reason );
 159+ return;
 160+ }
 161+ if( !in_array( $type, array( WikiSet::OPTIN, WikiSet::OPTOUT ) ) ) {
 162+ $this->buildSetView( $id, wfMsgHtml( 'centralauth-editset-badtype' ), $name, $type, $wikis, $reason );
 163+ return;
 164+ }
 165+ if( !$wikis ) {
 166+ $this->buildSetView( $id, wfMsgHtml( 'centralauth-editset-nowikis' ), $name, $type, $wikis, $reason );
 167+ return;
 168+ }
 169+ $badwikis = array();
 170+ $allwikis = CentralAuthUser::getWikiList();
 171+ foreach( $wikis as $wiki )
 172+ if( !in_array( $wiki, $allwikis ) )
 173+ $badwikis[] = $wiki;
 174+ if( $badwikis ) {
 175+ $this->buildSetView( $id, wfMsgExt( 'centralauth-editset-badwikis', array( 'escapenoentities' ), implode( ', ', $badwikis ) ),
 176+ $name, $type, $wikis, $reason );
 177+ return;
 178+ }
 179+
 180+ $set = WikiSet::newFromID( $id );
 181+ if( $set ) {
 182+ $oldname = $set->getName();
 183+ $oldtype = $set->getType();
 184+ $oldwikis = $set->getWikisRaw();
 185+ } else {
 186+ $set = new WikiSet();
 187+ $oldname = $oldtype = null; $oldwikis = array();
 188+ }
 189+ $set->setName( $name );
 190+ $set->setType( $type );
 191+ $set->setWikisRaw( $wikis );
 192+ $set->commit();
 193+
 194+ // Now logging
 195+ $log = new LogPage( 'gblrights' );
 196+ $title = SpecialPage::getTitleFor( 'EditWikiSets', $set->getID() );
 197+ if( !$oldname ) {
 198+ // New set
 199+ $log->addEntry( 'newset', $title, $reason, array( $name, $type, implode( ', ', $wikis ) ) );
 200+ } else {
 201+ if( $oldname != $name )
 202+ $log->addEntry( 'setrename', $title, $reason, array( $name, $oldname ) );
 203+ if( $oldtype != $type )
 204+ $log->addEntry( 'setnewtype', $title, $reason, array( $name, $oldtype, $type ) );
 205+ $added = implode( ', ', array_diff( $wikis, $oldwikis ) );
 206+ $removed = implode( ', ', array_diff( $oldwikis, $wikis ) );
 207+ if( $added || $removed ) {
 208+ $log->addEntry( 'setchange', $title, $reason, array( $name, $added, $removed ) );
 209+ }
 210+ }
 211+
 212+ $this->buildMainView( '<strong class="success">' . wfMsgHtml( 'centralauth-editset-success' ) . '</strong>' );
 213+ }
 214+}
Index: trunk/extensions/CentralAuth/SpecialGlobalGroupPermissions.php
@@ -112,7 +112,7 @@
113113 }
114114
115115 function buildGroupView( $group ) {
116 - global $wgOut, $wgUser,$wgScript;
 116+ global $wgOut, $wgUser, $wgScript;
117117
118118 $wgOut->setSubtitle( wfMsg( 'centralauth-editgroup-subtitle', $group ) );
119119
@@ -127,6 +127,7 @@
128128 $fields['centralauth-editgroup-display'] = wfMsgExt( 'centralauth-editgroup-display-edit', array( 'parseinline' ), $group, User::getGroupName( $group ) );
129129 $fields['centralauth-editgroup-member'] = wfMsgExt( 'centralauth-editgroup-member-edit', array( 'parseinline' ), $group, User::getGroupMember( $group ) );
130130 $fields['centralauth-editgroup-members'] = wfMsgExt( 'centralauth-editgroup-members-link', array( 'parseinline' ), $group, User::getGroupMember( $group ) );
 131+ $fields['centralauth-editgroup-restrictions'] = $this->buildWikiSetSelector($group);
131132 $fields['centralauth-editgroup-perms'] = $this->buildCheckboxes($group);
132133 $fields['centralauth-editgroup-reason'] = wfInput( 'wpReason' );
133134
@@ -139,7 +140,21 @@
140141
141142 $this->showLogFragment( $group, $wgOut );
142143 }
143 -
 144+
 145+ function buildWikiSetSelector( $group ) {
 146+ $sets = WikiSet::getAllWikiSets();
 147+ $default = WikiSet::getWikiSetForGroup( $group );
 148+
 149+ $select = new XmlSelect( 'set', 'wikiset', $default );
 150+ $select->addOption( wfMsg( 'centralauth-editgroup-noset' ), '0' );
 151+ foreach( $sets as $set ) {
 152+ $select->addOption( $set->getName(), $set->getID() );
 153+ }
 154+
 155+ $editlink = wfMsgExt( "centralauth-editgroup-editsets", array( "parseinline" ) );
 156+ return $select->getHTML() . "&nbsp;{$editlink}";
 157+ }
 158+
144159 function buildCheckboxes( $group ) {
145160
146161 $rights = User::getAllRights();
@@ -221,7 +236,15 @@
222237 // Log it
223238 if (!(count($addRights)==0 && count($removeRights)==0))
224239 $this->addLogEntry( $group, $addRights, $removeRights, $reason );
225 -
 240+
 241+ // Change set
 242+ $current = WikiSet::getWikiSetForGroup( $group );
 243+ $new = $wgRequest->getVal( 'set' );
 244+ if( $current != $new ) {
 245+ $this->setRestrictions( $group, $new );
 246+ $this->addLogEntry2( $group, $current, $new, $reason );
 247+ }
 248+
226249 $this->invalidateRightsCache( $group );
227250
228251 // Display success
@@ -262,10 +285,8 @@
263286 global $wgRequest;
264287
265288 $log = new LogPage( 'gblrights' );
266 -
267 - $added =
268289
269 - $log->addEntry( 'groupperms2',
 290+ $log->addEntry( 'groupprms2',
270291 SpecialPage::getTitleFor( 'GlobalUsers', $group ),
271292 $reason,
272293 array(
@@ -278,7 +299,40 @@
279300 function makeRightsList( $ids ) {
280301 return (bool)count($ids) ? implode( ', ', $ids ) : wfMsgForContent( 'rightsnone' );
281302 }
282 -
 303+
 304+ function setRestrictions( $group, $set ) {
 305+ $dbw = CentralAuthUser::getCentralDB();
 306+ if( $set == 0 ) {
 307+ $dbw->delete( 'global_group_restrictions', array( 'ggr_group' => $group ), __METHOD__ );
 308+ } else {
 309+ $dbw->replace( 'global_group_restrictions', array( 'ggr_group' ),
 310+ array( 'ggr_group' => $group, 'ggr_set' => $set, ), __METHOD__ );
 311+ }
 312+ return (bool)$dbw->affectedRows();
 313+ }
 314+
 315+ function addLogEntry2( $group, $old, $new, $reason ) {
 316+ global $wgRequest;
 317+
 318+ $log = new LogPage( 'gblrights' );
 319+
 320+ $log->addEntry( 'groupprms3',
 321+ SpecialPage::getTitleFor( 'GlobalUsers', $group ),
 322+ $reason,
 323+ array(
 324+ $this->getWikiSetName( $old ),
 325+ $this->getWikiSetName( $new ),
 326+ )
 327+ );
 328+ }
 329+
 330+ function getWikiSetName( $id ) {
 331+ if( $id )
 332+ return WikiSet::newFromID( $id )->getName();
 333+ else
 334+ return wfMsgForContent( 'centralauth-editgroup-noset' );
 335+ }
 336+
283337 function invalidateRightsCache( $group ) {
284338 global $wgMemc;
285339
Index: trunk/extensions/CentralAuth/CentralAuth.php
@@ -136,12 +136,14 @@
137137 $wgAutoloadClasses['CentralAuthHooks'] = "$caBase/CentralAuthHooks.php";
138138 $wgAutoloadClasses['WikiMap'] = "$caBase/WikiMap.php";
139139 $wgAutoloadClasses['WikiReference'] = "$caBase/WikiMap.php";
 140+$wgAutoloadClasses['WikiSet'] = "$caBase/WikiSet.php";
140141 $wgAutoloadClasses['SpecialAutoLogin'] = "$caBase/SpecialAutoLogin.php";
141142 $wgAutoloadClasses['CentralAuthUserArray'] = "$caBase/CentralAuthUserArray.php";
142143 $wgAutoloadClasses['CentralAuthUserArrayFromResult'] = "$caBase/CentralAuthUserArray.php";
143144 $wgAutoloadClasses['SpecialGlobalGroupMembership'] = "$caBase/SpecialGlobalGroupMembership.php";
144145 $wgAutoloadClasses['CentralAuthGroupMembershipProxy'] = "$caBase/CentralAuthGroupMembershipProxy.php";
145146 $wgAutoloadClasses['SpecialGlobalGroupPermissions'] = "$caBase/SpecialGlobalGroupPermissions.php";
 147+$wgAutoloadClasses['SpecialEditWikiSets'] = "$caBase/SpecialEditWikiSets.php";
146148
147149 $wgExtensionMessagesFiles['SpecialCentralAuth'] = "$caBase/CentralAuth.i18n.php";
148150
@@ -182,6 +184,7 @@
183185 $wgSpecialPages['MergeAccount'] = 'SpecialMergeAccount';
184186 $wgSpecialPages['GlobalGroupMembership'] = 'SpecialGlobalGroupMembership';
185187 $wgSpecialPages['GlobalGroupPermissions'] = 'SpecialGlobalGroupPermissions';
 188+$wgSpecialPages['EditWikiSets'] = 'SpecialEditWikiSets';
186189 $wgSpecialPages['GlobalUsers'] = 'SpecialGlobalUsers';
187190 $wgSpecialPageGroups['GlobalUsers'] = 'users';
188191
@@ -195,9 +198,26 @@
196199 $wgLogActions['globalauth/unhide'] = 'centralauth-log-entry-unhide';
197200 $wgLogActions['globalauth/lockandhid'] = 'centralauth-log-entry-lockandhide';
198201
199 -$wgLogTypes[] = 'gblrights';
200 -$wgLogNames['gblrights'] = 'centralauth-rightslog-name';
201 -$wgLogHeaders['gblrights'] = 'centralauth-rightslog-header';
202 -$wgLogActions['gblrights/usergroups'] = 'centralauth-rightslog-entry-usergroups';
203 -$wgLogActions['gblrights/groupperms'] = 'centralauth-rightslog-entry-groupperms';
204 -$wgLogActions['gblrights/groupperms2'] = 'centralauth-rightslog-entry-groupperms2';
 202+$wgLogTypes[] = 'gblrights';
 203+$wgLogNames['gblrights'] = 'centralauth-rightslog-name';
 204+$wgLogHeaders['gblrights'] = 'centralauth-rightslog-header';
 205+$wgLogActions['gblrights/usergroups'] = 'centralauth-rightslog-entry-usergroups';
 206+$wgLogActions['gblrights/groupperms'] = 'centralauth-rightslog-entry-groupperms';
 207+$wgLogActions['gblrights/groupprms2'] = 'centralauth-rightslog-entry-groupperms2';
 208+$wgLogActions['gblrights/groupprms3'] = 'centralauth-rightslog-entry-groupperms3';
 209+foreach( array( 'newset', 'setrename', 'setnewtype', 'setchange' ) as $type )
 210+ $wgLogActionsHandlers["gblrights/{$type}"] = 'efHandleWikiSetLogEntry';
 211+
 212+function efHandleWikiSetLogEntry( $type, $action, $title, $skin, $params, $filterWikilinks = false ) {
 213+ wfLoadExtensionMessages('SpecialCentralAuth');
 214+ $link = $skin ? $skin->makeLinkObj( $title, $params[0] ) : $params[0];
 215+ if( $action == 'newset' )
 216+ $args = array( WikiSet::formatType( $params[1] ), $params[2] );
 217+ if( $action == 'setrename' )
 218+ $args = array( $params[1] );
 219+ if( $action == 'setnewtype' )
 220+ $args = array( WikiSet::formatType( $params[1] ), WikiSet::formatType( $params[2] ) );
 221+ if( $action == 'setchange' )
 222+ $args = array( $params[1] ? $params[1] : wfMsg( 'rightsnone' ), $params[2] ? $params[2] : wfMsg( 'rightsnone' ) );
 223+ return wfMsgReal( "centralauth-rightslog-entry-{$action}", array_merge( array( $link ), $args ), true, !$skin );
 224+}
\ No newline at end of file
Index: trunk/extensions/CentralAuth/WikiSet.php
@@ -0,0 +1,183 @@
 2+<?php
 3+
 4+class WikiSet {
 5+ const OPTIN = 'optin';
 6+ const OPTOUT = 'optout';
 7+ const VERSION = 1;
 8+
 9+ private $mId; //ID of the group
 10+ private $mName; //Display name of the group
 11+ private $mType; //Opt-in based or opt-out based
 12+ private $mWikis; //List of wikis
 13+ private $mVersion = self::VERSION; //Caching purposes
 14+
 15+ static $mCacheVars = array(
 16+ 'mId',
 17+ 'mName',
 18+ 'mType',
 19+ 'mWikis',
 20+ 'mVersion',
 21+ );
 22+
 23+ public function __construct( $name = '', $type = self::OPTIN, $wikis = array(), $id = 0 ) {
 24+ $this->mId = $id;
 25+ $this->mName = $name;
 26+ $this->mType = $type;
 27+ $this->mWikis = $wikis;
 28+ }
 29+
 30+ protected static function memcKey( $k ) { return "wikiset:{$k}"; }
 31+
 32+ public function getId() { return $this->mId; }
 33+ public function exists() { return (bool)$this->getID(); }
 34+ public function getName() { return $this->mName; }
 35+ public function setName( $n, $commit = false ) { return $this->setDbField( 'ws_name', $n, $commit ); }
 36+ public function getWikisRaw() { return $this->mWikis; }
 37+ public function setWikisRaw( $w, $commit = false ) { return $this->setDbField( 'ws_wikis', $w, $commit ); }
 38+ public function getType() { return $this->mType; }
 39+ public function setType( $t, $commit = false ) {
 40+ if( !in_array( $t, array( self::OPTIN, self::OPTOUT ) ) )
 41+ return false;
 42+ return $this->setDbField( 'ws_type', $t, $commit );
 43+ }
 44+ protected function setDbField( $field, $value, $commit ) {
 45+ $map = array( 'ws_name' => 'mName', 'ws_type' => 'mType', 'ws_wikis' => 'mWikis' );
 46+ $mname = $map[$field];
 47+ $this->$mname = $value;
 48+ if( $commit )
 49+ $this->commit();
 50+ }
 51+
 52+ public static function newFromRow( $row ) {
 53+ if( !$row ) return null;
 54+ return new WikiSet(
 55+ $row->ws_name,
 56+ $row->ws_type,
 57+ explode( ',', $row->ws_wikis ),
 58+ $row->ws_id
 59+ );
 60+ }
 61+
 62+ public static function newFromName( $id, $useCache = true ) {
 63+ if( $useCache ) {
 64+ global $wgMemc;
 65+ $data = $wgMemc->get( self::memcKey( "name:" . md5( $id ) ) );
 66+ if( $data ) {
 67+ if( $data['mVersion'] == self::VERSION ) {
 68+ $ws = new WikiSet( null, null, null );
 69+ foreach( $data as $name => $val )
 70+ $ws->$name = $val;
 71+ return $ws;
 72+ }
 73+ }
 74+ }
 75+ $dbr = CentralAuthUser::getCentralSlaveDB();
 76+ $row = $dbr->selectRow(
 77+ 'wikiset', '*', array( 'ws_name' => $id ), __METHOD__
 78+ );
 79+ if( !$row )
 80+ return null;
 81+ $ws = self::newFromRow( $row );
 82+ $ws->saveToCache();
 83+ return $ws;
 84+ }
 85+
 86+ public static function newFromID( $id, $useCache = true ) {
 87+ if( $useCache ) {
 88+ global $wgMemc;
 89+ $data = $wgMemc->get( self::memcKey( $id ) );
 90+ if( $data ) {
 91+ if( $data['mVersion'] == self::VERSION ) {
 92+ $ws = new WikiSet( null, null, null );
 93+ foreach( $data as $name => $val )
 94+ $ws->$name = $val;
 95+ return $ws;
 96+ }
 97+ }
 98+ }
 99+ $dbr = CentralAuthUser::getCentralSlaveDB();
 100+ $row = $dbr->selectRow(
 101+ 'wikiset', '*', array( 'ws_id' => $id ), __METHOD__
 102+ );
 103+ if( !$row )
 104+ return null;
 105+ $ws = self::newFromRow( $row );
 106+ $ws->saveToCache();
 107+ return $ws;
 108+ }
 109+
 110+ public function commit() {
 111+ $dbw = CentralAuthUser::getCentralDB();
 112+ $dbw->replace( 'wikiset', array( 'ws_id' ),
 113+ array(
 114+ 'ws_id' => $this->mId,
 115+ 'ws_name' => $this->mName,
 116+ 'ws_type' => $this->mType,
 117+ 'ws_wikis' => implode( ',', $this->mWikis ),
 118+ ), __METHOD__
 119+ );
 120+ $dbw->commit();
 121+ if( !$this->mId )
 122+ $this->mId = $dbw->insertId();
 123+ $this->purge();
 124+ return (bool)$dbw->affectedRows();
 125+ }
 126+
 127+ public function purge() {
 128+ global $wgMemc;
 129+ $wgMemc->delete( self::memcKey( $this->mId ) );
 130+ $wgMemc->delete( self::memcKey( "name:" . md5( $this->mName ) ) );
 131+ }
 132+
 133+ public function saveToCache() {
 134+ global $wgMemc;
 135+ $data = array();
 136+ foreach( self::$mCacheVars as $var ) {
 137+ $data[$var] = $this->$var;
 138+ }
 139+ $wgMemc->set( self::memcKey( $this->mId ), $data );
 140+ }
 141+
 142+ public function getWikis() {
 143+ if( $this->mType == self::OPTIN )
 144+ return $this->mWikis;
 145+ else
 146+ return array_diff( CentralAuthUser::getWikiList(), $this->mWikis );
 147+ }
 148+
 149+ public function inSet( $wiki = '' ) {
 150+ if( !$wiki )
 151+ $wiki = wfWikiID();
 152+ return in_array( $wiki, $this->getWikis() );
 153+ }
 154+
 155+ public function getRestrictedGroups() {
 156+ $dbr = CentralAuthUser::getCentralSlaveDB();
 157+ $r = $dbr->select(
 158+ 'global_group_restrictions', '*', array( 'ggr_set' => $this->mId ), __METHOD__
 159+ );
 160+ $result = array();
 161+ foreach( $r as $row )
 162+ $result[] = $row->ggr_group;
 163+ return $result;
 164+ }
 165+
 166+ public static function getAllWikiSets() {
 167+ $dbr = CentralAuthUser::getCentralSlaveDB();
 168+ $res = $dbr->select( 'wikiset', '*', false, __METHOD__ );
 169+ $result = array();
 170+ while( $row = $dbr->fetchObject( $res ) )
 171+ $result[] = self::newFromRow( $row );
 172+ return $result;
 173+ }
 174+
 175+ public static function getWikiSetForGroup( $group ) {
 176+ $dbr = CentralAuthUser::getCentralSlaveDB();
 177+ $res = $dbr->selectRow( 'global_group_restrictions', '*', array( 'ggr_group' => $group ), __METHOD__ );
 178+ return $res ? $res->ggr_set : 0;
 179+ }
 180+
 181+ public static function formatType( $type ) {
 182+ return wfMsgHtml( "centralauth-rightslog-set-{$type}" );
 183+ }
 184+}
Index: trunk/extensions/CentralAuth/CentralAuth.i18n.php
@@ -235,12 +235,20 @@
236236 'centralauth-log-entry-unhide' => 'unhid global account "<nowiki>$1</nowiki>"',
237237 'centralauth-log-entry-lockandhide' => 'locked and hid global account "<nowiki>$1</nowiki>"',
238238
239 - 'centralauth-rightslog-name' => 'Global rights log',
240 - 'centralauth-rightslog-entry-usergroups' => 'changed global group membership for $1 from $2 to $3',
241 - 'centralauth-rightslog-entry-groupperms' => 'changed group permissions for $1 from $2 to $3',
 239+ 'centralauth-rightslog-name' => 'Global rights log',
 240+ 'centralauth-rightslog-entry-usergroups' => 'changed global group membership for $1 from $2 to $3',
 241+ 'centralauth-rightslog-entry-groupperms' => 'changed group permissions for $1 from $2 to $3',
242242 'centralauth-rightslog-entry-groupperms2' => 'changed group permissions for $1. Added $2; Removed $3',
243 - 'centralauth-rightslog-header' => 'This log contains operations on global groups: membership and permissions changes',
 243+ 'centralauth-rightslog-entry-groupperms3' => 'changed group restricted wikis set for $1 from $2 to $3',
 244+ 'centralauth-rightslog-header' => 'This log contains operations on global groups: membership and permissions changes',
244245
 246+ 'centralauth-rightslog-entry-newset' => 'created $2 wiki set $1 with following wikis: $3',
 247+ 'centralauth-rightslog-entry-setrename' => 'renamed wiki set "$2" to "$1"',
 248+ 'centralauth-rightslog-entry-setnewtype' => 'changed type of "$1" from $2 to $3',
 249+ 'centralauth-rightslog-entry-setchange' => 'changed wikis in "$1": added: $2; removed: $3',
 250+ 'centralauth-rightslog-set-optin' => 'opt-in based',
 251+ 'centralauth-rightslog-set-optout' => 'opt-out based',
 252+
245253 // Global group membership
246254 'globalgroupmembership' => 'Membership in global groups',
247255
@@ -249,7 +257,7 @@
250258 'centralauth-globalgroupperms-grouplist' => 'The following global groups have been configured.
251259 You may view and edit the permissions assigned to any group.
252260 A group may be deleted by removing all rights from it.',
253 - 'centralauth-globalgroupperms-grouplistitem' => '$1 ([[Special:GlobalGroupPermissions/$2|View and edit permissions]])',
 261+ 'centralauth-globalgroupperms-grouplistitem' => '$1 ([[Special:GlobalGroupPermissions/$2|view/edit]])',
254262 'centralauth-existinggroup-legend' => 'Existing groups',
255263 'centralauth-newgroup-legend' => 'Create a new group',
256264 'centralauth-newgroup-intro' => 'You can use this form to assign permissions to a new group.
@@ -265,16 +273,45 @@
266274 'centralauth-editgroup-member-edit' => '$2 ([[MediaWiki:Group-$1-member|edit]])',
267275 'centralauth-editgroup-members' => 'Member list:',
268276 'centralauth-editgroup-members-link' => '[[Special:Globalusers/$1|List of users with $2 rights]]',
 277+ 'centralauth-editgroup-restrictions' => 'Set of wikis where this group is active:',
 278+ 'centralauth-editgroup-noset' => '(none)',
269279 'centralauth-editgroup-submit' => 'Save changes to group permissions',
270280 'centralauth-editgroup-perms' => 'Assigned permissions:',
271281 'centralauth-editgroup-reason' => 'Reason for change:',
272282 'centralauth-editgroup-success' => 'Group permissions changed',
273283 'centralauth-editgroup-success-text' => 'You have successfully changed the group permissions for the $1 group.
274284 [[Special:GlobalGroupPermissions|Return to group management]]',
275 - 'centralauth-globalgrouppermissions-knownwiki' => "Select a wiki on which they have an account:",
 285+ 'centralauth-editgroup-editsets' => '([[Special:EditWikiSets|edit]])',
 286+ 'centralauth-globalgrouppermissions-knownwiki' => "Wiki on which they have an account:",
276287 'centralauth-globalgroupmembership-badknownwiki' => "The global user '''$1''' is not active on the wiki you specified ('' $2 '').
277288 You may be attempting to assign rights to the wrong user!",
278289
 290+ // Wiki sets editing
 291+ 'centralauth-editset' => 'Edit wiki sets',
 292+ 'centralauth-editset-legend' => 'Edit or create wiki set',
 293+ 'centralauth-editset-intro' => 'The following wiki sets have already been created. You may view and modify any of them, or create a new set.',
 294+ 'centralauth-editset-item' => '$1 ([[Special:EditWikiSets/$2|view/edit]])',
 295+ 'centralauth-editset-new' => 'Create a new set',
 296+ 'centralauth-editset-notfound' => 'Wiki set "$1" not found.',
 297+ 'centralauth-editset-optin' => 'Opt-in based (includes only specified wikis)',
 298+ 'centralauth-editset-optout' => 'Opt-out based (includes all wikis except specified)',
 299+ 'centralauth-editset-legend-edit' => 'Editing wiki set "$1"',
 300+ 'centralauth-editset-legend-new' => 'Creating new wiki set',
 301+ 'centralauth-editset-name' => 'Name:',
 302+ 'centralauth-editset-type' => 'Type:',
 303+ 'centralauth-editset-wikis' => 'Wikis:',
 304+ 'centralauth-editset-reason' => 'Reason:',
 305+ 'centralauth-editset-submit' => 'Submit',
 306+ 'centralauth-editset-badname' => 'Invalid or empty set name.',
 307+ 'centralauth-editset-badtype' => 'Invalid set type.',
 308+ 'centralauth-editset-setexists' => 'Set with that name already exists',
 309+ 'centralauth-editset-nowikis' => 'No wikis specified.',
 310+ 'centralauth-editset-grouplink' => '[[Special:GlobalGroupPermissions/$1|$1]]',
 311+ 'centralauth-editset-nouse' => '(none)',
 312+ 'centralauth-editset-usage' => 'Used in groups:',
 313+ 'centralauth-editset-badwikis' => 'Following wikis do not exist: $1.',
 314+ 'centralauth-editset-success' => 'Successfully changed wiki set.',
 315+
279316 // User rights
280317 'right-globalgroupmembership' => 'Edit membership to global groups',
281318 'right-centralauth-admin' => 'Administrate global accounts',

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r37975* (bug 14556) Global groups defined for certain sets of wikis...vasilievvv20:24, 23 July 2008

Status & tagging log