REST API: Include a refreshed nonce in a X-WP-Nonce
header when responding to an authenticated request.
Props adamsilverstein, welcher, markjaquith, aidvu. Fixes #35662. git-svn-id: https://develop.svn.wordpress.org/trunk@37905 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
e81a5da327
commit
0e6a328782
@ -548,10 +548,12 @@ function rest_output_link_header() {
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @global mixed $wp_rest_auth_cookie
|
||||
* @global mixed $wp_rest_auth_cookie
|
||||
* @global WP_REST_Server $wp_rest_server REST server instance.
|
||||
*
|
||||
* @param WP_Error|mixed $result Error from another authentication handler, null if we should handle it,
|
||||
* or another value if not.
|
||||
* @param WP_Error|mixed $result Error from another authentication handler,
|
||||
* null if we should handle it, or another value
|
||||
* if not.
|
||||
* @return WP_Error|mixed|bool WP_Error if the cookie is invalid, the $result, otherwise true.
|
||||
*/
|
||||
function rest_cookie_check_errors( $result ) {
|
||||
@ -559,7 +561,7 @@ function rest_cookie_check_errors( $result ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
global $wp_rest_auth_cookie;
|
||||
global $wp_rest_auth_cookie, $wp_rest_server;
|
||||
|
||||
/*
|
||||
* Is cookie authentication being used? (If we get an auth
|
||||
@ -592,6 +594,9 @@ function rest_cookie_check_errors( $result ) {
|
||||
return new WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie nonce is invalid' ), array( 'status' => 403 ) );
|
||||
}
|
||||
|
||||
// Send a refreshed nonce in header.
|
||||
$wp_rest_server->send_header( 'X-WP-Nonce', wp_create_nonce( 'wp_rest' ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
|
||||
public function tearDown() {
|
||||
// Remove our temporary spy server
|
||||
$GLOBALS['wp_rest_server'] = null;
|
||||
unset( $_REQUEST['_wpnonce'] );
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
@ -893,4 +894,92 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
|
||||
public function filter_wp_rest_server_class() {
|
||||
return 'Spy_REST_Server';
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshed nonce should not be present in header when an invalid nonce is passed for logged in user.
|
||||
*
|
||||
* @ticket 35662
|
||||
*/
|
||||
public function test_rest_send_refreshed_nonce_invalid_nonce() {
|
||||
$this->helper_setup_user_for_rest_send_refreshed_nonce_tests();
|
||||
|
||||
$_REQUEST['_wpnonce'] = 'random invalid nonce';
|
||||
|
||||
$headers = $this->helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests();
|
||||
|
||||
$this->assertArrayNotHasKey( 'X-WP-Nonce', $headers );
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshed nonce should be present in header when a valid nonce is
|
||||
* passed for logged in/anonymous user and not present when nonce is not
|
||||
* passed.
|
||||
*
|
||||
* @ticket 35662
|
||||
*
|
||||
* @dataProvider data_rest_send_refreshed_nonce
|
||||
*
|
||||
* @param bool $has_logged_in_user Will there be a logged in user for this test.
|
||||
* @param bool $has_nonce Are we passing the nonce.
|
||||
*/
|
||||
public function test_rest_send_refreshed_nonce( $has_logged_in_user, $has_nonce ) {
|
||||
if ( true === $has_logged_in_user ) {
|
||||
$this->helper_setup_user_for_rest_send_refreshed_nonce_tests();
|
||||
}
|
||||
|
||||
if ( $has_nonce ) {
|
||||
$_REQUEST['_wpnonce'] = wp_create_nonce( 'wp_rest' );
|
||||
}
|
||||
|
||||
$headers = $this->helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests();
|
||||
|
||||
if ( $has_nonce ) {
|
||||
$this->assertArrayHasKey( 'X-WP-Nonce', $headers );
|
||||
} else {
|
||||
$this->assertArrayNotHasKey( 'X-WP-Nonce', $headers );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array {
|
||||
* @type array {
|
||||
* @type bool $has_logged_in_user Are we registering a user for the test.
|
||||
* @type bool $has_nonce Is the nonce passed.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
function data_rest_send_refreshed_nonce() {
|
||||
return array(
|
||||
array( true, true ),
|
||||
array( true, false ),
|
||||
array( false, true ),
|
||||
array( false, false ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to setup a users and auth cookie global for the
|
||||
* rest_send_refreshed_nonce related tests.
|
||||
*/
|
||||
protected function helper_setup_user_for_rest_send_refreshed_nonce_tests() {
|
||||
$author = self::factory()->user->create( array( 'role' => 'author' ) );
|
||||
wp_set_current_user( $author );
|
||||
|
||||
global $wp_rest_auth_cookie;
|
||||
|
||||
$wp_rest_auth_cookie = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to make the request and get the headers for the
|
||||
* rest_send_refreshed_nonce related tests.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function helper_make_request_and_return_headers_for_rest_send_refreshed_nonce_tests() {
|
||||
$request = new WP_REST_Request( 'GET', '/', array() );
|
||||
$result = $this->server->serve_request( '/' );
|
||||
|
||||
return $this->server->sent_headers;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user