WordPress.org

Make WordPress Core

Ticket #35662: 35662.6.diff

File 35662.6.diff, 5.2 KB (added by markjaquith, 3 years ago)

Just refreshing the existing patch so it applies to core

  • src/wp-includes/rest-api/class-wp-rest-server.php

    diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php
    index 12e4086..2ca8bc6 100644
    a b class WP_REST_Server { 
    251251                        }
    252252                }
    253253
     254                $nonce = null;
     255
     256                // Find existing nonce.
     257                if ( isset( $_REQUEST['_wpnonce'] ) ) {
     258                        $nonce = $_REQUEST['_wpnonce'];
     259                } elseif ( isset( $_SERVER['HTTP_X_WP_NONCE'] ) ) {
     260                        $nonce = $_SERVER['HTTP_X_WP_NONCE'];
     261                }
     262
     263                // Check the nonce.
     264                $nonce_is_valid = wp_verify_nonce( $nonce, 'wp_rest' );
     265                $user_and_nonce = is_user_logged_in() && $nonce_is_valid;
     266
     267                /**
     268                 * Filter whether the REST API should send a refreshed nonce header in responses to
     269                 * authenticated requests that include a valid nonce.
     270                 *
     271                 * @since 4.5.0
     272                 *
     273                 * @param bool $rest_send_refreshed_nonce Whether to send a refreshed nonce in the response headers.
     274                 *                                        Defaults to true if the user is logged in and the the
     275                 *                                        existing request nonce is valid.
     276                 */
     277                $rest_send_refreshed_nonce = apply_filters( 'rest_send_refreshed_nonce', $user_and_nonce );
     278                if ( $rest_send_refreshed_nonce ) {
     279                        $this->send_header( 'X-WP-Nonce', wp_create_nonce( 'wp_rest' ) );
     280                }
     281
    254282                /**
    255283                 * Filters whether the REST API is enabled.
    256284                 *
  • tests/phpunit/tests/rest-api/rest-server.php

    diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php
    index 8a53360..2813081 100644
    a b class Tests_REST_Server extends WP_Test_REST_TestCase { 
    882882        public function filter_wp_rest_server_class() {
    883883                return 'Spy_REST_Server';
    884884        }
     885
     886
     887        /**
     888         * Baseline test for the rest_send_refreshed_nonce.
     889         *
     890         * @ticket 35662
     891         */
     892        function test_rest_send_refreshed_nonce_logged_in_user() {
     893                // Create and set the current user.
     894                $this->helper_setup_user_for_rest_send_refreshed_nonce_tests();
     895
     896                // Fake the nonce we need.
     897                $nonce = wp_create_nonce( 'wp_rest' );
     898                $_REQUEST['_wpnonce'] = $nonce;
     899
     900                $headers = $this->helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests();
     901
     902                $this->assertArrayHasKey( 'X-WP-Nonce', $headers );
     903        }
     904
     905        /**
     906         * Testing that the headers are not set for anonymous users.
     907         *
     908         * @ticket 35662
     909         */
     910        function test_rest_send_refreshed_nonce_anonymous_user() {
     911                // Make the request.
     912                $headers = $this->helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests();
     913
     914                // Run the assertions.
     915                $this->assertArrayNotHasKey( 'X-WP-Nonce', $headers );
     916        }
     917
     918        /**
     919         * Testing the rest_send_refreshed_nonce filter.
     920         *
     921         * If the nonce is valid and the user is logged in, we're filtering as false so the header is not sent
     922         * and vice-versa for the opposite setup.
     923         *
     924         * @ticket 35662
     925         *
     926         * @dataProvider data_rest_send_refreshed_nonce_filtered
     927         *
     928         * @param bool   $has_logged_in_user Will there be a logged in user for this test.
     929         * @param string $filter_callback    The callback to be used by the add_filter.
     930         * @param bool   $has_key            Should the X-WP-Nonce key be in the sent_headers array.
     931         */
     932        function test_rest_send_refreshed_nonce_filtered( $has_logged_in_user, $filter_callback, $has_key ) {
     933
     934                if ( true === $has_logged_in_user ) {
     935                        // Creat and set the current user.
     936                        $this->helper_setup_user_for_rest_send_refreshed_nonce_tests();
     937                }
     938
     939                // Make the request.
     940                add_filter( 'rest_send_refreshed_nonce', $filter_callback );
     941
     942                $headers = $this->helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests();
     943
     944                remove_filter( 'rest_send_refreshed_nonce', $filter_callback );
     945
     946                // Run the assertions.
     947                if ( true === $has_key ) {
     948                        $this->assertArrayHasKey( 'X-WP-Nonce', $headers );
     949                } else {
     950                        $this->assertArrayNotHasKey( 'X-WP-Nonce', $headers );
     951                }
     952        }
     953
     954        /**
     955         * Dataprovider to automate the filter tests.
     956         *
     957         * @return array {
     958         *     @type array {
     959         *         @type bool   $has_logged_in_user Are we registering a user for the test.
     960         *         @type string $filter_callback   The callback passed to the filter.
     961         *         @type bool   $has_key           Should the X-WP-Nonce key be in the sent_headers array.
     962         *     }
     963         * }
     964         */
     965        function data_rest_send_refreshed_nonce_filtered() {
     966                return array(
     967                        array( false, '__return_true', true ),
     968                        array( true, '__return_false', false ),
     969                );
     970        }
     971
     972        /**
     973         * Helper to setup a users for the rest_send_refreshed_nonce related tests.
     974         */
     975        function helper_setup_user_for_rest_send_refreshed_nonce_tests() {
     976                // Create and set the current user.
     977                $author = self::factory()->user->create( array( 'role' => 'author' ) );
     978                wp_set_current_user( $author );
     979        }
     980
     981        /**
     982         * Helper to make the request and get the headers for the rest_send_refreshed_nonce related tests.
     983         *
     984         * @return array
     985         */
     986        function helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests() {
     987                $request = new WP_REST_Request( 'GET', '/', array() );
     988                $result  = $this->server->serve_request( '/' );
     989
     990                return $this->server->sent_headers;
     991        }
    885992}