Site Health, App Passwords: Test if the Authorization header is populated correctly.

App Passwords rely on the Authorization header to transport the Basic Auth credentials. For Apache web servers, WordPress automatically includes a RewriteRule to populate the value for servers running in CGI or FastCGI that wouldn't ordinarily populate the value. 

This tests if the header is being filled with the expected values. For Apache users, we direct the user to visit the Permalinks settings to flush their permalinks. For all other users, we direct them to a help document on developer.wordpress.org.

Props Clorith, marybaum, TimothyBlynJacobs.
Fixes #51638.

Built from https://develop.svn.wordpress.org/trunk@49334


git-svn-id: http://core.svn.wordpress.org/trunk@49095 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
TimothyBlynJacobs 2020-10-27 18:32:07 +00:00
parent 219079f7a3
commit 2df94804d4
5 changed files with 104 additions and 3 deletions

View File

@ -135,6 +135,7 @@ class WP_Site_Health {
'test' => $test['test'],
'has_rest' => ( isset( $test['has_rest'] ) ? $test['has_rest'] : false ),
'completed' => false,
'headers' => isset( $test['headers'] ) ? $test['headers'] : array(),
);
}
}
@ -2078,6 +2079,62 @@ class WP_Site_Health {
return $result;
}
/**
* Tests if the Authorization header has the expected values.
*
* @since 5.6.0
*
* @return array
*/
public function get_test_authorization_header() {
$result = array(
'label' => __( 'The Authorization header is working as expected.' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Security' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'The Authorization header comes from the third-party applications you approve. Without it, those apps cannot connect to your site.' )
),
'actions' => '',
'test' => 'authorization_header',
);
if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) {
$result['label'] = __( 'The authorization header is missing.' );
} elseif ( 'user' !== $_SERVER['PHP_AUTH_USER'] || 'pwd' !== $_SERVER['PHP_AUTH_PW'] ) {
$result['label'] = __( 'The authorization header is invalid.' );
} else {
return $result;
}
$result['status'] = 'recommended';
if ( ! function_exists( 'got_mod_rewrite' ) ) {
require_once ABSPATH . 'wp-admin/includes/misc.php';
}
if ( got_mod_rewrite() ) {
$result['actions'] .= sprintf(
'<p><a href="%s">%s</a></p>',
esc_url( admin_url( 'options-permalink.php' ) ),
__( 'Flush permalinks' )
);
} else {
$result['actions'] .= sprintf(
'<p><a href="%s" target="_blank" rel="noopener">%s <span class="screen-reader-text">%s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
'https://developer.wordpress.org/rest-api/frequently-asked-questions/#why-is-authentication-not-working',
__( 'Learn how to configure the Authorization header.' ),
/* translators: Accessibility text. */
__( '(opens in a new tab)' )
);
}
return $result;
}
/**
* Return a set of tests that belong to the site status page.
*
@ -2177,6 +2234,13 @@ class WP_Site_Health {
'has_rest' => true,
'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ),
),
'authorization_header' => array(
'label' => __( 'Authorization header' ),
'test' => rest_url( 'wp-site-health/v1/tests/authorization-header' ),
'has_rest' => true,
'headers' => array( 'Authorization' => 'Basic ' . base64_encode( 'user:pwd' ) ),
'skip_cron' => true,
),
),
);
@ -2203,6 +2267,7 @@ class WP_Site_Health {
*
* @since 5.2.0
* @since 5.6.0 Added the `async_direct_test` array key.
* Added the `skip_cron` array key.
*
* @param array $test_type {
* An associative array, where the `$test_type` is either `direct` or
@ -2217,6 +2282,7 @@ class WP_Site_Health {
* @type mixed $test A callable to perform a direct test, or a string AJAX action
* to be called to perform an async test.
* @type boolean $has_rest Optional. Denote if `$test` has a REST API endpoint.
* @type boolean $skip_cron Whether to skip this test when running as cron.
* @type callable $async_direct_test A manner of directly calling the test marked as asynchronous,
* as the scheduled event can not authenticate, and endpoints
* may require authentication.
@ -2557,6 +2623,10 @@ class WP_Site_Health {
}
foreach ( $tests['async'] as $test ) {
if ( ! empty( $test['skip_cron'] ) ) {
continue;
}
// Local endpoints may require authentication, so asynchronous tests can pass a direct test runner as well.
if ( ! empty( $test['async_direct_test'] ) && is_callable( $test['async_direct_test'] ) ) {
// This test is callable, do so and continue to the next asynchronous check.

View File

@ -212,7 +212,8 @@ jQuery( document ).ready( function( $ ) {
if ( 'undefined' !== typeof( this.has_rest ) && this.has_rest ) {
wp.apiRequest( {
url: this.test
url: this.test,
headers: this.headers
} )
.done( function( response ) {
/** This filter is documented in wp-admin/includes/class-wp-site-health.php */

File diff suppressed because one or more lines are too long

View File

@ -104,6 +104,25 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
)
);
register_rest_route(
$this->namespace,
sprintf(
'/%s/%s',
$this->rest_base,
'authorization-header'
),
array(
array(
'methods' => 'GET',
'callback' => array( $this, 'test_authorization_header' ),
'permission_callback' => function () {
return $this->validate_request_permission( 'authorization_header' );
},
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
register_rest_route(
$this->namespace,
sprintf(
@ -177,6 +196,17 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
return $this->site_health->get_test_loopback_requests();
}
/**
* Checks that the authorization header is valid.
*
* @since 5.6.0
*
* @return array
*/
public function test_authorization_header() {
return $this->site_health->get_test_authorization_header();
}
/**
* Gets the current directory sizes for this install.
*

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.6-beta1-49333';
$wp_version = '5.6-beta1-49334';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.