From 1cf4ee5dcddd0515a146095f501291afa522ed80 Mon Sep 17 00:00:00 2001 From: NGUEREZA Tony Date: Sat, 23 Sep 2023 08:02:43 +0100 Subject: [PATCH] Update Auth implementation --- src/Auth/Authentication/JWTAuthentication.php | 36 ++++++++++++++++--- .../Authentication/SessionAuthentication.php | 33 ++++++++++++++--- tests/Audit/ApiUserTest.php | 1 - tests/Audit/SessionUserTest.php | 1 - .../Authentication/JWTAuthenticationTest.php | 16 +++++++-- 5 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/Auth/Authentication/JWTAuthentication.php b/src/Auth/Authentication/JWTAuthentication.php index 779722d..8545c59 100644 --- a/src/Auth/Authentication/JWTAuthentication.php +++ b/src/Auth/Authentication/JWTAuthentication.php @@ -50,6 +50,8 @@ use DateTime; use Platine\Config\Config; use Platine\Framework\Auth\ApiAuthenticationInterface; +use Platine\Framework\Auth\Entity\Token; +use Platine\Framework\Auth\Entity\User; use Platine\Framework\Auth\Exception\AccountLockedException; use Platine\Framework\Auth\Exception\AccountNotFoundException; use Platine\Framework\Auth\Exception\InvalidCredentialsException; @@ -210,11 +212,9 @@ public function login(array $credentials = []): array $username = $credentials['username']; $password = $credentials['password']; - $user = $this->userRepository - ->with('roles.permissions') - ->findBy(['username' => $username]); + $user = $this->getUserEntity($username, $password); - if (!$user) { + if ($user === null) { throw new AccountNotFoundException('Can not find the user with the given information', 401); } elseif ($user->status === 'D') { throw new AccountLockedException( @@ -279,6 +279,32 @@ public function login(array $credentials = []): array 'refresh_token' => $refreshToken, ]; - return $data; + return array_merge($data, $this->getUserData($user, $token)); + } + + /** + * Return the user entity + * @param string $username + * @param string $password + * @return User|null + */ + protected function getUserEntity(string $username, string $password): ?User + { + return $this->userRepository + ->with('roles.permissions') + ->findBy(['username' => $username]); + } + + /** + * Return the user additional data + * @param User $user + * @param Token $token + * @return array + */ + protected function getUserData(User $user, Token $token): array + { + return [ + 'token_expire' => $token->expire_at->getTimestamp() + ]; } } diff --git a/src/Auth/Authentication/SessionAuthentication.php b/src/Auth/Authentication/SessionAuthentication.php index c781c94..95bc7ef 100644 --- a/src/Auth/Authentication/SessionAuthentication.php +++ b/src/Auth/Authentication/SessionAuthentication.php @@ -49,6 +49,7 @@ use Platine\Framework\App\Application; use Platine\Framework\Auth\AuthenticationInterface; +use Platine\Framework\Auth\Entity\User; use Platine\Framework\Auth\Event\AuthInvalidPasswordEvent; use Platine\Framework\Auth\Event\AuthLoginEvent; use Platine\Framework\Auth\Exception\AccountLockedException; @@ -153,10 +154,9 @@ public function login(array $credentials = [], bool $remeberMe = false): bool $username = $credentials['username']; $password = $credentials['password']; - $user = $this->userRepository - ->with('roles.permissions') - ->findBy(['username' => $username]); - if (!$user) { + + $user = $this->getUserEntity($username, $password); + if ($user === null) { throw new AccountNotFoundException('Can not find the user with the given information', 401); } elseif ($user->status === 'D') { throw new AccountLockedException( @@ -192,7 +192,7 @@ public function login(array $credentials = [], bool $remeberMe = false): bool 'permissions' => array_unique($permissions), ]; - $this->session->set('user', $data); + $this->session->set('user', array_merge($data, $this->getUserData($user))); $this->app->dispatch(new AuthLoginEvent($user)); @@ -206,4 +206,27 @@ public function logout(): void { $this->session->remove('user'); } + + /** + * Return the user entity + * @param string $username + * @param string $password + * @return User|null + */ + protected function getUserEntity(string $username, string $password): ?User + { + return $this->userRepository + ->with('roles.permissions') + ->findBy(['username' => $username]); + } + + /** + * Return the user additional data + * @param User $user + * @return array + */ + protected function getUserData(User $user): array + { + return []; + } } diff --git a/tests/Audit/ApiUserTest.php b/tests/Audit/ApiUserTest.php index e4480dc..ea7893a 100644 --- a/tests/Audit/ApiUserTest.php +++ b/tests/Audit/ApiUserTest.php @@ -39,5 +39,4 @@ public function testGet(): void $this->assertEquals(123, $o->getUserId()); } - } diff --git a/tests/Audit/SessionUserTest.php b/tests/Audit/SessionUserTest.php index 60fd9b5..1aa7e41 100644 --- a/tests/Audit/SessionUserTest.php +++ b/tests/Audit/SessionUserTest.php @@ -41,5 +41,4 @@ public function testGet(): void $this->assertEquals(123, $o->getUserId()); } - } diff --git a/tests/Auth/Authentication/JWTAuthenticationTest.php b/tests/Auth/Authentication/JWTAuthenticationTest.php index 089e18e..0dedc0d 100644 --- a/tests/Auth/Authentication/JWTAuthenticationTest.php +++ b/tests/Auth/Authentication/JWTAuthenticationTest.php @@ -4,11 +4,13 @@ namespace Platine\Test\Framework\Auth\Authentication; +use DateTime; use Platine\Config\Config; use Platine\Dev\PlatineTestCase; use Platine\Framework\Auth\Authentication\JWTAuthentication; use Platine\Framework\Auth\Entity\Permission; use Platine\Framework\Auth\Entity\Role; +use Platine\Framework\Auth\Entity\Token; use Platine\Framework\Auth\Entity\User; use Platine\Framework\Auth\Exception\AccountLockedException; use Platine\Framework\Auth\Exception\AccountNotFoundException; @@ -384,6 +386,14 @@ public function testLoginSuccess(): void ] ]); + $dt = new DateTime(); + + $token = $this->getMockInstanceMap(Token::class, [ + '__get' => [ + ['expire_at', $dt] + ] + ]); + $role = $this->getMockInstanceMap(Role::class, [ '__get' => [ ['permissions', [$permission]] @@ -411,7 +421,9 @@ public function testLoginSuccess(): void ] ]); - $tokenRepository = $this->getMockInstance(TokenRepository::class); + $tokenRepository = $this->getMockInstance(TokenRepository::class, [ + 'create' => $token + ]); $hash = $this->getMockInstance(BcryptHash::class, [ 'verify' => true ]); @@ -440,6 +452,6 @@ public function testLoginSuccess(): void ]; $data = $o->login($credentials); - $this->assertCount(3, $data); + $this->assertCount(4, $data); } }