MediaWiki REL1_37
ApiUserrights.php
Go to the documentation of this file.
1<?php
2
30
34class ApiUserrights extends ApiBase {
35
36 private $mUser = null;
37
40
46 public function __construct(
47 ApiMain $mainModule,
48 $moduleName,
50 ) {
51 parent::__construct( $mainModule, $moduleName );
52 // This class is extended and therefor fallback to global state - T285797
53 $this->userGroupManager = $userGroupManager ?? MediaWikiServices::getInstance()->getUserGroupManager();
54 }
55
60 protected function getUserRightsPage() {
61 return new UserrightsPage;
62 }
63
68 protected function getAllGroups() {
69 return $this->userGroupManager->listAllGroups();
70 }
71
72 public function execute() {
73 $pUser = $this->getUser();
74
75 // Deny if the user is blocked and doesn't have the full 'userrights' permission.
76 // This matches what Special:UserRights does for the web UI.
77 if ( !$this->getAuthority()->isAllowed( 'userrights' ) ) {
78 $block = $pUser->getBlock( Authority::READ_LATEST );
79 if ( $block && $block->isSitewide() ) {
80 $this->dieBlocked( $block );
81 }
82 }
83
84 $params = $this->extractRequestParams();
85
86 // Figure out expiry times from the input
87 // $params['expiry'] is not set in CentralAuth's ApiGlobalUserRights subclass
88 if ( isset( $params['expiry'] ) ) {
89 $expiry = (array)$params['expiry'];
90 } else {
91 $expiry = [ 'infinity' ];
92 }
93 $add = (array)$params['add'];
94 if ( !$add ) {
95 $expiry = [];
96 } elseif ( count( $expiry ) !== count( $add ) ) {
97 if ( count( $expiry ) === 1 ) {
98 $expiry = array_fill( 0, count( $add ), $expiry[0] );
99 } else {
100 $this->dieWithError( [
101 'apierror-toofewexpiries',
102 count( $expiry ),
103 count( $add )
104 ] );
105 }
106 }
107
108 // Validate the expiries
109 $groupExpiries = [];
110 foreach ( $expiry as $index => $expiryValue ) {
111 $group = $add[$index];
112 $groupExpiries[$group] = UserrightsPage::expiryToTimestamp( $expiryValue );
113
114 if ( $groupExpiries[$group] === false ) {
115 $this->dieWithError( [ 'apierror-invalidexpiry', wfEscapeWikiText( $expiryValue ) ] );
116 }
117
118 // not allowed to have things expiring in the past
119 if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) {
120 $this->dieWithError( [ 'apierror-pastexpiry', wfEscapeWikiText( $expiryValue ) ] );
121 }
122 }
123
124 $user = $this->getUrUser( $params );
125
126 $tags = $params['tags'];
127
128 // Check if user can add tags
129 if ( $tags !== null ) {
130 $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $tags, $this->getAuthority() );
131 if ( !$ableToTag->isOK() ) {
132 $this->dieStatus( $ableToTag );
133 }
134 }
135
136 $form = $this->getUserRightsPage();
137 $form->setContext( $this->getContext() );
138 $r = [];
139 $r['user'] = $user->getName();
140 $r['userid'] = $user->getId();
141 list( $r['added'], $r['removed'] ) = $form->doSaveUserGroups(
142 // Don't pass null to doSaveUserGroups() for array params, cast to empty array
143 $user, $add, (array)$params['remove'],
144 $params['reason'], (array)$tags, $groupExpiries
145 );
146
147 $result = $this->getResult();
148 ApiResult::setIndexedTagName( $r['added'], 'group' );
149 ApiResult::setIndexedTagName( $r['removed'], 'group' );
150 $result->addValue( null, $this->getModuleName(), $r );
151 }
152
157 private function getUrUser( array $params ) {
158 if ( $this->mUser !== null ) {
159 return $this->mUser;
160 }
161
162 $this->requireOnlyOneParameter( $params, 'user', 'userid' );
163
164 $user = $params['user'] ?? '#' . $params['userid'];
165
166 $form = $this->getUserRightsPage();
167 $form->setContext( $this->getContext() );
168 $status = $form->fetchUser( $user );
169 if ( !$status->isOK() ) {
170 $this->dieStatus( $status );
171 }
172
173 $this->mUser = $status->value;
174
175 return $status->value;
176 }
177
178 public function mustBePosted() {
179 return true;
180 }
181
182 public function isWriteMode() {
183 return true;
184 }
185
186 public function getAllowedParams( $flags = 0 ) {
187 $allGroups = $this->getAllGroups();
188
189 if ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
190 sort( $allGroups );
191 }
192
193 $a = [
194 'user' => [
195 ApiBase::PARAM_TYPE => 'user',
196 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'id' ],
197 ],
198 'userid' => [
199 ApiBase::PARAM_TYPE => 'integer',
201 ],
202 'add' => [
203 ApiBase::PARAM_TYPE => $allGroups,
205 ],
206 'expiry' => [
209 ApiBase::PARAM_DFLT => 'infinite',
210 ],
211 'remove' => [
212 ApiBase::PARAM_TYPE => $allGroups,
214 ],
215 'reason' => [
217 ],
218 'token' => [
219 // Standard definition automatically inserted
220 ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
221 ],
222 'tags' => [
223 ApiBase::PARAM_TYPE => 'tags',
225 ],
226 ];
227 // CentralAuth's ApiGlobalUserRights subclass can't handle expiries
228 if ( !$this->getUserRightsPage()->canProcessExpiries() ) {
229 unset( $a['expiry'] );
230 }
231 return $a;
232 }
233
234 public function needsToken() {
235 return 'userrights';
236 }
237
238 protected function getWebUITokenSalt( array $params ) {
239 return $this->getUrUser( $params )->getName();
240 }
241
242 protected function getExamplesMessages() {
243 $a = [
244 'action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
245 => 'apihelp-userrights-example-user',
246 'action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
247 => 'apihelp-userrights-example-userid',
248 ];
249 if ( $this->getUserRightsPage()->canProcessExpiries() ) {
250 $a['action=userrights&user=SometimeSysop&add=sysop&expiry=1%20month&token=123ABC']
251 = 'apihelp-userrights-example-expiry';
252 }
253 return $a;
254 }
255
256 public function getHelpUrls() {
257 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:User_group_membership';
258 }
259}
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:55
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1436
const PARAM_DEPRECATED
Definition ApiBase.php:101
const PARAM_TYPE
Definition ApiBase.php:81
const PARAM_DFLT
Definition ApiBase.php:73
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:97
requireOnlyOneParameter( $params,... $required)
Die if none or more than one of a certain set of parameters is set and not false.
Definition ApiBase.php:901
getResult()
Get the result object.
Definition ApiBase.php:628
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:764
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:497
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1495
dieBlocked(Block $block)
Throw an ApiUsageException, which will (if uncaught) call the main module's error handler and die wit...
Definition ApiBase.php:1463
const PARAM_ISMULTI
Definition ApiBase.php:77
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:49
__construct(ApiMain $mainModule, $moduleName, UserGroupManager $userGroupManager=null)
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.
UserGroupManager $userGroupManager
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, Authority $performer=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
getContext()
Get the base IContextSource object.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Type definition for user types.
Definition UserDef.php:25
Special page to allow managing user group membership.
static expiryToTimestamp( $expiry)
Converts a user group membership expiry string into a timestamp.
This interface represents the authority associated the current execution context, such as a web reque...
Definition Authority.php:37
return true
Definition router.php:92