Skip to content

Commit 1e2daa3

Browse files
committed
updates
1 parent 5fee55e commit 1e2daa3

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

src/Cms/Cli/Commands/User/ResetPasswordCommand.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,52 @@ public function execute( array $parameters = [] ): int
5757

5858
$hasher = new PasswordHasher();
5959

60+
// Load password policy from configuration
61+
try
62+
{
63+
$settings = Registry::getInstance()->get( RegistryKeys::SETTINGS );
64+
65+
if( $settings )
66+
{
67+
// Read password policy from auth.passwords section
68+
$minLength = $settings->get( 'auth', 'passwords', 'min_length' );
69+
$requireUppercase = $settings->get( 'auth', 'passwords', 'require_uppercase' );
70+
$requireLowercase = $settings->get( 'auth', 'passwords', 'require_lowercase' );
71+
$requireNumbers = $settings->get( 'auth', 'passwords', 'require_numbers' );
72+
$requireSpecialChars = $settings->get( 'auth', 'passwords', 'require_special_chars' );
73+
74+
// Configure hasher with policy
75+
if( $minLength !== null )
76+
{
77+
$hasher->setMinLength( (int)$minLength );
78+
}
79+
80+
if( $requireUppercase !== null )
81+
{
82+
$hasher->setRequireUppercase( (bool)$requireUppercase );
83+
}
84+
85+
if( $requireLowercase !== null )
86+
{
87+
$hasher->setRequireLowercase( (bool)$requireLowercase );
88+
}
89+
90+
if( $requireNumbers !== null )
91+
{
92+
$hasher->setRequireNumbers( (bool)$requireNumbers );
93+
}
94+
95+
if( $requireSpecialChars !== null )
96+
{
97+
$hasher->setRequireSpecialChars( (bool)$requireSpecialChars );
98+
}
99+
}
100+
}
101+
catch( \Exception $e )
102+
{
103+
// Fall back to defaults on any exception
104+
}
105+
60106
// Get username or email from options or prompt
61107
$username = $this->input->getOption( 'username' );
62108
$email = $this->input->getOption( 'email' );

tests/Unit/Cms/Cli/Commands/User/ResetPasswordCommandTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,4 +503,65 @@ public function testExecuteFailsWhenDatabaseUpdateFails(): void
503503
// Should fail with exit code 1
504504
$this->assertEquals(1, $exitCode);
505505
}
506+
507+
public function testExecuteLoadsPasswordPolicyFromConfiguration(): void
508+
{
509+
$this->inputReader->addResponses([
510+
'testuser',
511+
'yes',
512+
'abcdefghij', // 10 chars, all lowercase, no numbers - should fail with default policy
513+
'abcdefghij'
514+
]);
515+
516+
$user = new User();
517+
$user->setId(1);
518+
$user->setUsername('testuser');
519+
$user->setEmail('test@example.com');
520+
$user->setRole('admin');
521+
522+
$repository = $this->createMock(DatabaseUserRepository::class);
523+
$repository->expects($this->once())
524+
->method('findByUsername')
525+
->willReturn($user);
526+
527+
// Mock settings to return custom password policy
528+
$settings = $this->createMock(SettingManager::class);
529+
$settings->method('get')
530+
->willReturnCallback(function(...$args) {
531+
if ($args === ['auth', 'passwords', 'min_length']) {
532+
return 8;
533+
}
534+
if ($args === ['auth', 'passwords', 'require_uppercase']) {
535+
return true; // Require uppercase - should fail
536+
}
537+
if ($args === ['auth', 'passwords', 'require_lowercase']) {
538+
return true;
539+
}
540+
if ($args === ['auth', 'passwords', 'require_numbers']) {
541+
return true; // Require numbers - should fail
542+
}
543+
if ($args === ['auth', 'passwords', 'require_special_chars']) {
544+
return false;
545+
}
546+
return null;
547+
});
548+
549+
Registry::getInstance()->set('Settings', $settings);
550+
551+
$command = $this->getMockBuilder(ResetPasswordCommand::class)
552+
->onlyMethods(['getUserRepository'])
553+
->getMock();
554+
$command->expects($this->once())
555+
->method('getUserRepository')
556+
->willReturn($repository);
557+
558+
$command->setInput($this->input);
559+
$command->setOutput($this->output);
560+
$command->setInputReader($this->inputReader);
561+
562+
$exitCode = $command->execute();
563+
564+
// Should fail because password doesn't meet configured requirements
565+
$this->assertEquals(1, $exitCode);
566+
}
506567
}

0 commit comments

Comments
 (0)