Make WordPress Core

Changeset 57222


Ignore:
Timestamp:
12/22/2023 02:10:18 AM (12 months ago)
Author:
isabel_brison
Message:

REST API: check parent and revision ids match before retrieving revision.

Adds a condition to check that parent id matches revision parent id in WP_REST_Revisions_Controller get_item method.

Props ramonopoly, adamsilverstein, danielbachhuber, spacedmonkey, andrewserong.
Fixes #59875.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php

    r56714 r57222  
    388388     *
    389389     * @since 4.7.0
     390     * @since 6.5.0 Added a condition to check that parent id matches revision parent id.
    390391     *
    391392     * @param WP_REST_Request $request Full details about the request.
     
    401402        if ( is_wp_error( $revision ) ) {
    402403            return $revision;
     404        }
     405
     406        if ( (int) $parent->ID !== (int) $revision->post_parent ) {
     407            return new WP_Error(
     408                'rest_revision_parent_id_mismatch',
     409                /* translators: %d: A post id. */
     410                sprintf( __( 'The revision does not belong to the specified parent with id of "%d"' ), $parent->ID ),
     411                array( 'status' => 404 )
     412            );
    403413        }
    404414
  • trunk/tests/phpunit/tests/rest-api/rest-revisions-controller.php

    r56714 r57222  
    1010class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase {
    1111    protected static $post_id;
     12    protected static $post_id_2;
    1213    protected static $page_id;
    1314
     
    2324    private $revision_3;
    2425    private $revision_id3;
     26    private $revision_2_1_id;
    2527
    2628    public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
    27         self::$post_id = $factory->post->create();
    28         self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) );
     29        self::$post_id   = $factory->post->create();
     30        self::$post_id_2 = $factory->post->create();
     31        self::$page_id   = $factory->post->create( array( 'post_type' => 'page' ) );
    2932
    3033        self::$editor_id      = $factory->user->create(
     
    5659                'post_content' => 'This content is fantastic.',
    5760                'ID'           => self::$post_id,
     61            )
     62        );
     63        wp_update_post(
     64            array(
     65                'post_content' => 'A second post.',
     66                'ID'           => self::$post_id_2,
     67            )
     68        );
     69        wp_update_post(
     70            array(
     71                'post_content' => 'A second post. How prolific.',
     72                'ID'           => self::$post_id_2,
    5873            )
    5974        );
     
    6479        // Also deletes revisions.
    6580        wp_delete_post( self::$post_id, true );
     81        wp_delete_post( self::$post_id_2, true );
    6682        wp_delete_post( self::$page_id, true );
    6783
     
    7389        parent::set_up();
    7490
     91        // Set first post revision vars.
    7592        $revisions             = wp_get_post_revisions( self::$post_id );
    7693        $this->total_revisions = count( $revisions );
     
    8299        $this->revision_3      = array_pop( $revisions );
    83100        $this->revision_id3    = $this->revision_3->ID;
     101
     102        // Set second post revision vars.
     103        $revisions             = wp_get_post_revisions( self::$post_id_2 );
     104        $post_2_revision       = array_pop( $revisions );
     105        $this->revision_2_1_id = $post_2_revision->ID;
    84106    }
    85107
     
    233255        $response = rest_get_server()->dispatch( $request );
    234256        $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
     257    }
     258
     259    /**
     260     * @ticket 59875
     261     */
     262    public function test_get_item_valid_parent_id() {
     263        wp_set_current_user( self::$editor_id );
     264        $request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );
     265        $response = rest_get_server()->dispatch( $request );
     266        $data     = $response->get_data();
     267        $this->assertSame( self::$post_id, $data['parent'], "The returned revision's id should match the parent id." );
     268        $this->check_get_revision_response( $response, $this->revision_1 );
     269    }
     270
     271    /**
     272     * @ticket 59875
     273     */
     274    public function test_get_item_invalid_parent_id() {
     275        wp_set_current_user( self::$editor_id );
     276        $request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_2_1_id );
     277        $response = rest_get_server()->dispatch( $request );
     278        $this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 );
     279
     280        $expected_message = 'The revision does not belong to the specified parent with id of "' . self::$post_id . '"';
     281        $this->assertSame( $expected_message, $response->as_error()->get_error_messages()[0], 'The message must contain the correct parent ID.' );
    235282    }
    236283
  • trunk/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php

    r56819 r57222  
    2323     * @var string
    2424     */
     25    const TEMPLATE_NAME_2 = 'my_template_2';
     26
     27    /**
     28     * @var string
     29     */
    2530    const PARENT_POST_TYPE = 'wp_template';
    2631
     
    5156     */
    5257    private static $template_post;
     58
     59    /**
     60     * Template post.
     61     *
     62     * @since 6.5.0
     63     *
     64     * @var WP_Post
     65     */
     66    private static $template_post_2;
    5367
    5468    /**
     
    124138            )
    125139        );
     140
     141        // Create a new template post to test the get_item method.
     142        self::$template_post_2 = $factory->post->create_and_get(
     143            array(
     144                'post_type'    => self::PARENT_POST_TYPE,
     145                'post_name'    => self::TEMPLATE_NAME_2,
     146                'post_title'   => 'My Template 2',
     147                'post_content' => 'Content 2',
     148                'post_excerpt' => 'Description of my template 2',
     149                'tax_input'    => array(
     150                    'wp_theme' => array(
     151                        self::TEST_THEME,
     152                    ),
     153                ),
     154            )
     155        );
     156        wp_set_post_terms( self::$template_post_2->ID, self::TEST_THEME, 'wp_theme' );
     157
     158        var_dump( self::$template_post->ID );
     159        var_dump( self::$template_post_2->ID );
    126160    }
    127161
     
    335369        $response = rest_get_server()->dispatch( $request );
    336370        $this->assertErrorResponse( 'rest_post_invalid_parent', $response, WP_Http::NOT_FOUND );
     371    }
     372
     373    /**
     374     * @ticket 59875
     375     */
     376    public function test_get_item_invalid_parent_id() {
     377        wp_set_current_user( self::$admin_id );
     378        $revisions   = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
     379        $revision_id = array_shift( $revisions );
     380
     381        $request = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME_2 . '/revisions/' . $revision_id );
     382
     383        $response = rest_get_server()->dispatch( $request );
     384        $this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 );
     385
     386        $expected_message = 'The revision does not belong to the specified parent with id of "' . self::$template_post_2->ID . '"';
     387        $this->assertSame( $expected_message, $response->as_error()->get_error_messages()[0], 'The message must contain the correct parent ID.' );
    337388    }
    338389
Note: See TracChangeset for help on using the changeset viewer.