Skip to content

Commit 539b854

Browse files
committed
Multisite: Handle capability check for removing oneself via map_meta_cap().
Site administrators should not be able to remove themselves from a site. This moves the enforcement of this rule from `wp-admin/users.php` to `remove_user_from_blog()` via the `remove_user` capability, which furthermore allows us to get rid of two additional clauses and their `is_super_admin()` checks in `wp-admin/users.php`. A unit test for the new behavior has been added. Fixes #39063. See #37616. git-svn-id: https://develop.svn.wordpress.org/trunk@39588 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 87e6390 commit 539b854

3 files changed

Lines changed: 24 additions & 9 deletions

File tree

src/wp-admin/users.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,6 @@
321321
$update = 'remove';
322322
foreach ( $userids as $id ) {
323323
$id = (int) $id;
324-
if ( $id == $current_user->ID && !is_super_admin() ) {
325-
$update = 'err_admin_remove';
326-
continue;
327-
}
328324
if ( !current_user_can('remove_user', $id) ) {
329325
$update = 'err_admin_remove';
330326
continue;
@@ -377,10 +373,7 @@
377373
foreach ( $userids as $id ) {
378374
$id = (int) $id;
379375
$user = get_userdata( $id );
380-
if ( $id == $current_user->ID && !is_super_admin() ) {
381-
/* translators: 1: user id, 2: user login */
382-
echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>The current user will not be removed.</strong>'), $id, $user->user_login) . "</li>\n";
383-
} elseif ( !current_user_can('remove_user', $id) ) {
376+
if ( ! current_user_can( 'remove_user', $id ) ) {
384377
/* translators: 1: user id, 2: user login */
385378
echo "<li>" . sprintf(__('ID #%1$s: %2$s <strong>Sorry, you are not allowed to remove this user.</strong>'), $id, $user->user_login) . "</li>\n";
386379
} else {

src/wp-includes/capabilities.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ function map_meta_cap( $cap, $user_id ) {
3232

3333
switch ( $cap ) {
3434
case 'remove_user':
35-
$caps[] = 'remove_users';
35+
// In multisite the user must be a super admin to remove themselves.
36+
if ( isset( $args[0] ) && $user_id == $args[0] && ! is_super_admin( $user_id ) ) {
37+
$caps[] = 'do_not_allow';
38+
} else {
39+
$caps[] = 'remove_users';
40+
}
3641
break;
3742
case 'promote_user':
3843
case 'add_users':

tests/phpunit/tests/user/capabilities.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,4 +1757,21 @@ public function test_user_cannot_add_user_meta() {
17571757
wp_set_current_user( self::$users['editor']->ID );
17581758
$this->assertFalse( current_user_can( 'add_user_meta', self::$users['subscriber']->ID, 'foo' ) );
17591759
}
1760+
1761+
/**
1762+
* @ticket 39063
1763+
*/
1764+
public function test_only_super_admins_can_remove_themselves_on_multisite() {
1765+
if ( ! is_multisite() ) {
1766+
$this->markTestSkipped( 'Test only runs in multisite.' );
1767+
}
1768+
1769+
$this->assertTrue( user_can( self::$super_admin->ID, 'remove_user', self::$super_admin->ID ) );
1770+
1771+
$this->assertFalse( user_can( self::$users['administrator']->ID, 'remove_user', self::$users['administrator']->ID ) );
1772+
$this->assertFalse( user_can( self::$users['editor']->ID, 'remove_user', self::$users['editor']->ID ) );
1773+
$this->assertFalse( user_can( self::$users['author']->ID, 'remove_user', self::$users['author']->ID ) );
1774+
$this->assertFalse( user_can( self::$users['contributor']->ID, 'remove_user', self::$users['contributor']->ID ) );
1775+
$this->assertFalse( user_can( self::$users['subscriber']->ID, 'remove_user', self::$users['subscriber']->ID ) );
1776+
}
17601777
}

0 commit comments

Comments
 (0)