mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-22 17:18:32 +01:00
4e167c593d
It is recommended that for every option it is explicitly set whether to autoload it or not. This changeset updates relevant `update_option()` and `add_option()` calls. Note that the `$autoload` parameter is only needed for `update_option()` if the option is potentially not present yet, i.e. the call will pass through to `add_option()`. Since WordPress core adds the majority of its options to the database during installation, only `update_option()` calls for dynamically added options need to be modified, which is what this changeset does. As part of revisiting the autoload values for dynamically added WordPress core options, this changeset modifies some options to no longer be autoloaded, since they are only accessed in a few specific places that are not relevant for a regular request. These options are: * `recently_activated` * `_wp_suggested_policy_text_has_changed` * `{upgradeLock}.lock` * `dashboard_widget_options` * `ftp_credentials` * `adminhash` * `nav_menu_options` * `wp_force_deactivated_plugins` * `delete_blog_hash` * `allowedthemes` * `{sessionId}_paused_extensions` * `recovery_keys` * `https_detection_errors` * `fresh_site` An upgrade routine is present as well that sets those options to no longer autoload for existing sites. Props pbearne, flixos90, mukesh27, swissspidy, SergeyBiryukov, joemcgill, adamsilverstein. Fixes #61103. Built from https://develop.svn.wordpress.org/trunk@58975 git-svn-id: http://core.svn.wordpress.org/trunk@58371 1a063a9b-81f0-0310-95a4-ce76da25c4cd
193 lines
4.5 KiB
PHP
193 lines
4.5 KiB
PHP
<?php
|
|
/**
|
|
* Error Protection API: WP_Recovery_Mode_Key_Service class
|
|
*
|
|
* @package WordPress
|
|
* @since 5.2.0
|
|
*/
|
|
|
|
/**
|
|
* Core class used to generate and validate keys used to enter Recovery Mode.
|
|
*
|
|
* @since 5.2.0
|
|
*/
|
|
#[AllowDynamicProperties]
|
|
final class WP_Recovery_Mode_Key_Service {
|
|
|
|
/**
|
|
* The option name used to store the keys.
|
|
*
|
|
* @since 5.2.0
|
|
* @var string
|
|
*/
|
|
private $option_name = 'recovery_keys';
|
|
|
|
/**
|
|
* Creates a recovery mode token.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @return string A random string to identify its associated key in storage.
|
|
*/
|
|
public function generate_recovery_mode_token() {
|
|
return wp_generate_password( 22, false );
|
|
}
|
|
|
|
/**
|
|
* Creates a recovery mode key.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
|
|
*
|
|
* @param string $token A token generated by {@see generate_recovery_mode_token()}.
|
|
* @return string Recovery mode key.
|
|
*/
|
|
public function generate_and_store_recovery_mode_key( $token ) {
|
|
|
|
global $wp_hasher;
|
|
|
|
$key = wp_generate_password( 22, false );
|
|
|
|
if ( empty( $wp_hasher ) ) {
|
|
require_once ABSPATH . WPINC . '/class-phpass.php';
|
|
$wp_hasher = new PasswordHash( 8, true );
|
|
}
|
|
|
|
$hashed = $wp_hasher->HashPassword( $key );
|
|
|
|
$records = $this->get_keys();
|
|
|
|
$records[ $token ] = array(
|
|
'hashed_key' => $hashed,
|
|
'created_at' => time(),
|
|
);
|
|
|
|
$this->update_keys( $records );
|
|
|
|
/**
|
|
* Fires when a recovery mode key is generated.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @param string $token The recovery data token.
|
|
* @param string $key The recovery mode key.
|
|
*/
|
|
do_action( 'generate_recovery_mode_key', $token, $key );
|
|
|
|
return $key;
|
|
}
|
|
|
|
/**
|
|
* Verifies if the recovery mode key is correct.
|
|
*
|
|
* Recovery mode keys can only be used once; the key will be consumed in the process.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
|
|
*
|
|
* @param string $token The token used when generating the given key.
|
|
* @param string $key The unhashed key.
|
|
* @param int $ttl Time in seconds for the key to be valid for.
|
|
* @return true|WP_Error True on success, error object on failure.
|
|
*/
|
|
public function validate_recovery_mode_key( $token, $key, $ttl ) {
|
|
global $wp_hasher;
|
|
|
|
$records = $this->get_keys();
|
|
|
|
if ( ! isset( $records[ $token ] ) ) {
|
|
return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) );
|
|
}
|
|
|
|
$record = $records[ $token ];
|
|
|
|
$this->remove_key( $token );
|
|
|
|
if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) {
|
|
return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) );
|
|
}
|
|
|
|
if ( empty( $wp_hasher ) ) {
|
|
require_once ABSPATH . WPINC . '/class-phpass.php';
|
|
$wp_hasher = new PasswordHash( 8, true );
|
|
}
|
|
|
|
if ( ! $wp_hasher->CheckPassword( $key, $record['hashed_key'] ) ) {
|
|
return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) );
|
|
}
|
|
|
|
if ( time() > $record['created_at'] + $ttl ) {
|
|
return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Removes expired recovery mode keys.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @param int $ttl Time in seconds for the keys to be valid for.
|
|
*/
|
|
public function clean_expired_keys( $ttl ) {
|
|
|
|
$records = $this->get_keys();
|
|
|
|
foreach ( $records as $key => $record ) {
|
|
if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) {
|
|
unset( $records[ $key ] );
|
|
}
|
|
}
|
|
|
|
$this->update_keys( $records );
|
|
}
|
|
|
|
/**
|
|
* Removes a used recovery key.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @param string $token The token used when generating a recovery mode key.
|
|
*/
|
|
private function remove_key( $token ) {
|
|
|
|
$records = $this->get_keys();
|
|
|
|
if ( ! isset( $records[ $token ] ) ) {
|
|
return;
|
|
}
|
|
|
|
unset( $records[ $token ] );
|
|
|
|
$this->update_keys( $records );
|
|
}
|
|
|
|
/**
|
|
* Gets the recovery key records.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @return array Associative array of $token => $data pairs, where $data has keys 'hashed_key'
|
|
* and 'created_at'.
|
|
*/
|
|
private function get_keys() {
|
|
return (array) get_option( $this->option_name, array() );
|
|
}
|
|
|
|
/**
|
|
* Updates the recovery key records.
|
|
*
|
|
* @since 5.2.0
|
|
*
|
|
* @param array $keys Associative array of $token => $data pairs, where $data has keys 'hashed_key'
|
|
* and 'created_at'.
|
|
* @return bool True on success, false on failure.
|
|
*/
|
|
private function update_keys( array $keys ) {
|
|
return update_option( $this->option_name, $keys, false );
|
|
}
|
|
}
|