MediaWiki REL1_35
ApiUserrights.php
Go to the documentation of this file.
1<?php
2
27
31class 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, $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' => [
189 ApiBase::PARAM_DFLT => 'infinite',
190 ],
191 'remove' => [
192 ApiBase::PARAM_TYPE => $allGroups,
194 ],
195 'reason' => [
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}
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:52
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1437
const PARAM_DEPRECATED
Definition ApiBase.php:98
const PARAM_TYPE
Definition ApiBase.php:78
const PARAM_DFLT
Definition ApiBase.php:70
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition ApiBase.php:169
const PARAM_ALLOW_DUPLICATES
Definition ApiBase.php:94
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition ApiBase.php:692
requireOnlyOneParameter( $params,... $required)
Die if none or more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:909
dieBlocked(AbstractBlock $block)
Throw an ApiUsageException, which will (if uncaught) call the main module's error handler and die wit...
Definition ApiBase.php:1464
getResult()
Get the result object.
Definition ApiBase.php:620
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:772
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
Definition ApiBase.php:233
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:499
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1495
const PARAM_ISMULTI
Definition ApiBase.php:74
getHelpUrls()
Return links to more detailed help pages about the module.
getAllowedParams( $flags=0)
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
mustBePosted()
Indicates whether this module must be called with a POST request Stable to override.
getUrUser(array $params)
getUserRightsPage()
Get a UserrightsPage object, or subclass.
needsToken()
Returns the token type this module requires in order to execute.
getAllGroups()
Get all available groups.
isWriteMode()
Indicates whether this module requires write mode.
getExamplesMessages()
Returns usage examples for this module.
getWebUITokenSalt(array $params)
Fetch the salt used in the Web UI corresponding to this module.
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...
getUser()
Stable to override.
getContext()
Get the base IContextSource object.
Type definition for user types.
Definition UserDef.php:23
static getAllGroups()
Return the set of defined explicit groups.
Definition User.php:4262
Special page to allow managing user group membership.
static expiryToTimestamp( $expiry)
Converts a user group membership expiry string into a timestamp.
return true
Definition router.php:92