From 4d2abda74a8bb70b65b94bd3d03bb5ac10d2fb3c Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Thu, 4 Mar 2021 00:14:04 +0000 Subject: [PATCH] Roles/Caps: Return same result from `current_user_can` and `user_can()`. Ensure `current_user_can()` and `user_can()` return the same results for logged out users. For core capabilities this changes `user_can( 0, 'exist' )` to return `true` rather than `false` in line with `current_user_can( 'exist' )` for logged out users. Convert `current_user_can()` and `current_user_can_for_blog()` to wrapper functions ultimately calling `user_can()`. Add anonymous user to primitive capability checks as appropriate. Convert `Tests_User_Capabilities::test_other_caps_for_all_roles()` to use a data provider and add tests to check whether user exists in the database (`WP_User::exists()`) as that intentionally differs from the `exist` capability. Props jjj, johnbillion, peterwilsoncc, SergeyBiryukov, TimothyBlynJacobs. Fixes #52076. Built from https://develop.svn.wordpress.org/trunk@50490 git-svn-id: http://core.svn.wordpress.org/trunk@50103 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/capabilities.php | 27 ++++++++------------------- wp-includes/class-wp-user.php | 3 +++ wp-includes/version.php | 2 +- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/wp-includes/capabilities.php b/wp-includes/capabilities.php index f7ff5cbab2..3ff0481fd4 100644 --- a/wp-includes/capabilities.php +++ b/wp-includes/capabilities.php @@ -679,6 +679,7 @@ function map_meta_cap( $cap, $user_id, ...$args ) { * @since 2.0.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. + * @since 5.8.0 Converted to wrapper for the user_can() function. * * @see WP_User::has_cap() * @see map_meta_cap() @@ -689,13 +690,7 @@ function map_meta_cap( $cap, $user_id, ...$args ) { * passed, whether the current user has the given meta capability for the given object. */ function current_user_can( $capability, ...$args ) { - $current_user = wp_get_current_user(); - - if ( empty( $current_user ) ) { - return false; - } - - return $current_user->has_cap( $capability, ...$args ); + return user_can( wp_get_current_user(), $capability, ...$args ); } /** @@ -714,6 +709,7 @@ function current_user_can( $capability, ...$args ) { * @since 3.0.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. + * @since 5.8.0 Wraps current_user_can() after switching to blog. * * @param int $blog_id Site ID. * @param string $capability Capability name. @@ -723,16 +719,7 @@ function current_user_can( $capability, ...$args ) { function current_user_can_for_blog( $blog_id, $capability, ...$args ) { $switched = is_multisite() ? switch_to_blog( $blog_id ) : false; - $current_user = wp_get_current_user(); - - if ( empty( $current_user ) ) { - if ( $switched ) { - restore_current_blog(); - } - return false; - } - - $can = $current_user->has_cap( $capability, ...$args ); + $can = current_user_can( $capability, ...$args ); if ( $switched ) { restore_current_blog(); @@ -805,8 +792,10 @@ function user_can( $user, $capability, ...$args ) { $user = get_userdata( $user ); } - if ( ! $user || ! $user->exists() ) { - return false; + if ( empty( $user ) ) { + // User is logged out, create anonymous user object. + $user = new WP_User( 0 ); + $user->init( new stdClass ); } return $user->has_cap( $capability, ...$args ); diff --git a/wp-includes/class-wp-user.php b/wp-includes/class-wp-user.php index 87518c45c8..195bc24341 100644 --- a/wp-includes/class-wp-user.php +++ b/wp-includes/class-wp-user.php @@ -167,6 +167,9 @@ class WP_User { * @param int $site_id Optional. The site ID to initialize for. */ public function init( $data, $site_id = '' ) { + if ( ! isset( $data->ID ) ) { + $data->ID = 0; + } $this->data = $data; $this->ID = (int) $data->ID; diff --git a/wp-includes/version.php b/wp-includes/version.php index 3541c83d2e..dfaecb3319 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.8-alpha-50488'; +$wp_version = '5.8-alpha-50490'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.