Make WordPress Core

Changeset 59048


Ignore:
Timestamp:
09/18/2024 05:17:05 AM (4 weeks ago)
Author:
ramonopoly
Message:

Global Styles: allow read access to users with edit_posts capabilities

This patch any role that can edit a post, including custom post types, or edit theme options to read global styles from the API. This enables read-only access to global styles in the post editor. Test coverage in included.

Props ramonopoly, peterwilsoncc, mukesh27, aaronrobertshaw, mamaduka, spacedmonkey, talldanwp, timothyblynjacobs.
Fixes #62042.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/post.php

    r59045 r59048  
    490490            'late_route_registration'         => true,
    491491            'capabilities'                    => array(
    492                 'read'                   => 'edit_theme_options',
     492                'read'                   => 'edit_posts',
    493493                'create_posts'           => 'edit_theme_options',
    494494                'edit_posts'             => 'edit_theme_options',
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php

    r59009 r59048  
    510510     *
    511511     * @since 5.9.0
     512     * @since 6.7.0 Allow users with edit post capabilities to view theme global styles.
    512513     *
    513514     * @param WP_REST_Request $request Full details about the request.
     
    516517    public function get_theme_item_permissions_check( $request ) {
    517518        /*
     519         * Verify if the current user has edit_posts capability.
     520         * This capability is required to view global styles.
     521         */
     522        if ( current_user_can( 'edit_posts' ) ) {
     523            return true;
     524        }
     525
     526        foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
     527            if ( current_user_can( $post_type->cap->edit_posts ) ) {
     528                return true;
     529            }
     530        }
     531
     532        /*
    518533         * Verify if the current user has edit_theme_options capability.
    519          * This capability is required to edit/view/delete global styles.
    520534         */
    521         if ( ! current_user_can( 'edit_theme_options' ) ) {
    522             return new WP_Error(
    523                 'rest_cannot_manage_global_styles',
    524                 __( 'Sorry, you are not allowed to access the global styles on this site.' ),
    525                 array(
    526                     'status' => rest_authorization_required_code(),
    527                 )
    528             );
    529         }
    530 
    531         return true;
     535        if ( current_user_can( 'edit_theme_options' ) ) {
     536            return true;
     537        }
     538
     539        return new WP_Error(
     540            'rest_cannot_read_global_styles',
     541            __( 'Sorry, you are not allowed to access the global styles on this site.' ),
     542            array(
     543                'status' => rest_authorization_required_code(),
     544            )
     545        );
    532546    }
    533547
     
    590604     *
    591605     * @since 6.0.0
     606     * @since 6.7.0 Allow users with edit post capabilities to view theme global styles.
    592607     *
    593608     * @param WP_REST_Request $request Full details about the request.
     
    595610     */
    596611    public function get_theme_items_permissions_check( $request ) {
    597         /*
    598          * Verify if the current user has edit_theme_options capability.
    599          * This capability is required to edit/view/delete global styles.
    600          */
    601         if ( ! current_user_can( 'edit_theme_options' ) ) {
    602             return new WP_Error(
    603                 'rest_cannot_manage_global_styles',
    604                 __( 'Sorry, you are not allowed to access the global styles on this site.' ),
    605                 array(
    606                     'status' => rest_authorization_required_code(),
    607                 )
    608             );
    609         }
    610 
    611         return true;
     612        return $this->get_theme_item_permissions_check( $request );
    612613    }
    613614
     
    633634        }
    634635
    635         $response   = array();
     636        $response = array();
    636637
    637638        // Register theme-defined variations e.g. from block style variation partials under `/styles`.
  • trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php

    r58466 r59048  
    2020     * @var int
    2121     */
     22    protected static $editor_id;
     23
     24    /**
     25     * @var int
     26     */
    2227    protected static $subscriber_id;
     28
     29    /**
     30     * @var int
     31     */
     32    protected static $theme_manager_id;
    2333
    2434    /**
     
    5565        );
    5666
     67        self::$editor_id = $factory->user->create(
     68            array(
     69                'role' => 'editor',
     70            )
     71        );
     72
    5773        self::$subscriber_id = $factory->user->create(
    5874            array(
     
    6076            )
    6177        );
     78
     79        self::$theme_manager_id = $factory->user->create(
     80            array(
     81                'role' => 'subscriber',
     82            )
     83        );
     84
     85        // Add the 'edit_theme_options' capability to the theme manager (subscriber).
     86        $theme_manager_id = get_user_by( 'id', self::$theme_manager_id );
     87        if ( $theme_manager_id instanceof WP_User ) {
     88            $theme_manager_id->add_cap( 'edit_theme_options' );
     89        }
    6290
    6391        // This creates the global styles for the current theme.
     
    79107
    80108    /**
    81      *
     109     * Clean up after our tests run.
    82110     */
    83111    public static function wpTearDownAfterClass() {
    84112        self::delete_user( self::$admin_id );
     113        self::delete_user( self::$editor_id );
    85114        self::delete_user( self::$subscriber_id );
     115        self::delete_user( self::$theme_manager_id );
    86116    }
    87117
     
    265295        $request  = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );
    266296        $response = rest_get_server()->dispatch( $request );
    267         $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 401 );
     297        $this->assertErrorResponse( 'rest_cannot_read_global_styles', $response, 401 );
    268298    }
    269299
     
    271301     * @covers WP_REST_Global_Styles_Controller::get_theme_item
    272302     * @ticket 54516
    273      */
    274     public function test_get_theme_item_permission_check() {
     303     * @ticket 62042
     304     */
     305    public function test_get_theme_item_subscriber_permission_check() {
    275306        wp_set_current_user( self::$subscriber_id );
    276307        $request  = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );
    277308        $response = rest_get_server()->dispatch( $request );
    278         $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 403 );
     309        $this->assertErrorResponse( 'rest_cannot_read_global_styles', $response, 403 );
     310    }
     311
     312    /**
     313     * @covers WP_REST_Global_Styles_Controller::get_theme_item
     314     * @ticket 62042
     315     */
     316    public function test_get_theme_item_editor_permission_check() {
     317        wp_set_current_user( self::$editor_id );
     318        $request  = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );
     319        $response = rest_get_server()->dispatch( $request );
     320        // Checks that the response has the expected keys.
     321        $data  = $response->get_data();
     322        $links = $response->get_links();
     323        $this->assertArrayHasKey( 'settings', $data, 'Data does not have "settings" key' );
     324        $this->assertArrayHasKey( 'styles', $data, 'Data does not have "styles" key' );
     325        $this->assertArrayHasKey( 'self', $links, 'Links do not have a "self" key' );
     326    }
     327
     328    /**
     329     * @covers WP_REST_Global_Styles_Controller_Gutenberg::get_theme_item
     330     * @ticket 62042
     331     */
     332    public function test_get_theme_item_theme_options_manager_permission_check() {
     333        wp_set_current_user( self::$theme_manager_id );
     334        switch_theme( 'emptytheme' );
     335        $request  = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/emptytheme' );
     336        $response = rest_get_server()->dispatch( $request );
     337        // Checks that the response has the expected keys.
     338        $data  = $response->get_data();
     339        $links = $response->get_links();
     340        $this->assertArrayHasKey( 'settings', $data, 'Data does not have "settings" key' );
     341        $this->assertArrayHasKey( 'styles', $data, 'Data does not have "styles" key' );
     342        $this->assertArrayHasKey( 'self', $links, 'Links do not have a "self" key' );
    279343    }
    280344
     
    608672     * of saving via the API.
    609673     *
    610      * @covers WP_REST_Global_Styles_Controller_Gutenberg::update_item
     674     * @covers WP_REST_Global_Styles_Controller::update_item
    611675     * @ticket 61312
    612676     * @ticket 61451
Note: See TracChangeset for help on using the changeset viewer.