Skip to content

Commit

Permalink
Merge pull request #1083 from rochamarcelo/feature/account-lockout-po…
Browse files Browse the repository at this point in the history
…licy

Feature/account lockout policy
  • Loading branch information
steinkel authored Mar 29, 2024
2 parents 4ae200f + ef0a2df commit 1d93a14
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .semver
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
:major: 11
:minor: 3
:major: 14
:minor: 1
:patch: 0
:special: ''
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ Changelog
=========
Releases for CakePHP 5
-------------
* 14.1
* New feature "Account lockout policy"
* 14.0
* Set dependecy for CakeDC/Auth to 10.0. Perform 2FA refactoring,

Expand All @@ -23,7 +25,7 @@ Releases for CakePHP 4.5
* Update Permissions.md
* fix: config for updateLastLogin
* fix: remove deprecated code on profile logic
* feat:flash message on login, on cake4
* feat:flash message on login, on cake4

* 11.3.4
* Fix `Detected invalid UTF-8 for field...` issue when storing session data from `Webauthn` in a mongo database.
Expand Down
28 changes: 28 additions & 0 deletions Docs/Documentation/Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,34 @@ The default list for ``Auth.Identifiers`` is:

These identifiers are loaded by the ``\CakeDC\Users\Loader\AuthenticationServiceLoader`` class in the ``loadIdentifiers`` method. See [Authentication Service Loader](#authentication-service-loader) on how to adjust it to your needs.

Account lockout policy
----------------------
Lock a users account after a number of failed password attempts in a certain time window.

To enable this updated your config/users.php file with:
```php
'Auth.Identifiers.Password.className' => 'CakeDC/Users.PasswordLockout',
'Auth.PasswordRehash' => [
'identifiers' => ['PasswordLockout'],
],
```
Additionally, you can set number of attempts until lock, lockout time, time window and more, eg:
```
'Auth.Identifiers.Password.className' => 'CakeDC/Users.PasswordLockout',
'Auth.PasswordRehash' => [
'identifiers' => ['PasswordLockout'],
],
'Auth.Identifiers.Password.lockoutHandler' => [
'timeWindowInSeconds' => 30 * 60,//30 minutes (default is 15 minutes)
'lockoutTimeInSeconds' => 100 * 60,//100 minutes (default is 30 minutes)
'numberOfAttemptsFail' => 4, (default is 6 attempts)
'failedPasswordAttemptsModel' => 'CakeDC/Users.FailedPasswordAttempts',
'userLockoutField' => 'lockout_time',//Field in user entity used to lock the user.
'usersModel' => 'Users',
],
```


Handling Login Result
---------------------

Expand Down
1 change: 1 addition & 0 deletions Docs/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ I want to
</details>
- [use user's email to login](./Documentation/Configuration.md#using-the-users-email-to-login)
- [override the password hasher](./Documentation/Configuration.md#password-hasher-customization)
- [lock a users account after a number of failed password attempts](./Documentation/Authentication.md#account-lockout-policy)

- add custom logic before
- [user logout](./Documentation/Events.md#i-want-to-add-custom-logic-before-user-logout)
Expand Down
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ CakeDC Users Plugin
Versions and branches
---------------------

| CakePHP | CakeDC Users Plugin | Tag | Notes |
| :-------------: | :------------------------: | :--: | :---- |
| ^5.0 | [12.0](https://github.com/cakedc/users/tree/12.next-cake5) | 12.next-cake5-dev | beta |
| ^4.3 | [11.0](https://github.com/cakedc/users/tree/11.next-cake4) | 11.1.0 | stable |
| ^4.0 | [9.0](https://github.com/cakedc/users/tree/9.next) | 9.0.5 | stable |
| ^3.7 <4.0 | [8.5](https://github.com/cakedc/users/tree/8.next) | 8.5.1 | stable |
| ^3.7 <4.0 | [develop](https://github.com/cakedc/users/tree/develop) | - | unstable |
| 3.6 | [8.1](https://github.com/cakedc/users/tree/8.1.0) | 8.1.0 | stable |
| 3.5 | [6.x](https://github.com/cakedc/users/tree/6.x) | 6.0.1 | stable |
| 3.4 | [5.x](https://github.com/cakedc/users/tree/5.x) | 5.2.0 | stable |
| >=3.2.9 <3.4.0 | [4.x](https://github.com/cakedc/users/tree/4.x) | 4.2.1 | stable |
| ^2.10 | [2.x](https://github.com/cakedc/users/tree/2.x) | 2.2.0 |stable |
| CakePHP | CakeDC Users Plugin | Tag | Notes |
|:--------------:|:----------------------------------------------------------:|:-----------------:| :---- |
| ^5.0 | [14.1](https://github.com/cakedc/users/tree/14.next-cake5) | 14.next-cake5-dev | beta |
| ^4.5 | [13.0](https://github.com/cakedc/users/tree/13.next-cake4) | 13.0.1 | stable |
| ^5.0 | [12.0](https://github.com/cakedc/users/tree/12.next-cake5) | 12.0 | beta |
| ^4.3 | [11.0](https://github.com/cakedc/users/tree/11.next-cake4) | 11.1.0 | stable |
| ^4.0 | [9.0](https://github.com/cakedc/users/tree/9.next) | 9.0.5 | stable |
| ^3.7 <4.0 | [8.5](https://github.com/cakedc/users/tree/8.next) | 8.5.1 | stable |
| ^3.7 <4.0 | [develop](https://github.com/cakedc/users/tree/develop) | - | unstable |
| 3.6 | [8.1](https://github.com/cakedc/users/tree/8.1.0) | 8.1.0 | stable |
| 3.5 | [6.x](https://github.com/cakedc/users/tree/6.x) | 6.0.1 | stable |
| 3.4 | [5.x](https://github.com/cakedc/users/tree/5.x) | 5.2.0 | stable |
| >=3.2.9 <3.4.0 | [4.x](https://github.com/cakedc/users/tree/4.x) | 4.2.1 | stable |
| ^2.10 | [2.x](https://github.com/cakedc/users/tree/2.x) | 2.2.0 |stable |

The **Users** plugin covers the following features:

Expand Down
4 changes: 2 additions & 2 deletions src/Identifier/PasswordLockout/LockoutHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class LockoutHandler implements LockoutHandlerInterface
* @var array{timeWindowInSeconds: int, lockoutTimeInSeconds: int, numberOfAttemptsFail:int}
*/
protected array $_defaultConfig = [
'timeWindowInSeconds' => 5 * 60,
'lockoutTimeInSeconds' => 5 * 60,
'timeWindowInSeconds' => 15 * 60,
'lockoutTimeInSeconds' => 30 * 60,
'numberOfAttemptsFail' => 6,
'failedPasswordAttemptsModel' => 'CakeDC/Users.FailedPasswordAttempts',
'userLockoutField' => 'lockout_time',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,11 @@ public function testIsUnlockedSaveLockoutAndCompleted()
$handler = new LockoutHandler([
'numberOfAttemptsFail' => 7,
]);
$expiredTimeout = $handler->getConfig('lockoutTimeInSeconds') + 10;
$this->assertGreaterThan(10, $expiredTimeout);
$UsersTable = TableRegistry::getTableLocator()->get('Users');
$userId = '00000000-0000-0000-0000-000000000004';
$UsersTable->updateAll(['lockout_time' => new DateTime('-6 minutes')], ['id' => $userId]);
$UsersTable->updateAll(['lockout_time' => new DateTime('-' . $expiredTimeout . 'minutes')], ['id' => $userId]);
$userBefore = $UsersTable->get($userId);
$this->assertInstanceOf(DateTime::class, $userBefore->lockout_time);

Expand Down

0 comments on commit 1d93a14

Please sign in to comment.