MediaWiki  master
ApiUserrights.php
Go to the documentation of this file.
1 <?php
2 
27 
31 class ApiUserrights extends ApiBase {
32 
33  private $mUser = null;
34 
39  protected function getUserRightsPage() {
40  return new UserrightsPage;
41  }
42 
47  protected function getAllGroups() {
48  return User::getAllGroups();
49  }
50 
51  public function execute() {
52  $pUser = $this->getUser();
53 
54  // Deny if the user is blocked and doesn't have the full 'userrights' permission.
55  // This matches what Special:UserRights does for the web UI.
56  if ( !$this->getPermissionManager()->userHasRight( $pUser, 'userrights' ) ) {
57  $block = $pUser->getBlock();
58  if ( $block && $block->isSitewide() ) {
59  $this->dieBlocked( $block );
60  }
61  }
62 
63  $params = $this->extractRequestParams();
64 
65  // Figure out expiry times from the input
66  // $params['expiry'] is not set in CentralAuth's ApiGlobalUserRights subclass
67  if ( isset( $params['expiry'] ) ) {
68  $expiry = (array)$params['expiry'];
69  } else {
70  $expiry = [ 'infinity' ];
71  }
72  $add = (array)$params['add'];
73  if ( !$add ) {
74  $expiry = [];
75  } elseif ( count( $expiry ) !== count( $add ) ) {
76  if ( count( $expiry ) === 1 ) {
77  $expiry = array_fill( 0, count( $add ), $expiry[0] );
78  } else {
79  $this->dieWithError( [
80  'apierror-toofewexpiries',
81  count( $expiry ),
82  count( $add )
83  ] );
84  }
85  }
86 
87  // Validate the expiries
88  $groupExpiries = [];
89  foreach ( $expiry as $index => $expiryValue ) {
90  $group = $add[$index];
91  $groupExpiries[$group] = UserrightsPage::expiryToTimestamp( $expiryValue );
92 
93  if ( $groupExpiries[$group] === false ) {
94  $this->dieWithError( [ 'apierror-invalidexpiry', wfEscapeWikiText( $expiryValue ) ] );
95  }
96 
97  // not allowed to have things expiring in the past
98  if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) {
99  $this->dieWithError( [ 'apierror-pastexpiry', wfEscapeWikiText( $expiryValue ) ] );
100  }
101  }
102 
103  $user = $this->getUrUser( $params );
104 
105  $tags = $params['tags'];
106 
107  // Check if user can add tags
108  if ( $tags !== null ) {
109  $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $tags, $pUser );
110  if ( !$ableToTag->isOK() ) {
111  $this->dieStatus( $ableToTag );
112  }
113  }
114 
115  $form = $this->getUserRightsPage();
116  $form->setContext( $this->getContext() );
117  $r = [];
118  $r['user'] = $user->getName();
119  $r['userid'] = $user->getId();
120  list( $r['added'], $r['removed'] ) = $form->doSaveUserGroups(
121  // Don't pass null to doSaveUserGroups() for array params, cast to empty array
122  $user, (array)$add, (array)$params['remove'],
123  $params['reason'], (array)$tags, $groupExpiries
124  );
125 
126  $result = $this->getResult();
127  ApiResult::setIndexedTagName( $r['added'], 'group' );
128  ApiResult::setIndexedTagName( $r['removed'], 'group' );
129  $result->addValue( null, $this->getModuleName(), $r );
130  }
131 
136  private function getUrUser( array $params ) {
137  if ( $this->mUser !== null ) {
138  return $this->mUser;
139  }
140 
141  $this->requireOnlyOneParameter( $params, 'user', 'userid' );
142 
143  $user = $params['user'] ?? '#' . $params['userid'];
144 
145  $form = $this->getUserRightsPage();
146  $form->setContext( $this->getContext() );
147  $status = $form->fetchUser( $user );
148  if ( !$status->isOK() ) {
149  $this->dieStatus( $status );
150  }
151 
152  $this->mUser = $status->value;
153 
154  return $status->value;
155  }
156 
157  public function mustBePosted() {
158  return true;
159  }
160 
161  public function isWriteMode() {
162  return true;
163  }
164 
165  public function getAllowedParams( $flags = 0 ) {
166  $allGroups = $this->getAllGroups();
167 
168  if ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
169  sort( $allGroups );
170  }
171 
172  $a = [
173  'user' => [
174  ApiBase::PARAM_TYPE => 'user',
175  UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'id' ],
176  UserDef::PARAM_RETURN_OBJECT => true,
177  ],
178  'userid' => [
179  ApiBase::PARAM_TYPE => 'integer',
181  ],
182  'add' => [
183  ApiBase::PARAM_TYPE => $allGroups,
185  ],
186  'expiry' => [
187  ApiBase::PARAM_ISMULTI => true,
189  ApiBase::PARAM_DFLT => 'infinite',
190  ],
191  'remove' => [
192  ApiBase::PARAM_TYPE => $allGroups,
194  ],
195  'reason' => [
196  ApiBase::PARAM_DFLT => ''
197  ],
198  'token' => [
199  // Standard definition automatically inserted
200  ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
201  ],
202  'tags' => [
203  ApiBase::PARAM_TYPE => 'tags',
205  ],
206  ];
207  // CentralAuth's ApiGlobalUserRights subclass can't handle expiries
208  if ( !$this->getUserRightsPage()->canProcessExpiries() ) {
209  unset( $a['expiry'] );
210  }
211  return $a;
212  }
213 
214  public function needsToken() {
215  return 'userrights';
216  }
217 
218  protected function getWebUITokenSalt( array $params ) {
219  return $this->getUrUser( $params )->getName();
220  }
221 
222  protected function getExamplesMessages() {
223  $a = [
224  'action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
225  => 'apihelp-userrights-example-user',
226  'action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
227  => 'apihelp-userrights-example-userid',
228  ];
229  if ( $this->getUserRightsPage()->canProcessExpiries() ) {
230  $a['action=userrights&user=SometimeSysop&add=sysop&expiry=1%20month&token=123ABC']
231  = 'apihelp-userrights-example-expiry';
232  }
233  return $a;
234  }
235 
236  public function getHelpUrls() {
237  return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:User_group_membership';
238  }
239 }
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:40
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1379
true
return true
Definition: router.php:90
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:60
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:538
ApiUserrights\$mUser
$mUser
Definition: ApiUserrights.php:33
ApiUserrights\mustBePosted
mustBePosted()
Indicates whether this module must be called with a POST request.
Definition: ApiUserrights.php:157
ApiBase\dieBlocked
dieBlocked(AbstractBlock $block)
Throw an ApiUsageException, which will (if uncaught) call the main module's error handler and die wit...
Definition: ApiBase.php:1406
ApiUserrights\needsToken
needsToken()
Returns the token type this module requires in order to execute.
Definition: ApiUserrights.php:214
ApiBase\PARAM_ALLOW_DUPLICATES
const PARAM_ALLOW_DUPLICATES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:64
ContextSource\getUser
getUser()
Definition: ContextSource.php:120
ApiBase\PARAM_HELP_MSG_APPEND
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition: ApiBase.php:103
ApiUserrights\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiUserrights.php:222
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:48
Wikimedia\ParamValidator\ParamValidator::TypeDef\UserDef
Type definition for user types.
Definition: UserDef.php:23
ApiUserrights\execute
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
Definition: ApiUserrights.php:51
UserrightsPage\expiryToTimestamp
static expiryToTimestamp( $expiry)
Converts a user group membership expiry string into a timestamp.
Definition: SpecialUserrights.php:254
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:65
UserrightsPage
Special page to allow managing user group membership.
Definition: SpecialUserrights.php:31
ApiUserrights\getWebUITokenSalt
getWebUITokenSalt(array $params)
Fetch the salt used in the Web UI corresponding to this module.
Definition: ApiUserrights.php:218
ApiUserrights\getUrUser
getUrUser(array $params)
Definition: ApiUserrights.php:136
ApiUserrights\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiUserrights.php:236
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:659
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1835
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:604
ApiBase\requireOnlyOneParameter
requireOnlyOneParameter( $params,... $required)
Die if none or more than one of a certain set of parameters is set and not false.
Definition: ApiBase.php:796
ApiUserrights\getAllowedParams
getAllowedParams( $flags=0)
Definition: ApiUserrights.php:165
ApiBase\GET_VALUES_FOR_HELP
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition: ApiBase.php:167
ApiUserrights
Definition: ApiUserrights.php:31
ApiBase\getPermissionManager
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition: ApiBase.php:608
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1485
User\getAllGroups
static getAllGroups()
Return the set of defined explicit groups.
Definition: User.php:4553
ChangeTags\canAddTagsAccompanyingChange
static canAddTagsAccompanyingChange(array $tags, User $user=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
Definition: ChangeTags.php:528
ApiBase\PARAM_DFLT
const PARAM_DFLT
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:58
ApiBase\dieStatus
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:1437
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:418
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:59
ApiUserrights\getAllGroups
getAllGroups()
Get all available groups.
Definition: ApiUserrights.php:47
ApiUserrights\isWriteMode
isWriteMode()
Indicates whether this module requires write mode.
Definition: ApiUserrights.php:161
ApiUserrights\getUserRightsPage
getUserRightsPage()
Get a UserrightsPage object, or subclass.
Definition: ApiUserrights.php:39