Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion pirate-parrot.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,21 @@ function derive_secret( $context, $length ) {
}

function get_admin_password() {
return $this->derive_secret( 'admin', self::ADMIN_PASSWORD_LENGTH );
$this->get_options();
if ( empty( $this->_options['seed'] ) ) {
return '';
}
// map the raw digest onto the full password alphabet — a hex-only
// password looks weak and some hosts enforce mixed character classes
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+';
$digest = hash_hmac( 'sha256', 'admin|' . $this->_options['seed'], wp_salt( 'auth' ), true );
$size = strlen( $alphabet );
$password = '';
for ( $i = 0; $i < self::ADMIN_PASSWORD_LENGTH; $i++ ) {
$password .= $alphabet[ ord( $digest[ $i ] ) % $size ];
}

return $password;
}

function get_agent_token() {
Expand Down
9 changes: 7 additions & 2 deletions tests/test-agent-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ public function test_parrot_page_shows_details_after_generation() {

$this->assertStringContainsString( 'Access active', $page );
$this->assertStringContainsString( 'Details to share with support', $page );
$this->assertStringContainsString( $this->agent_token, $page );
$this->assertStringContainsString( $this->parrot->get_admin_password(), $page );
// the page escapes the row values, so assert the escaped forms — the
// password alphabet includes & and other HTML-special characters
$this->assertStringContainsString( esc_html( $this->agent_token ), $page );
$this->assertStringContainsString( esc_html( $this->parrot->get_admin_password() ), $page );
}

public function test_credentials_are_redisplayable_across_requests() {
Expand All @@ -108,6 +110,9 @@ public function test_admin_password_derives_and_matches_the_account() {
$user = get_user_by( 'login', 'ti_parrot' );

$this->assertSame( TI_Parrot::ADMIN_PASSWORD_LENGTH, strlen( $password ) );
$this->assertMatchesRegularExpression( '/^[a-zA-Z0-9!@#$%^&*()\-_=+]+$/', $password );
// drawn from the full alphabet, not the digest's hex form
$this->assertMatchesRegularExpression( '/[^a-f0-9]/', $password );
$this->assertInstanceOf( 'WP_User', $user );
$this->assertTrue( wp_check_password( $password, $user->user_pass, $user->ID ) );
$this->assertTrue( $this->parrot->is_admin_password_in_sync() );
Expand Down
Loading