From 32cc59228d2e99ef62daf0abacbe84b0f9fdec6d Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Thu, 28 Jan 2021 23:29:08 +0200 Subject: [PATCH] auth refactoring --- .../Espo/Core/Authentication/Result.php | 30 +++-- .../Espo/Core/Authentication/ResultData.php | 115 ++++++++++++++++++ .../TwoFactor/Methods/CodeVerify.php | 8 +- .../Authentication/TwoFactor/Methods/Totp.php | 22 ++-- .../Authentication/TwoFactor/User/Totp.php | 11 +- 5 files changed, 156 insertions(+), 30 deletions(-) create mode 100644 application/Espo/Core/Authentication/ResultData.php diff --git a/application/Espo/Core/Authentication/Result.php b/application/Espo/Core/Authentication/Result.php index 190e6c8061..cf65039363 100644 --- a/application/Espo/Core/Authentication/Result.php +++ b/application/Espo/Core/Authentication/Result.php @@ -58,16 +58,17 @@ class Result protected $failReason = null; - protected function __construct(string $status, ?User $user = null, ?StdClass $params = null) + protected function __construct(string $status, ?User $user = null, ?ResultData $data = null) { $this->user = $user; $this->status = $status; - if ($params) { - $this->message = $params->message ?? null; - $this->token = $params->token ?? null; - $this->view = $params->view ?? null; - $this->loggedUser = $params->loggedUser ?? null; - $this->failReason = $params->failReason ?? null; + + if ($data) { + $this->message = $data->getMessage(); + $this->token = $data->getToken(); + $this->view = $data->getView(); + $this->loggedUser = $data->getLoggedUser(); + $this->failReason = $data->getFailReason(); } } @@ -84,17 +85,19 @@ class Result */ public static function fail(?string $reason = null) { - return new Result(self::STATUS_FAIL, null, (object) [ - 'failReason' => $reason, - ]); + $data = $reason ? + ResultData::fromFailReason($reason) : + ResultData::fromNothing(); + + return new Result(self::STATUS_FAIL, null, $data); } /** * Create an instance for a login requiring a second step. E.g. for 2FA. */ - public static function secondStepRequired(User $user, StdClass $params) + public static function secondStepRequired(User $user, ResultData $data) { - return new Result(self::STATUS_SECOND_STEP_REQUIRED, $user, $params); + return new Result(self::STATUS_SECOND_STEP_REQUIRED, $user, $data); } /** @@ -130,7 +133,8 @@ class Result } /** - * Get a logged user. Considered that an admin user can log in as another user. The logged user will be an admin user. + * Get a logged user. Considered that an admin user can log in as another user. + * The logged user will be an admin user. */ public function getLoggedUser() : ?User { diff --git a/application/Espo/Core/Authentication/ResultData.php b/application/Espo/Core/Authentication/ResultData.php new file mode 100644 index 0000000000..66d0fecaf0 --- /dev/null +++ b/application/Espo/Core/Authentication/ResultData.php @@ -0,0 +1,115 @@ +message = $message; + $this->failReason = $failReason; + $this->token = $token; + $this->view = $view; + $this->loggedUser = $loggedUser; + } + + public static function fromNothing() : self + { + return new self(); + } + + public static function fromFailReason(string $failReason) : self + { + return new self(null, $failReason); + } + + public static function fromMessage(string $message) : self + { + return new self($message); + } + + public static function fromArray(array $data) : self + { + return new self( + $data['message'] ?? null, + $data['failReason'] ?? null, + $data['token'] ?? null, + $data['view'] ?? null, + $data['loggedUser'] ?? null + ); + } + + public function getLoggedUser() : ?User + { + return $this->loggedUser; + } + + public function getStatus() : string + { + return $this->status; + } + + public function getView() : ?string + { + return $this->view; + } + + public function getMessage() : ?string + { + return $this->message; + } + + public function getToken() : ?string + { + return $this->token; + } + + public function getFailReason() : ?string + { + return $this->failReason; + } +} diff --git a/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php b/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php index f486d111dd..18ffc23ae1 100644 --- a/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php +++ b/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php @@ -31,7 +31,9 @@ namespace Espo\Core\Authentication\TwoFactor\Methods; use Espo\Entities\User; -use StdClass; +use Espo\Core\Authentication\{ + ResultData, +}; interface CodeVerify { @@ -41,7 +43,7 @@ interface CodeVerify public function verifyCode(User $user, string $code) : bool; /** - * Data to be sent to frontend for showing a form for a second step. + * Data to be sent to the front-end for showing a form for a second step. */ - public function getLoginData(User $user) : StdClass; + public function getLoginData(User $user) : ResultData; } diff --git a/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php b/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php index dcae20bd19..18bcce1891 100644 --- a/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php +++ b/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php @@ -29,16 +29,20 @@ namespace Espo\Core\Authentication\TwoFactor\Methods; -use Espo\Entities\User; +use Espo\{ + ORM\EntityManager, + Entities\User, +}; -use Espo\ORM\EntityManager; -use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils; - -use StdClass; +use Espo\Core\Authentication\{ + TwoFactor\Utils\Totp as TotpUtils, + ResultData, +}; class Totp implements CodeVerify { protected $entityManager; + protected $totp; public function __construct(EntityManager $entityManager, TotpUtils $totp) @@ -61,7 +65,7 @@ class Totp implements CodeVerify return false; } - if ($userData->get('auth2FAMethod') != 'Totp') { + if ($userData->get('auth2FAMethod') !== 'Totp') { return false; } @@ -74,10 +78,8 @@ class Totp implements CodeVerify return $this->totp->verifyCode($secret, $code); } - public function getLoginData(User $user) : StdClass + public function getLoginData(User $user) : ResultData { - return (object) [ - 'message' => 'enterTotpCode', - ]; + return ResultData::fromMessage('enterTotpCode'); } } diff --git a/application/Espo/Core/Authentication/TwoFactor/User/Totp.php b/application/Espo/Core/Authentication/TwoFactor/User/Totp.php index e70e77a3d6..8053225fce 100644 --- a/application/Espo/Core/Authentication/TwoFactor/User/Totp.php +++ b/application/Espo/Core/Authentication/TwoFactor/User/Totp.php @@ -30,8 +30,11 @@ namespace Espo\Core\Authentication\TwoFactor\User; use Espo\Entities\UserData; -use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils; -use Espo\Core\Utils\Config; + +use Espo\Core\{ + Authentication\TwoFactor\Utils\Totp as TotpUtils, + Utils\Config, +}; use StdClass; @@ -64,10 +67,10 @@ class Totp implements CodeVerify return false; } - $code = str_replace(' ', '', trim($code)); + $codeModified = str_replace(' ', '', trim($code)); $secret = $userData->get('auth2FATotpSecret'); - return $this->totp->verifyCode($secret, $code); + return $this->totp->verifyCode($secret, $codeModified); } }