MediaWiki REL1_31
ApiUserrightsTest.php
Go to the documentation of this file.
1<?php
2
19 protected function setPermissions( $add = [], $remove = [] ) {
21
22 $this->setGroupPermissions( 'bureaucrat', 'userrights', false );
23
24 if ( $add ) {
25 $this->stashMwGlobals( 'wgAddGroups' );
26 $wgAddGroups['bureaucrat'] = $add;
27 }
28 if ( $remove ) {
29 $this->stashMwGlobals( 'wgRemoveGroups' );
30 $wgRemoveGroups['bureaucrat'] = $remove;
31 }
32 }
33
48 protected function doSuccessfulRightsChange(
49 $expectedGroups = 'sysop', array $params = [], User $user = null
50 ) {
51 $expectedGroups = (array)$expectedGroups;
52 $params['action'] = 'userrights';
53
54 if ( !$user ) {
55 $user = $this->getMutableTestUser()->getUser();
56 }
57
58 $this->assertTrue( TestUserRegistry::isMutable( $user ),
59 'Immutable user passed to doSuccessfulRightsChange!' );
60
61 if ( !isset( $params['user'] ) && !isset( $params['userid'] ) ) {
62 $params['user'] = $user->getName();
63 }
64 if ( !isset( $params['add'] ) && !isset( $params['remove'] ) ) {
65 $params['add'] = 'sysop';
66 }
67
69
70 $user->clearInstanceCache();
71 $this->assertSame( $expectedGroups, $user->getGroups() );
72
73 $this->assertArrayNotHasKey( 'warnings', $res[0] );
74 }
75
85 protected function doFailedRightsChange(
86 $expectedException, array $params = [], User $user = null
87 ) {
88 $params['action'] = 'userrights';
89
90 $this->setExpectedException( ApiUsageException::class, $expectedException );
91
92 if ( !$user ) {
93 // If 'user' or 'userid' is specified and $user was not specified,
94 // the user we're creating now will have nothing to do with the API
95 // request, but that's okay, since we're just testing that it has
96 // no groups.
97 $user = $this->getMutableTestUser()->getUser();
98 }
99
100 $this->assertTrue( TestUserRegistry::isMutable( $user ),
101 'Immutable user passed to doFailedRightsChange!' );
102
103 if ( !isset( $params['user'] ) && !isset( $params['userid'] ) ) {
104 $params['user'] = $user->getName();
105 }
106 if ( !isset( $params['add'] ) && !isset( $params['remove'] ) ) {
107 $params['add'] = 'sysop';
108 }
109 $expectedGroups = $user->getGroups();
110
111 try {
113 } finally {
114 $user->clearInstanceCache();
115 $this->assertSame( $expectedGroups, $user->getGroups() );
116 }
117 }
118
119 public function testAdd() {
121 }
122
123 public function testBlockedWithUserrights() {
124 global $wgUser;
125
126 $block = new Block( [ 'address' => $wgUser, 'by' => $wgUser->getId(), ] );
127 $block->insert();
128
129 try {
131 } finally {
132 $block->delete();
133 $wgUser->clearInstanceCache();
134 }
135 }
136
138 $user = $this->getTestSysop()->getUser();
139
140 $this->setPermissions( true, true );
141
142 $block = new Block( [ 'address' => $user, 'by' => $user->getId() ] );
143 $block->insert();
144
145 try {
146 $this->doFailedRightsChange( 'You have been blocked from editing.' );
147 } finally {
148 $block->delete();
149 $user->clearInstanceCache();
150 }
151 }
152
153 public function testAddMultiple() {
155 [ 'bureaucrat', 'sysop' ],
156 [ 'add' => 'bureaucrat|sysop' ]
157 );
158 }
159
160 public function testTooFewExpiries() {
162 '2 expiry timestamps were provided where 3 were needed.',
163 [ 'add' => 'sysop|bureaucrat|bot', 'expiry' => 'infinity|tomorrow' ]
164 );
165 }
166
167 public function testTooManyExpiries() {
169 '3 expiry timestamps were provided where 2 were needed.',
170 [ 'add' => 'sysop|bureaucrat', 'expiry' => 'infinity|tomorrow|never' ]
171 );
172 }
173
174 public function testInvalidExpiry() {
175 $this->doFailedRightsChange( 'Invalid expiry time', [ 'expiry' => 'yummy lollipops!' ] );
176 }
177
178 public function testMultipleInvalidExpiries() {
180 'Invalid expiry time "foo".',
181 [ 'add' => 'sysop|bureaucrat', 'expiry' => 'foo|bar' ]
182 );
183 }
184
185 public function testWithTag() {
186 ChangeTags::defineTag( 'custom tag' );
187
188 $user = $this->getMutableTestUser()->getUser();
189
190 $this->doSuccessfulRightsChange( 'sysop', [ 'tags' => 'custom tag' ], $user );
191
193 $this->assertSame(
194 'custom tag',
195 $dbr->selectField(
196 [ 'change_tag', 'logging' ],
197 'ct_tag',
198 [
199 'ct_log_id = log_id',
200 'log_namespace' => NS_USER,
201 'log_title' => strtr( $user->getName(), ' ', '_' )
202 ],
203 __METHOD__
204 )
205 );
206 }
207
208 public function testWithoutTagPermission() {
209 global $wgGroupPermissions;
210
211 ChangeTags::defineTag( 'custom tag' );
212
213 $this->stashMwGlobals( 'wgGroupPermissions' );
214 $wgGroupPermissions['user']['applychangetags'] = false;
215
217 'You do not have permission to apply change tags along with your changes.',
218 [ 'tags' => 'custom tag' ]
219 );
220 }
221
222 public function testNonexistentUser() {
224 'There is no user by the name "Nonexistent user". Check your spelling.',
225 [ 'user' => 'Nonexistent user' ]
226 );
227 }
228
229 public function testWebToken() {
230 $sysop = $this->getTestSysop()->getUser();
231 $user = $this->getMutableTestUser()->getUser();
232
233 $token = $sysop->getEditToken( $user->getName() );
234
235 $res = $this->doApiRequest( [
236 'action' => 'userrights',
237 'user' => $user->getName(),
238 'add' => 'sysop',
239 'token' => $token,
240 ] );
241
242 $user->clearInstanceCache();
243 $this->assertSame( [ 'sysop' ], $user->getGroups() );
244
245 $this->assertArrayNotHasKey( 'warnings', $res[0] );
246 }
247
256 private function getMockForProcessingExpiries( $canProcessExpiries ) {
257 $sysop = $this->getTestSysop()->getUser();
258 $user = $this->getMutableTestUser()->getUser();
259
260 $token = $sysop->getEditToken( 'userrights' );
261
262 $main = new ApiMain( new FauxRequest( [
263 'action' => 'userrights',
264 'user' => $user->getName(),
265 'add' => 'sysop',
266 'token' => $token,
267 ] ) );
268
269 $mockUserRightsPage = $this->getMockBuilder( UserrightsPage::class )
270 ->setMethods( [ 'canProcessExpiries' ] )
271 ->getMock();
272 $mockUserRightsPage->method( 'canProcessExpiries' )->willReturn( $canProcessExpiries );
273
274 $mockApi = $this->getMockBuilder( ApiUserrights::class )
275 ->setConstructorArgs( [ $main, 'userrights' ] )
276 ->setMethods( [ 'getUserRightsPage' ] )
277 ->getMock();
278 $mockApi->method( 'getUserRightsPage' )->willReturn( $mockUserRightsPage );
279
280 return $mockApi;
281 }
282
283 public function testCanProcessExpiries() {
284 $mock1 = $this->getMockForProcessingExpiries( true );
285 $this->assertArrayHasKey( 'expiry', $mock1->getAllowedParams() );
286
287 $mock2 = $this->getMockForProcessingExpiries( false );
288 $this->assertArrayNotHasKey( 'expiry', $mock2->getAllowedParams() );
289 }
290
300 public function testAddAndRemoveGroups(
301 array $permissions = null, array $groupsToChange, array $expectedGroups
302 ) {
303 if ( $permissions !== null ) {
304 $this->setPermissions( $permissions[0], $permissions[1] );
305 }
306
307 $params = [
308 'add' => implode( '|', $groupsToChange[0] ),
309 'remove' => implode( '|', $groupsToChange[1] ),
310 ];
311
312 // We'll take a bot so we have a group to remove
313 $user = $this->getMutableTestUser( [ 'bot' ] )->getUser();
314
315 $this->doSuccessfulRightsChange( $expectedGroups, $params, $user );
316 }
317
318 public function addAndRemoveGroupsProvider() {
319 return [
320 'Simple add' => [
321 [ [ 'sysop' ], [] ],
322 [ [ 'sysop' ], [] ],
323 [ 'bot', 'sysop' ]
324 ], 'Add with only remove permission' => [
325 [ [], [ 'sysop' ] ],
326 [ [ 'sysop' ], [] ],
327 [ 'bot' ],
328 ], 'Add with global remove permission' => [
329 [ [], true ],
330 [ [ 'sysop' ], [] ],
331 [ 'bot' ],
332 ], 'Simple remove' => [
333 [ [], [ 'bot' ] ],
334 [ [], [ 'bot' ] ],
335 [],
336 ], 'Remove with only add permission' => [
337 [ [ 'bot' ], [] ],
338 [ [], [ 'bot' ] ],
339 [ 'bot' ],
340 ], 'Remove with global add permission' => [
341 [ true, [] ],
342 [ [], [ 'bot' ] ],
343 [ 'bot' ],
344 ], 'Add and remove same new group' => [
345 null,
346 [ [ 'sysop' ], [ 'sysop' ] ],
347 // The userrights code does removals before adds, so it doesn't remove the sysop
348 // group here and only adds it.
349 [ 'bot', 'sysop' ],
350 ], 'Add and remove same existing group' => [
351 null,
352 [ [ 'bot' ], [ 'bot' ] ],
353 // But here it first removes the existing group and then re-adds it.
354 [ 'bot' ],
355 ],
356 ];
357 }
358}
$wgRemoveGroups
$wgAddGroups
$wgAddGroups and $wgRemoveGroups can be used to give finer control over who can assign which groups a...
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
$wgGroupPermissions['sysop']['replacetext']
$wgUser
Definition Setup.php:902
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:43
doApiRequestWithToken(array $params, array $session=null, User $user=null, $tokenType='auto')
Convenience function to access the token parameter of doApiRequest() more succinctly.
doApiRequest(array $params, array $session=null, $appendModule=false, User $user=null, $tokenType=null)
Does the API request and returns the result.
API Database medium.
testAddAndRemoveGroups(array $permissions=null, array $groupsToChange, array $expectedGroups)
Tests adding and removing various groups with various permissions.
doFailedRightsChange( $expectedException, array $params=[], User $user=null)
Perform an API userrights request that's expected to fail.
doSuccessfulRightsChange( $expectedGroups='sysop', array $params=[], User $user=null)
Perform an API userrights request that's expected to be successful.
setPermissions( $add=[], $remove=[])
Unsets $wgGroupPermissions['bureaucrat']['userrights'], and sets $wgAddGroups['bureaucrat'] and $wgRe...
getMockForProcessingExpiries( $canProcessExpiries)
Helper for testCanProcessExpiries that returns a mock ApiUserrights that either can or cannot process...
static defineTag( $tag)
Defines a tag in the valid_tag table, without checking that the tag name is valid.
WebRequest clone which takes values from a provided array.
static getMutableTestUser( $groups=[])
Convenience method for getting a mutable test user.
setGroupPermissions( $newPerms, $newKey=null, $newValue=null)
Alters $wgGroupPermissions for the duration of the test.
static getTestSysop()
Convenience method for getting an immutable admin test user.
stashMwGlobals( $globalKeys)
Stashes the global, will be restored in tearDown()
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:53
$res
Definition database.txt:21
the array() calling protocol came about after MediaWiki 1.4rc1.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition hooks.txt:2006
const DB_REPLICA
Definition defines.php:25
$params