[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WP_Application_Passwords class 4 * 5 * @package WordPress 6 * @since 5.6.0 7 */ 8 9 /** 10 * Class for displaying, modifying, and sanitizing application passwords. 11 * 12 * @package WordPress 13 */ 14 #[AllowDynamicProperties] 15 class WP_Application_Passwords { 16 17 /** 18 * The application passwords user meta key. 19 * 20 * @since 5.6.0 21 * 22 * @var string 23 */ 24 const USERMETA_KEY_APPLICATION_PASSWORDS = '_application_passwords'; 25 26 /** 27 * The option name used to store whether application passwords are in use. 28 * 29 * @since 5.6.0 30 * 31 * @var string 32 */ 33 const OPTION_KEY_IN_USE = 'using_application_passwords'; 34 35 /** 36 * The generated application password length. 37 * 38 * @since 5.6.0 39 * 40 * @var int 41 */ 42 const PW_LENGTH = 24; 43 44 /** 45 * Checks if application passwords are being used by the site. 46 * 47 * This returns true if at least one application password has ever been created. 48 * 49 * @since 5.6.0 50 * 51 * @return bool 52 */ 53 public static function is_in_use() { 54 $network_id = get_main_network_id(); 55 return (bool) get_network_option( $network_id, self::OPTION_KEY_IN_USE ); 56 } 57 58 /** 59 * Creates a new application password. 60 * 61 * @since 5.6.0 62 * @since 5.7.0 Returns WP_Error if application name already exists. 63 * 64 * @param int $user_id User ID. 65 * @param array $args { 66 * Arguments used to create the application password. 67 * 68 * @type string $name The name of the application password. 69 * @type string $app_id A UUID provided by the application to uniquely identify it. 70 * } 71 * @return array|WP_Error { 72 * Application password details, or a WP_Error instance if an error occurs. 73 * 74 * @type string $0 The generated application password in plain text. 75 * @type array $1 { 76 * The details about the created password. 77 * 78 * @type string $uuid The unique identifier for the application password. 79 * @type string $app_id A UUID provided by the application to uniquely identify it. 80 * @type string $name The name of the application password. 81 * @type string $password A one-way hash of the password. 82 * @type int $created Unix timestamp of when the password was created. 83 * @type null $last_used Null. 84 * @type null $last_ip Null. 85 * } 86 * } 87 */ 88 public static function create_new_application_password( $user_id, $args = array() ) { 89 if ( ! empty( $args['name'] ) ) { 90 $args['name'] = sanitize_text_field( $args['name'] ); 91 } 92 93 if ( empty( $args['name'] ) ) { 94 return new WP_Error( 'application_password_empty_name', __( 'An application name is required to create an application password.' ), array( 'status' => 400 ) ); 95 } 96 97 $new_password = wp_generate_password( static::PW_LENGTH, false ); 98 $hashed_password = wp_hash_password( $new_password ); 99 100 $new_item = array( 101 'uuid' => wp_generate_uuid4(), 102 'app_id' => empty( $args['app_id'] ) ? '' : $args['app_id'], 103 'name' => $args['name'], 104 'password' => $hashed_password, 105 'created' => time(), 106 'last_used' => null, 107 'last_ip' => null, 108 ); 109 110 $passwords = static::get_user_application_passwords( $user_id ); 111 $passwords[] = $new_item; 112 $saved = static::set_user_application_passwords( $user_id, $passwords ); 113 114 if ( ! $saved ) { 115 return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); 116 } 117 118 $network_id = get_main_network_id(); 119 if ( ! get_network_option( $network_id, self::OPTION_KEY_IN_USE ) ) { 120 update_network_option( $network_id, self::OPTION_KEY_IN_USE, true ); 121 } 122 123 /** 124 * Fires when an application password is created. 125 * 126 * @since 5.6.0 127 * 128 * @param int $user_id The user ID. 129 * @param array $new_item { 130 * The details about the created password. 131 * 132 * @type string $uuid The unique identifier for the application password. 133 * @type string $app_id A UUID provided by the application to uniquely identify it. 134 * @type string $name The name of the application password. 135 * @type string $password A one-way hash of the password. 136 * @type int $created Unix timestamp of when the password was created. 137 * @type null $last_used Null. 138 * @type null $last_ip Null. 139 * } 140 * @param string $new_password The generated application password in plain text. 141 * @param array $args { 142 * Arguments used to create the application password. 143 * 144 * @type string $name The name of the application password. 145 * @type string $app_id A UUID provided by the application to uniquely identify it. 146 * } 147 */ 148 do_action( 'wp_create_application_password', $user_id, $new_item, $new_password, $args ); 149 150 return array( $new_password, $new_item ); 151 } 152 153 /** 154 * Gets a user's application passwords. 155 * 156 * @since 5.6.0 157 * 158 * @param int $user_id User ID. 159 * @return array { 160 * The list of application passwords. 161 * 162 * @type array ...$0 { 163 * @type string $uuid The unique identifier for the application password. 164 * @type string $app_id A UUID provided by the application to uniquely identify it. 165 * @type string $name The name of the application password. 166 * @type string $password A one-way hash of the password. 167 * @type int $created Unix timestamp of when the password was created. 168 * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. 169 * @type string|null $last_ip The IP address the application password was last used by. 170 * } 171 * } 172 */ 173 public static function get_user_application_passwords( $user_id ) { 174 $passwords = get_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, true ); 175 176 if ( ! is_array( $passwords ) ) { 177 return array(); 178 } 179 180 $save = false; 181 182 foreach ( $passwords as $i => $password ) { 183 if ( ! isset( $password['uuid'] ) ) { 184 $passwords[ $i ]['uuid'] = wp_generate_uuid4(); 185 $save = true; 186 } 187 } 188 189 if ( $save ) { 190 static::set_user_application_passwords( $user_id, $passwords ); 191 } 192 193 return $passwords; 194 } 195 196 /** 197 * Gets a user's application password with the given UUID. 198 * 199 * @since 5.6.0 200 * 201 * @param int $user_id User ID. 202 * @param string $uuid The password's UUID. 203 * @return array|null { 204 * The application password if found, null otherwise. 205 * 206 * @type string $uuid The unique identifier for the application password. 207 * @type string $app_id A UUID provided by the application to uniquely identify it. 208 * @type string $name The name of the application password. 209 * @type string $password A one-way hash of the password. 210 * @type int $created Unix timestamp of when the password was created. 211 * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. 212 * @type string|null $last_ip The IP address the application password was last used by. 213 * } 214 */ 215 public static function get_user_application_password( $user_id, $uuid ) { 216 $passwords = static::get_user_application_passwords( $user_id ); 217 218 foreach ( $passwords as $password ) { 219 if ( $password['uuid'] === $uuid ) { 220 return $password; 221 } 222 } 223 224 return null; 225 } 226 227 /** 228 * Checks if an application password with the given name exists for this user. 229 * 230 * @since 5.7.0 231 * 232 * @param int $user_id User ID. 233 * @param string $name Application name. 234 * @return bool Whether the provided application name exists. 235 */ 236 public static function application_name_exists_for_user( $user_id, $name ) { 237 $passwords = static::get_user_application_passwords( $user_id ); 238 239 foreach ( $passwords as $password ) { 240 if ( strtolower( $password['name'] ) === strtolower( $name ) ) { 241 return true; 242 } 243 } 244 245 return false; 246 } 247 248 /** 249 * Updates an application password. 250 * 251 * @since 5.6.0 252 * 253 * @param int $user_id User ID. 254 * @param string $uuid The password's UUID. 255 * @param array $update { 256 * Information about the application password to update. 257 * 258 * @type string $uuid The unique identifier for the application password. 259 * @type string $app_id A UUID provided by the application to uniquely identify it. 260 * @type string $name The name of the application password. 261 * @type string $password A one-way hash of the password. 262 * @type int $created Unix timestamp of when the password was created. 263 * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. 264 * @type string|null $last_ip The IP address the application password was last used by. 265 * } 266 * @return true|WP_Error True if successful, otherwise a WP_Error instance is returned on error. 267 */ 268 public static function update_application_password( $user_id, $uuid, $update = array() ) { 269 $passwords = static::get_user_application_passwords( $user_id ); 270 271 foreach ( $passwords as &$item ) { 272 if ( $item['uuid'] !== $uuid ) { 273 continue; 274 } 275 276 if ( ! empty( $update['name'] ) ) { 277 $update['name'] = sanitize_text_field( $update['name'] ); 278 } 279 280 $save = false; 281 282 if ( ! empty( $update['name'] ) && $item['name'] !== $update['name'] ) { 283 $item['name'] = $update['name']; 284 $save = true; 285 } 286 287 if ( $save ) { 288 $saved = static::set_user_application_passwords( $user_id, $passwords ); 289 290 if ( ! $saved ) { 291 return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); 292 } 293 } 294 295 /** 296 * Fires when an application password is updated. 297 * 298 * @since 5.6.0 299 * 300 * @param int $user_id The user ID. 301 * @param array $item { 302 * The updated application password details. 303 * 304 * @type string $uuid The unique identifier for the application password. 305 * @type string $app_id A UUID provided by the application to uniquely identify it. 306 * @type string $name The name of the application password. 307 * @type string $password A one-way hash of the password. 308 * @type int $created Unix timestamp of when the password was created. 309 * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. 310 * @type string|null $last_ip The IP address the application password was last used by. 311 * } 312 * @param array $update The information to update. 313 */ 314 do_action( 'wp_update_application_password', $user_id, $item, $update ); 315 316 return true; 317 } 318 319 return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); 320 } 321 322 /** 323 * Records that an application password has been used. 324 * 325 * @since 5.6.0 326 * 327 * @param int $user_id User ID. 328 * @param string $uuid The password's UUID. 329 * @return true|WP_Error True if the usage was recorded, a WP_Error if an error occurs. 330 */ 331 public static function record_application_password_usage( $user_id, $uuid ) { 332 $passwords = static::get_user_application_passwords( $user_id ); 333 334 foreach ( $passwords as &$password ) { 335 if ( $password['uuid'] !== $uuid ) { 336 continue; 337 } 338 339 // Only record activity once a day. 340 if ( $password['last_used'] + DAY_IN_SECONDS > time() ) { 341 return true; 342 } 343 344 $password['last_used'] = time(); 345 $password['last_ip'] = $_SERVER['REMOTE_ADDR']; 346 347 $saved = static::set_user_application_passwords( $user_id, $passwords ); 348 349 if ( ! $saved ) { 350 return new WP_Error( 'db_error', __( 'Could not save application password.' ) ); 351 } 352 353 return true; 354 } 355 356 // Specified application password not found! 357 return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); 358 } 359 360 /** 361 * Deletes an application password. 362 * 363 * @since 5.6.0 364 * 365 * @param int $user_id User ID. 366 * @param string $uuid The password's UUID. 367 * @return true|WP_Error Whether the password was successfully found and deleted, a WP_Error otherwise. 368 */ 369 public static function delete_application_password( $user_id, $uuid ) { 370 $passwords = static::get_user_application_passwords( $user_id ); 371 372 foreach ( $passwords as $key => $item ) { 373 if ( $item['uuid'] === $uuid ) { 374 unset( $passwords[ $key ] ); 375 $saved = static::set_user_application_passwords( $user_id, $passwords ); 376 377 if ( ! $saved ) { 378 return new WP_Error( 'db_error', __( 'Could not delete application password.' ) ); 379 } 380 381 /** 382 * Fires when an application password is deleted. 383 * 384 * @since 5.6.0 385 * 386 * @param int $user_id The user ID. 387 * @param array $item The data about the application password. 388 */ 389 do_action( 'wp_delete_application_password', $user_id, $item ); 390 391 return true; 392 } 393 } 394 395 return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) ); 396 } 397 398 /** 399 * Deletes all application passwords for the given user. 400 * 401 * @since 5.6.0 402 * 403 * @param int $user_id User ID. 404 * @return int|WP_Error The number of passwords that were deleted or a WP_Error on failure. 405 */ 406 public static function delete_all_application_passwords( $user_id ) { 407 $passwords = static::get_user_application_passwords( $user_id ); 408 409 if ( $passwords ) { 410 $saved = static::set_user_application_passwords( $user_id, array() ); 411 412 if ( ! $saved ) { 413 return new WP_Error( 'db_error', __( 'Could not delete application passwords.' ) ); 414 } 415 416 foreach ( $passwords as $item ) { 417 /** This action is documented in wp-includes/class-wp-application-passwords.php */ 418 do_action( 'wp_delete_application_password', $user_id, $item ); 419 } 420 421 return count( $passwords ); 422 } 423 424 return 0; 425 } 426 427 /** 428 * Sets a user's application passwords. 429 * 430 * @since 5.6.0 431 * 432 * @param int $user_id User ID. 433 * @param array $passwords { 434 * The list of application passwords. 435 * 436 * @type array ...$0 { 437 * @type string $uuid The unique identifier for the application password. 438 * @type string $app_id A UUID provided by the application to uniquely identify it. 439 * @type string $name The name of the application password. 440 * @type string $password A one-way hash of the password. 441 * @type int $created Unix timestamp of when the password was created. 442 * @type int|null $last_used The Unix timestamp of the GMT date the application password was last used. 443 * @type string|null $last_ip The IP address the application password was last used by. 444 * } 445 * } 446 * @return int|bool User meta ID if the key didn't exist (ie. this is the first time that an application password 447 * has been saved for the user), true on successful update, false on failure or if the value passed 448 * is the same as the one that is already in the database. 449 */ 450 protected static function set_user_application_passwords( $user_id, $passwords ) { 451 return update_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, $passwords ); 452 } 453 454 /** 455 * Sanitizes and then splits a password into smaller chunks. 456 * 457 * @since 5.6.0 458 * 459 * @param string $raw_password The raw application password. 460 * @return string The chunked password. 461 */ 462 public static function chunk_password( $raw_password ) { 463 $raw_password = preg_replace( '/[^a-z\d]/i', '', $raw_password ); 464 465 return trim( chunk_split( $raw_password, 4, ' ' ) ); 466 } 467 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |