REST API: Introduce Application Passwords for API authentication.

In WordPress 4.4 the REST API was first introduced. A few releases later in WordPress 4.7, the Content API endpoints were added, paving the way for Gutenberg and countless in-site experiences. In the intervening years, numerous plugins have built on top of the REST API. Many developers shared a common frustration, the lack of external authentication to the REST API.

This commit introduces Application Passwords to allow users to connect to external applications to their WordPress website. Users can generate individual passwords for each application, allowing for easy revocation and activity monitoring. An authorization flow is introduced to make the connection flow simple for users and application developers.

Application Passwords uses Basic Authentication, and by default is only available over an SSL connection.

Props georgestephanis, kasparsd, timothyblynjacobs, afercia, akkspro, andraganescu, arippberger, aristath, austyfrosty, ayesh, batmoo, bradyvercher, brianhenryie, helen, ipstenu, jeffmatson, jeffpaul, joostdevalk, joshlevinson, kadamwhite, kjbenk, koke, michael-arestad, Otto42, pekz0r, salzano, spacedmonkey, valendesigns.
Fixes #42790.


git-svn-id: https://develop.svn.wordpress.org/trunk@49109 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
TimothyBlynJacobs
2020-10-08 22:12:02 +00:00
parent 79703088c4
commit 1856d0fe2a
25 changed files with 3493 additions and 3 deletions
+79 -1
View File
@@ -209,6 +209,7 @@ function rest_api_default_filters() {
add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 );
add_filter( 'rest_index', 'rest_add_application_passwords_to_index' );
}
/**
@@ -264,6 +265,10 @@ function create_initial_rest_routes() {
$controller = new WP_REST_Users_Controller;
$controller->register_routes();
// Application Passwords
$controller = new WP_REST_Application_Passwords_Controller();
$controller->register_routes();
// Comments.
$controller = new WP_REST_Comments_Controller;
$controller->register_routes();
@@ -310,7 +315,6 @@ function create_initial_rest_routes() {
// Block Directory.
$controller = new WP_REST_Block_Directory_Controller();
$controller->register_routes();
}
/**
@@ -1034,6 +1038,80 @@ function rest_cookie_collect_status() {
$wp_rest_auth_cookie = true;
}
/**
* Collects the status of authenticating with an application password.
*
* @since 5.6.0
*
* @global WP_User|WP_Error|null $wp_rest_application_password_status
*
* @param WP_Error $user_or_error The authenticated user or error instance.
*/
function rest_application_password_collect_status( $user_or_error ) {
global $wp_rest_application_password_status;
$wp_rest_application_password_status = $user_or_error;
}
/**
* Checks for errors when using application password-based authentication.
*
* @since 5.6.0
*
* @global WP_User|WP_Error|null $wp_rest_application_password_status
*
* @param WP_Error|null|true $result Error from another authentication handler,
* null if we should handle it, or another value if not.
* @return WP_Error|null|true WP_Error if the application password is invalid, the $result, otherwise true.
*/
function rest_application_password_check_errors( $result ) {
global $wp_rest_application_password_status;
if ( ! empty( $result ) ) {
return $result;
}
if ( is_wp_error( $wp_rest_application_password_status ) ) {
$data = $wp_rest_application_password_status->get_error_data();
if ( ! isset( $data['status'] ) ) {
$data['status'] = 401;
}
$wp_rest_application_password_status->add_data( $data );
return $wp_rest_application_password_status;
}
if ( $wp_rest_application_password_status instanceof WP_User ) {
return true;
}
return $result;
}
/**
* Adds Application Passwords info to the REST API index.
*
* @since 5.6.0
*
* @param WP_REST_Response $response The index response object.
* @return WP_REST_Response
*/
function rest_add_application_passwords_to_index( $response ) {
if ( ! wp_is_application_passwords_available() ) {
return $response;
}
$response->data['authentication']['application-passwords'] = array(
'endpoints' => array(
'authorization' => admin_url( 'authorize-application.php' ),
),
);
return $response;
}
/**
* Retrieves the avatar urls in various sizes.
*