From 13a43a6e7cf9f46d672b3f453db77382001bc646 Mon Sep 17 00:00:00 2001 From: Lenny ROUANET Date: Mon, 24 Oct 2022 09:39:52 +0200 Subject: [PATCH] Hello world ! --- .gitignore | 3 +- README.md | 32 +- .../Domain/DataStructure/AccessToken.php | 95 ----- .../Domain/DataStructure/Application.php | 50 --- .../DataStructure/Application/ApiKey.php | 31 -- .../DataStructure/Application/Collection.php | 40 -- .../Domain/DataStructure/Application/Name.php | 16 - .../Domain/DataStructure/RequestAccess.php | 156 -------- .../RequestAccess/AuthMethod.php | 22 -- .../DataStructure/RequestAccess/Otp.php | 34 -- .../DataStructure/RequestAccess/State.php | 45 --- .../DataStructure/RequestAccessFromApiKey.php | 36 -- .../DataStructure/RequestAccessFromOtp.php | 71 ---- .../RequestAccessFromThirdParty.php | 43 --- component/Domain/DataStructure/SslKey.php | 66 ---- component/Domain/DataStructure/User.php | 36 -- component/Domain/DataStructure/User/Role.php | 8 - component/Domain/Entity/AccessToken.php | 93 +++++ .../AccessToken/Expire.php | 3 +- .../Application => Entity/AccessToken}/Id.php | 3 +- .../AccessToken/Jwt.php | 3 +- component/Domain/Entity/Application.php | 71 ++++ .../Domain/Entity/Application/ApiKey.php | 33 ++ .../Domain/Entity/Application/Collection.php | 49 +++ .../AccessToken => Entity/Application}/Id.php | 3 +- .../Application/Logo.php | 3 +- component/Domain/Entity/Application/Name.php | 17 + component/Domain/Entity/RequestAccess.php | 109 ++++++ .../Entity/RequestAccess/AuthMethod.php | 28 ++ .../RequestAccess/CallbackUrl.php | 3 +- .../RequestAccess/Id.php | 3 +- component/Domain/Entity/RequestAccess/Otp.php | 35 ++ .../Domain/Entity/RequestAccess/State.php | 49 +++ .../RequestAccess/Token.php | 3 +- .../Domain/Entity/RequestAccessFromApiKey.php | 32 ++ .../Domain/Entity/RequestAccessFromOtp.php | 66 ++++ .../Entity/RequestAccessFromThirdParty.php | 34 ++ component/Domain/Entity/SslKey.php | 54 +++ component/Domain/Entity/User.php | 47 +++ .../User/EmailAddress.php | 3 +- .../User/Firstname.php | 3 +- .../User/Lastname.php | 3 +- component/Domain/Entity/User/Role.php | 9 + component/Domain/Port/Application.php | 19 +- component/Domain/Port/OtpSender.php | 11 +- component/Domain/Port/RequestAccess.php | 9 +- component/Domain/Serialize/Application.php | 37 +- component/Domain/Serialize/User.php | 21 +- component/Domain/Service/AccessToken.php | 124 +++--- component/Domain/Service/Application.php | 100 ++--- component/Domain/Service/RequestAccess.php | 89 ++--- .../Service/RequestAccessFromApiKey.php | 119 +++--- .../Domain/Service/RequestAccessFromOtp.php | 216 ++++++----- .../Service/RequestAccessFromThirdParty.php | 172 +++++---- .../Fixture/DataStructure/AccessToken.php | 83 ++-- .../Fixture/DataStructure/Application.php | 115 +++--- .../DataStructure/RequestAccessFromApiKey.php | 49 +-- .../DataStructure/RequestAccessFromOtp.php | 55 +-- .../RequestAccessFromThirdParty.php | 55 +-- component/Fixture/DataStructure/SslKey.php | 41 +- component/Fixture/DataStructure/User.php | 31 +- component/Fixture/Port/Application.php | 99 ++--- component/Fixture/Port/OtpSender.php | 31 +- component/Fixture/Port/RequestAccess.php | 57 +-- component/Fixture/Service/AccessToken.php | 15 +- component/Fixture/Service/Application.php | 17 +- component/Fixture/Service/RequestAccess.php | 19 +- .../Service/RequestAccessFromApiKey.php | 25 +- .../Fixture/Service/RequestAccessFromOtp.php | 25 +- .../Service/RequestAccessFromThirdParty.php | 19 +- composer.json | 6 +- test/Domain/DataStructure/AccessTokenTest.php | 170 +++++---- .../DataStructure/Application/ApiKeyTest.php | 53 +-- .../Application/CollectionTest.php | 107 +++--- .../DataStructure/Application/NameTest.php | 31 +- test/Domain/DataStructure/ApplicationTest.php | 154 ++++---- .../RequestAccess/AuthMethodTest.php | 45 ++- .../DataStructure/RequestAccess/OtpTest.php | 79 ++-- .../DataStructure/RequestAccess/StateTest.php | 234 ++++++------ .../RequestAccessFromApiKeyTest.php | 51 +-- .../RequestAccessFromOtpTest.php | 173 ++++----- .../RequestAccessFromThirdPartyTest.php | 67 ++-- .../DataStructure/RequestAccessTest.php | 355 +++++++++--------- test/Domain/DataStructure/SslKeyTest.php | 125 +++--- test/Domain/DataStructure/UserTest.php | 49 +-- test/Domain/Serialize/ApplicationTest.php | 43 +-- test/Domain/Serialize/UserTest.php | 43 +-- test/Domain/Service/AccessTokenTest.php | 117 +++--- test/Domain/Service/ApplicationTest.php | 95 ++--- .../Service/RequestAccessFromApiKeyTest.php | 60 +-- .../Service/RequestAccessFromOtpTest.php | 266 ++++++------- .../RequestAccessFromThirdPartyTest.php | 159 ++++---- test/Domain/Service/RequestAccessTest.php | 129 +++---- 93 files changed, 2972 insertions(+), 2835 deletions(-) delete mode 100644 component/Domain/DataStructure/AccessToken.php delete mode 100644 component/Domain/DataStructure/Application.php delete mode 100644 component/Domain/DataStructure/Application/ApiKey.php delete mode 100644 component/Domain/DataStructure/Application/Collection.php delete mode 100644 component/Domain/DataStructure/Application/Name.php delete mode 100644 component/Domain/DataStructure/RequestAccess.php delete mode 100644 component/Domain/DataStructure/RequestAccess/AuthMethod.php delete mode 100644 component/Domain/DataStructure/RequestAccess/Otp.php delete mode 100644 component/Domain/DataStructure/RequestAccess/State.php delete mode 100644 component/Domain/DataStructure/RequestAccessFromApiKey.php delete mode 100644 component/Domain/DataStructure/RequestAccessFromOtp.php delete mode 100644 component/Domain/DataStructure/RequestAccessFromThirdParty.php delete mode 100644 component/Domain/DataStructure/SslKey.php delete mode 100644 component/Domain/DataStructure/User.php delete mode 100644 component/Domain/DataStructure/User/Role.php create mode 100644 component/Domain/Entity/AccessToken.php rename component/Domain/{DataStructure => Entity}/AccessToken/Expire.php (64%) rename component/Domain/{DataStructure/Application => Entity/AccessToken}/Id.php (61%) rename component/Domain/{DataStructure => Entity}/AccessToken/Jwt.php (62%) create mode 100644 component/Domain/Entity/Application.php create mode 100644 component/Domain/Entity/Application/ApiKey.php create mode 100644 component/Domain/Entity/Application/Collection.php rename component/Domain/{DataStructure/AccessToken => Entity/Application}/Id.php (61%) rename component/Domain/{DataStructure => Entity}/Application/Logo.php (62%) create mode 100644 component/Domain/Entity/Application/Name.php create mode 100644 component/Domain/Entity/RequestAccess.php create mode 100644 component/Domain/Entity/RequestAccess/AuthMethod.php rename component/Domain/{DataStructure => Entity}/RequestAccess/CallbackUrl.php (63%) rename component/Domain/{DataStructure => Entity}/RequestAccess/Id.php (60%) create mode 100644 component/Domain/Entity/RequestAccess/Otp.php create mode 100644 component/Domain/Entity/RequestAccess/State.php rename component/Domain/{DataStructure => Entity}/RequestAccess/Token.php (65%) create mode 100644 component/Domain/Entity/RequestAccessFromApiKey.php create mode 100644 component/Domain/Entity/RequestAccessFromOtp.php create mode 100644 component/Domain/Entity/RequestAccessFromThirdParty.php create mode 100644 component/Domain/Entity/SslKey.php create mode 100644 component/Domain/Entity/User.php rename component/Domain/{DataStructure => Entity}/User/EmailAddress.php (69%) rename component/Domain/{DataStructure => Entity}/User/Firstname.php (68%) rename component/Domain/{DataStructure => Entity}/User/Lastname.php (68%) create mode 100644 component/Domain/Entity/User/Role.php diff --git a/.gitignore b/.gitignore index 5976415..d90c60c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,9 @@ vendor/* .phpunit* test/storage/* !test/storage/.gitkeep -public/coverage/* +.coverage/* # Dev .DS_Store .nova/* +.php-cs-fixer.cache diff --git a/README.md b/README.md index 7fdd0c1..ad0c302 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ For each use case the following setup is required. ```php use Phant\Auth\Domain\Service\AccessToken as ServiceAccessToken; use Phant\Auth\Domain\Service\RequestAccess as ServiceRequestAccess; -use Phant\Auth\Domain\DataStructure\SslKey; +use Phant\Auth\Domain\Entity\SslKey; use App\RepositoryRequestAccess; @@ -93,26 +93,26 @@ $accessToken = $serviceRequestAccessFromApiKey->getAccessToken($apiKey); ``` -### From OTP +### From Otp Process : 1. The application asks the user to authenticate himself by providing his contact details (last name, first name and e-mail address), 2. The application generates an access request by providing its identity and the user's contact details (last name, first name and e-mail address), -3. The service generates an OTP and requests its sending to the user, -4. The user receives an OTP, -5. The application retrieves the OTP from the user, -6. The user transmits the received OTP to the application, -7. The application verifies the OTP with the service, +3. The service generates an Otp and requests its sending to the user, +4. The user receives an Otp, +5. The application retrieves the Otp from the user, +6. The user transmits the received Otp to the application, +7. The application verifies the Otp with the service, 8. The application requests an access token, 9. The service provides an access token. -The OTP is sent to user by your own OtpSender service (e-mail, SMS, etc.). +The Otp is sent to user by your own OtpSender service (e-mail, SMS, etc.). ```php use Phant\Auth\Domain\Service\RequestAccessFromOtp as ServiceRequestAccessFromOtp; -use Phant\Auth\Domain\DataStructure\Application; -use Phant\Auth\Domain\DataStructure\User; +use Phant\Auth\Domain\Entity\Application; +use Phant\Auth\Domain\Entity\User; use App\OtpSender; @@ -148,13 +148,13 @@ $application = new Application( $requestAccessToken = $serviceRequestAccessFromOtp->generate($user, $application); -// Obtain OTP from user +// Obtain Otp from user /* @todo */ $otp = '123456'; -// Verify OTP +// Verify Otp $isValid = $serviceRequestAccessFromOtp->verify($otp); @@ -184,8 +184,8 @@ Process : ```php use Phant\Auth\Domain\Service\RequestAccessFromThirdParty as ServiceRequestAccessFromThirdParty; -use Phant\Auth\Domain\DataStructure\Application; -use Phant\Auth\Domain\DataStructure\User; +use Phant\Auth\Domain\Entity\Application; +use Phant\Auth\Domain\Entity\User; use App\RepositoryRequestAccess; @@ -311,7 +311,7 @@ try { The application can verify the integrity of the token with the service. ```php -use Phant\Auth\Domain\DataStructure\Application; +use Phant\Auth\Domain\Entity\Application; $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', @@ -328,7 +328,7 @@ $isValid = $serviceAccessToken->check($accessToken, $application); The app can get the token payload from the service. ```php -use Phant\Auth\Domain\DataStructure\Application; +use Phant\Auth\Domain\Entity\Application; $application = new Application( 'eb7c9c44-32c2-4e88-8410-4ebafb18fdf7', diff --git a/component/Domain/DataStructure/AccessToken.php b/component/Domain/DataStructure/AccessToken.php deleted file mode 100644 index f0f6c95..0000000 --- a/component/Domain/DataStructure/AccessToken.php +++ /dev/null @@ -1,95 +0,0 @@ -value = $value; - } - - public function __toString(): string - { - return $this->value; - } - - public function check(SslKey $sslKey, Application $application): bool - { - try { - - $payload = (new Jwt($this->value))->decode($sslKey->getPublic()); - - $id = $payload[ self::PAYLOAD_KEY_APP ]->id ?? null; - - if (!$id) return false; - - if (!$application->isHisId($id)) return false; - - } catch (\Exception $e) { - return false; - } - - return true; - } - - public function getPayload(SslKey $sslKey): ?array - { - try { - - $payLoad = (new Jwt($this->value))->decode($sslKey->getPublic()); - - return $payLoad; - - } catch (\Exception $e) { - return null; - } - } - - public static function generate( - SslKey $sslKey, - AuthMethod $authMethod, - Application $application, - ?User $user, - int $lifetime - ): self - { - $expire = (new Expire(time() + $lifetime))->getUtc(); - - $payload = [ - self::PAYLOAD_KEY_EXPIRE => (string) $expire, - self::PAYLOAD_KEY_AUTH_METHOD => (string) $authMethod, - self::PAYLOAD_KEY_APP => SerializeApplication::serializeForPayload($application), - ]; - - if ($user) { - $payload[ self::PAYLOAD_KEY_USER ] = SerializeUser::serialize($user); - } - - return new self((string)Jwt::encode($sslKey->getPrivate(), $payload, $lifetime)); - } -} diff --git a/component/Domain/DataStructure/Application.php b/component/Domain/DataStructure/Application.php deleted file mode 100644 index fb0114a..0000000 --- a/component/Domain/DataStructure/Application.php +++ /dev/null @@ -1,50 +0,0 @@ -id = $id; - $this->name = $name; - $this->logo = $logo; - $this->apiKey = $apiKey; - } - - public function isHisApiKey(string|ApiKey $apiKey): bool - { - if (is_string($apiKey)) $apiKey = new ApiKey($apiKey); - - return ((string)$this->apiKey === (string)$apiKey); - } - - public function isHisId(string|Id $id): bool - { - if (is_string($id)) $id = new Id($id); - - return ((string)$this->id === (string)$id); - } -} diff --git a/component/Domain/DataStructure/Application/ApiKey.php b/component/Domain/DataStructure/Application/ApiKey.php deleted file mode 100644 index af25c8a..0000000 --- a/component/Domain/DataStructure/Application/ApiKey.php +++ /dev/null @@ -1,31 +0,0 @@ -value === (string)$apiKey; - } - - private static function generateRandomString($length = 10) { - $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - - $charactersLength = strlen($characters); - $randomString = ''; - for ($i = 0; $i < $length; $i++) { - $randomString .= $characters[rand(0, $charactersLength - 1)]; - } - - return $randomString; - } -} diff --git a/component/Domain/DataStructure/Application/Collection.php b/component/Domain/DataStructure/Application/Collection.php deleted file mode 100644 index 3177d86..0000000 --- a/component/Domain/DataStructure/Application/Collection.php +++ /dev/null @@ -1,40 +0,0 @@ -itemsIterator() as $entity) { - if ($entity->isHisId($id)) return $entity; - } - - return null; - } - - public function searchByApiKey(string|ApiKey $apiKey): ?Application - { - if (is_string($apiKey)) $apiKey = new ApiKey($apiKey); - - foreach ($this->itemsIterator() as $entity) { - if ($entity->isHisApiKey($apiKey)) return $entity; - } - - return null; - } -} diff --git a/component/Domain/DataStructure/Application/Name.php b/component/Domain/DataStructure/Application/Name.php deleted file mode 100644 index 53d2ce5..0000000 --- a/component/Domain/DataStructure/Application/Name.php +++ /dev/null @@ -1,16 +0,0 @@ -id = $id; - $this->application = $application; - $this->user = $user; - $this->authMethod = $authMethod; - $this->state = $state; - $this->lifetime = $lifetime; - $this->expiration = time() + $lifetime; - } - - public function getId(): Id - { - return $this->id; - } - - public function setApplication(Application $application): void - { - if ($this->application) { - throw new NotAuthorized('It is not allowed to modify the application'); - } - - $this->application = $application; - } - - public function getApplication(): ?Application - { - return $this->application; - } - - public function setUser(User $user): void - { - if ($this->user) { - throw new NotAuthorized('It is not allowed to modify the user'); - } - - $this->user = $user; - } - - public function getUser(): ?User - { - return $this->user; - } - - public function getAuthMethod(): AuthMethod - { - return $this->authMethod; - } - - public function canBeSetStateTo(State $state): bool - { - return $this->state->canBeSetTo($state); - } - - public function setState(State $state): self - { - if (!$this->state->canBeSetTo($state)) { - throw new NotAuthorized('State can be set to set to : ' . $state); - } - - $this->state = $state; - - return $this; - } - - public function getState(): State - { - return $this->state; - } - - public function getLifetime(): int - { - return $this->lifetime; - } - - public function getExpiration(): int - { - return $this->expiration; - } - - public function tokenizeId(SslKey $sslKey): Token - { - $id = (string)$this->id; - - $datas = json_encode([ - self::TOKEN_PAYLOAD_LIFETIME => $this->lifetime, - self::TOKEN_PAYLOAD_EXPIRATION => $this->expiration, - self::TOKEN_PAYLOAD_ID => $id, - ]); - - $token = $sslKey->encrypt($datas); - - $token = strtr(base64_encode($token), '+/=', '._-'); - - return new Token($token); - } - - public static function untokenizeId(Token $token, SslKey $sslKey): Id - { - $token = base64_decode(strtr((string)$token, '._-', '+/=')); - - $datas = $sslKey->decrypt($token); - - $datas = json_decode($datas, true); - - $expiration = $datas[ self::TOKEN_PAYLOAD_EXPIRATION ] ?? 0; - if ($expiration < time()) { - throw new NotCompliant('Token expired'); - } - - $id = $datas[ self::TOKEN_PAYLOAD_ID ]; - - return new Id($id); - } -} diff --git a/component/Domain/DataStructure/RequestAccess/AuthMethod.php b/component/Domain/DataStructure/RequestAccess/AuthMethod.php deleted file mode 100644 index fad7350..0000000 --- a/component/Domain/DataStructure/RequestAccess/AuthMethod.php +++ /dev/null @@ -1,22 +0,0 @@ - 'API key', - self::OTP => 'OTP', - self::THIRD_PARTY => 'Third party', - ]; - - public function is(string|self $authMethod): bool - { - return ($this->value == (string)$authMethod); - } -} diff --git a/component/Domain/DataStructure/RequestAccess/Otp.php b/component/Domain/DataStructure/RequestAccess/Otp.php deleted file mode 100644 index 178e173..0000000 --- a/component/Domain/DataStructure/RequestAccess/Otp.php +++ /dev/null @@ -1,34 +0,0 @@ -value === (string)$otp; - } - - public static function generate(): self - { - $otp = ''; - - $characters = '0123456789'; - for ($i = 0; $i < self::LENGTH; $i++) { - $otp.= $characters[mt_rand(0, strlen($characters) - 1)]; - } - - return new self($otp); - } -} diff --git a/component/Domain/DataStructure/RequestAccess/State.php b/component/Domain/DataStructure/RequestAccess/State.php deleted file mode 100644 index 4219766..0000000 --- a/component/Domain/DataStructure/RequestAccess/State.php +++ /dev/null @@ -1,45 +0,0 @@ - 'Requested', - self::REFUSED => 'Refused', - self::VERIFIED => 'Verified', - self::GRANTED => 'Granted', - ]; - - public function canBeSetTo(string|self $state): bool - { - if (is_string($state)) $state = new self($state); - - switch ($state->getValue()) { - case State::REQUESTED : - - break; - - case State::REFUSED : - - return ($this->value == State::REQUESTED); - - case State::VERIFIED : - - return ($this->value == State::REQUESTED); - - case State::GRANTED : - - return ($this->value == State::VERIFIED); - - } - - return false; - } -} diff --git a/component/Domain/DataStructure/RequestAccessFromApiKey.php b/component/Domain/DataStructure/RequestAccessFromApiKey.php deleted file mode 100644 index e9a3618..0000000 --- a/component/Domain/DataStructure/RequestAccessFromApiKey.php +++ /dev/null @@ -1,36 +0,0 @@ -apiKey = $apiKey; - } -} diff --git a/component/Domain/DataStructure/RequestAccessFromOtp.php b/component/Domain/DataStructure/RequestAccessFromOtp.php deleted file mode 100644 index dd0279c..0000000 --- a/component/Domain/DataStructure/RequestAccessFromOtp.php +++ /dev/null @@ -1,71 +0,0 @@ -otp = Otp::generate(); - $this->numberOfRemainingAttempts = $numberOfAttemptsLimit; - } - - public function getOtp(): Otp - { - return $this->otp; - } - - public function getNumberOfRemainingAttempts(): int - { - return $this->numberOfRemainingAttempts; - } - - public function checkOtp(string|Otp $otp): bool - { - if ($this->numberOfRemainingAttempts <= 0) { - throw new NotAuthorized('The number of attempts is reach'); - } - - if (is_string($otp)) $otp = new Otp($otp); - - $this->numberOfRemainingAttempts--; - - return $this->otp->check($otp); - } -} diff --git a/component/Domain/DataStructure/RequestAccessFromThirdParty.php b/component/Domain/DataStructure/RequestAccessFromThirdParty.php deleted file mode 100644 index 7c9ef38..0000000 --- a/component/Domain/DataStructure/RequestAccessFromThirdParty.php +++ /dev/null @@ -1,43 +0,0 @@ -callbackUrl = $callbackUrl; - } - - public function getCallbackUrl(): CallbackUrl - { - return $this->callbackUrl; - } -} diff --git a/component/Domain/DataStructure/SslKey.php b/component/Domain/DataStructure/SslKey.php deleted file mode 100644 index 0ff57a1..0000000 --- a/component/Domain/DataStructure/SslKey.php +++ /dev/null @@ -1,66 +0,0 @@ -private = $private; - $this->public = $public; - } - - public function getPrivate(): string - { - return $this->private; - } - - public function getPublic(): string - { - return $this->public; - } - - public function encrypt(string $data): string - { - try { - $success = openssl_private_encrypt( - $data, - $encryptedData, - $this->private - ); - } catch (\Exception $e) { - $success = false; - } - - if (!$success) { - throw new NotCompliant('Encryption invalid, verify private key'); - } - - return $encryptedData; - } - - public function decrypt(string $encryptedData): string - { - try { - $success = openssl_public_decrypt( - $encryptedData, - $data, - $this->public - ); - } catch (\Exception $e) { - $success = false; - } - - if (!$success) { - throw new NotCompliant('Decryption invalid, verify encrypted data or public key'); - } - - return $data; - } -} diff --git a/component/Domain/DataStructure/User.php b/component/Domain/DataStructure/User.php deleted file mode 100644 index 125ee5c..0000000 --- a/component/Domain/DataStructure/User.php +++ /dev/null @@ -1,36 +0,0 @@ -emailAddress = $emailAddress; - $this->lastname = $lastname; - $this->firstname = $firstname; - $this->role = $role; - } -} diff --git a/component/Domain/DataStructure/User/Role.php b/component/Domain/DataStructure/User/Role.php deleted file mode 100644 index ac6fac0..0000000 --- a/component/Domain/DataStructure/User/Role.php +++ /dev/null @@ -1,8 +0,0 @@ -value; + } + + public function check(SslKey $sslKey, Application $application): bool + { + try { + $payload = (new Jwt($this->value))->decode($sslKey->public); + + $id = $payload[ self::PAYLOAD_KEY_APP ]->id ?? null; + + if (!$id) { + return false; + } + + if (!$application->isHisId($id)) { + return false; + } + } catch (\Exception $e) { + return false; + } + + return true; + } + + public function getPayload(SslKey $sslKey): ?array + { + try { + $payLoad = (new Jwt($this->value))->decode($sslKey->public); + + return $payLoad; + } catch (\Exception $e) { + return null; + } + } + + public static function generate( + SslKey $sslKey, + AuthMethod $authMethod, + Application $application, + ?User $user, + int $lifetime + ): self { + $expire = (new Expire(time() + $lifetime))->getUtc(); + + $payload = [ + self::PAYLOAD_KEY_EXPIRE => (string) $expire, + self::PAYLOAD_KEY_AUTH_METHOD => (string) $authMethod->value, + self::PAYLOAD_KEY_APP => SerializeApplication::serializeForPayload($application), + ]; + + if ($user) { + $payload[ self::PAYLOAD_KEY_USER ] = SerializeUser::serialize($user); + } + + return new self((string)Jwt::encode($sslKey->private, $payload, $lifetime)); + } +} diff --git a/component/Domain/DataStructure/AccessToken/Expire.php b/component/Domain/Entity/AccessToken/Expire.php similarity index 64% rename from component/Domain/DataStructure/AccessToken/Expire.php rename to component/Domain/Entity/AccessToken/Expire.php index d698c2a..4c7f8cc 100644 --- a/component/Domain/DataStructure/AccessToken/Expire.php +++ b/component/Domain/Entity/AccessToken/Expire.php @@ -1,7 +1,8 @@ apiKey === (string)$apiKey); + } + + public function isHisId(string|Id $id): bool + { + if (is_string($id)) { + $id = new Id($id); + } + + return ((string)$this->id === (string)$id); + } + + public static function make( + null|string|Id $id, + null|string|Name $name, + null|string|Logo $logo, + string|ApiKey $apiKey + ): self { + if (is_null($id)) { + $id = Id::generate(); + } + if (is_string($id)) { + $id = new Id($id); + } + if (is_string($name)) { + $name = new Name($name); + } + if (is_string($logo)) { + $logo = new Logo($logo); + } + if (is_string($apiKey)) { + $apiKey = new ApiKey($apiKey); + } + + return new self( + $id, + $name, + $logo, + $apiKey + ); + } +} diff --git a/component/Domain/Entity/Application/ApiKey.php b/component/Domain/Entity/Application/ApiKey.php new file mode 100644 index 0000000..fa31287 --- /dev/null +++ b/component/Domain/Entity/Application/ApiKey.php @@ -0,0 +1,33 @@ +value === (string)$apiKey; + } + + private static function generateRandomString($length = 10) + { + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + + return $randomString; + } +} diff --git a/component/Domain/Entity/Application/Collection.php b/component/Domain/Entity/Application/Collection.php new file mode 100644 index 0000000..d935863 --- /dev/null +++ b/component/Domain/Entity/Application/Collection.php @@ -0,0 +1,49 @@ +itemsIterator() as $entity) { + if ($entity->isHisId($id)) { + return $entity; + } + } + + return null; + } + + public function searchByApiKey(string|ApiKey $apiKey): ?Application + { + if (is_string($apiKey)) { + $apiKey = new ApiKey($apiKey); + } + + foreach ($this->itemsIterator() as $entity) { + if ($entity->isHisApiKey($apiKey)) { + return $entity; + } + } + + return null; + } +} diff --git a/component/Domain/DataStructure/AccessToken/Id.php b/component/Domain/Entity/Application/Id.php similarity index 61% rename from component/Domain/DataStructure/AccessToken/Id.php rename to component/Domain/Entity/Application/Id.php index 8303912..8eecaf3 100644 --- a/component/Domain/DataStructure/AccessToken/Id.php +++ b/component/Domain/Entity/Application/Id.php @@ -1,7 +1,8 @@ expiration = time() + $lifetime; + } + + public function setApplication(Application $application): void + { + if ($this->application) { + throw new NotAuthorized('It is not allowed to modify the application'); + } + + $this->application = $application; + } + + public function setUser(User $user): void + { + if ($this->user) { + throw new NotAuthorized('It is not allowed to modify the user'); + } + + $this->user = $user; + } + + public function canBeSetStateTo(State $state): bool + { + return $this->state->canBeSetTo($state); + } + + public function setState(State $state): self + { + if (!$this->state->canBeSetTo($state)) { + throw new NotAuthorized('State can be set to set to : ' . $state->value); + } + + $this->state = $state; + + return $this; + } + + public function tokenizeId(SslKey $sslKey): Token + { + $id = (string)$this->id; + + $datas = json_encode([ + self::TOKEN_PAYLOAD_LIFETIME => $this->lifetime, + self::TOKEN_PAYLOAD_EXPIRATION => $this->expiration, + self::TOKEN_PAYLOAD_ID => $id, + ]); + + $token = $sslKey->encrypt($datas); + + $token = strtr(base64_encode($token), '+/=', '._-'); + + return new Token($token); + } + + public static function untokenizeId(Token $token, SslKey $sslKey): Id + { + $token = base64_decode(strtr((string)$token, '._-', '+/=')); + + $datas = $sslKey->decrypt($token); + + $datas = json_decode($datas, true); + + $expiration = $datas[ self::TOKEN_PAYLOAD_EXPIRATION ] ?? 0; + if ($expiration < time()) { + throw new NotCompliant('Token expired'); + } + + $id = $datas[ self::TOKEN_PAYLOAD_ID ]; + + return new Id($id); + } +} diff --git a/component/Domain/Entity/RequestAccess/AuthMethod.php b/component/Domain/Entity/RequestAccess/AuthMethod.php new file mode 100644 index 0000000..d676a06 --- /dev/null +++ b/component/Domain/Entity/RequestAccess/AuthMethod.php @@ -0,0 +1,28 @@ + 'API key', + self::Otp => 'Otp', + self::ThirdParty => 'Third party', + }; + } + + public function is(self|array $typeList): bool + { + return is_array($typeList) ? in_array($this, $typeList) : $this == $typeList; + } +} diff --git a/component/Domain/DataStructure/RequestAccess/CallbackUrl.php b/component/Domain/Entity/RequestAccess/CallbackUrl.php similarity index 63% rename from component/Domain/DataStructure/RequestAccess/CallbackUrl.php rename to component/Domain/Entity/RequestAccess/CallbackUrl.php index 15c1007..ff6a66b 100644 --- a/component/Domain/DataStructure/RequestAccess/CallbackUrl.php +++ b/component/Domain/Entity/RequestAccess/CallbackUrl.php @@ -1,7 +1,8 @@ value === (string)$otp; + } + + public static function generate(): self + { + $otp = ''; + + $characters = '0123456789'; + for ($i = 0; $i < self::LENGTH; $i++) { + $otp.= $characters[mt_rand(0, strlen($characters) - 1)]; + } + + return new self($otp); + } +} diff --git a/component/Domain/Entity/RequestAccess/State.php b/component/Domain/Entity/RequestAccess/State.php new file mode 100644 index 0000000..84b9146 --- /dev/null +++ b/component/Domain/Entity/RequestAccess/State.php @@ -0,0 +1,49 @@ + 'Requested', + self::Refused => 'Refused', + self::Verified => 'Verified', + self::Granted => 'Granted', + }; + } + + public function canBeSetTo(self $state): bool + { + switch ($state) { + case State::Requested: + + break; + + case State::Refused: + + return ($this == State::Requested); + + case State::Verified: + + return ($this == State::Requested); + + case State::Granted: + + return ($this == State::Verified); + } + + return false; + } +} diff --git a/component/Domain/DataStructure/RequestAccess/Token.php b/component/Domain/Entity/RequestAccess/Token.php similarity index 65% rename from component/Domain/DataStructure/RequestAccess/Token.php rename to component/Domain/Entity/RequestAccess/Token.php index 30263ff..5242e92 100644 --- a/component/Domain/DataStructure/RequestAccess/Token.php +++ b/component/Domain/Entity/RequestAccess/Token.php @@ -1,7 +1,8 @@ otp = Otp::generate(); + + parent::__construct( + Id::generate(), + $application, + $user, + AuthMethod::Otp, + State::Requested, + $lifetime + ); + } + + public function getNumberOfRemainingAttempts(): int + { + return $this->numberOfRemainingAttempts; + } + + public function checkOtp(string|Otp $otp): bool + { + if ($this->numberOfRemainingAttempts <= 0) { + throw new NotAuthorized('The number of attempts is reach'); + } + + if (is_string($otp)) { + $otp = new Otp($otp); + } + + $this->numberOfRemainingAttempts--; + + return $this->otp->check($otp); + } +} diff --git a/component/Domain/Entity/RequestAccessFromThirdParty.php b/component/Domain/Entity/RequestAccessFromThirdParty.php new file mode 100644 index 0000000..57f25bd --- /dev/null +++ b/component/Domain/Entity/RequestAccessFromThirdParty.php @@ -0,0 +1,34 @@ +private + ); + } catch (\Exception $e) { + $success = false; + } + + if (!$success) { + throw new NotCompliant('Encryption invalid, verify private key'); + } + + return $encryptedData; + } + + public function decrypt(string $encryptedData): string + { + try { + $success = openssl_public_decrypt( + $encryptedData, + $data, + $this->public + ); + } catch (\Exception $e) { + $success = false; + } + + if (!$success) { + throw new NotCompliant('Decryption invalid, verify encrypted data or public key'); + } + + return $data; + } +} diff --git a/component/Domain/Entity/User.php b/component/Domain/Entity/User.php new file mode 100644 index 0000000..449c951 --- /dev/null +++ b/component/Domain/Entity/User.php @@ -0,0 +1,47 @@ + (string) $application->id, - 'name' => (string) $application->name, - 'logo' => $application->logo ? (string) $application->logo : null, - 'api_key' => (string) $application->apiKey, - ]; - } - - public static function serializeForPayload(EntityApplication $application): array - { - return [ - 'id' => (string) $application->id, - 'name' => (string) $application->name, - ]; - } + public static function serialize(EntityApplication $application): array + { + return [ + 'id' => (string) $application->id, + 'name' => (string) $application->name, + 'logo' => $application->logo ? (string) $application->logo : null, + 'api_key' => (string) $application->apiKey, + ]; + } + + public static function serializeForPayload(EntityApplication $application): array + { + return [ + 'id' => (string) $application->id, + 'name' => (string) $application->name, + ]; + } } diff --git a/component/Domain/Serialize/User.php b/component/Domain/Serialize/User.php index d33231e..34358ae 100644 --- a/component/Domain/Serialize/User.php +++ b/component/Domain/Serialize/User.php @@ -1,19 +1,20 @@ (string)$user->emailAddress, - 'lastname' => $user->lastname ? (string)$user->lastname : null, - 'firstname' => $user->firstname ? (string)$user->firstname : null, - 'role' => $user->role ? (string)$user->role : null, - ]; - } + public static function serialize(EntityUser $user): array + { + return [ + 'email_address' => (string)$user->emailAddress, + 'lastname' => $user->lastname ? (string)$user->lastname : null, + 'firstname' => $user->firstname ? (string)$user->firstname : null, + 'role' => $user->role ? (string)$user->role : null, + ]; + } } diff --git a/component/Domain/Service/AccessToken.php b/component/Domain/Service/AccessToken.php index 70393f3..1c7bfbb 100644 --- a/component/Domain/Service/AccessToken.php +++ b/component/Domain/Service/AccessToken.php @@ -1,76 +1,76 @@ sslKey = $sslKey; - $this->serviceRequestAccess = $serviceRequestAccess; - } - - public function getPublicKey(): string - { - return $this->sslKey->getPublic(); - } - - public function check(string $accessToken, Application $application): bool - { - return (new EntityAccessToken($accessToken))->check( - $this->sslKey, - $application - ); - } - - public function getPayload(string $accessToken): ?array - { - return (new EntityAccessToken($accessToken))->getPayload($this->sslKey); - } - - public function getFromToken(RequestAccess $requestAccess, int $lifetime = self::LIFETIME): EntityAccessToken - { - // Check request access status - if (!$requestAccess->canBeSetStateTo(new State(State::GRANTED))) { - throw new NotAuthorized('The access request is invalid'); - } - - // Generate new access token - $accessToken = EntityAccessToken::generate( - $this->sslKey, - $requestAccess->getAuthMethod(), - $requestAccess->getApplication(), - $requestAccess->getUser(), - $lifetime - ); - - // Change state - $this->serviceRequestAccess->set( - $requestAccess - ->setState(new State(State::GRANTED)) - ); - - return $accessToken; - } + public const LIFETIME = 86400; // 24h + + public function __construct( + protected readonly SslKey $sslKey, + protected readonly ServiceRequestAccess $serviceRequestAccess + ) { + } + + public function getPublicKey(): string + { + return $this->sslKey->public; + } + + public function check( + string $accessToken, + Application $application + ): bool { + return (new EntityAccessToken($accessToken))->check( + $this->sslKey, + $application + ); + } + + public function getPayload( + string $accessToken + ): ?array { + return (new EntityAccessToken($accessToken))->getPayload($this->sslKey); + } + + public function getFromToken( + RequestAccess $requestAccess, + int $lifetime = self::LIFETIME + ): EntityAccessToken { + // Check request access status + if (!$requestAccess->canBeSetStateTo(State::Granted)) { + throw new NotAuthorized('The access request is invalid'); + } + + // Generate new access token + $accessToken = EntityAccessToken::generate( + $this->sslKey, + $requestAccess->authMethod, + $requestAccess->application, + $requestAccess->user, + $lifetime + ); + + // Change state + $this->serviceRequestAccess->set( + $requestAccess + ->setState(State::Granted) + ); + + return $accessToken; + } } diff --git a/component/Domain/Service/Application.php b/component/Domain/Service/Application.php index f3b70a5..dd825e1 100644 --- a/component/Domain/Service/Application.php +++ b/component/Domain/Service/Application.php @@ -1,59 +1,65 @@ repository = $repository; - } - - public function add(string $name, ?string $logo = null): EntityApplication - { - $application = new EntityApplication( - Id::generate(), - new Name($name), - $logo ? new Logo($logo) : null, - ApiKey::generate() - ); - - $this->repository->set($application); - - return $application; - } - - public function set(EntityApplication $application): void - { - $this->repository->set($application); - } - - public function get(string|Id $id): EntityApplication - { - if (is_string($id)) $id = new Id($id); - - return $this->repository->get($id); - } - - public function getFromApiKey(string|ApiKey $apiKey): EntityApplication - { - if (is_string($apiKey)) $apiKey = new ApiKey($apiKey); - - return $this->repository->getFromApiKey($apiKey); - } + public function __construct( + protected readonly PortApplication $repository + ) { + } + + public function add( + string $name, + ?string $logo = null + ): EntityApplication { + $application = new EntityApplication( + Id::generate(), + new Name($name), + $logo ? new Logo($logo) : null, + ApiKey::generate() + ); + + $this->repository->set($application); + + return $application; + } + + public function set( + EntityApplication $application + ): void { + $this->repository->set($application); + } + + public function get( + string|Id $id + ): EntityApplication { + if (is_string($id)) { + $id = new Id($id); + } + + return $this->repository->get($id); + } + + public function getFromApiKey( + string|ApiKey $apiKey + ): EntityApplication { + if (is_string($apiKey)) { + $apiKey = new ApiKey($apiKey); + } + + return $this->repository->getFromApiKey($apiKey); + } } diff --git a/component/Domain/Service/RequestAccess.php b/component/Domain/Service/RequestAccess.php index bdf63ae..43452b6 100644 --- a/component/Domain/Service/RequestAccess.php +++ b/component/Domain/Service/RequestAccess.php @@ -1,56 +1,59 @@ repository = $repository; - $this->sslKey = $sslKey; - } - - public function set(EntityRequestAccess $requestAccess): void - { - $this->repository->set($requestAccess); - } - - public function get(string|Id $id): EntityRequestAccess - { - if (is_string($id)) $id = new Id($id); - - return $this->repository->get($id); - } - - public function getToken(EntityRequestAccess $requestAccess): Token - { - return $requestAccess->tokenizeId($this->sslKey); - } - - public function getFromToken(string|Token $token): EntityRequestAccess - { - if (is_string($token)) $token = new Id($token); - - $id = EntityRequestAccess::untokenizeId($token, $this->sslKey); - - return $this->get($id); - } + public function __construct( + protected readonly PortRequestAccess $repository, + protected readonly SslKey $sslKey + ) { + } + + public function set( + EntityRequestAccess $requestAccess + ): void { + $this->repository->set($requestAccess); + } + + public function get( + string|Id $id + ): EntityRequestAccess { + if (is_string($id)) { + $id = new Id($id); + } + + return $this->repository->get($id); + } + + public function getToken( + EntityRequestAccess $requestAccess + ): Token { + return $requestAccess->tokenizeId($this->sslKey); + } + + public function getFromToken( + string|Token $token + ): EntityRequestAccess { + if (is_string($token)) { + $token = new Token($token); + } + + $id = EntityRequestAccess::untokenizeId($token, $this->sslKey); + + return $this->get($id); + } } diff --git a/component/Domain/Service/RequestAccessFromApiKey.php b/component/Domain/Service/RequestAccessFromApiKey.php index 8ae2513..466f51a 100644 --- a/component/Domain/Service/RequestAccessFromApiKey.php +++ b/component/Domain/Service/RequestAccessFromApiKey.php @@ -1,74 +1,75 @@ serviceRequestAccess = $serviceRequestAccess; - $this->serviceAccessToken = $serviceAccessToken; - $this->repositoryApplication = $repositoryApplication; - } - - public function getAccessToken(string|ApiKey $apiKey, int $lifetime = self::LIFETIME): ?AccessToken - { - if (is_string($apiKey)) $apiKey = new ApiKey($apiKey); - - $requestAccess = $this->build($apiKey, $lifetime); - - $application = $this->repositoryApplication->getFromApiKey($apiKey); - - if ( ! $application) return null; - - if ( ! $application->isHisApiKey($apiKey)) return null; - - $requestAccess->setApplication($application); - - $requestAccess->setState(new State(State::VERIFIED)); - - $this->serviceRequestAccess->set($requestAccess); - - $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); - - return $accessToken; - } - - private function build(ApiKey $apiKey, int $lifetime): EntityRequestAccessFromApiKey - { - return new EntityRequestAccessFromApiKey( - $apiKey, - $lifetime - ); - } + public const LIFETIME = 300; // 5 min + + public function __construct( + protected readonly ServiceRequestAccess $serviceRequestAccess, + protected readonly ServiceAccessToken $serviceAccessToken, + protected readonly PortApplication $repositoryApplication + ) { + } + + public function getAccessToken( + string|ApiKey $apiKey, + int $lifetime = self::LIFETIME + ): ?AccessToken { + if (is_string($apiKey)) { + $apiKey = new ApiKey($apiKey); + } + + $requestAccess = $this->build($apiKey, $lifetime); + + try { + $application = $this->repositoryApplication->getFromApiKey($apiKey); + } catch (NotFound $e) { + throw new NotFound('Application not found'); + } + + $requestAccess->setApplication($application); + + $requestAccess->setState(State::Verified); + + $this->serviceRequestAccess->set($requestAccess); + + $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); + + return $accessToken; + } + + private function build( + ApiKey $apiKey, + int $lifetime + ): EntityRequestAccessFromApiKey { + return new EntityRequestAccessFromApiKey( + $apiKey, + $lifetime + ); + } } diff --git a/component/Domain/Service/RequestAccessFromOtp.php b/component/Domain/Service/RequestAccessFromOtp.php index 374e2e5..9e4d589 100644 --- a/component/Domain/Service/RequestAccessFromOtp.php +++ b/component/Domain/Service/RequestAccessFromOtp.php @@ -1,118 +1,130 @@ serviceRequestAccess = $serviceRequestAccess; - $this->serviceAccessToken = $serviceAccessToken; - $this->otpSender = $otpSender; - } - - public function generate(Application $application, User $user, int $numberOfAttemptsLimit = 3, int $lifetime = self::LIFETIME): Token - { - $requestAccess = $this->build($application, $user, $numberOfAttemptsLimit, $lifetime); - - $requestAccessToken = $this->serviceRequestAccess->getToken($requestAccess); - - $this->otpSender->send($requestAccessToken, $requestAccess, $requestAccess->getOtp()); - - $this->serviceRequestAccess->set($requestAccess); - - return $requestAccessToken; - } - - public function verify(string|Token $requestAccessToken, string|Otp $otp): bool - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - if ( ! $requestAccess->canBeSetStateTo(new State(State::VERIFIED)) - || ! $requestAccess->canBeSetStateTo(new State(State::REFUSED)) ) { - throw new NotAuthorized('The verification is not authorized'); - } - - if (is_string($otp)) $otp = new Otp($otp); - - if ( ! $requestAccess->checkOtp($otp)) { - - if ( ! $requestAccess->getNumberOfRemainingAttempts()) { - $requestAccess->setState(new State(State::REFUSED)); - } - - $this->serviceRequestAccess->set($requestAccess); - - return false; - } - - $requestAccess->setState(new State(State::VERIFIED)); - - $this->serviceRequestAccess->set($requestAccess); - - return true; - } - - public function getNumberOfRemainingAttempts(string|Token $requestAccessToken): int - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - return $requestAccess->getNumberOfRemainingAttempts($requestAccess); - } - - public function getAccessToken(string|Token $requestAccessToken): ?AccessToken - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); - - return $accessToken; - } - - private function build(Application $application, User $user, int $numberOfAttemptsLimit, int $lifetime): EntityRequestAccessFromOtp - { - return new EntityRequestAccessFromOtp( - $application, - $user, - $numberOfAttemptsLimit, - $lifetime - ); - } + public const LIFETIME = 900; // 15 min + + public function __construct( + protected readonly ServiceRequestAccess $serviceRequestAccess, + protected readonly ServiceAccessToken $serviceAccessToken, + protected readonly OtpSender $otpSender + ) { + } + + public function generate( + Application $application, + User $user, + int $numberOfAttemptsLimit = 3, + int $lifetime = self::LIFETIME + ): Token { + $requestAccess = $this->build($application, $user, $numberOfAttemptsLimit, $lifetime); + + $requestAccessToken = $this->serviceRequestAccess->getToken($requestAccess); + + $this->otpSender->send($requestAccessToken, $requestAccess, $requestAccess->otp); + + $this->serviceRequestAccess->set($requestAccess); + + return $requestAccessToken; + } + + public function verify( + string|Token $requestAccessToken, + string|Otp $otp + ): bool { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + if (! $requestAccess->canBeSetStateTo(State::Verified) + || ! $requestAccess->canBeSetStateTo(State::Refused)) { + throw new NotAuthorized('The verification is not authorized'); + } + + if (is_string($otp)) { + $otp = new Otp($otp); + } + + if (! $requestAccess->checkOtp($otp)) { + if (! $requestAccess->getNumberOfRemainingAttempts()) { + $requestAccess->setState(State::Refused); + } + + $this->serviceRequestAccess->set($requestAccess); + + return false; + } + + $requestAccess->setState(State::Verified); + + $this->serviceRequestAccess->set($requestAccess); + + return true; + } + + public function getNumberOfRemainingAttempts( + string|Token $requestAccessToken + ): int { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + return $requestAccess->getNumberOfRemainingAttempts($requestAccess); + } + + public function getAccessToken( + string|Token $requestAccessToken + ): ?AccessToken { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); + + return $accessToken; + } + + private function build( + Application $application, + User $user, + int $numberOfAttemptsLimit, + int $lifetime + ): EntityRequestAccessFromOtp { + return new EntityRequestAccessFromOtp( + $application, + $user, + $numberOfAttemptsLimit, + $lifetime + ); + } } diff --git a/component/Domain/Service/RequestAccessFromThirdParty.php b/component/Domain/Service/RequestAccessFromThirdParty.php index f3d7632..4745046 100644 --- a/component/Domain/Service/RequestAccessFromThirdParty.php +++ b/component/Domain/Service/RequestAccessFromThirdParty.php @@ -1,93 +1,107 @@ serviceRequestAccess = $serviceRequestAccess; - $this->serviceAccessToken = $serviceAccessToken; - } - - public function generate(Application $application, string|CallbackUrl $callbackUrl, int $lifetime = self::LIFETIME): Token - { - if (is_string($callbackUrl)) $callbackUrl = new CallbackUrl($callbackUrl); - - $requestAccess = $this->build($application, $callbackUrl, $lifetime); - - $requestAccessToken = $this->serviceRequestAccess->getToken($requestAccess); - - $this->serviceRequestAccess->set($requestAccess); - - return $requestAccessToken; - } - - public function setStatus(string|Token $requestAccessToken, User $user, bool $isAuthorized): void - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - $requestAccess->setUser($user); - $requestAccess->setState(new State($isAuthorized ? State::VERIFIED : State::REFUSED)); - - $this->serviceRequestAccess->set($requestAccess); - } - - public function getCallbackUrl(string|Token $requestAccessToken): CallbackUrl - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - return $requestAccess->getCallbackUrl(); - } - - public function getAccessToken(string|Token $requestAccessToken): ?AccessToken - { - if (is_string($requestAccessToken)) $requestAccessToken = new Token($requestAccessToken); - - $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); - - $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); - - return $accessToken; - } - - private function build(Application $application, CallbackUrl $callbackUrl, int $lifetime): EntityRequestAccessFromThirdParty - { - return new EntityRequestAccessFromThirdParty( - $application, - $callbackUrl, - $lifetime - ); - } + public const LIFETIME = 900; // 15 min + + public function __construct( + protected readonly ServiceRequestAccess $serviceRequestAccess, + protected readonly ServiceAccessToken $serviceAccessToken + ) { + } + + public function generate( + Application $application, + string|CallbackUrl $callbackUrl, + int $lifetime = self::LIFETIME + ): Token { + if (is_string($callbackUrl)) { + $callbackUrl = new CallbackUrl($callbackUrl); + } + + $requestAccess = $this->build($application, $callbackUrl, $lifetime); + + $requestAccessToken = $this->serviceRequestAccess->getToken($requestAccess); + + $this->serviceRequestAccess->set($requestAccess); + + return $requestAccessToken; + } + + public function setStatus( + string|Token $requestAccessToken, + User $user, + bool $isAuthorized + ): void { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + $requestAccess->setUser($user); + $requestAccess->setState($isAuthorized ? State::Verified : State::Refused); + + $this->serviceRequestAccess->set($requestAccess); + } + + public function getCallbackUrl( + string|Token $requestAccessToken + ): CallbackUrl { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + return $requestAccess->callbackUrl; + } + + public function getAccessToken( + string|Token $requestAccessToken + ): ?AccessToken { + if (is_string($requestAccessToken)) { + $requestAccessToken = new Token($requestAccessToken); + } + + $requestAccess = $this->serviceRequestAccess->getFromToken($requestAccessToken); + + $accessToken = $this->serviceAccessToken->getFromToken($requestAccess); + + return $accessToken; + } + + private function build( + Application $application, + CallbackUrl $callbackUrl, + int $lifetime + ): EntityRequestAccessFromThirdParty { + return new EntityRequestAccessFromThirdParty( + $application, + $callbackUrl, + $lifetime + ); + } } diff --git a/component/Fixture/DataStructure/AccessToken.php b/component/Fixture/DataStructure/AccessToken.php index 3b6cb9b..c27b60e 100644 --- a/component/Fixture/DataStructure/AccessToken.php +++ b/component/Fixture/DataStructure/AccessToken.php @@ -1,49 +1,58 @@ private, [], 86400) + ); + } } diff --git a/component/Fixture/DataStructure/Application.php b/component/Fixture/DataStructure/Application.php index 35dbc68..8c0b6c9 100644 --- a/component/Fixture/DataStructure/Application.php +++ b/component/Fixture/DataStructure/Application.php @@ -1,67 +1,68 @@ 'c2280258-78e9-48fd-905f-2c8e023acb9c', - 'name' => 'Flashpoint', - 'logo' => 'https://via.placeholder.com/400x200?text=Flashpoint', - 'api_key' => 'fw9LAIpY.rP6ogyVSQtLu9dV1pj94vXnzzEO5sHJWGxwa5c1g6Lkz06Z9tcnsmF4SbyTjyDSh', - ], - [ - 'id' => 'fa9a72a5-5c21-4056-818a-66b26626874a', - 'name' => 'LiveTube', - 'logo' => 'https://via.placeholder.com/400x200?text=LiveTube', - 'api_key' => 'kMgyGJlO.H6pYDtv8E51rK9D0gDSTYknvM7oEGgLL3Lbekj3EqWsMpDSz0Oo6ri5l7mDVnpkE', - ], - [ - 'id' => '1fa914ab-5d34-48d5-82fd-fc364c62b0f9', - 'name' => 'Taskeo', - 'logo' => 'https://via.placeholder.com/400x200?text=Taskeo', - 'api_key' => 'R2FpV3FU.w5skjmLm4VDylSrH1cSu7EQfrHVkIB5vacBF63Ni5WI8sIKAIQ2WJqISx7sl4TlJ', - ], - ]; - - public static function get(): EntityApplication - { - $datas = self::DATAS[0]; - - return self::buildFromDatas($datas); - } - - public static function getCollection(): Collection - { - $collection = new Collection(); - - foreach (self::DATAS as $datas) { - $collection->addApplication( - self::buildFromDatas($datas) - ); - } - - return $collection; - } - - private static function buildFromDatas(array $datas): EntityApplication - { - return new EntityApplication( - new Id($datas['id']), - new Name($datas['name']), - new Logo($datas['logo']), - new ApiKey($datas['api_key']) - ); - } + public const DATAS = [ + [ + 'id' => 'c2280258-78e9-48fd-905f-2c8e023acb9c', + 'name' => 'Flashpoint', + 'logo' => 'https://via.placeholder.com/400x200?text=Flashpoint', + 'api_key' => 'fw9LAIpY.rP6ogyVSQtLu9dV1pj94vXnzzEO5sHJWGxwa5c1g6Lkz06Z9tcnsmF4SbyTjyDSh', + ], + [ + 'id' => 'fa9a72a5-5c21-4056-818a-66b26626874a', + 'name' => 'LiveTube', + 'logo' => 'https://via.placeholder.com/400x200?text=LiveTube', + 'api_key' => 'kMgyGJlO.H6pYDtv8E51rK9D0gDSTYknvM7oEGgLL3Lbekj3EqWsMpDSz0Oo6ri5l7mDVnpkE', + ], + [ + 'id' => '1fa914ab-5d34-48d5-82fd-fc364c62b0f9', + 'name' => 'Taskeo', + 'logo' => 'https://via.placeholder.com/400x200?text=Taskeo', + 'api_key' => 'R2FpV3FU.w5skjmLm4VDylSrH1cSu7EQfrHVkIB5vacBF63Ni5WI8sIKAIQ2WJqISx7sl4TlJ', + ], + ]; + + public static function get(): EntityApplication + { + $datas = self::DATAS[0]; + + return self::buildFromDatas($datas); + } + + public static function getCollection(): Collection + { + $collection = new Collection(); + + foreach (self::DATAS as $datas) { + $collection->addApplication( + self::buildFromDatas($datas) + ); + } + + return $collection; + } + + private static function buildFromDatas(array $datas): EntityApplication + { + return new EntityApplication( + new Id($datas['id']), + new Name($datas['name']), + new Logo($datas['logo']), + new ApiKey($datas['api_key']) + ); + } } diff --git a/component/Fixture/DataStructure/RequestAccessFromApiKey.php b/component/Fixture/DataStructure/RequestAccessFromApiKey.php index c72a2f3..7445478 100644 --- a/component/Fixture/DataStructure/RequestAccessFromApiKey.php +++ b/component/Fixture/DataStructure/RequestAccessFromApiKey.php @@ -1,34 +1,37 @@ apiKey, - $lifetime - ); - } - - public static function getExpired(?State $state = null): EntityRequestAccessFromApiKey - { - return self::get($state, -9999); - } - - public static function getVerified(): EntityRequestAccessFromApiKey - { - return (self::get()) - ->setApplication(FixtureApplication::get()) - ->setState(new State(State::VERIFIED)); - } + public static function get(?State $state = null, int $lifetime = 300): EntityRequestAccessFromApiKey + { + if (is_null($state)) { + $state = State::Requested; + } + + return new EntityRequestAccessFromApiKey( + FixtureApplication::get()->apiKey, + $lifetime + ); + } + + public static function getExpired(?State $state = null): EntityRequestAccessFromApiKey + { + return self::get($state, -9999); + } + + public static function getVerified(): EntityRequestAccessFromApiKey + { + return (self::get()) + ->setApplication(FixtureApplication::get()) + ->setState(State::Verified); + } } diff --git a/component/Fixture/DataStructure/RequestAccessFromOtp.php b/component/Fixture/DataStructure/RequestAccessFromOtp.php index 5db7a3d..dbb977e 100644 --- a/component/Fixture/DataStructure/RequestAccessFromOtp.php +++ b/component/Fixture/DataStructure/RequestAccessFromOtp.php @@ -1,12 +1,13 @@ setState(new State(State::VERIFIED)); - } + public static function get(?State $state = null, int $numberOfAttemptsLimit = 3, int $lifetime = 900): EntityRequestAccessFromOtp + { + if (is_null($state)) { + $state = State::Requested; + } + + return new EntityRequestAccessFromOtp( + FixtureApplication::get(), + FixtureUser::get(), + $numberOfAttemptsLimit, + $lifetime + ); + } + + public static function getExpired(?State $state = null, int $numberOfAttemptsLimit = 3): EntityRequestAccessFromOtp + { + return self::get($state, $numberOfAttemptsLimit, -9999); + } + + public static function getVerified(): EntityRequestAccessFromOtp + { + return (self::get()) + ->setState(State::Verified); + } } diff --git a/component/Fixture/DataStructure/RequestAccessFromThirdParty.php b/component/Fixture/DataStructure/RequestAccessFromThirdParty.php index 3622053..9ae8db4 100644 --- a/component/Fixture/DataStructure/RequestAccessFromThirdParty.php +++ b/component/Fixture/DataStructure/RequestAccessFromThirdParty.php @@ -1,12 +1,13 @@ setUser(FixtureUser::get()) - ->setState(new State(State::VERIFIED)); - } + public static function get(?State $state = null, int $lifetime = 900): EntityRequestAccessFromThirdParty + { + if (is_null($state)) { + $state = State::Requested; + } + + return new EntityRequestAccessFromThirdParty( + FixtureApplication::get(), + new CallbackUrl('https://domain.ext/path'), + $lifetime + ); + } + + public static function getExpired(?State $state = null): EntityRequestAccessFromThirdParty + { + return self::get($state, -9999); + } + + public static function getVerified(): EntityRequestAccessFromThirdParty + { + return (self::get()) + ->setUser(FixtureUser::get()) + ->setState(State::Verified); + } } diff --git a/component/Fixture/DataStructure/SslKey.php b/component/Fixture/DataStructure/SslKey.php index 5f2a561..eb50640 100644 --- a/component/Fixture/DataStructure/SslKey.php +++ b/component/Fixture/DataStructure/SslKey.php @@ -1,13 +1,14 @@ cache = $cache; - } - - public function set(EntityApplication $application): void - { - $this->cache->set((string)$application->id, $application); - } - - public function get(Id $id): EntityApplication - { - $entity = $this->cache->get((string)$id); - if ($entity) return $entity; - - foreach (FixtureApplication::getCollection()->itemsIterator() as $entity) { - if ((string)$entity->id != (string)$id) continue; - - return $entity; - } - - throw new NotFound('Application not found from Id : ' . $id); - } - - public function getFromApiKey(ApiKey $apiKey): EntityApplication - { - foreach (FixtureApplication::getCollection()->itemsIterator() as $entity) { - if ((string)$entity->apiKey != (string)$apiKey) continue; - - return $entity; - } - - throw new NotFound('Application not found from API key : ' . $apiKey); - } - - public function getList(): Collection - { - return FixtureApplication::getCollection(); - } + protected CacheInterface $cache; + + public function __construct(CacheInterface $cache) + { + $this->cache = $cache; + } + + public function set(EntityApplication $application): void + { + $this->cache->set((string)$application->id, $application); + } + + public function get(Id $id): EntityApplication + { + $entity = $this->cache->get((string)$id); + if ($entity) { + return $entity; + } + + foreach (FixtureApplication::getCollection()->itemsIterator() as $entity) { + if ((string)$entity->id != (string)$id) { + continue; + } + + return $entity; + } + + throw new NotFound('Application not found from Id : ' . $id); + } + + public function getFromApiKey(ApiKey $apiKey): EntityApplication + { + foreach (FixtureApplication::getCollection()->itemsIterator() as $entity) { + if ((string)$entity->apiKey != (string)$apiKey) { + continue; + } + + return $entity; + } + + throw new NotFound('Application not found from API key : ' . $apiKey); + } + + public function getList(): Collection + { + return FixtureApplication::getCollection(); + } } diff --git a/component/Fixture/Port/OtpSender.php b/component/Fixture/Port/OtpSender.php index 54802bd..d0ce6d3 100644 --- a/component/Fixture/Port/OtpSender.php +++ b/component/Fixture/Port/OtpSender.php @@ -1,26 +1,27 @@ cache = $cache; - } - - public function send(Token $requestAccessToken, RequestAccess $requestAccess, Otp $otp): void - { - $this->cache->set((string)$requestAccessToken, $otp); - } + protected CacheInterface $cache; + + public function __construct(CacheInterface $cache) + { + $this->cache = $cache; + } + + public function send(Token $requestAccessToken, RequestAccess $requestAccess, Otp $otp): void + { + $this->cache->set((string)$requestAccessToken, $otp); + } } diff --git a/component/Fixture/Port/RequestAccess.php b/component/Fixture/Port/RequestAccess.php index 7b3c35e..b3b4a3d 100644 --- a/component/Fixture/Port/RequestAccess.php +++ b/component/Fixture/Port/RequestAccess.php @@ -1,10 +1,11 @@ cache = $cache; - } - - public function set(EntityRequestAccess $requestAccess): void - { - $this->cache->set((string)$requestAccess->getId(), $requestAccess); - } - - public function get(Id $id): EntityRequestAccess - { - $entity = $this->cache->get((string)$id); - if ($entity) return $entity; - - $entity = FixtureRequestAccessFromOtp::get(); - - if ((string)$entity->getId() == (string)$id) { - throw $entity; - } - - throw new NotFound('Request access not found from Id : ' . $id); - } + protected CacheInterface $cache; + + public function __construct(CacheInterface $cache) + { + $this->cache = $cache; + } + + public function set(EntityRequestAccess $requestAccess): void + { + $this->cache->set((string)$requestAccess->id, $requestAccess); + } + + public function get(Id $id): EntityRequestAccess + { + $entity = $this->cache->get((string)$id); + if ($entity) { + return $entity; + } + + $entity = FixtureRequestAccessFromOtp::get(); + + if ((string)$entity->id == (string)$id) { + throw $entity; + } + + throw new NotFound('Request access not found from Id : ' . $id); + } } diff --git a/component/Fixture/Service/AccessToken.php b/component/Fixture/Service/AccessToken.php index 2705231..3345cd6 100644 --- a/component/Fixture/Service/AccessToken.php +++ b/component/Fixture/Service/AccessToken.php @@ -1,4 +1,5 @@ =8.1", - "phant/data-structure": "3.*" + "phant/data-structure": "4.*" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", "psr/simple-cache": "^3.0", "phpstan/phpstan": "^1.4", "phpunit/phpunit": "^9.5", "phant/cache": "1.*" }, "scripts": { + "lint": "vendor/bin/php-cs-fixer fix ./ --rules=@PSR12", "analyse": "vendor/bin/phpstan analyse component --memory-limit=4G", "test": "vendor/bin/phpunit test --testdox", - "code-coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit test --coverage-html public/coverage/html" + "coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit test --coverage-html .coverage/html" }, "autoload": { "psr-4": { diff --git a/test/Domain/DataStructure/AccessTokenTest.php b/test/Domain/DataStructure/AccessTokenTest.php index 0ddff72..825fddd 100644 --- a/test/Domain/DataStructure/AccessTokenTest.php +++ b/test/Domain/DataStructure/AccessTokenTest.php @@ -1,91 +1,103 @@ fixture = FixtureAccessToken::get(); - } - - public function testConstruct(): void - { - $entity = new AccessToken((string)$this->fixture); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } - - public function testCheck(): void - { - $result = $this->fixture->check( - FixtureSslKey::get(), - FixtureApplication::get() - ); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testCheckInvalid(): void - { - $result = $this->fixture->check( - FixtureSslKey::getInvalid(), - FixtureApplication::get() - ); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } - - public function testGetPayload(): void - { - $result = $this->fixture->getPayload( - FixtureSslKey::get() - ); - - $this->assertIsArray($result); - $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_EXPIRE, $result); - $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_AUTH_METHOD, $result); - $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_APP, $result); - $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_USER, $result); - } - - public function testGetPayloadInvalid(): void - { - $result = $this->fixture->getPayload( - FixtureSslKey::getInvalid() - ); - - $this->assertNull($result); - } - - public function testGenerate(): void - { - $entity = AccessToken::generate( - FixtureSslKey::get(), - new AuthMethod(AuthMethod::API_KEY), - FixtureApplication::get(), - FixtureUser::get(), - 86400 - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } + protected AccessToken $fixture; + + public function setUp(): void + { + $this->fixture = FixtureAccessToken::get(); + } + + public function testConstruct(): void + { + $entity = new AccessToken((string)$this->fixture); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } + + public function testCheck(): void + { + $result = $this->fixture->check( + FixtureSslKey::get(), + FixtureApplication::get() + ); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testCheckInvalidPayload(): void + { + $result = FixtureAccessToken::getInvalid()->check( + FixtureSslKey::get(), + FixtureApplication::get() + ); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } + + public function testCheckInvalidApplication(): void + { + $result = $this->fixture->check( + FixtureSslKey::getInvalid(), + FixtureApplication::get() + ); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } + + public function testGetPayload(): void + { + $result = $this->fixture->getPayload( + FixtureSslKey::get() + ); + + $this->assertIsArray($result); + $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_EXPIRE, $result); + $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_AUTH_METHOD, $result); + $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_APP, $result); + $this->assertArrayHasKey(AccessToken::PAYLOAD_KEY_USER, $result); + } + + public function testGetPayloadInvalid(): void + { + $result = $this->fixture->getPayload( + FixtureSslKey::getInvalid() + ); + + $this->assertNull($result); + } + + public function testGenerate(): void + { + $entity = AccessToken::generate( + FixtureSslKey::get(), + AuthMethod::ApiKey, + FixtureApplication::get(), + FixtureUser::get(), + 86400 + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } } diff --git a/test/Domain/DataStructure/Application/ApiKeyTest.php b/test/Domain/DataStructure/Application/ApiKeyTest.php index 31caabd..8d805a2 100644 --- a/test/Domain/DataStructure/Application/ApiKeyTest.php +++ b/test/Domain/DataStructure/Application/ApiKeyTest.php @@ -1,35 +1,36 @@ assertIsObject($value); - $this->assertInstanceOf(ApiKey::class, $value); - } - - public function testCheck(): void - { - $value = ApiKey::generate(); - $result = $value->check($value); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testCheckInvalid(): void - { - $value = ApiKey::generate(); - $result = $value->check(ApiKey::generate()); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } + public function testGenerate(): void + { + $value = ApiKey::generate(); + + $this->assertIsObject($value); + $this->assertInstanceOf(ApiKey::class, $value); + } + + public function testCheck(): void + { + $value = ApiKey::generate(); + $result = $value->check($value); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testCheckInvalid(): void + { + $value = ApiKey::generate(); + $result = $value->check(ApiKey::generate()); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } } diff --git a/test/Domain/DataStructure/Application/CollectionTest.php b/test/Domain/DataStructure/Application/CollectionTest.php index d0db244..8c276dd 100644 --- a/test/Domain/DataStructure/Application/CollectionTest.php +++ b/test/Domain/DataStructure/Application/CollectionTest.php @@ -1,63 +1,64 @@ assertEquals(0, $collection->getNbItems()); - - $collection->addApplication( - FixtureApplication::get() - ); - - $this->assertEquals(1, $collection->getNbItems()); - } - - public function testSearchById(): void - { - $collection = FixtureApplication::getCollection(); - - $result = $collection->searchById( - FixtureApplication::get()->id - ); - - $this->assertIsObject($result); - - $collection = FixtureApplication::getCollection(); - - $result = $collection->searchById( - '1b3f18e5-c12d-4063-bf27-d77c2558ea1a' - ); - - $this->assertNull($result); - } - - public function testSearchByApiKey(): void - { - $collection = FixtureApplication::getCollection(); - - $result = $collection->searchByApiKey( - FixtureApplication::get()->apiKey - ); - - $this->assertIsObject($result); - - $collection = FixtureApplication::getCollection(); - - $result = $collection->searchByApiKey( - 'XXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' - ); - - $this->assertNull($result); - } + protected Collection $fixture; + + public function testAddApplication(): void + { + $collection = new Collection(); + + $this->assertEquals(0, $collection->getNbItems()); + + $collection->addApplication( + FixtureApplication::get() + ); + + $this->assertEquals(1, $collection->getNbItems()); + } + + public function testSearchById(): void + { + $collection = FixtureApplication::getCollection(); + + $result = $collection->searchById( + FixtureApplication::get()->id + ); + + $this->assertIsObject($result); + + $collection = FixtureApplication::getCollection(); + + $result = $collection->searchById( + '1b3f18e5-c12d-4063-bf27-d77c2558ea1a' + ); + + $this->assertNull($result); + } + + public function testSearchByApiKey(): void + { + $collection = FixtureApplication::getCollection(); + + $result = $collection->searchByApiKey( + FixtureApplication::get()->apiKey + ); + + $this->assertIsObject($result); + + $collection = FixtureApplication::getCollection(); + + $result = $collection->searchByApiKey( + 'XXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + ); + + $this->assertNull($result); + } } diff --git a/test/Domain/DataStructure/Application/NameTest.php b/test/Domain/DataStructure/Application/NameTest.php index b7377b5..3e3df14 100644 --- a/test/Domain/DataStructure/Application/NameTest.php +++ b/test/Domain/DataStructure/Application/NameTest.php @@ -1,26 +1,27 @@ assertIsObject($result); - $this->assertInstanceOf(Name::class, $result); - } - - public function testConstructFail(): void - { - $this->expectException(NotCompliant::class); - - new Name('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'); - } + public function testConstruct(): void + { + $result = new Name('Foo bar'); + + $this->assertIsObject($result); + $this->assertInstanceOf(Name::class, $result); + } + + public function testConstructFail(): void + { + $this->expectException(NotCompliant::class); + + new Name('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'); + } } diff --git a/test/Domain/DataStructure/ApplicationTest.php b/test/Domain/DataStructure/ApplicationTest.php index cf5c6d8..1fa66f8 100644 --- a/test/Domain/DataStructure/ApplicationTest.php +++ b/test/Domain/DataStructure/ApplicationTest.php @@ -1,77 +1,101 @@ fixture = FixtureApplication::get(); - } - - public function testConstruct(): void - { - $entity = new Application( - Id::generate(), - new Name('Foo bar'), - new Logo('https://domain.ext/file.ext'), - ApiKey::generate() - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(Application::class, $entity); - } - - public function testCheck(): void - { - $result = $this->fixture->isHisApiKey( - $this->fixture->apiKey - ); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testCheckInvalid(): void - { - $result = $this->fixture->isHisApiKey( - ApiKey::generate() - ); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } - - public function testIsHisId(): void - { - $result = $this->fixture->isHisId( - $this->fixture->id - ); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testIsHisIdInvalid(): void - { - $result = $this->fixture->isHisId( - Id::generate() - ); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } + protected Application $fixture; + + public function setUp(): void + { + $this->fixture = FixtureApplication::get(); + } + + public function testConstruct(): void + { + $entity = new Application( + Id::generate(), + new Name('Foo bar'), + new Logo('https://domain.ext/file.ext'), + ApiKey::generate() + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + } + + public function testIsHisApiKey(): void + { + $result = $this->fixture->isHisApiKey( + (string) $this->fixture->apiKey + ); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testCheckInvalid(): void + { + $result = $this->fixture->isHisApiKey( + ApiKey::generate() + ); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } + + public function testIsHisId(): void + { + $result = $this->fixture->isHisId( + (string) $this->fixture->id + ); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testIsHisIdInvalid(): void + { + $result = $this->fixture->isHisId( + Id::generate() + ); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } + + public function testMake(): void + { + $entity = Application::make( + null, + 'Foo bar', + 'https://domain.ext/file.ext', + (string) ApiKey::generate() + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + + $entity = Application::make( + (string) Id::generate(), + 'Foo bar', + 'https://domain.ext/file.ext', + (string) ApiKey::generate() + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + } } diff --git a/test/Domain/DataStructure/RequestAccess/AuthMethodTest.php b/test/Domain/DataStructure/RequestAccess/AuthMethodTest.php index 6b98c77..0be2c90 100644 --- a/test/Domain/DataStructure/RequestAccess/AuthMethodTest.php +++ b/test/Domain/DataStructure/RequestAccess/AuthMethodTest.php @@ -1,25 +1,38 @@ is(AuthMethod::API_KEY); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testIsDifferent(): void - { - $result = (new AuthMethod(AuthMethod::API_KEY))->is(AuthMethod::OTP); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } + public function testCases(): void + { + $this->assertCount(3, AuthMethod::cases()); + } + + public function testGetLabel(): void + { + $this->assertIsString(AuthMethod::ApiKey->getLabel()); + $this->assertIsString(AuthMethod::Otp->getLabel()); + $this->assertIsString(AuthMethod::ThirdParty->getLabel()); + } + + public function testIs(): void + { + $result = AuthMethod::ApiKey->is(AuthMethod::ApiKey); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testIsDifferent(): void + { + $result = AuthMethod::ApiKey->is(AuthMethod::Otp); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } } diff --git a/test/Domain/DataStructure/RequestAccess/OtpTest.php b/test/Domain/DataStructure/RequestAccess/OtpTest.php index b45a64e..3dbdc08 100644 --- a/test/Domain/DataStructure/RequestAccess/OtpTest.php +++ b/test/Domain/DataStructure/RequestAccess/OtpTest.php @@ -1,50 +1,51 @@ assertIsObject($result); - $this->assertInstanceOf(Otp::class, $result); - } - - public function testConstructFail(): void - { - $this->expectException(NotCompliant::class); - - new Otp('I23456'); - } - - public function testCheck(): void - { - $result = (new Otp('123456'))->check('123456'); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testCheckDifferent(): void - { - $result = (new Otp('123456'))->check('I23456'); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } - - public function testGenerate(): void - { - $result = Otp::generate(); - - $this->assertIsObject($result); - $this->assertInstanceOf(Otp::class, $result); - } + public function testConstruct(): void + { + $result = new Otp('123456'); + + $this->assertIsObject($result); + $this->assertInstanceOf(Otp::class, $result); + } + + public function testConstructFail(): void + { + $this->expectException(NotCompliant::class); + + new Otp('I23456'); + } + + public function testCheck(): void + { + $result = (new Otp('123456'))->check('123456'); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testCheckDifferent(): void + { + $result = (new Otp('123456'))->check('I23456'); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } + + public function testGenerate(): void + { + $result = Otp::generate(); + + $this->assertIsObject($result); + $this->assertInstanceOf(Otp::class, $result); + } } diff --git a/test/Domain/DataStructure/RequestAccess/StateTest.php b/test/Domain/DataStructure/RequestAccess/StateTest.php index e8ada3b..0b139db 100644 --- a/test/Domain/DataStructure/RequestAccess/StateTest.php +++ b/test/Domain/DataStructure/RequestAccess/StateTest.php @@ -1,127 +1,125 @@ canBeSetTo(State::REQUESTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::REQUESTED)) - ->canBeSetTo(State::REFUSED); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - - - $result = (new State(State::REQUESTED)) - ->canBeSetTo(State::VERIFIED); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - - - $result = (new State(State::REQUESTED)) - ->canBeSetTo(State::GRANTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - // Refused to ... - $result = (new State(State::REFUSED)) - ->canBeSetTo(State::REQUESTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::REFUSED)) - ->canBeSetTo(State::REFUSED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::REFUSED)) - ->canBeSetTo(State::VERIFIED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::REFUSED)) - ->canBeSetTo(State::GRANTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - // Verified to ... - $result = (new State(State::VERIFIED)) - ->canBeSetTo(State::REQUESTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::VERIFIED)) - ->canBeSetTo(State::REFUSED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::VERIFIED)) - ->canBeSetTo(State::VERIFIED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::VERIFIED)) - ->canBeSetTo(State::GRANTED); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - - - // Granted to ... - $result = (new State(State::GRANTED)) - ->canBeSetTo(State::REQUESTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::GRANTED)) - ->canBeSetTo(State::REFUSED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::GRANTED)) - ->canBeSetTo(State::VERIFIED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - - $result = (new State(State::GRANTED)) - ->canBeSetTo(State::GRANTED); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - } + public function testCases(): void + { + $this->assertCount(4, State::cases()); + } + + public function testGetLabel(): void + { + $this->assertIsString(State::Requested->getLabel()); + $this->assertIsString(State::Refused->getLabel()); + $this->assertIsString(State::Verified->getLabel()); + $this->assertIsString(State::Granted->getLabel()); + } + + public function testCanBeSetTo(): void + { + // Requested to ... + $result = State::Requested->canBeSetTo(State::Requested); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Requested->canBeSetTo(State::Refused); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + + + $result = State::Requested->canBeSetTo(State::Verified); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + + + $result = State::Requested->canBeSetTo(State::Granted); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + // Refused to ... + $result = State::Refused->canBeSetTo(State::Requested); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Refused->canBeSetTo(State::Refused); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Refused->canBeSetTo(State::Verified); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Refused->canBeSetTo(State::Granted); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + // Verified to ... + $result = State::Verified->canBeSetTo(State::Requested); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Verified->canBeSetTo(State::Refused); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Verified->canBeSetTo(State::Verified); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Verified->canBeSetTo(State::Granted); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + + + // Granted to ... + $result = State::Granted->canBeSetTo(State::Requested); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Granted->canBeSetTo(State::Refused); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Granted->canBeSetTo(State::Verified); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + + $result = State::Granted->canBeSetTo(State::Granted); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + } } diff --git a/test/Domain/DataStructure/RequestAccessFromApiKeyTest.php b/test/Domain/DataStructure/RequestAccessFromApiKeyTest.php index 1985461..e88b687 100644 --- a/test/Domain/DataStructure/RequestAccessFromApiKeyTest.php +++ b/test/Domain/DataStructure/RequestAccessFromApiKeyTest.php @@ -1,38 +1,39 @@ fixture = FixtureRequestAccessFromApiKey::get(); - } - - public function testConstruct(): void - { - $entity = new RequestAccessFromApiKey( - FixtureApplication::get()->apiKey, - 300 - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromApiKey::class, $entity); - } + protected RequestAccessFromApiKey $fixture; + + public function setUp(): void + { + $this->fixture = FixtureRequestAccessFromApiKey::get(); + } + + public function testConstruct(): void + { + $entity = new RequestAccessFromApiKey( + FixtureApplication::get()->apiKey, + 300 + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromApiKey::class, $entity); + } } diff --git a/test/Domain/DataStructure/RequestAccessFromOtpTest.php b/test/Domain/DataStructure/RequestAccessFromOtpTest.php index 07082f5..95b1dc2 100644 --- a/test/Domain/DataStructure/RequestAccessFromOtpTest.php +++ b/test/Domain/DataStructure/RequestAccessFromOtpTest.php @@ -1,101 +1,102 @@ fixture = FixtureRequestAccessFromOtp::get(); - } - - public function testConstruct(): void - { - $entity = new RequestAccessFromOtp( - FixtureApplication::get(), - FixtureUser::get(), - 3, - 900 - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); - } - - public function testGetOtp(): void - { - $value = $this->fixture->getOtp(); - - $this->assertIsObject($value); - $this->assertInstanceOf(Otp::class, $value); - } - - public function testCheckOtp(): void - { - $result = $this->fixture->checkOtp( - $this->fixture->getOtp() - ); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testGetNumberOfRemainingAttempts(): void - { - $result = $this->fixture->getNumberOfRemainingAttempts(); - - $this->assertIsInt($result); - $this->assertEquals(3, $result); - } - - public function testCheckOtpNotAuthorized(): void - { - $this->expectException(NotAuthorized::class); - - $result = $this->fixture->checkOtp( - '000000' - ); - $this->assertEquals(false, $result); - - $result = $this->fixture->getNumberOfRemainingAttempts(); - $this->assertEquals(2, $result); - - $result = $this->fixture->checkOtp( - '000000' - ); - $this->assertEquals(false, $result); - - $result = $this->fixture->getNumberOfRemainingAttempts(); - $this->assertEquals(1, $result); - - $result = $this->fixture->checkOtp( - '000000' - ); - $this->assertEquals(false, $result); - - $result = $this->fixture->getNumberOfRemainingAttempts(); - $this->assertEquals(0, $result); - - $this->fixture->checkOtp( - '000000' - ); - } + protected RequestAccessFromOtp $fixture; + + public function setUp(): void + { + $this->fixture = FixtureRequestAccessFromOtp::get(); + } + + public function testConstruct(): void + { + $entity = new RequestAccessFromOtp( + FixtureApplication::get(), + FixtureUser::get(), + 3, + 900 + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); + } + + public function testGetOtp(): void + { + $value = $this->fixture->otp; + + $this->assertIsObject($value); + $this->assertInstanceOf(Otp::class, $value); + } + + public function testCheckOtp(): void + { + $result = $this->fixture->checkOtp( + $this->fixture->otp + ); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testGetNumberOfRemainingAttempts(): void + { + $result = $this->fixture->getNumberOfRemainingAttempts(); + + $this->assertIsInt($result); + $this->assertEquals(3, $result); + } + + public function testCheckOtpNotAuthorized(): void + { + $this->expectException(NotAuthorized::class); + + $result = $this->fixture->checkOtp( + '000000' + ); + $this->assertEquals(false, $result); + + $result = $this->fixture->getNumberOfRemainingAttempts(); + $this->assertEquals(2, $result); + + $result = $this->fixture->checkOtp( + '000000' + ); + $this->assertEquals(false, $result); + + $result = $this->fixture->getNumberOfRemainingAttempts(); + $this->assertEquals(1, $result); + + $result = $this->fixture->checkOtp( + '000000' + ); + $this->assertEquals(false, $result); + + $result = $this->fixture->getNumberOfRemainingAttempts(); + $this->assertEquals(0, $result); + + $this->fixture->checkOtp( + '000000' + ); + } } diff --git a/test/Domain/DataStructure/RequestAccessFromThirdPartyTest.php b/test/Domain/DataStructure/RequestAccessFromThirdPartyTest.php index 7a76d44..a259053 100644 --- a/test/Domain/DataStructure/RequestAccessFromThirdPartyTest.php +++ b/test/Domain/DataStructure/RequestAccessFromThirdPartyTest.php @@ -1,46 +1,47 @@ fixture = FixtureRequestAccessFromThirdParty::get(); - } - - public function testConstruct(): void - { - $entity = new RequestAccessFromThirdParty( - FixtureApplication::get(), - new CallbackUrl('https://domain.ext/path'), - 900 - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromThirdParty::class, $entity); - } - - public function testGetCallbackUrl(): void - { - $value = $this->fixture->getCallbackUrl(); - - $this->assertIsObject($value); - $this->assertInstanceOf(CallbackUrl::class, $value); - } + protected RequestAccessFromThirdParty $fixture; + + public function setUp(): void + { + $this->fixture = FixtureRequestAccessFromThirdParty::get(); + } + + public function testConstruct(): void + { + $entity = new RequestAccessFromThirdParty( + FixtureApplication::get(), + new CallbackUrl('https://domain.ext/path'), + 900 + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromThirdParty::class, $entity); + } + + public function testGetCallbackUrl(): void + { + $value = $this->fixture->callbackUrl; + + $this->assertIsObject($value); + $this->assertInstanceOf(CallbackUrl::class, $value); + } } diff --git a/test/Domain/DataStructure/RequestAccessTest.php b/test/Domain/DataStructure/RequestAccessTest.php index cd76425..fd8d59e 100644 --- a/test/Domain/DataStructure/RequestAccessTest.php +++ b/test/Domain/DataStructure/RequestAccessTest.php @@ -1,26 +1,27 @@ fixture = FixtureRequestAccessFromApiKey::get(); - } - - public function testGetId(): void - { - $value = $this->fixture->getId(); - - $this->assertIsObject($value); - $this->assertInstanceOf(Id::class, $value); - } - - public function testGetApplication(): void - { - $value = $this->fixture->getApplication(); - - $this->assertNull($value); - } - - public function testSetApplication(): void - { - $this->fixture->setApplication(FixtureApplication::get()); - - $value = $this->fixture->getApplication(); - - $this->assertIsObject($value); - $this->assertInstanceOf(Application::class, $value); - $this->assertEquals(FixtureApplication::get(), $value); - } - - public function testSetApplicationInvalid(): void - { - $this->expectException(NotAuthorized::class); - - $this->fixture->setApplication(FixtureApplication::get()); - $this->fixture->setApplication(FixtureApplication::get()); - } - - public function testGetUser(): void - { - $value = $this->fixture->getUser(); - - $this->assertNull($value); - } - - public function testSetUser(): void - { - $this->fixture->setUser(FixtureUser::get()); - - $value = $this->fixture->getUser(); - - $this->assertIsObject($value); - $this->assertInstanceOf(User::class, $value); - $this->assertEquals(FixtureUser::get(), $value); - } - - public function testSetUserInvalid(): void - { - $this->expectException(NotAuthorized::class); - - $this->fixture->setUser(FixtureUser::get()); - $this->fixture->setUser(FixtureUser::get()); - } - - public function testGetAuthMethod(): void - { - $value = $this->fixture->getAuthMethod(); - - $this->assertIsObject($value); - $this->assertInstanceOf(AuthMethod::class, $value); - } - - public function testGetState(): void - { - $value = $this->fixture->getState(); - - $this->assertIsObject($value); - $this->assertInstanceOf(State::class, $value); - } - - public function testCanBeSetStateTo(): void - { - $result = $this->fixture->canBeSetStateTo(new State(State::VERIFIED)); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testSetState(): void - { - $entity = $this->fixture->setState(new State(State::VERIFIED)); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromApiKey::class, $entity); - - $this->assertIsObject($entity->getState()); - $this->assertInstanceOf(State::class, $entity->getState()); - $this->assertEquals(new State(State::VERIFIED), $entity->getState()); - } - - public function testSetStateInvalid(): void - { - $this->expectException(NotAuthorized::class); - - $entity = $this->fixture->setState(new State(State::REQUESTED)); - } - - public function testGetLifetime(): void - { - $value = $this->fixture->getLifetime(); - - $this->assertIsInt($value); - } - - public function testGetExpiration(): void - { - $value = $this->fixture->getExpiration(); - - $this->assertIsInt($value); - } - - public function testTokenizeIdAndUntokenizeId(): void - { - $result = $this->fixture->tokenizeId(FixtureSslKey::get()); - - $this->assertIsObject($result); - $this->assertInstanceOf(Token::class, $result); - - $entity = $this->fixture->untokenizeId($result, FixtureSslKey::get()); - - $this->assertIsObject($entity); - $this->assertInstanceOf(Id::class, $entity); - } - - public function testTokenizeIdInvalid(): void - { - $this->expectException(NotCompliant::class); - - $this->fixture->tokenizeId(FixtureSslKey::getInvalid()); - } - - public function testUntokenizeIdInvalid(): void - { - $this->expectException(NotCompliant::class); - - $this->fixture->untokenizeId( - $this->fixture->tokenizeId(FixtureSslKey::get()), - FixtureSslKey::getInvalid() - ); - } - - public function testUntokenizeIdExpired(): void - { - $this->expectException(NotCompliant::class); - - $this->fixture->untokenizeId( - FixtureRequestAccessFromApiKey::getExpired()->tokenizeId(FixtureSslKey::get()), - FixtureSslKey::get() - ); - } + protected RequestAccessFromApiKey $fixture; + + public function setUp(): void + { + $this->fixture = FixtureRequestAccessFromApiKey::get(); + } + + public function testGetId(): void + { + $value = $this->fixture->id; + + $this->assertIsObject($value); + $this->assertInstanceOf(Id::class, $value); + } + + public function testGetApplication(): void + { + $value = $this->fixture->application; + + $this->assertNull($value); + } + + public function testSetApplication(): void + { + $this->fixture->setApplication(FixtureApplication::get()); + + $value = $this->fixture->application; + + $this->assertIsObject($value); + $this->assertInstanceOf(Application::class, $value); + $this->assertEquals(FixtureApplication::get(), $value); + } + + public function testSetApplicationInvalid(): void + { + $this->expectException(NotAuthorized::class); + + $this->fixture->setApplication(FixtureApplication::get()); + $this->fixture->setApplication(FixtureApplication::get()); + } + + public function testGetUser(): void + { + $value = $this->fixture->user; + + $this->assertNull($value); + } + + public function testSetUser(): void + { + $this->fixture->setUser(FixtureUser::get()); + + $value = $this->fixture->user; + + $this->assertIsObject($value); + $this->assertInstanceOf(User::class, $value); + $this->assertEquals(FixtureUser::get(), $value); + } + + public function testSetUserInvalid(): void + { + $this->expectException(NotAuthorized::class); + + $this->fixture->setUser(FixtureUser::get()); + $this->fixture->setUser(FixtureUser::get()); + } + + public function testGetAuthMethod(): void + { + $value = $this->fixture->authMethod; + + $this->assertIsObject($value); + $this->assertInstanceOf(AuthMethod::class, $value); + } + + public function testGetState(): void + { + $value = $this->fixture->state; + + $this->assertIsObject($value); + $this->assertInstanceOf(State::class, $value); + } + + public function testCanBeSetStateTo(): void + { + $result = $this->fixture->canBeSetStateTo(State::Verified); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testSetState(): void + { + $entity = $this->fixture->setState(State::Verified); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromApiKey::class, $entity); + + $this->assertIsObject($entity->state); + $this->assertInstanceOf(State::class, $entity->state); + $this->assertEquals(State::Verified, $entity->state); + } + + public function testSetStateInvalid(): void + { + $this->expectException(NotAuthorized::class); + + $entity = $this->fixture->setState(State::Requested); + } + + public function testGetLifetime(): void + { + $value = $this->fixture->lifetime; + + $this->assertIsInt($value); + } + + public function testGetExpiration(): void + { + $value = $this->fixture->expiration; + + $this->assertIsInt($value); + } + + public function testTokenizeIdAndUntokenizeId(): void + { + $result = $this->fixture->tokenizeId(FixtureSslKey::get()); + + $this->assertIsObject($result); + $this->assertInstanceOf(Token::class, $result); + + $entity = $this->fixture->untokenizeId($result, FixtureSslKey::get()); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Id::class, $entity); + } + + public function testTokenizeIdInvalid(): void + { + $this->expectException(NotCompliant::class); + + $this->fixture->tokenizeId(FixtureSslKey::getInvalid()); + } + + public function testUntokenizeIdInvalid(): void + { + $this->expectException(NotCompliant::class); + + $this->fixture->untokenizeId( + $this->fixture->tokenizeId(FixtureSslKey::get()), + FixtureSslKey::getInvalid() + ); + } + + public function testUntokenizeIdExpired(): void + { + $this->expectException(NotCompliant::class); + + $this->fixture->untokenizeId( + FixtureRequestAccessFromApiKey::getExpired()->tokenizeId(FixtureSslKey::get()), + FixtureSslKey::get() + ); + } } diff --git a/test/Domain/DataStructure/SslKeyTest.php b/test/Domain/DataStructure/SslKeyTest.php index d8dccbf..419bef7 100644 --- a/test/Domain/DataStructure/SslKeyTest.php +++ b/test/Domain/DataStructure/SslKeyTest.php @@ -1,74 +1,75 @@ fixture = FixtureSslKey::get(); - $this->fixtureInvalid = FixtureSslKey::getInvalid(); - } - - public function testGetPrivate(): void - { - $result = $this->fixture->getPrivate(); - - $this->assertIsString($result); - } - - public function testGetPublic(): void - { - $result = $this->fixture->getPublic(); - - $this->assertIsString($result); - } - - public function testEncrypt(): void - { - $result = $this->fixture->encrypt('Foo bar'); - - $this->assertIsString($result); - } - - public function testEncryptInvalid(): void - { - $this->expectException(NotCompliant::class); - - $result = $this->fixtureInvalid->encrypt('Foo bar'); - } - - public function testEncryptInvalidBis(): void - { - $this->expectException(NotCompliant::class); - - $result = $this->fixtureInvalid->encrypt(''); - } - - public function testDecrypt(): void - { - $result = $this->fixture->decrypt( - $this->fixture->encrypt('Foo bar') - ); - - $this->assertIsString($result); - } - - public function testDecryptInvalid(): void - { - $this->expectException(NotCompliant::class); - - $result = $this->fixtureInvalid->decrypt( - $this->fixture->encrypt('Foo bar') - ); - } + protected SslKey $fixture; + protected SslKey $fixtureInvalid; + + public function setUp(): void + { + $this->fixture = FixtureSslKey::get(); + $this->fixtureInvalid = FixtureSslKey::getInvalid(); + } + + public function testGetPrivate(): void + { + $result = $this->fixture->private; + + $this->assertIsString($result); + } + + public function testGetPublic(): void + { + $result = $this->fixture->public; + + $this->assertIsString($result); + } + + public function testEncrypt(): void + { + $result = $this->fixture->encrypt('Foo bar'); + + $this->assertIsString($result); + } + + public function testEncryptInvalid(): void + { + $this->expectException(NotCompliant::class); + + $result = $this->fixtureInvalid->encrypt('Foo bar'); + } + + public function testEncryptInvalidBis(): void + { + $this->expectException(NotCompliant::class); + + $result = $this->fixtureInvalid->encrypt(''); + } + + public function testDecrypt(): void + { + $result = $this->fixture->decrypt( + $this->fixture->encrypt('Foo bar') + ); + + $this->assertIsString($result); + } + + public function testDecryptInvalid(): void + { + $this->expectException(NotCompliant::class); + + $result = $this->fixtureInvalid->decrypt( + $this->fixture->encrypt('Foo bar') + ); + } } diff --git a/test/Domain/DataStructure/UserTest.php b/test/Domain/DataStructure/UserTest.php index a2978e4..0bfa162 100644 --- a/test/Domain/DataStructure/UserTest.php +++ b/test/Domain/DataStructure/UserTest.php @@ -1,36 +1,37 @@ fixture = FixtureUser::get(); - } - - public function testConstruct(): void - { - $entity = new User( - 'john.doe@domain.ext', - 'John', - 'DOE' - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(User::class, $entity); - } + protected User $fixture; + + public function setUp(): void + { + $this->fixture = FixtureUser::get(); + } + + public function testConstruct(): void + { + $entity = User::make( + 'john.doe@domain.ext', + 'John', + 'DOE' + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(User::class, $entity); + } } diff --git a/test/Domain/Serialize/ApplicationTest.php b/test/Domain/Serialize/ApplicationTest.php index 943c39d..851260a 100644 --- a/test/Domain/Serialize/ApplicationTest.php +++ b/test/Domain/Serialize/ApplicationTest.php @@ -1,33 +1,34 @@ fixture = FixtureApplication::get(); - } - - public function testSerialize(): void - { - $value = SerializeApplication::serialize( - $this->fixture - ); - - $this->assertIsArray($value); - $this->assertCount(4, $value); - $this->assertArrayHasKey('id', $value); - $this->assertArrayHasKey('name', $value); - $this->assertArrayHasKey('logo', $value); - $this->assertArrayHasKey('api_key', $value); - } + protected Application $fixture; + + public function setUp(): void + { + $this->fixture = FixtureApplication::get(); + } + + public function testSerialize(): void + { + $value = SerializeApplication::serialize( + $this->fixture + ); + + $this->assertIsArray($value); + $this->assertCount(4, $value); + $this->assertArrayHasKey('id', $value); + $this->assertArrayHasKey('name', $value); + $this->assertArrayHasKey('logo', $value); + $this->assertArrayHasKey('api_key', $value); + } } diff --git a/test/Domain/Serialize/UserTest.php b/test/Domain/Serialize/UserTest.php index e7b07a6..f6a93cd 100644 --- a/test/Domain/Serialize/UserTest.php +++ b/test/Domain/Serialize/UserTest.php @@ -1,33 +1,34 @@ fixture = FixtureUser::get(); - } - - public function testSerialize(): void - { - $value = SerializeUser::serialize( - $this->fixture - ); - - $this->assertIsArray($value); - $this->assertCount(4, $value); - $this->assertArrayHasKey('email_address', $value); - $this->assertArrayHasKey('lastname', $value); - $this->assertArrayHasKey('firstname', $value); - $this->assertArrayHasKey('role', $value); - } + protected User $fixture; + + public function setUp(): void + { + $this->fixture = FixtureUser::get(); + } + + public function testSerialize(): void + { + $value = SerializeUser::serialize( + $this->fixture + ); + + $this->assertIsArray($value); + $this->assertCount(4, $value); + $this->assertArrayHasKey('email_address', $value); + $this->assertArrayHasKey('lastname', $value); + $this->assertArrayHasKey('firstname', $value); + $this->assertArrayHasKey('role', $value); + } } diff --git a/test/Domain/Service/AccessTokenTest.php b/test/Domain/Service/AccessTokenTest.php index 74fac05..794a1e3 100644 --- a/test/Domain/Service/AccessTokenTest.php +++ b/test/Domain/Service/AccessTokenTest.php @@ -1,15 +1,16 @@ service = (new FixtureServiceAccessToken())(); - $this->fixture = FixtureAccessToken::get(); - } - - public function testGetPublicKey(): void - { - $value = $this->service->getPublicKey(); - - $this->assertIsString($value); - } - - public function testCheck(): void - { - $value = $this->service->check( - (string)$this->fixture, - FixtureApplication::get() - ); - - $this->assertIsBool($value); - $this->assertEquals(true, $value); - } - - public function testGetPayload(): void - { - $value = $this->service->getPayload( - (string)$this->fixture - ); - - $this->assertIsArray($value); - } - - public function testGetFromToken(): void - { - $entity = $this->service->getFromToken( - FixtureRequestAccessFromOtp::getVerified() - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } - - public function testGetFromTokenInvalid(): void - { - $this->expectException(NotAuthorized::class); - - $entity = $this->service->getFromToken( - FixtureRequestAccessFromOtp::get() - ); - } + protected ServiceAccessToken $service; + protected AccessToken $fixture; + + public function setUp(): void + { + $this->service = (new FixtureServiceAccessToken())(); + $this->fixture = FixtureAccessToken::get(); + } + + public function testGetPublicKey(): void + { + $value = $this->service->getPublicKey(); + + $this->assertIsString($value); + } + + public function testCheck(): void + { + $value = $this->service->check( + (string)$this->fixture, + FixtureApplication::get() + ); + + $this->assertIsBool($value); + $this->assertEquals(true, $value); + } + + public function testGetPayload(): void + { + $value = $this->service->getPayload( + (string)$this->fixture + ); + + $this->assertIsArray($value); + } + + public function testGetFromToken(): void + { + $entity = $this->service->getFromToken( + FixtureRequestAccessFromOtp::getVerified() + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } + + public function testGetFromTokenInvalid(): void + { + $this->expectException(NotAuthorized::class); + + $entity = $this->service->getFromToken( + FixtureRequestAccessFromOtp::get() + ); + } } diff --git a/test/Domain/Service/ApplicationTest.php b/test/Domain/Service/ApplicationTest.php index dcdd64d..c989a0c 100644 --- a/test/Domain/Service/ApplicationTest.php +++ b/test/Domain/Service/ApplicationTest.php @@ -1,9 +1,10 @@ fixture = (new FixtureServiceApplication())(); - } - - public function testAdd(): void - { - $entity = $this->fixture->add( - 'Foo bar', - 'https://domain.ext/file.ext' - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(Application::class, $entity); - } - - public function testSet(): void - { - $this->fixture->set( - FixtureApplication::get() - ); - - $this->addToAssertionCount(1); - } - - public function testGet(): void - { - $entity = $this->fixture->get( - FixtureApplication::get()->id - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(Application::class, $entity); - } - - public function testGetFromApiKey(): void - { - $entity = $this->fixture->getFromApiKey( - FixtureApplication::get()->apiKey - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(Application::class, $entity); - } + protected ServiceApplication $fixture; + + public function setUp(): void + { + $this->fixture = (new FixtureServiceApplication())(); + } + + public function testAdd(): void + { + $entity = $this->fixture->add( + 'Foo bar', + 'https://domain.ext/file.ext' + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + } + + public function testSet(): void + { + $this->fixture->set( + FixtureApplication::get() + ); + + $this->addToAssertionCount(1); + } + + public function testGet(): void + { + $entity = $this->fixture->get( + (string) FixtureApplication::get()->id + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + } + + public function testGetFromApiKey(): void + { + $entity = $this->fixture->getFromApiKey( + (string) FixtureApplication::get()->apiKey + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(Application::class, $entity); + } } diff --git a/test/Domain/Service/RequestAccessFromApiKeyTest.php b/test/Domain/Service/RequestAccessFromApiKeyTest.php index f103fc4..4137360 100644 --- a/test/Domain/Service/RequestAccessFromApiKeyTest.php +++ b/test/Domain/Service/RequestAccessFromApiKeyTest.php @@ -1,9 +1,11 @@ service = (new FixtureServiceRequestAccessFromApiKey())(); - } - - public function testGetAccessToken(): void - { - $entity = $this->service->getAccessToken( - FixtureApplication::get()->apiKey - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } - - public function testGetAccessTokenInvalid(): void - { - $this->expectException(NotFound::class); - - $entity = $this->service->getAccessToken( - ApiKey::generate() - ); - - $this->assertNull($entity); - } + protected ServiceRequestAccessFromApiKey $service; + + public function setUp(): void + { + $this->service = (new FixtureServiceRequestAccessFromApiKey())(); + } + + public function testGetAccessToken(): void + { + $entity = $this->service->getAccessToken( + (string) FixtureApplication::get()->apiKey + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } + + public function testGetAccessTokenNotFound(): void + { + $this->expectException(NotFound::class); + + $entity = $this->service->getAccessToken( + ApiKey::generate() + ); + + $this->assertNull($entity); + } } diff --git a/test/Domain/Service/RequestAccessFromOtpTest.php b/test/Domain/Service/RequestAccessFromOtpTest.php index 7d0b885..c7c758a 100644 --- a/test/Domain/Service/RequestAccessFromOtpTest.php +++ b/test/Domain/Service/RequestAccessFromOtpTest.php @@ -1,25 +1,26 @@ service = (new FixtureServiceRequestAccessFromOtp())(); - $this->fixture = $this->service->generate( - FixtureApplication::get(), - FixtureUser::get() - ); - $this->cache = new SimpleCache(realpath(__DIR__ . '/../../../test/storage/'), 'user-notification'); - } - - public function testGenerate(): void - { - $this->assertIsObject($this->fixture); - $this->assertInstanceOf(Token::class, $this->fixture); - } - - public function testGenerateInvalid(): void - { - $this->expectException(NotCompliant::class); - - $this->service->generate( - FixtureApplication::get(), - FixtureUser::get(), - 0 - ); - } - - public function testVerify(): void - { - $otp = $this->cache->get((string)$this->fixture); - - $result = $this->service->verify( - $this->fixture, - $otp - ); - - $this->assertIsBool($result); - $this->assertEquals(true, $result); - } - - public function testVerifyInvalid(): void - { - $result = $this->service->verify( - $this->fixture, - '000000' - ); - - $this->assertIsBool($result); - $this->assertEquals(false, $result); - - $result = $this->service->getNumberOfRemainingAttempts( - $this->fixture - ); - $this->assertEquals(2, $result); - - $result = $this->service->verify( - $this->fixture, - '000000' - ); - $result = $this->service->getNumberOfRemainingAttempts( - $this->fixture - ); - $this->assertEquals(1, $result); - - $result = $this->service->verify( - $this->fixture, - '000000' - ); - $result = $this->service->getNumberOfRemainingAttempts( - $this->fixture - ); - $this->assertEquals(0, $result); - } - - public function testVerifyNotAuthorized(): void - { - $this->expectException(NotAuthorized::class); - - $otp = $this->cache->get((string)$this->fixture); - - $result = $this->service->verify( - $this->fixture, - $otp - ); - - $otp = $this->cache->get((string)$this->fixture); - - $result = $this->service->verify( - $this->fixture, - $otp - ); - } - - public function testGetNumberOfRemainingAttempts(): void - { - $result = $this->service->getNumberOfRemainingAttempts( - $this->fixture - ); - - $this->assertIsInt($result); - $this->assertEquals(3, $result); - } - - public function testGetAccessToken(): void - { - $otp = $this->cache->get((string)$this->fixture); - - $result = $this->service->verify( - $this->fixture, - $otp - ); - - $entity = $this->service->getAccessToken( - $this->fixture, - $otp - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } + protected ServiceRequestAccessFromOtp $service; + protected Token $fixture; + protected SimpleCache $cache; + + public function setUp(): void + { + $this->service = (new FixtureServiceRequestAccessFromOtp())(); + $this->fixture = $this->service->generate( + FixtureApplication::get(), + FixtureUser::get() + ); + $this->cache = new SimpleCache(realpath(__DIR__ . '/../../../test/storage/'), 'user-notification'); + } + + public function testGenerate(): void + { + $this->assertIsObject($this->fixture); + $this->assertInstanceOf(Token::class, $this->fixture); + } + + public function testGenerateInvalid(): void + { + $this->expectException(NotCompliant::class); + + $this->service->generate( + FixtureApplication::get(), + FixtureUser::get(), + 0 + ); + } + + public function testVerify(): void + { + $otp = $this->cache->get((string)$this->fixture); + + $result = $this->service->verify( + (string) $this->fixture, + $otp + ); + + $this->assertIsBool($result); + $this->assertEquals(true, $result); + } + + public function testVerifyInvalid(): void + { + $result = $this->service->verify( + $this->fixture, + '000000' + ); + + $this->assertIsBool($result); + $this->assertEquals(false, $result); + + $result = $this->service->getNumberOfRemainingAttempts( + $this->fixture + ); + $this->assertEquals(2, $result); + + $result = $this->service->verify( + $this->fixture, + '000000' + ); + $result = $this->service->getNumberOfRemainingAttempts( + $this->fixture + ); + $this->assertEquals(1, $result); + + $result = $this->service->verify( + $this->fixture, + '000000' + ); + $result = $this->service->getNumberOfRemainingAttempts( + $this->fixture + ); + $this->assertEquals(0, $result); + } + + public function testVerifyNotAuthorized(): void + { + $this->expectException(NotAuthorized::class); + + $otp = $this->cache->get((string)$this->fixture); + + $result = $this->service->verify( + $this->fixture, + $otp + ); + + $otp = $this->cache->get((string)$this->fixture); + + $result = $this->service->verify( + $this->fixture, + $otp + ); + } + + public function testGetNumberOfRemainingAttempts(): void + { + $result = $this->service->getNumberOfRemainingAttempts( + (string) $this->fixture + ); + + $this->assertIsInt($result); + $this->assertEquals(3, $result); + } + + public function testGetAccessToken(): void + { + $otp = $this->cache->get((string)$this->fixture); + + $result = $this->service->verify( + $this->fixture, + $otp + ); + + $entity = $this->service->getAccessToken( + (string) $this->fixture + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } } diff --git a/test/Domain/Service/RequestAccessFromThirdPartyTest.php b/test/Domain/Service/RequestAccessFromThirdPartyTest.php index 7bc1283..cd0e885 100644 --- a/test/Domain/Service/RequestAccessFromThirdPartyTest.php +++ b/test/Domain/Service/RequestAccessFromThirdPartyTest.php @@ -1,98 +1,99 @@ service = (new FixtureServiceRequestAccessFromThirdParty())(); - $this->fixture = $this->service->generate( - FixtureApplication::get(), - 'https://domain.ext/path' - ); - } - - public function testGenerate(): void - { - $this->assertIsObject($this->fixture); - $this->assertInstanceOf(Token::class, $this->fixture); - } - - public function testSetStatus(): void - { - $this->service->setStatus( - $this->fixture, - FixtureUser::get(), - true - ); - - $this->addToAssertionCount(1); - } - - public function testSetStatusToken(): void - { - $this->service->setStatus( - $this->fixture, - FixtureUser::get(), - true - ); - - $entity = $this->service->getAccessToken( - $this->fixture - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(AccessToken::class, $entity); - } - - public function testGetCallbackUrl(): void - { - $value = $this->service->getCallbackUrl( - $this->fixture - ); - - $this->assertIsObject($value); - $this->assertInstanceOf(CallbackUrl::class, $value); - } - - public function testGetAccessTokenInvalid(): void - { - $this->expectException(NotAuthorized::class); - - $this->service->setStatus( - $this->fixture, - FixtureUser::get(), - false - ); - - $entity = $this->service->getAccessToken( - $this->fixture - ); - } + protected ServiceRequestAccessFromThirdParty $service; + protected Token $fixture; + + public function setUp(): void + { + $this->service = (new FixtureServiceRequestAccessFromThirdParty())(); + $this->fixture = $this->service->generate( + FixtureApplication::get(), + 'https://domain.ext/path' + ); + } + + public function testGenerate(): void + { + $this->assertIsObject($this->fixture); + $this->assertInstanceOf(Token::class, $this->fixture); + } + + public function testSetStatus(): void + { + $this->service->setStatus( + (string) $this->fixture, + FixtureUser::get(), + true + ); + + $this->addToAssertionCount(1); + } + + public function testSetStatusToken(): void + { + $this->service->setStatus( + $this->fixture, + FixtureUser::get(), + true + ); + + $entity = $this->service->getAccessToken( + (string) $this->fixture + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(AccessToken::class, $entity); + } + + public function testGetCallbackUrl(): void + { + $value = $this->service->getCallbackUrl( + (string) $this->fixture + ); + + $this->assertIsObject($value); + $this->assertInstanceOf(CallbackUrl::class, $value); + } + + public function testGetAccessTokenInvalid(): void + { + $this->expectException(NotAuthorized::class); + + $this->service->setStatus( + $this->fixture, + FixtureUser::get(), + false + ); + + $entity = $this->service->getAccessToken( + $this->fixture + ); + } } diff --git a/test/Domain/Service/RequestAccessTest.php b/test/Domain/Service/RequestAccessTest.php index af54bba..cf9f7c6 100644 --- a/test/Domain/Service/RequestAccessTest.php +++ b/test/Domain/Service/RequestAccessTest.php @@ -1,10 +1,11 @@ service = (new FixtureServiceRequestAccess())(); - $this->fixture = FixtureRequestAccessFromOtp::get(); - } - - public function testSet(): void - { - $this->service->set( - $this->fixture - ); - - $this->addToAssertionCount(1); - } - - public function testGet(): void - { - $this->service->set( - $this->fixture - ); - - $entity = $this->service->get( - $this->fixture->getId() - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); - } - - public function testGetToken(): void - { - $this->service->set( - $this->fixture - ); - - $value = $this->service->getToken( - $this->fixture - ); - - $this->assertIsObject($value); - $this->assertInstanceOf(Token::class, $value); - } - - public function testGetFromToken(): void - { - $this->service->set( - $this->fixture - ); - - $entity = $this->service->getFromToken( - $this->service->getToken( - $this->fixture - ) - ); - - $this->assertIsObject($entity); - $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); - } + protected ServiceRequestAccess $service; + protected RequestAccessFromOtp $fixture; + + public function setUp(): void + { + $this->service = (new FixtureServiceRequestAccess())(); + $this->fixture = FixtureRequestAccessFromOtp::get(); + } + + public function testSet(): void + { + $this->service->set( + $this->fixture + ); + + $this->addToAssertionCount(1); + } + + public function testGet(): void + { + $this->service->set( + $this->fixture + ); + + $entity = $this->service->get( + (string) $this->fixture->id + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); + } + + public function testGetToken(): void + { + $this->service->set( + $this->fixture + ); + + $value = $this->service->getToken( + $this->fixture + ); + + $this->assertIsObject($value); + $this->assertInstanceOf(Token::class, $value); + } + + public function testGetFromToken(): void + { + $this->service->set( + $this->fixture + ); + + $token = $this->service->getToken( + $this->fixture + ); + + $entity = $this->service->getFromToken( + (string)$token + ); + + $this->assertIsObject($entity); + $this->assertInstanceOf(RequestAccessFromOtp::class, $entity); + } }