Skip to content

Commit f3f2d1d

Browse files
authored
Merge pull request #2 from amosfolz/pw-security-updates
Add PasswordSecurity as a service
2 parents fc69108 + cca5ffb commit f3f2d1d

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

app/sprinkles/account/config/default.php

+7-4
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@
116116
]
117117
],
118118
'password_security' => [
119-
'enforce_no_compromised' => '0' // Set to false to turn off this feature. Otherwise, provide a numeric string, which sets the maximum number
120-
// of times that is "acceptable" for a password to have appeared in breaches. The recommended and most secure
121-
// option is '0' - meaning only passwords that are not on the list of compromised passwords will be allowed.
122-
]
119+
'enforce_no_compromised' => [
120+
'breaches' => '0', // Set to '-1' to turn off this feature. Otherwise, provide a numeric string, which sets the maximum number
121+
// of times that is "acceptable" for a password to have appeared in breaches. The recommended and most secure
122+
// option is '0' - meaning only passwords that are not on the list of compromised passwords will be allowed.
123+
'cache' => 10080 // Duration in minutes to store HIBP API responses in cache.
124+
]
125+
]
123126
],
124127

125128
/*

app/sprinkles/account/src/Authenticate/PasswordSecurity.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,21 @@ private function getHashArrayFromAPI($hashPrefix)
116116
return $hashArray;
117117
}
118118

119-
public function isEnabled()
119+
/**
120+
* Checks if compromised password reset feature is enabeld.
121+
*
122+
* @return bool True if the feature is enabled.
123+
*/
124+
public function resetCompromisedEnabled()
120125
{
121126
return $this->config['site.login.enforce_reset_compromised'];
122127
}
123128

129+
/**
130+
* Checks the maximum number of times that is acceptable for a password to have appeared in breaches.
131+
*
132+
* @return string Numeric string with -1 meaning disabled.
133+
*/
124134
public function breachThreshold()
125135
{
126136
return $this->config['site.password_security.enforce_no_compromised.breaches'];

app/sprinkles/account/src/Controller/AccountController.php

+7-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use UserFrosting\Support\Exception\BadRequestException;
2929
use UserFrosting\Support\Exception\ForbiddenException;
3030
use UserFrosting\Support\Exception\NotFoundException;
31-
use UserFrosting\Sprinkle\Account\Authenticate\PasswordSecurity;
3231

3332
/**
3433
* Controller class for /account/* URLs. Handles account-related activities, including login, registration, password recovery, and account settings.
@@ -428,12 +427,14 @@ public function login(Request $request, Response $response, $args)
428427

429428
$currentUser = $authenticator->attempt(($isEmail ? 'email' : 'user_name'), $userIdentifier, $data['password'], $data['rememberme']);
430429

431-
// Check if the enforced password update setting is configured.
432-
if ($this->ci->config['site.login.enforce_reset_compromised'] == true) {
430+
$passwordSecurity = $this->ci->passwordSecurity;
431+
432+
// Check if the enforce password update setting is configured.
433+
if ($passwordSecurity->resetCompromisedEnabled()) {
433434
// Check if the password is on the compromised password list.
434-
$numberOfBreaches = PasswordSecurity::checkPassword($data['password']);
435+
$numberOfBreaches = $passwordSecurity->checkPassword($data['password']);
435436

436-
if ($numberOfBreaches > $this->ci->config['site.password_security.enforce_no_compromised']) {
437+
if ($passwordSecurity->breachThreshold() != '-1' && $numberOfBreaches > $passwordSecurity->breachThreshold()) {
437438

438439
// Try to generate a new password reset request.
439440
// Use timeout for "reset password"
@@ -452,7 +453,7 @@ public function login(Request $request, Response $response, $args)
452453
]
453454
], $token);
454455

455-
$ms->addMessageTranslated('info', 'PASSWORD.SECURITY.RESET_REQUIRED');
456+
$ms->addMessageTranslated('info', 'PASSWORD.SECURITY.RESET_REQUIRED.COMPROMISED');
456457

457458
return $response->withRedirect($forcePasswordChange);
458459
}

app/sprinkles/account/src/ServicesProvider/ServicesProvider.php

+14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use UserFrosting\Sprinkle\Account\Authenticate\Authenticator;
1919
use UserFrosting\Sprinkle\Account\Authenticate\AuthGuard;
2020
use UserFrosting\Sprinkle\Account\Authenticate\Hasher;
21+
use UserFrosting\Sprinkle\Account\Authenticate\PasswordSecurity;
2122
use UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager;
2223
use UserFrosting\Sprinkle\Account\Database\Models\User;
2324
use UserFrosting\Sprinkle\Account\Log\UserActivityDatabaseHandler;
@@ -173,6 +174,19 @@ public function register(ContainerInterface $container)
173174
return $authenticator;
174175
};
175176

177+
/**
178+
* PasswordSecurity service.
179+
*
180+
* Handles password security features.
181+
*
182+
* @return \UserFrosting\Sprinkle\Account\Authenticate\PasswordSecurity
183+
*/
184+
$container['passwordSecurity'] = function ($c) {
185+
$cache = $c->cache;
186+
$config = $c->config;
187+
188+
return new PasswordSecurity($cache, $config);
189+
};
176190
/**
177191
* Sets up the AuthGuard middleware, used to limit access to authenticated users for certain routes.
178192
*

0 commit comments

Comments
 (0)