[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> class-wp-recovery-mode-key-service.php (source)

   1  <?php
   2  /**
   3   * Error Protection API: WP_Recovery_Mode_Key_Service class
   4   *
   5   * @package WordPress
   6   * @since 5.2.0
   7   */
   8  
   9  /**
  10   * Core class used to generate and validate keys used to enter Recovery Mode.
  11   *
  12   * @since 5.2.0
  13   */
  14  #[AllowDynamicProperties]
  15  final class WP_Recovery_Mode_Key_Service {
  16  
  17      /**
  18       * The option name used to store the keys.
  19       *
  20       * @since 5.2.0
  21       * @var string
  22       */
  23      private $option_name = 'recovery_keys';
  24  
  25      /**
  26       * Creates a recovery mode token.
  27       *
  28       * @since 5.2.0
  29       *
  30       * @return string A random string to identify its associated key in storage.
  31       */
  32  	public function generate_recovery_mode_token() {
  33          return wp_generate_password( 22, false );
  34      }
  35  
  36      /**
  37       * Creates a recovery mode key.
  38       *
  39       * @since 5.2.0
  40       *
  41       * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
  42       *
  43       * @param string $token A token generated by {@see generate_recovery_mode_token()}.
  44       * @return string Recovery mode key.
  45       */
  46  	public function generate_and_store_recovery_mode_key( $token ) {
  47  
  48          global $wp_hasher;
  49  
  50          $key = wp_generate_password( 22, false );
  51  
  52          if ( empty( $wp_hasher ) ) {
  53              require_once  ABSPATH . WPINC . '/class-phpass.php';
  54              $wp_hasher = new PasswordHash( 8, true );
  55          }
  56  
  57          $hashed = $wp_hasher->HashPassword( $key );
  58  
  59          $records = $this->get_keys();
  60  
  61          $records[ $token ] = array(
  62              'hashed_key' => $hashed,
  63              'created_at' => time(),
  64          );
  65  
  66          $this->update_keys( $records );
  67  
  68          /**
  69           * Fires when a recovery mode key is generated.
  70           *
  71           * @since 5.2.0
  72           *
  73           * @param string $token The recovery data token.
  74           * @param string $key   The recovery mode key.
  75           */
  76          do_action( 'generate_recovery_mode_key', $token, $key );
  77  
  78          return $key;
  79      }
  80  
  81      /**
  82       * Verifies if the recovery mode key is correct.
  83       *
  84       * Recovery mode keys can only be used once; the key will be consumed in the process.
  85       *
  86       * @since 5.2.0
  87       *
  88       * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
  89       *
  90       * @param string $token The token used when generating the given key.
  91       * @param string $key   The unhashed key.
  92       * @param int    $ttl   Time in seconds for the key to be valid for.
  93       * @return true|WP_Error True on success, error object on failure.
  94       */
  95  	public function validate_recovery_mode_key( $token, $key, $ttl ) {
  96          global $wp_hasher;
  97  
  98          $records = $this->get_keys();
  99  
 100          if ( ! isset( $records[ $token ] ) ) {
 101              return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) );
 102          }
 103  
 104          $record = $records[ $token ];
 105  
 106          $this->remove_key( $token );
 107  
 108          if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) {
 109              return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) );
 110          }
 111  
 112          if ( empty( $wp_hasher ) ) {
 113              require_once  ABSPATH . WPINC . '/class-phpass.php';
 114              $wp_hasher = new PasswordHash( 8, true );
 115          }
 116  
 117          if ( ! $wp_hasher->CheckPassword( $key, $record['hashed_key'] ) ) {
 118              return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) );
 119          }
 120  
 121          if ( time() > $record['created_at'] + $ttl ) {
 122              return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) );
 123          }
 124  
 125          return true;
 126      }
 127  
 128      /**
 129       * Removes expired recovery mode keys.
 130       *
 131       * @since 5.2.0
 132       *
 133       * @param int $ttl Time in seconds for the keys to be valid for.
 134       */
 135  	public function clean_expired_keys( $ttl ) {
 136  
 137          $records = $this->get_keys();
 138  
 139          foreach ( $records as $key => $record ) {
 140              if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) {
 141                  unset( $records[ $key ] );
 142              }
 143          }
 144  
 145          $this->update_keys( $records );
 146      }
 147  
 148      /**
 149       * Removes a used recovery key.
 150       *
 151       * @since 5.2.0
 152       *
 153       * @param string $token The token used when generating a recovery mode key.
 154       */
 155  	private function remove_key( $token ) {
 156  
 157          $records = $this->get_keys();
 158  
 159          if ( ! isset( $records[ $token ] ) ) {
 160              return;
 161          }
 162  
 163          unset( $records[ $token ] );
 164  
 165          $this->update_keys( $records );
 166      }
 167  
 168      /**
 169       * Gets the recovery key records.
 170       *
 171       * @since 5.2.0
 172       *
 173       * @return array Associative array of $token => $data pairs, where $data has keys 'hashed_key'
 174       *               and 'created_at'.
 175       */
 176  	private function get_keys() {
 177          return (array) get_option( $this->option_name, array() );
 178      }
 179  
 180      /**
 181       * Updates the recovery key records.
 182       *
 183       * @since 5.2.0
 184       *
 185       * @param array $keys Associative array of $token => $data pairs, where $data has keys 'hashed_key'
 186       *                    and 'created_at'.
 187       * @return bool True on success, false on failure.
 188       */
 189  	private function update_keys( array $keys ) {
 190          return update_option( $this->option_name, $keys );
 191      }
 192  }


Generated : Thu Apr 25 08:20:02 2024 Cross-referenced by PHPXref