diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index 08cba90a23..5dda1a9360 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -11,6 +11,15 @@ * Base Global Styles REST API Controller. */ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { + + /** + * Post type. + * + * @since 5.9.0 + * @var string + */ + protected $post_type; + /** * Constructor. * @since 5.9.0 @@ -18,6 +27,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'global-styles'; + $this->post_type = 'wp_global_styles'; } /** @@ -75,22 +85,32 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { } /** - * Checks if the user has permissions to make the request. + * Checks if a given request has access to read a single global style. * * @since 5.9.0 * + * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ - protected function permissions_check() { - // Verify if the current user has edit_theme_options capability. - // This capability is required to edit/view/delete templates. - if ( ! current_user_can( 'edit_theme_options' ) ) { + public function get_item_permissions_check( $request ) { + $post = $this->get_post( $request['id'] ); + if ( is_wp_error( $post ) ) { + return $post; + } + + if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( - 'rest_cannot_manage_global_styles', - __( 'Sorry, you are not allowed to access the global styles on this site.' ), - array( - 'status' => rest_authorization_required_code(), - ) + 'rest_forbidden_context', + __( 'Sorry, you are not allowed to edit this global style.' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + + if ( ! $this->check_read_permission( $post ) ) { + return new WP_Error( + 'rest_cannot_view', + __( 'Sorry, you are not allowed to view this global style.' ), + array( 'status' => rest_authorization_required_code() ) ); } @@ -98,13 +118,15 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { } /** - * Checks if a given request has access to read a single global styles config. + * Checks if a global style can be read. * - * @param WP_REST_Request $request Full details about the request. - * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. + * @since 5.9.0 + * + * @param WP_Post $post Post object. + * @return bool Whether the post can be read. */ - public function get_item_permissions_check( $request ) { - return $this->permissions_check( $request ); + protected function check_read_permission( $post ) { + return current_user_can( 'read_post', $post->ID ); } /** @@ -117,9 +139,9 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { * @return WP_REST_Response|WP_Error */ public function get_item( $request ) { - $post = get_post( $request['id'] ); - if ( ! $post || 'wp_global_styles' !== $post->post_type ) { - return new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exist with that id.' ), array( 'status' => 404 ) ); + $post = $this->get_post( $request['id'] ); + if ( is_wp_error( $post ) ) { + return $post; } return $this->prepare_item_for_response( $post, $request ); @@ -134,7 +156,32 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { * @return true|WP_Error True if the request has write access for the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { - return $this->permissions_check( $request ); + $post = $this->get_post( $request['id'] ); + if ( is_wp_error( $post ) ) { + return $post; + } + + if ( $post && ! $this->check_update_permission( $post ) ) { + return new WP_Error( + 'rest_cannot_edit', + __( 'Sorry, you are not allowed to edit this global style.' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + + return true; + } + + /** + * Checks if a global style can be edited. + * + * @since 5.9.0 + * + * @param WP_Post $post Post object. + * @return bool Whether the post can be edited. + */ + protected function check_update_permission( $post ) { + return current_user_can( 'edit_post', $post->ID ); } /** @@ -146,9 +193,9 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { - $post_before = get_post( $request['id'] ); - if ( ! $post_before || 'wp_global_styles' !== $post_before->post_type ) { - return new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exist with that id.' ), array( 'status' => 404 ) ); + $post_before = $this->get_post( $request['id'] ); + if ( is_wp_error( $post_before ) ) { + return $post_before; } $changes = $this->prepare_item_for_database( $request ); @@ -289,6 +336,34 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { return $response; } + /** + * Get the post, if the ID is valid. + * + * @since 5.9.0 + * + * @param int $id Supplied ID. + * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. + */ + protected function get_post( $id ) { + $error = new WP_Error( + 'rest_global_styles_not_found', + __( 'No global styles config exist with that id.' ), + array( 'status' => 404 ) + ); + + $id = (int) $id; + if ( $id <= 0 ) { + return $error; + } + + $post = get_post( $id ); + if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { + return $error; + } + + return $post; + } + /** * Prepares links for the request. @@ -323,7 +398,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { protected function get_available_actions() { $rels = array(); - $post_type = get_post_type_object( 'wp_global_styles' ); + $post_type = get_post_type_object( $this->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } @@ -371,7 +446,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'wp_global_styles', + 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( @@ -426,7 +501,19 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_theme_item_permissions_check( $request ) { - return $this->permissions_check( $request ); + // Verify if the current user has edit_theme_options capability. + // This capability is required to edit/view/delete templates. + if ( ! current_user_can( 'edit_theme_options' ) ) { + return new WP_Error( + 'rest_cannot_manage_global_styles', + __( 'Sorry, you are not allowed to access the global styles on this site.' ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + return true; } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index fd428ed4fc..7d048d777e 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '5.9-beta1-52341'; +$wp_version = '5.9-beta1-52342'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.