ApiUserrights.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. /**
  3. * API userrights module
  4. *
  5. * Copyright © 2009 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. * http://www.gnu.org/copyleft/gpl.html
  21. *
  22. * @file
  23. */
  24. /**
  25. * @ingroup API
  26. */
  27. class ApiUserrights extends ApiBase {
  28. private $mUser = null;
  29. /**
  30. * Get a UserrightsPage object, or subclass.
  31. * @return UserrightsPage
  32. */
  33. protected function getUserRightsPage() {
  34. return new UserrightsPage;
  35. }
  36. /**
  37. * Get all available groups.
  38. * @return array
  39. */
  40. protected function getAllGroups() {
  41. return User::getAllGroups();
  42. }
  43. public function execute() {
  44. $pUser = $this->getUser();
  45. // Deny if the user is blocked and doesn't have the full 'userrights' permission.
  46. // This matches what Special:UserRights does for the web UI.
  47. if ( $pUser->isBlocked() && !$pUser->isAllowed( 'userrights' ) ) {
  48. $this->dieBlocked( $pUser->getBlock() );
  49. }
  50. $params = $this->extractRequestParams();
  51. // Figure out expiry times from the input
  52. // $params['expiry'] may not be set in subclasses
  53. if ( isset( $params['expiry'] ) ) {
  54. $expiry = (array)$params['expiry'];
  55. } else {
  56. $expiry = [ 'infinity' ];
  57. }
  58. if ( count( $expiry ) !== count( $params['add'] ) ) {
  59. if ( count( $expiry ) === 1 ) {
  60. $expiry = array_fill( 0, count( $params['add'] ), $expiry[0] );
  61. } else {
  62. $this->dieWithError( [
  63. 'apierror-toofewexpiries',
  64. count( $expiry ),
  65. count( $params['add'] )
  66. ] );
  67. }
  68. }
  69. // Validate the expiries
  70. $groupExpiries = [];
  71. foreach ( $expiry as $index => $expiryValue ) {
  72. $group = $params['add'][$index];
  73. $groupExpiries[$group] = UserrightsPage::expiryToTimestamp( $expiryValue );
  74. if ( $groupExpiries[$group] === false ) {
  75. $this->dieWithError( [ 'apierror-invalidexpiry', wfEscapeWikiText( $expiryValue ) ] );
  76. }
  77. // not allowed to have things expiring in the past
  78. if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) {
  79. $this->dieWithError( [ 'apierror-pastexpiry', wfEscapeWikiText( $expiryValue ) ] );
  80. }
  81. }
  82. $user = $this->getUrUser( $params );
  83. $tags = $params['tags'];
  84. // Check if user can add tags
  85. if ( !is_null( $tags ) ) {
  86. $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $tags, $pUser );
  87. if ( !$ableToTag->isOK() ) {
  88. $this->dieStatus( $ableToTag );
  89. }
  90. }
  91. $form = $this->getUserRightsPage();
  92. $form->setContext( $this->getContext() );
  93. $r['user'] = $user->getName();
  94. $r['userid'] = $user->getId();
  95. list( $r['added'], $r['removed'] ) = $form->doSaveUserGroups(
  96. $user, (array)$params['add'], (array)$params['remove'],
  97. $params['reason'], $tags, $groupExpiries
  98. );
  99. $result = $this->getResult();
  100. ApiResult::setIndexedTagName( $r['added'], 'group' );
  101. ApiResult::setIndexedTagName( $r['removed'], 'group' );
  102. $result->addValue( null, $this->getModuleName(), $r );
  103. }
  104. /**
  105. * @param array $params
  106. * @return User
  107. */
  108. private function getUrUser( array $params ) {
  109. if ( $this->mUser !== null ) {
  110. return $this->mUser;
  111. }
  112. $this->requireOnlyOneParameter( $params, 'user', 'userid' );
  113. $user = isset( $params['user'] ) ? $params['user'] : '#' . $params['userid'];
  114. $form = $this->getUserRightsPage();
  115. $form->setContext( $this->getContext() );
  116. $status = $form->fetchUser( $user );
  117. if ( !$status->isOK() ) {
  118. $this->dieStatus( $status );
  119. }
  120. $this->mUser = $status->value;
  121. return $status->value;
  122. }
  123. public function mustBePosted() {
  124. return true;
  125. }
  126. public function isWriteMode() {
  127. return true;
  128. }
  129. public function getAllowedParams() {
  130. $a = [
  131. 'user' => [
  132. ApiBase::PARAM_TYPE => 'user',
  133. ],
  134. 'userid' => [
  135. ApiBase::PARAM_TYPE => 'integer',
  136. ],
  137. 'add' => [
  138. ApiBase::PARAM_TYPE => $this->getAllGroups(),
  139. ApiBase::PARAM_ISMULTI => true
  140. ],
  141. 'expiry' => [
  142. ApiBase::PARAM_ISMULTI => true,
  143. ApiBase::PARAM_ALLOW_DUPLICATES => true,
  144. ApiBase::PARAM_DFLT => 'infinite',
  145. ],
  146. 'remove' => [
  147. ApiBase::PARAM_TYPE => $this->getAllGroups(),
  148. ApiBase::PARAM_ISMULTI => true
  149. ],
  150. 'reason' => [
  151. ApiBase::PARAM_DFLT => ''
  152. ],
  153. 'token' => [
  154. // Standard definition automatically inserted
  155. ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
  156. ],
  157. 'tags' => [
  158. ApiBase::PARAM_TYPE => 'tags',
  159. ApiBase::PARAM_ISMULTI => true
  160. ],
  161. ];
  162. if ( !$this->getUserRightsPage()->canProcessExpiries() ) {
  163. unset( $a['expiry'] );
  164. }
  165. return $a;
  166. }
  167. public function needsToken() {
  168. return 'userrights';
  169. }
  170. protected function getWebUITokenSalt( array $params ) {
  171. return $this->getUrUser( $params )->getName();
  172. }
  173. protected function getExamplesMessages() {
  174. $a = [
  175. 'action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
  176. => 'apihelp-userrights-example-user',
  177. 'action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
  178. => 'apihelp-userrights-example-userid',
  179. ];
  180. if ( $this->getUserRightsPage()->canProcessExpiries() ) {
  181. $a['action=userrights&user=SometimeSysop&add=sysop&expiry=1%20month&token=123ABC']
  182. = 'apihelp-userrights-example-expiry';
  183. }
  184. return $a;
  185. }
  186. public function getHelpUrls() {
  187. return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:User_group_membership';
  188. }
  189. }