PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/CentralAuth/specials/SpecialGlobalGroupPermissions.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 371 lines | 251 code | 91 blank | 29 comment | 37 complexity | f127500fac826c526ae646115337add5 MD5 | raw file
  1. <?php
  2. # This file is part of MediaWiki.
  3. # MediaWiki is free software: you can redistribute it and/or modify
  4. # it under the terms of version 2 of the GNU General Public License
  5. # as published by the Free Software Foundation.
  6. # MediaWiki is distributed in the hope that it will be useful,
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. # GNU General Public License for more details.
  10. /**
  11. * Special page to allow managing global groups
  12. * Prototype for a similar system in core.
  13. *
  14. * @file
  15. * @ingroup Extensions
  16. */
  17. if ( !defined( 'MEDIAWIKI' ) ) {
  18. echo "CentralAuth extension\n";
  19. exit( 1 );
  20. }
  21. class SpecialGlobalGroupPermissions extends SpecialPage {
  22. function __construct() {
  23. parent::__construct( 'GlobalGroupPermissions' );
  24. }
  25. function userCanEdit( $user ) {
  26. $globalUser = CentralAuthUser::getInstance( $user );
  27. # # Should be a global user
  28. if ( !$globalUser->exists() || !$globalUser->isAttached() ) {
  29. return false;
  30. }
  31. # # Permission MUST be gained from global rights.
  32. return $globalUser->hasGlobalPermission( 'globalgrouppermissions' );
  33. }
  34. function execute( $subpage ) {
  35. global $wgRequest, $wgOut, $wgUser;
  36. if ( !$this->userCanExecute( $wgUser ) ) {
  37. $this->displayRestrictionError();
  38. return;
  39. }
  40. $wgOut->setPageTitle( wfMsg( 'globalgrouppermissions' ) );
  41. $wgOut->setRobotPolicy( "noindex,nofollow" );
  42. $wgOut->setArticleRelated( false );
  43. $wgOut->enableClientCache( false );
  44. if ( $subpage == '' ) {
  45. $subpage = $wgRequest->getVal( 'wpGroup' );
  46. }
  47. if ( $subpage != '' && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
  48. $this->doSubmit( $subpage );
  49. } elseif ( $subpage != '' ) {
  50. $this->buildGroupView( $subpage );
  51. } else {
  52. $this->buildMainView();
  53. }
  54. }
  55. function buildMainView() {
  56. global $wgOut, $wgUser, $wgScript;
  57. $groups = CentralAuthUser::availableGlobalGroups();
  58. // Existing groups
  59. $html = Xml::fieldset( wfMsg( 'centralauth-existinggroup-legend' ) );
  60. $wgOut->addHTML( $html );
  61. if ( count( $groups ) ) {
  62. $wgOut->addWikiMsg( 'centralauth-globalgroupperms-grouplist' );
  63. $wgOut->addHTML( '<ul>' );
  64. foreach ( $groups as $group ) {
  65. $text = wfMsgExt( 'centralauth-globalgroupperms-grouplistitem', array( 'parseinline' ), User::getGroupName( $group ), $group, '<span class="centralauth-globalgroupperms-groupname">' . $group . '</span>' );
  66. $wgOut->addHTML( "<li> $text </li>" );
  67. }
  68. } else {
  69. $wgOut->addWikiMsg( 'centralauth-globalgroupperms-nogroups' );
  70. }
  71. $wgOut->addHTML( Xml::closeElement( 'ul' ) . Xml::closeElement( 'fieldset' ) );
  72. if ( $this->userCanEdit( $wgUser ) ) {
  73. // "Create a group" prompt
  74. $html = Xml::fieldset( wfMsg( 'centralauth-newgroup-legend' ) );
  75. $html .= wfMsgExt( 'centralauth-newgroup-intro', array( 'parse' ) );
  76. $html .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => $wgScript, 'name' => 'centralauth-globalgroups-newgroup' ) );
  77. $html .= Html::hidden( 'title', SpecialPage::getTitleFor( 'GlobalGroupPermissions' )->getPrefixedText() );
  78. $fields = array( 'centralauth-globalgroupperms-newgroupname' => Xml::input( 'wpGroup' ) );
  79. $html .= Xml::buildForm( $fields, 'centralauth-globalgroupperms-creategroup-submit' );
  80. $html .= Xml::closeElement( 'form' );
  81. $html .= Xml::closeElement( 'fieldset' );
  82. $wgOut->addHTML( $html );
  83. }
  84. }
  85. function buildGroupView( $group ) {
  86. global $wgOut, $wgUser;
  87. $editable = $this->userCanEdit( $wgUser );
  88. $wgOut->setSubtitle( wfMsg( 'centralauth-editgroup-subtitle', $group ) );
  89. $html = Xml::fieldset( wfMsg( 'centralauth-editgroup-fieldset', $group ) );
  90. if ( $editable ) {
  91. $html .= Xml::openElement( 'form', array( 'method' => 'post', 'action' => SpecialPage::getTitleFor( 'GlobalGroupPermissions', $group )->getLocalUrl(), 'name' => 'centralauth-globalgroups-newgroup' ) );
  92. $html .= Html::hidden( 'wpGroup', $group );
  93. $html .= Html::hidden( 'wpEditToken', $wgUser->editToken() );
  94. }
  95. $fields = array();
  96. $fields['centralauth-editgroup-name'] = $group;
  97. $fields['centralauth-editgroup-display'] = wfMsgExt( 'centralauth-editgroup-display-edit', array( 'parseinline' ), $group, User::getGroupName( $group ) );
  98. $fields['centralauth-editgroup-member'] = wfMsgExt( 'centralauth-editgroup-member-edit', array( 'parseinline' ), $group, User::getGroupMember( $group ) );
  99. $fields['centralauth-editgroup-members'] = wfMsgExt( 'centralauth-editgroup-members-link', array( 'parseinline' ), $group, User::getGroupMember( $group ) );
  100. $fields['centralauth-editgroup-restrictions'] = $this->buildWikiSetSelector( $group );
  101. $fields['centralauth-editgroup-perms'] = $this->buildCheckboxes( $group );
  102. if ( $editable ) {
  103. $fields['centralauth-editgroup-reason'] = Xml::input( 'wpReason', 60 );
  104. }
  105. $html .= Xml::buildForm( $fields, $editable ? 'centralauth-editgroup-submit' : null );
  106. if ( $editable )
  107. $html .= Xml::closeElement( 'form' );
  108. $html .= Xml::closeElement( 'fieldset' );
  109. $wgOut->addHTML( $html );
  110. $this->showLogFragment( $group, $wgOut );
  111. }
  112. function buildWikiSetSelector( $group ) {
  113. $sets = WikiSet::getAllWikiSets();
  114. $default = WikiSet::getWikiSetForGroup( $group );
  115. global $wgUser;
  116. if ( !$this->userCanEdit( $wgUser ) )
  117. return htmlspecialchars( $default );
  118. $select = new XmlSelect( 'set', 'wikiset', $default );
  119. $select->addOption( wfMsg( 'centralauth-editgroup-noset' ), '0' );
  120. foreach ( $sets as $set ) {
  121. $select->addOption( $set->getName(), $set->getID() );
  122. }
  123. $editlink = wfMsgExt( "centralauth-editgroup-editsets", array( "parseinline" ) );
  124. return $select->getHTML() . "&#160;{$editlink}";
  125. }
  126. function buildCheckboxes( $group ) {
  127. global $wgUser, $wgOut;
  128. $editable = $this->userCanEdit( $wgUser );
  129. $rights = User::getAllRights();
  130. $assignedRights = $this->getAssignedRights( $group );
  131. sort( $rights );
  132. $checkboxes = array();
  133. $attribs = array();
  134. if ( !$editable )
  135. $attribs['disabled'] = 'disabled';
  136. foreach ( $rights as $right ) {
  137. # Build a checkbox.
  138. $checked = in_array( $right, $assignedRights );
  139. $desc = $wgOut->parseInline( User::getRightDescription( $right ) ) . ' ' .
  140. Xml::element( 'tt', null, wfMsg( 'parentheses', $right ) );
  141. $checkbox = Xml::check( "wpRightAssigned-$right", $checked,
  142. array_merge( $attribs, array( 'id' => "wpRightAssigned-$right" ) ) );
  143. $label = Xml::tags( 'label', array( 'for' => "wpRightAssigned-$right" ),
  144. $desc );
  145. $checkboxes[] = "<li>$checkbox&#160;$label</li>";
  146. }
  147. $count = count( $checkboxes );
  148. $firstCol = round( $count / 2 );
  149. $checkboxes1 = array_slice( $checkboxes, 0, $firstCol );
  150. $checkboxes2 = array_slice( $checkboxes, $firstCol );
  151. $html = '<table><tbody><tr><td><ul>';
  152. foreach ( $checkboxes1 as $cb ) {
  153. $html .= $cb;
  154. }
  155. $html .= '</ul></td><td><ul>';
  156. foreach ( $checkboxes2 as $cb ) {
  157. $html .= $cb;
  158. }
  159. $html .= '</ul></td></tr></tbody></table>';
  160. return $html;
  161. }
  162. function getAssignedRights( $group ) {
  163. return CentralAuthUser::globalGroupPermissions( $group );
  164. }
  165. function doSubmit( $group ) {
  166. global $wgRequest, $wgOut, $wgUser;
  167. // Paranoia -- the edit token shouldn't match anyway
  168. if ( !$this->userCanEdit( $wgUser ) )
  169. return;
  170. $newRights = array();
  171. $addRights = array();
  172. $removeRights = array();
  173. $oldRights = $this->getAssignedRights( $group );
  174. $allRights = User::getAllRights();
  175. $reason = $wgRequest->getVal( 'wpReason', '' );
  176. foreach ( $allRights as $right ) {
  177. $alreadyAssigned = in_array( $right, $oldRights );
  178. if ( $wgRequest->getCheck( "wpRightAssigned-$right" ) ) {
  179. $newRights[] = $right;
  180. }
  181. if ( !$alreadyAssigned && $wgRequest->getCheck( "wpRightAssigned-$right" ) ) {
  182. $addRights[] = $right;
  183. } elseif ( $alreadyAssigned && !$wgRequest->getCheck( "wpRightAssigned-$right" ) ) {
  184. $removeRights[] = $right;
  185. } # Otherwise, do nothing.
  186. }
  187. // Assign the rights.
  188. if ( count( $addRights ) > 0 )
  189. $this->grantRightsToGroup( $group, $addRights );
  190. if ( count( $removeRights ) > 0 )
  191. $this->revokeRightsFromGroup( $group, $removeRights );
  192. // Log it
  193. if ( !( count( $addRights ) == 0 && count( $removeRights ) == 0 ) )
  194. $this->addLogEntry( $group, $addRights, $removeRights, $reason );
  195. // Change set
  196. $current = WikiSet::getWikiSetForGroup( $group );
  197. $new = $wgRequest->getVal( 'set' );
  198. if ( $current != $new ) {
  199. $this->setRestrictions( $group, $new );
  200. $this->addLogEntry2( $group, $current, $new, $reason );
  201. }
  202. $this->invalidateRightsCache( $group );
  203. // Display success
  204. $wgOut->setSubTitle( wfMsg( 'centralauth-editgroup-success' ) );
  205. $wgOut->addWikiMsg( 'centralauth-editgroup-success-text', $group );
  206. }
  207. function revokeRightsFromGroup( $group, $rights ) {
  208. $dbw = CentralAuthUser::getCentralDB();
  209. # Delete from the DB
  210. $dbw->delete( 'global_group_permissions', array( 'ggp_group' => $group, 'ggp_permission' => $rights ), __METHOD__ );
  211. }
  212. function grantRightsToGroup( $group, $rights ) {
  213. $dbw = CentralAuthUser::getCentralDB();
  214. if ( !is_array( $rights ) ) {
  215. $rights = array( $rights );
  216. }
  217. $insertRows = array();
  218. foreach ( $rights as $right ) {
  219. $insertRows[] = array( 'ggp_group' => $group, 'ggp_permission' => $right );
  220. }
  221. # Replace into the DB
  222. $dbw->replace( 'global_group_permissions', array( 'ggp_group', 'ggp_permission' ), $insertRows, __METHOD__ );
  223. }
  224. protected function showLogFragment( $group, $output ) {
  225. $title = SpecialPage::getTitleFor( 'GlobalUsers', $group );
  226. $output->addHTML( Xml::element( 'h2', null, LogPage::logName( 'gblrights' ) . "\n" ) );
  227. LogEventsList::showLogExtract( $output, 'gblrights', $title->getPrefixedText() );
  228. }
  229. function addLogEntry( $group, $addRights, $removeRights, $reason ) {
  230. $log = new LogPage( 'gblrights' );
  231. $log->addEntry( 'groupprms2',
  232. SpecialPage::getTitleFor( 'GlobalUsers', $group ),
  233. $reason,
  234. array(
  235. $this->makeRightsList( $addRights ),
  236. $this->makeRightsList( $removeRights )
  237. )
  238. );
  239. }
  240. function makeRightsList( $ids ) {
  241. return (bool)count( $ids ) ? implode( ', ', $ids ) : wfMsgForContent( 'rightsnone' );
  242. }
  243. function setRestrictions( $group, $set ) {
  244. $dbw = CentralAuthUser::getCentralDB();
  245. if ( $set == 0 ) {
  246. $dbw->delete( 'global_group_restrictions', array( 'ggr_group' => $group ), __METHOD__ );
  247. } else {
  248. $dbw->replace( 'global_group_restrictions', array( 'ggr_group' ),
  249. array( 'ggr_group' => $group, 'ggr_set' => $set, ), __METHOD__ );
  250. }
  251. return (bool)$dbw->affectedRows();
  252. }
  253. function addLogEntry2( $group, $old, $new, $reason ) {
  254. $log = new LogPage( 'gblrights' );
  255. $log->addEntry( 'groupprms3',
  256. SpecialPage::getTitleFor( 'GlobalUsers', $group ),
  257. $reason,
  258. array(
  259. $this->getWikiSetName( $old ),
  260. $this->getWikiSetName( $new ),
  261. )
  262. );
  263. }
  264. function getWikiSetName( $id ) {
  265. if ( $id )
  266. return WikiSet::newFromID( $id )->getName();
  267. else
  268. return wfMsgForContent( 'centralauth-editgroup-noset' );
  269. }
  270. function invalidateRightsCache( $group ) {
  271. // Figure out all the users in this group.
  272. $dbr = CentralAuthUser::getCentralDB();
  273. $res = $dbr->select( array( 'global_user_groups', 'globaluser' ), 'gu_name', array( 'gug_group' => $group, 'gu_id=gug_user' ), __METHOD__ );
  274. // Invalidate their rights cache.
  275. foreach ( $res as $row ) {
  276. $cu = new CentralAuthUser( $row->gu_name );
  277. $cu->quickInvalidateCache();
  278. }
  279. }
  280. }