| 165 | |
| 166 | /** |
| 167 | * @ticket 32429 |
| 168 | */ |
| 169 | function test_user_activation_key_is_checked() { |
| 170 | global $wpdb; |
| 171 | |
| 172 | $key = wp_generate_password( 20, false ); |
| 173 | $user = $this->factory->user->create_and_get(); |
| 174 | $wpdb->update( $wpdb->users, array( |
| 175 | 'user_activation_key' => strtotime( '-1 hour' ) . ':' . $this->wp_hasher->HashPassword( $key ), |
| 176 | ), array( |
| 177 | 'ID' => $user->ID, |
| 178 | ) ); |
| 179 | |
| 180 | // A valid key should be accepted |
| 181 | $check = check_password_reset_key( $key, $user->user_login ); |
| 182 | $this->assertInstanceOf( 'WP_User', $check ); |
| 183 | $this->assertSame( $user->ID, $check->ID ); |
| 184 | |
| 185 | // An invalid key should be rejected |
| 186 | $check = check_password_reset_key( 'key', $user->user_login ); |
| 187 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 188 | |
| 189 | // An empty key should be rejected |
| 190 | $check = check_password_reset_key( '', $user->user_login ); |
| 191 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 192 | |
| 193 | // A truncated key should be rejected |
| 194 | $partial = substr( $key, 0, 10 ); |
| 195 | $check = check_password_reset_key( $partial, $user->user_login ); |
| 196 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 197 | } |
| 198 | |
| 199 | /** |
| 200 | * @ticket 32429 |
| 201 | */ |
| 202 | function test_expired_user_activation_key_is_rejected() { |
| 203 | global $wpdb; |
| 204 | |
| 205 | $key = wp_generate_password( 20, false ); |
| 206 | $user = $this->factory->user->create_and_get(); |
| 207 | $wpdb->update( $wpdb->users, array( |
| 208 | 'user_activation_key' => strtotime( '-48 hours' ) . ':' . $this->wp_hasher->HashPassword( $key ), |
| 209 | ), array( |
| 210 | 'ID' => $user->ID, |
| 211 | ) ); |
| 212 | |
| 213 | // An expired but otherwise valid key should be rejected |
| 214 | $check = check_password_reset_key( $key, $user->user_login ); |
| 215 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 216 | } |
| 217 | |
| 218 | /** |
| 219 | * @ticket 32429 |
| 220 | */ |
| 221 | function test_empty_user_activation_key_fails_key_check() { |
| 222 | global $wpdb; |
| 223 | |
| 224 | $user = $this->factory->user->create_and_get(); |
| 225 | |
| 226 | // An empty user_activation_key should not allow any key to be accepted |
| 227 | $check = check_password_reset_key( 'key', $user->user_login ); |
| 228 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 229 | |
| 230 | // An empty user_activation_key should not allow an empty key to be accepted |
| 231 | $check = check_password_reset_key( '', $user->user_login ); |
| 232 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 233 | } |
| 234 | |
| 235 | /** |
| 236 | * @ticket 32429 |
| 237 | */ |
| 238 | function test_legacy_user_activation_key_is_accepted() { |
| 239 | global $wpdb; |
| 240 | |
| 241 | // A legacy user_activation_key is one without the `time()` prefix introduced in WordPress 4.3. |
| 242 | |
| 243 | $key = wp_generate_password( 20, false ); |
| 244 | $user = $this->factory->user->create_and_get(); |
| 245 | $wpdb->update( $wpdb->users, array( |
| 246 | 'user_activation_key' => $this->wp_hasher->HashPassword( $key ), |
| 247 | ), array( |
| 248 | 'ID' => $user->ID, |
| 249 | ) ); |
| 250 | |
| 251 | // A legacy user_activation_key should continue to function |
| 252 | $check = check_password_reset_key( $key, $user->user_login ); |
| 253 | |
| 254 | // @TODO remove before commit: |
| 255 | if ( is_wp_error( $check ) ) { |
| 256 | var_dump( $check->get_error_message() ); |
| 257 | } |
| 258 | |
| 259 | $this->assertInstanceOf( 'WP_User', $check ); |
| 260 | $this->assertSame( $user->ID, $check->ID ); |
| 261 | |
| 262 | // An empty key with a legacy user_activation_key should be rejected |
| 263 | $check = check_password_reset_key( '', $user->user_login ); |
| 264 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 265 | } |
| 266 | |
| 267 | /** |
| 268 | * @ticket 32429 |
| 269 | * @ticket 24783 |
| 270 | */ |
| 271 | function test_plaintext_user_activation_key_is_rejected() { |
| 272 | global $wpdb; |
| 273 | |
| 274 | // A plaintext user_activation_key is one stored before hashing was introduced in WordPress 3.7. |
| 275 | |
| 276 | $key = wp_generate_password( 20, false ); |
| 277 | $user = $this->factory->user->create_and_get(); |
| 278 | $wpdb->update( $wpdb->users, array( |
| 279 | 'user_activation_key' => $key, |
| 280 | ), array( |
| 281 | 'ID' => $user->ID, |
| 282 | ) ); |
| 283 | |
| 284 | // A plaintext user_activation_key should not allow an otherwise valid key to be accepted |
| 285 | $check = check_password_reset_key( $key, $user->user_login ); |
| 286 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 287 | |
| 288 | // A plaintext user_activation_key should not allow an empty key to be accepted |
| 289 | $check = check_password_reset_key( '', $user->user_login ); |
| 290 | $this->assertInstanceOf( 'WP_Error', $check ); |
| 291 | } |