Make WordPress Core

Ticket #46595: 46595.6.patch

File 46595.6.patch, 9.2 KB (added by pbearne, 6 years ago)

more code style tweeks

  • src/wp-includes/class-wp-recovery-mode-key-service.php

     
    1919         * @since 5.2.0
    2020         *
    2121         * @global PasswordHash $wp_hasher
    22          *
    23          * @return string Recovery mode key.
     22         * @return array Recovery mode key and Token.
    2423         */
    2524        public function generate_and_store_recovery_mode_key() {
    2625
     
    4443
    4544                $hashed = $wp_hasher->HashPassword( $key );
    4645
    47                 update_option(
    48                         'recovery_key',
    49                         array(
    50                                 'hashed_key' => $hashed,
    51                                 'created_at' => time(),
    52                         )
     46                $records = get_option( 'recovery_key', array() );
     47
     48                $token = wp_generate_password( 22, false );
     49
     50                $records[ $token ] = array(
     51                        'hashed_key' => $hashed,
     52                        'created_at' => time(),
    5353                );
    5454
    55                 return $key;
     55                update_option( 'recovery_key', $records );
     56
     57                return array( $key, $token );
    5658        }
    5759
    5860        /**
    5961         * Verifies if the recovery mode key is correct.
     62         * Removes any old keys and the key passed to it
    6063         *
    6164         * @since 5.2.0
    6265         *
    6366         * @param string $key The unhashed key.
     67         * @param string $token The data index
    6468         * @param int    $ttl Time in seconds for the key to be valid for.
    6569         * @return true|WP_Error True on success, error object on failure.
    6670         */
    67         public function validate_recovery_mode_key( $key, $ttl ) {
     71        public function validate_and_consume_recovery_mode_key( $key, $token, $ttl ) {
    6872
    69                 $record = get_option( 'recovery_key' );
     73                $records = get_option( 'recovery_key' );
    7074
    71                 if ( ! $record ) {
     75                if ( ! $records ) {
    7276                        return new WP_Error( 'no_recovery_key_set', __( 'Recovery Mode not initialized.' ) );
    7377                }
    7478
     79                if ( ! isset( $records[ $token ] ) ) {
     80                        return new WP_Error( 'recovery_key_data_missing', __( 'Recovery Mode not initialized.' ) );
     81                }
     82
     83                $record = $records[ $token ];
     84
     85                // remove so it a onetime use
     86                $this->clean_recovery_key_options( $ttl, $token );
     87
    7588                if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) {
    7689                        return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) );
    7790                }
     
    8699
    87100                return true;
    88101        }
     102
     103        /**
     104         * Removes old and used recovery keys.
     105         *
     106         * @since 5.2.0
     107         *
     108         * @param int    $ttl Unix timestamp
     109         * @param string $token The data index
     110         */
     111        public function clean_recovery_key_options( $ttl, $token = ''  ) {
     112
     113                $records = get_option( 'recovery_key' );
     114
     115                if ( '' !== $token ) {
     116                        unset( $records[ $token ] );
     117                }
     118
     119                foreach ( $records as $key => $record ) {
     120                        if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) {
     121                                unset( $records[ $key ] );
     122                        }
     123                }
     124
     125                update_option( 'recovery_key', $records );
     126        }
    89127}
  • src/wp-includes/functions.php

     
    797797 */
    798798function is_new_day() {
    799799        global $currentday, $previousday;
    800         if ( $currentday != $previousday ) {
     800        if ( $currentday !== $previousday ) {
    801801                return 1;
    802802        } else {
    803803                return 0;
  • tests/phpunit/tests/error-protection/recovery-mode-key-service.php

     
    2020         */
    2121        public function test_validate_recovery_mode_key_returns_wp_error_if_no_key_set() {
    2222                $service = new WP_Recovery_Mode_Key_Service();
    23                 $error   = $service->validate_recovery_mode_key( 'abcd', HOUR_IN_SECONDS );
     23                $error   = $service->validate_and_consume_recovery_mode_key( 'abcd', '', HOUR_IN_SECONDS );
    2424
    2525                $this->assertWPError( $error );
    2626                $this->assertEquals( 'no_recovery_key_set', $error->get_error_code() );
    2727        }
     28        /**
     29         * @ticket 46130
     30         */
     31        public function test_validate_recovery_mode_key_returns_wp_error_if_data_missing() {
     32                update_option( 'recovery_key', 'gibberish' );
    2833
     34                $service = new WP_Recovery_Mode_Key_Service();
     35                $error   = $service->validate_and_consume_recovery_mode_key( 'abcd', '', HOUR_IN_SECONDS );
     36
     37                $this->assertWPError( $error );
     38                $this->assertEquals( 'recovery_key_data_missing', $error->get_error_code() );
     39        }
     40
    2941        /**
    3042         * @ticket 46130
    3143         */
     44        public function test_validate_recovery_mode_key_returns_wp_error_if_bad() {
     45                update_option( 'recovery_key', array( 'token' => 'gibberish' ) );
     46
     47                $service = new WP_Recovery_Mode_Key_Service();
     48                $error   = $service->validate_and_consume_recovery_mode_key( 'abcd', 'token', HOUR_IN_SECONDS );
     49
     50                $this->assertWPError( $error );
     51                $this->assertEquals( 'invalid_recovery_key_format', $error->get_error_code() );
     52        }
     53
     54
     55        /**
     56         * @ticket 46130
     57         */
    3258        public function test_validate_recovery_mode_key_returns_wp_error_if_stored_format_is_invalid() {
    33                 update_option( 'recovery_key', 'gibberish' );
    3459
     60                $token =  wp_generate_password( 22, false );
     61                update_option( 'recovery_key', array( $token => 'gibberish' ) );
     62
    3563                $service = new WP_Recovery_Mode_Key_Service();
    36                 $error   = $service->validate_recovery_mode_key( 'abcd', HOUR_IN_SECONDS );
     64                $error   = $service->validate_and_consume_recovery_mode_key( 'abcd', $token, HOUR_IN_SECONDS );
    3765
    3866                $this->assertWPError( $error );
    3967                $this->assertEquals( 'invalid_recovery_key_format', $error->get_error_code() );
     
    4472         */
    4573        public function test_validate_recovery_mode_key_returns_wp_error_if_empty_key() {
    4674                $service = new WP_Recovery_Mode_Key_Service();
    47                 $service->generate_and_store_recovery_mode_key();
    48                 $error = $service->validate_recovery_mode_key( '', HOUR_IN_SECONDS );
     75                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
     76                $error = $service->validate_and_consume_recovery_mode_key( '', $token, HOUR_IN_SECONDS );
    4977
    5078                $this->assertWPError( $error );
    5179                $this->assertEquals( 'hash_mismatch', $error->get_error_code() );
     
    5684         */
    5785        public function test_validate_recovery_mode_key_returns_wp_error_if_hash_mismatch() {
    5886                $service = new WP_Recovery_Mode_Key_Service();
    59                 $service->generate_and_store_recovery_mode_key();
    60                 $error = $service->validate_recovery_mode_key( 'abcd', HOUR_IN_SECONDS );
     87                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
     88                $error = $service->validate_and_consume_recovery_mode_key( 'abcd', $token, HOUR_IN_SECONDS );
    6189
    6290                $this->assertWPError( $error );
    6391                $this->assertEquals( 'hash_mismatch', $error->get_error_code() );
     
    6896         */
    6997        public function test_validate_recovery_mode_key_returns_wp_error_if_expired() {
    7098                $service = new WP_Recovery_Mode_Key_Service();
    71                 $key    = $service->generate_and_store_recovery_mode_key();
     99                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
    72100
    73                 $record               = get_option( 'recovery_key' );
    74                 $record['created_at'] = time() - HOUR_IN_SECONDS - 30;
    75                 update_option( 'recovery_key', $record );
     101                $records                         = get_option( 'recovery_key' );
     102                $records[ $token ]['created_at'] = time() - HOUR_IN_SECONDS - 30;
     103                update_option( 'recovery_key', $records );
    76104
    77                 $error = $service->validate_recovery_mode_key( $key, HOUR_IN_SECONDS );
     105                $error = $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS );
    78106
    79107                $this->assertWPError( $error );
    80108                $this->assertEquals( 'key_expired', $error->get_error_code() );
     
    85113         */
    86114        public function test_validate_recovery_mode_key_returns_true_for_valid_key() {
    87115                $service = new WP_Recovery_Mode_Key_Service();
    88                 $key    = $service->generate_and_store_recovery_mode_key();
    89                 $this->assertTrue( $service->validate_recovery_mode_key( $key, HOUR_IN_SECONDS ) );
     116                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
     117                $this->assertTrue( $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS ) );
    90118        }
     119
     120
     121        /**
     122         * @ticket 46130
     123         */
     124        public function test_validate_recovery_mode_key_returns_error_if_token_used_more_than_once() {
     125                $service = new WP_Recovery_Mode_Key_Service();
     126                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
     127
     128                $this->assertTrue( $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS ) );
     129
     130                // data should be remove by first call
     131                $error  = $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS );
     132
     133                $this->assertWPError( $error );
     134                $this->assertEquals( 'no_recovery_key_set', $error->get_error_code() );
     135        }
     136
     137
     138        /**
     139         * @ticket 46130
     140         */
     141        public function test_validate_recovery_mode_key_returns_error_if_token_used_more_than_once_more_than_key_stored() {
     142                $service = new WP_Recovery_Mode_Key_Service();
     143
     144                //              create an extra key
     145                $service->generate_and_store_recovery_mode_key();
     146
     147                list( $key, $token ) = $service->generate_and_store_recovery_mode_key();
     148
     149                $this->assertTrue( $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS ) );
     150
     151                // data should be remove by first call
     152                $error  = $service->validate_and_consume_recovery_mode_key( $key, $token, HOUR_IN_SECONDS );
     153
     154                $this->assertWPError( $error );
     155                $this->assertEquals( 'recovery_key_data_missing', $error->get_error_code() );
     156        }
    91157}