@@ -1134,6 +1134,29 @@ public function test_phpass_application_password_is_accepted() {
11341134 $ this ->assertSame ( self ::$ user_id , $ user ->ID );
11351135 }
11361136
1137+ /**
1138+ * @ticket 21022
1139+ * @ticket 63203
1140+ */
1141+ public function test_plain_bcrypt_application_password_is_accepted () {
1142+ add_filter ( 'application_password_is_api_request ' , '__return_true ' );
1143+ add_filter ( 'wp_is_application_passwords_available ' , '__return_true ' );
1144+
1145+ $ password = 'password ' ;
1146+
1147+ // Set an application password with plain bcrypt, which mimics a password that was hashed with
1148+ // a custom `wp_hash_password()` in use.
1149+ $ uuid = self ::set_application_password_with_plain_bcrypt ( $ password , self ::$ user_id );
1150+
1151+ // Authenticate.
1152+ $ user = wp_authenticate_application_password ( null , self ::USER_LOGIN , $ password );
1153+
1154+ // Verify that the plain bcrypt hash for the application password was valid.
1155+ $ this ->assertNotWPError ( $ user );
1156+ $ this ->assertInstanceOf ( 'WP_User ' , $ user );
1157+ $ this ->assertSame ( self ::$ user_id , $ user ->ID );
1158+ }
1159+
11371160 /**
11381161 * @dataProvider data_usernames
11391162 *
@@ -1591,6 +1614,19 @@ public function test_application_password_authentication() {
15911614 $ this ->assertSame ( $ item ['uuid ' ], rest_get_authenticated_app_password () );
15921615 }
15931616
1617+ /**
1618+ * @ticket 21022
1619+ * @ticket 63203
1620+ *
1621+ * @covers WP_Application_Passwords::create_new_application_password
1622+ */
1623+ public function test_application_password_is_hashed_with_fast_hash () {
1624+ // Create a new app-only password.
1625+ list ( , $ item ) = WP_Application_Passwords::create_new_application_password ( self ::$ user_id , array ( 'name ' => 'phpunit ' ) );
1626+
1627+ $ this ->assertStringStartsWith ( '$generic$ ' , $ item ['password ' ] );
1628+ }
1629+
15941630 /**
15951631 * @ticket 42790
15961632 */
@@ -1963,6 +1999,37 @@ private static function set_user_password_with_plain_bcrypt( string $password, i
19631999 clean_user_cache ( $ user_id );
19642000 }
19652001
2002+ /**
2003+ * Test the tests
2004+ *
2005+ * @covers Tests_Auth::set_application_password_with_plain_bcrypt
2006+ *
2007+ * @ticket 21022
2008+ * @ticket 63203
2009+ */
2010+ public function test_set_application_password_with_plain_bcrypt () {
2011+ // Set an application password with the plain_bcrypt algorithm.
2012+ $ uuid = self ::set_application_password_with_plain_bcrypt ( 'password ' , self ::$ user_id );
2013+
2014+ // Ensure the password is hashed with plain_bcrypt.
2015+ $ hash = WP_Application_Passwords::get_user_application_password ( self ::$ user_id , $ uuid )['password ' ];
2016+ $ this ->assertStringStartsWith ( '$2y$ ' , $ hash );
2017+ }
2018+
2019+ /**
2020+ * Creates an application password that is hashed using bcrypt instead of the generic algorithm.
2021+ *
2022+ * This is ultimately used to mimic a plugged version of `wp_hash_password()` that uses bcrypt and
2023+ * facilitate backwards compatibility testing.
2024+ *
2025+ * @param string $password The password to hash.
2026+ * @param int $user_id The user ID to associate the password with.
2027+ * @return string The UUID of the application password.
2028+ */
2029+ private static function set_application_password_with_plain_bcrypt ( string $ password , int $ user_id ) {
2030+ return self ::set_application_password ( password_hash ( $ password , PASSWORD_BCRYPT ), $ user_id );
2031+ }
2032+
19662033 /**
19672034 * Test the tests
19682035 *
@@ -1979,13 +2046,33 @@ public function test_set_application_password_with_phpass() {
19792046 $ this ->assertStringStartsWith ( '$P$ ' , $ hash );
19802047 }
19812048
2049+ /**
2050+ * Creates an application password that is hashed using a phpass portable hash instead of the generic algorithm.
2051+ *
2052+ * This facilitate backwards compatibility testing.
2053+ *
2054+ * @param string $password The password to hash.
2055+ * @param int $user_id The user ID to associate the password with.
2056+ * @return string The UUID of the application password.
2057+ */
19822058 private static function set_application_password_with_phpass ( string $ password , int $ user_id ) {
2059+ return self ::set_application_password ( self ::$ wp_hasher ->HashPassword ( $ password ), $ user_id );
2060+ }
2061+
2062+ /**
2063+ * Creates an application password using the given password hash.
2064+ *
2065+ * @param string $hash The password hash.
2066+ * @param int $user_id The user ID to associate the password with.
2067+ * @return string The UUID of the application password.
2068+ */
2069+ private static function set_application_password ( string $ hash , int $ user_id ) {
19832070 $ uuid = wp_generate_uuid4 ();
19842071 $ item = array (
19852072 'uuid ' => $ uuid ,
19862073 'app_id ' => '' ,
19872074 'name ' => 'Test ' ,
1988- 'password ' => self :: $ wp_hasher -> HashPassword ( $ password ) ,
2075+ 'password ' => $ hash ,
19892076 'created ' => time (),
19902077 'last_used ' => null ,
19912078 'last_ip ' => null ,
0 commit comments