mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-07-01 07:40:07 +00:00
App Passwords: Prevent conflicts when Basic Auth is already used by the site.
Application Passwords uses Basic Authentication to transfer authentication details. If the site is already using Basic Auth, for instance to implement a private staging environment, then the REST API will treat this as an authentication attempt and would end up generating an error for any REST API request. Now, Application Password authentication will only be attempted if Application Passwords is in use by a site. This is flagged by setting an option whenever an Application Password is created. An upgrade routine is added to set this option if any App Passwords already exist. Lastly, creating an Application Password will be prevented if the site appears to already be using Basic Authentication. Props chexwarrior, georgestephanis, adamsilverstein, helen, Clorith, marybaum, TimothyBlynJacobs. Fixes #51939. git-svn-id: https://develop.svn.wordpress.org/trunk@49752 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -88,6 +88,18 @@ if ( is_wp_error( $is_valid ) ) {
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $_SERVER['PHP_AUTH_USER'] ) || ! empty( $_SERVER['PHP_AUTH_PW'] ) ) {
|
||||
wp_die(
|
||||
__( 'Your website appears to use Basic Authentication, which is not currently compatible with Application Passwords.' ),
|
||||
__( 'Cannot Authorize Application' ),
|
||||
array(
|
||||
'response' => 501,
|
||||
'link_text' => __( 'Go Back' ),
|
||||
'link_url' => $reject_url ? add_query_arg( 'error', 'disabled', $reject_url ) : admin_url(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! wp_is_application_passwords_available_for_user( $user ) ) {
|
||||
if ( wp_is_application_passwords_available() ) {
|
||||
$message = __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' );
|
||||
|
||||
@@ -874,7 +874,7 @@ function upgrade_all() {
|
||||
upgrade_550();
|
||||
}
|
||||
|
||||
if ( $wp_current_db_version < 49735 ) {
|
||||
if ( $wp_current_db_version < 49752 ) {
|
||||
upgrade_560();
|
||||
}
|
||||
|
||||
@@ -2278,6 +2278,19 @@ function upgrade_560() {
|
||||
if ( $wp_current_db_version < 49735 ) {
|
||||
delete_transient( 'dirsize_cache' );
|
||||
}
|
||||
|
||||
if ( $wp_current_db_version < 49752 ) {
|
||||
$results = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT 1 FROM {$wpdb->usermeta} WHERE meta_key = %s LIMIT 1",
|
||||
WP_Application_Passwords::USERMETA_KEY_APPLICATION_PASSWORDS
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $results ) ) {
|
||||
update_site_option( WP_Application_Passwords::OPTION_KEY_IN_USE, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -738,27 +738,34 @@ endif;
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="create-application-password form-wrap">
|
||||
<div class="form-field">
|
||||
<label for="new_application_password_name"><?php _e( 'New Application Password Name' ); ?></label>
|
||||
<input type="text" size="30" id="new_application_password_name" name="new_application_password_name" placeholder="<?php esc_attr_e( 'WordPress App on My Phone' ); ?>" class="input" aria-required="true" aria-describedby="new_application_password_name_desc" />
|
||||
<p class="description" id="new_application_password_name_desc"><?php _e( 'Required to create an Application Password, but not to update the user.' ); ?></p>
|
||||
|
||||
if ( empty( $_SERVER['PHP_AUTH_USER'] ) && empty( $_SERVER['PHP_AUTH_PW'] ) ) {
|
||||
?>
|
||||
<div class="create-application-password form-wrap">
|
||||
<div class="form-field">
|
||||
<label for="new_application_password_name"><?php _e( 'New Application Password Name' ); ?></label>
|
||||
<input type="text" size="30" id="new_application_password_name" name="new_application_password_name" placeholder="<?php esc_attr_e( 'WordPress App on My Phone' ); ?>" class="input" aria-required="true" aria-describedby="new_application_password_name_desc" />
|
||||
<p class="description" id="new_application_password_name_desc"><?php _e( 'Required to create an Application Password, but not to update the user.' ); ?></p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires in the create Application Passwords form.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param WP_User $profileuser The current WP_User object.
|
||||
*/
|
||||
do_action( 'wp_create_application_password_form', $profileuser );
|
||||
?>
|
||||
|
||||
<?php submit_button( __( 'Add New Application Password' ), 'secondary', 'do_new_application_password' ); ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires in the create Application Passwords form.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param WP_User $profileuser The current WP_User object.
|
||||
*/
|
||||
do_action( 'wp_create_application_password_form', $profileuser );
|
||||
?>
|
||||
|
||||
<?php submit_button( __( 'Add New Application Password' ), 'secondary', 'do_new_application_password' ); ?>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div class="notice notice-error inline">
|
||||
<p><?php _e( 'Your website appears to use Basic Authentication, which is not currently compatible with Application Passwords.' ); ?></p>
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
<div class="application-passwords-list-table-wrapper">
|
||||
<?php
|
||||
|
||||
@@ -22,6 +22,15 @@ class WP_Application_Passwords {
|
||||
*/
|
||||
const USERMETA_KEY_APPLICATION_PASSWORDS = '_application_passwords';
|
||||
|
||||
/**
|
||||
* The option name used to store whether application passwords is in use.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
const OPTION_KEY_IN_USE = 'using_application_passwords';
|
||||
|
||||
/**
|
||||
* The generated application password length.
|
||||
*
|
||||
@@ -31,6 +40,19 @@ class WP_Application_Passwords {
|
||||
*/
|
||||
const PW_LENGTH = 24;
|
||||
|
||||
/**
|
||||
* Checks if Application Passwords are being used by the site.
|
||||
*
|
||||
* This returns true if at least one App Password has ever been created.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_in_use() {
|
||||
return (bool) get_site_option( self::OPTION_KEY_IN_USE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new application password.
|
||||
*
|
||||
@@ -67,6 +89,10 @@ class WP_Application_Passwords {
|
||||
return new WP_Error( 'db_error', __( 'Could not save application password.' ) );
|
||||
}
|
||||
|
||||
if ( ! get_site_option( self::OPTION_KEY_IN_USE ) ) {
|
||||
update_site_option( self::OPTION_KEY_IN_USE, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when an application password is created.
|
||||
*
|
||||
|
||||
@@ -313,6 +313,10 @@ function wp_authenticate_application_password( $input_user, $username, $password
|
||||
return $input_user;
|
||||
}
|
||||
|
||||
if ( ! WP_Application_Passwords::is_in_use() ) {
|
||||
return $input_user;
|
||||
}
|
||||
|
||||
$is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) );
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ $wp_version = '5.7-alpha-49644-src';
|
||||
*
|
||||
* @global int $wp_db_version
|
||||
*/
|
||||
$wp_db_version = 49735;
|
||||
$wp_db_version = 49752;
|
||||
|
||||
/**
|
||||
* Holds the TinyMCE version.
|
||||
|
||||
@@ -37,6 +37,7 @@ class Tests_Auth extends WP_UnitTestCase {
|
||||
|
||||
$this->user = clone self::$_user;
|
||||
wp_set_current_user( self::$user_id );
|
||||
update_site_option( 'using_application_passwords', 1 );
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
@@ -604,4 +605,14 @@ class Tests_Auth extends WP_UnitTestCase {
|
||||
$this->assertInstanceOf( WP_User::class, $user );
|
||||
$this->assertSame( self::$user_id, $user->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 51939
|
||||
*/
|
||||
public function test_authenticate_application_password_returns_null_if_not_in_use() {
|
||||
delete_site_option( 'using_application_passwords' );
|
||||
|
||||
$authenticated = wp_authenticate_application_password( null, 'idonotexist', 'password' );
|
||||
$this->assertNull( $authenticated );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +404,22 @@ class WP_Test_REST_Application_Passwords_Controller extends WP_Test_REST_Control
|
||||
$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 51939
|
||||
*/
|
||||
public function test_create_item_records_app_passwords_in_use() {
|
||||
wp_set_current_user( self::$admin );
|
||||
|
||||
$this->assertFalse( WP_Application_Passwords::is_in_use() );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wp/v2/users/me/application-passwords' );
|
||||
$request->set_body_params( array( 'name' => 'App' ) );
|
||||
$response = rest_do_request( $request );
|
||||
|
||||
$this->assertSame( 201, $response->get_status() );
|
||||
$this->assertTrue( WP_Application_Passwords::is_in_use() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 42790
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user