Make WordPress Core

Changeset 57222


Ignore:
Timestamp:
12/22/2023 02:10:18 AM (3 years 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.