diff --git a/src/wp-includes/class-wp-user.php b/src/wp-includes/class-wp-user.php index 0b0bb1023a..7cf311dbad 100644 --- a/src/wp-includes/class-wp-user.php +++ b/src/wp-includes/class-wp-user.php @@ -748,6 +748,9 @@ class WP_User { // Everyone is allowed to exist. $capabilities['exist'] = true; + // Nobody is allowed to do things they are not allowed to do. + unset( $capabilities['do_not_allow'] ); + // Must have ALL requested caps. foreach ( (array) $caps as $cap ) { if ( empty( $capabilities[ $cap ] ) ) diff --git a/tests/phpunit/tests/user/capabilities.php b/tests/phpunit/tests/user/capabilities.php index 241270495c..2070a64fa4 100644 --- a/tests/phpunit/tests/user/capabilities.php +++ b/tests/phpunit/tests/user/capabilities.php @@ -494,6 +494,57 @@ class Tests_User_Capabilities extends WP_UnitTestCase { $this->assertTrue( user_can( $user, 'exist' ), "User with the {$role} role should have the exist capability" ); } + /** + * @ticket 41059 + */ + public function test_do_not_allow_is_denied_for_all_roles() { + foreach ( self::$users as $role => $user ) { + + # Test adding the cap directly to the user + $user->add_cap( 'do_not_allow' ); + $has_cap = $user->has_cap( 'do_not_allow' ); + $user->remove_cap( 'do_not_allow' ); + $this->assertFalse( $has_cap, "User with the {$role} role should not have the do_not_allow capability" ); + + # Test adding the cap to the user's role + $role_obj = get_role( $role ); + $role_obj->add_cap( 'do_not_allow' ); + $has_cap = $user->has_cap( 'do_not_allow' ); + $role_obj->remove_cap( 'do_not_allow' ); + $this->assertFalse( $has_cap, "User with the {$role} role should not have the do_not_allow capability" ); + + # Test adding the cap via a filter + add_filter( 'user_has_cap', array( $this, 'grant_do_not_allow' ), 10, 4 ); + $has_cap = $user->has_cap( 'do_not_allow' ); + remove_filter( 'user_has_cap', array( $this, 'grant_do_not_allow' ), 10, 4 ); + $this->assertFalse( $has_cap, "User with the {$role} role should not have the do_not_allow capability" ); + + } + } + + /** + * @group ms-required + * @ticket 41059 + */ + public function test_do_not_allow_is_denied_for_super_admins() { + # Test adding the cap directly to the user + self::$super_admin->add_cap( 'do_not_allow' ); + $has_cap = self::$super_admin->has_cap( 'do_not_allow' ); + self::$super_admin->remove_cap( 'do_not_allow' ); + $this->assertFalse( $has_cap, 'Super admins should not have the do_not_allow capability' ); + + # Test adding the cap via a filter + add_filter( 'user_has_cap', array( $this, 'grant_do_not_allow' ), 10, 4 ); + $has_cap = self::$super_admin->has_cap( 'do_not_allow' ); + remove_filter( 'user_has_cap', array( $this, 'grant_do_not_allow' ), 10, 4 ); + $this->assertFalse( $has_cap, 'Super admins should not have the do_not_allow capability' ); + } + + public function grant_do_not_allow( $allcaps, $caps, $args, $user ) { + $allcaps['do_not_allow'] = true; + return $allcaps; + } + // special case for the link manager function test_link_manager_caps() { $caps = array(