Skip to content

Commit

Permalink
Merge pull request #1087 from AReveron/feature/improve-lockout-config
Browse files Browse the repository at this point in the history
Add config option to customize the user foreign key field in LockoutHandler
  • Loading branch information
steinkel authored May 8, 2024
2 parents 1d93a14 + 967dc9b commit 360b2e1
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
1 change: 1 addition & 0 deletions Docs/Documentation/Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ Additionally, you can set number of attempts until lock, lockout time, time wind
'failedPasswordAttemptsModel' => 'CakeDC/Users.FailedPasswordAttempts',
'userLockoutField' => 'lockout_time',//Field in user entity used to lock the user.
'usersModel' => 'Users',
'userForeignKeyField' => 'user_id', //Field defined in the 'failed_password_attempts' table as foreignKey of the model Users.
],
```

Expand Down
17 changes: 9 additions & 8 deletions src/Identifier/PasswordLockout/LockoutHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
namespace CakeDC\Users\Identifier\PasswordLockout;

use Cake\Core\InstanceConfigTrait;
use Cake\Datasource\EntityInterface;
use Cake\I18n\DateTime;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\ORM\Query\SelectQuery;
use CakeDC\Users\Model\Entity\FailedPasswordAttempt;

class LockoutHandler implements LockoutHandlerInterface
{
Expand All @@ -36,6 +36,7 @@ class LockoutHandler implements LockoutHandlerInterface
'failedPasswordAttemptsModel' => 'CakeDC/Users.FailedPasswordAttempts',
'userLockoutField' => 'lockout_time',
'usersModel' => 'Users',
'userForeignKeyField' => 'user_id',
];

/**
Expand Down Expand Up @@ -73,9 +74,9 @@ public function isUnlocked(\ArrayAccess|array $identity): bool
$lastAttempt = $this->getLastAttempt($identity['id'], $timeWindow);
$this->getTableLocator()
->get($this->getConfig('usersModel'))
->updateAll([$lockoutField => $lastAttempt->created], ['id' => $identity['id']]);
->updateAll([$lockoutField => $lastAttempt->get('created')], ['id' => $identity['id']]);

return $this->checkLockoutTime($lastAttempt->created);
return $this->checkLockoutTime($lastAttempt->get('created'));
}

/**
Expand All @@ -86,7 +87,7 @@ public function newFail(string|int $id): void
{
$timeWindow = $this->getTimeWindow();
$Table = $this->getTable();
$entity = $Table->newEntity(['user_id' => $id]);
$entity = $Table->newEntity([$this->getConfig('userForeignKeyField') => $id]);
$Table->saveOrFail($entity);
$Table->deleteAll($Table->query()->newExpr()->lt('created', $timeWindow));
}
Expand All @@ -96,7 +97,7 @@ public function newFail(string|int $id): void
*/
protected function getTable(): \Cake\ORM\Table
{
return $this->getTableLocator()->get('CakeDC/Users.FailedPasswordAttempts');
return $this->getTableLocator()->get($this->getConfig('failedPasswordAttemptsModel'));
}

/**
Expand All @@ -112,9 +113,9 @@ protected function getAttemptsCount(string|int $id, DateTime $timeWindow): int
/**
* @param string|int $id
* @param \Cake\I18n\DateTime $timeWindow
* @return \CakeDC\Users\Model\Entity\FailedPasswordAttempt
* @return \Cake\Datasource\EntityInterface
*/
protected function getLastAttempt(int|string $id, DateTime $timeWindow): FailedPasswordAttempt
protected function getLastAttempt(int|string $id, DateTime $timeWindow): EntityInterface
{
/**
* @var \CakeDC\Users\Model\Entity\FailedPasswordAttempt $attempt
Expand All @@ -135,7 +136,7 @@ protected function getAttemptsQuery(int|string $id, DateTime $timeWindow): Selec

return $query
->where([
'user_id' => $id,
$this->getConfig('userForeignKeyField') => $id,
$query->newExpr()->gte('created', $timeWindow),
])
->orderByDesc('created');
Expand Down

0 comments on commit 360b2e1

Please sign in to comment.