From bb29373e16b9914c34fe1cbb98a93b6ccd5d7f3d Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sat, 11 Jul 2020 12:24:35 +0300 Subject: [PATCH] refactoring --- application/Espo/Controllers/App.php | 8 +++-- application/Espo/Core/Acl/EntityAcl.php | 3 ++ application/Espo/Core/Acl/ScopeAcl.php | 3 ++ application/Espo/Core/Acl/Table.php | 3 +- application/Espo/Core/Api/Auth.php | 28 ++++++++-------- application/Espo/Core/Api/ErrorOutput.php | 7 +++- .../Core/AppParams/TemplateEntityTypeList.php | 3 ++ application/Espo/Core/Application.php | 10 +++--- .../Authentication.php} | 32 ++++++++++--------- .../Authentication/{ => Login}/ApiKey.php | 2 +- .../Core/Authentication/{ => Login}/Espo.php | 2 +- .../Core/Authentication/{ => Login}/Hmac.php | 2 +- .../Core/Authentication/{ => Login}/LDAP.php | 2 +- .../Core/Authentication/{ => Login}/Login.php | 11 ++++++- ...enticationFactory.php => LoginFactory.php} | 10 +++--- .../{TwoFA/Utils => TwoFactor}/Factory.php | 6 ++-- .../Methods}/CodeVerify.php | 6 ++-- .../{TwoFA => TwoFactor/Methods}/Totp.php | 10 +++--- .../{TwoFA => TwoFactor}/User/CodeVerify.php | 6 ++-- .../{TwoFA => TwoFactor}/User/Totp.php | 8 +++-- .../Utils => TwoFactor}/UserFactory.php | 6 ++-- .../{TwoFA => TwoFactor}/Utils/Totp.php | 2 +- .../metadata/app/containerServices.json | 10 +++--- application/Espo/Services/UserSecurity.php | 22 +++++++------ 24 files changed, 121 insertions(+), 81 deletions(-) rename application/Espo/Core/{Utils/Auth.php => Authentication/Authentication.php} (96%) rename application/Espo/Core/Authentication/{ => Login}/ApiKey.php (98%) rename application/Espo/Core/Authentication/{ => Login}/Espo.php (98%) rename application/Espo/Core/Authentication/{ => Login}/Hmac.php (98%) rename application/Espo/Core/Authentication/{ => Login}/LDAP.php (99%) rename application/Espo/Core/Authentication/{ => Login}/Login.php (83%) rename application/Espo/Core/Authentication/{Utils/AuthenticationFactory.php => LoginFactory.php} (88%) rename application/Espo/Core/Authentication/{TwoFA/Utils => TwoFactor}/Factory.php (92%) rename application/Espo/Core/Authentication/{TwoFA => TwoFactor/Methods}/CodeVerify.php (92%) rename application/Espo/Core/Authentication/{TwoFA => TwoFactor/Methods}/Totp.php (91%) rename application/Espo/Core/Authentication/{TwoFA => TwoFactor}/User/CodeVerify.php (90%) rename application/Espo/Core/Authentication/{TwoFA => TwoFactor}/User/Totp.php (90%) rename application/Espo/Core/Authentication/{TwoFA/Utils => TwoFactor}/UserFactory.php (92%) rename application/Espo/Core/Authentication/{TwoFA => TwoFactor}/Utils/Totp.php (97%) diff --git a/application/Espo/Controllers/App.php b/application/Espo/Controllers/App.php index 0f7475cc4b..0f4987235b 100644 --- a/application/Espo/Controllers/App.php +++ b/application/Espo/Controllers/App.php @@ -31,10 +31,12 @@ namespace Espo\Controllers; use Espo\Core\Exceptions\BadRequest; -use Espo\Core\Utils\Auth; +use Espo\Core\Authentication\Authentication; use Espo\Core\Di; use Espo\Core\Api\Request; +use StdClass; + class App implements Di\ServiceFactoryAware, @@ -48,12 +50,12 @@ class App implements return $this->serviceFactory->create('App')->getUserData(); } - public function postActionDestroyAuthToken(array $params, \StdClass $data, Request $request) + public function postActionDestroyAuthToken(array $params, StdClass $data, Request $request) { if (empty($data->token)) { throw new BadRequest(); } - $auth = $this->injectableFactory->create(Auth::class); + $auth = $this->injectableFactory->create(Authentication::class); return $auth->destroyAuthToken($data->token, $request); } } diff --git a/application/Espo/Core/Acl/EntityAcl.php b/application/Espo/Core/Acl/EntityAcl.php index 01a9ce2768..c734654dcb 100644 --- a/application/Espo/Core/Acl/EntityAcl.php +++ b/application/Espo/Core/Acl/EntityAcl.php @@ -32,6 +32,9 @@ namespace Espo\Core\Acl; use Espo\Entities\User; use Espo\ORM\Entity; +/** + * @todo Add methods. + */ interface EntityAcl { diff --git a/application/Espo/Core/Acl/ScopeAcl.php b/application/Espo/Core/Acl/ScopeAcl.php index b8f617ed4c..75c601aa76 100644 --- a/application/Espo/Core/Acl/ScopeAcl.php +++ b/application/Espo/Core/Acl/ScopeAcl.php @@ -32,6 +32,9 @@ namespace Espo\Core\Acl; use Espo\Entities\User; use Espo\ORM\Entity; +/** + * @todo Add methods. + */ interface ScopeAcl { diff --git a/application/Espo/Core/Acl/Table.php b/application/Espo/Core/Acl/Table.php index c72eff9524..89ce04887d 100644 --- a/application/Espo/Core/Acl/Table.php +++ b/application/Espo/Core/Acl/Table.php @@ -40,7 +40,8 @@ use Espo\Core\Utils\FieldManagerUtil; use Espo\Core\Utils\File\Manager as FileManager; /** - * A table is generated for each user. It's resulted from merging of multitple roles. + * A table is generated for each user. Multiple roles are merged into a single table. + * This table is used for access checking. */ class Table { diff --git a/application/Espo/Core/Api/Auth.php b/application/Espo/Core/Api/Auth.php index 1c94bb73cb..55c6f2b29c 100644 --- a/application/Espo/Core/Api/Auth.php +++ b/application/Espo/Core/Api/Auth.php @@ -33,20 +33,22 @@ use Exception; use Espo\Core\Exceptions\BadRequest; -use Espo\Core\Utils\Auth as AuthUtil; +use Espo\Core\Authentication\Authentication; use Espo\Core\{ Api\Request, Api\Response, }; +use StdClass; + /** * Determines which auth method to use. Fetches a username and password from headers and server parameters. * Then tries to log in. */ class Auth { - protected $auth; + protected $authentication; protected $authRequired; @@ -54,9 +56,9 @@ class Auth private $isResolvedUseNoAuth = false; - public function __construct(AuthUtil $auth, bool $authRequired = true, bool $isEntryPoint = false) + public function __construct(Authentication $authentication, bool $authRequired = true, bool $isEntryPoint = false) { - $this->auth = $auth; + $this->authentication = $authentication; $this->authRequired = $authRequired; $this->isEntryPoint = $isEntryPoint; } @@ -137,7 +139,7 @@ class Auth if (!$this->authRequired) { if (!$this->isEntryPoint && $hasAuthData) { try { - $isAuthenticated = $this->auth->login($username, $password, $request, $authenticationMethod); + $isAuthenticated = $this->authentication->login($username, $password, $request, $authenticationMethod); } catch (Exception $e) { $this->processException($response, $e); return; @@ -153,7 +155,7 @@ class Auth if ($hasAuthData) { try { - $authResult = $this->auth->login($username, $password, $request, $authenticationMethod); + $authResult = $this->authentication->login($username, $password, $request, $authenticationMethod); } catch (Exception $e) { $this->processException($response, $e); } @@ -182,24 +184,24 @@ class Auth return explode(':', $string, 2); } - protected function handleAuthResult(Response $response, array $authResult) + protected function handleAuthResult(Response $response, StdClass $authResult) { - $status = $authResult['status']; + $status = $authResult->status; - if ($status === AuthUtil::STATUS_SUCCESS) { + if ($status === Authentication::STATUS_SUCCESS) { $this->resolve(); return; } - if ($status === AuthUtil::STATUS_SECOND_STEP_REQUIRED) { + if ($status === Authentication::STATUS_SECOND_STEP_REQUIRED) { $response->setStatus(401); $response->setHeader('X-Status-Reason', 'second-step-required'); $bodyData = [ 'status' => $status, - 'message' => $authResult['message'] ?? null, - 'view' => $authResult['view'] ?? null, - 'token' => $authResult['token'] ?? null, + 'message' => $authResult->message ?? null, + 'view' => $authResult->view ?? null, + 'token' => $authResult->token ?? null, ]; $response->writeBody(json_encode($bodyData)); } diff --git a/application/Espo/Core/Api/ErrorOutput.php b/application/Espo/Core/Api/ErrorOutput.php index 9f154042eb..a64687b17e 100644 --- a/application/Espo/Core/Api/ErrorOutput.php +++ b/application/Espo/Core/Api/ErrorOutput.php @@ -34,6 +34,11 @@ use Espo\Core\{ Api\Response, }; +use Throwable; + +/** + * Processes an error output. If an exception occured, it will be passed to here. + */ class ErrorOutput { protected $errorDescriptions = [ @@ -62,7 +67,7 @@ class ErrorOutput public function process( Response $response, - \Throwable $exception, + Throwable $exception, bool $toPrint = false, ?array $route = null, ?array $routeParams = null diff --git a/application/Espo/Core/AppParams/TemplateEntityTypeList.php b/application/Espo/Core/AppParams/TemplateEntityTypeList.php index db8867c206..2f1573240f 100644 --- a/application/Espo/Core/AppParams/TemplateEntityTypeList.php +++ b/application/Espo/Core/AppParams/TemplateEntityTypeList.php @@ -33,6 +33,9 @@ use Espo\Core\Acl; use Espo\Core\SelectManagerFactory; use Espo\ORM\EntityManager; +/** + * Returns a list of entity types for which a PDF template exists. + */ class TemplateEntityTypeList { protected $acl; diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index b40fac0ff5..15b86bd999 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -38,12 +38,12 @@ use Espo\Core\{ InjectableFactory, EntryPointManager, CronManager, + Authentication\Authentication, Api\Auth as ApiAuth, Api\ErrorOutput as ApiErrorOutput, Api\RequestWrapper, Api\ResponseWrapper, Api\RouteProcessor, - Utils\Auth, Utils\Route, Utils\Autoload, Utils\Config, @@ -131,7 +131,7 @@ class Application try { $authRequired = !($item['noAuth'] ?? false); - $apiAuth = new ApiAuth($this->createAuth(), $authRequired); + $apiAuth = new ApiAuth($this->createAuthentication(), $authRequired); $apiAuth->process($requestWrapped, $responseWrapped); if (!$apiAuth->isResolved()) { @@ -200,7 +200,7 @@ class Application $responseWrapped = new ResponseWrapper($handler->handle($request)); try { - $apiAuth = new ApiAuth($this->createAuth($authNotStrict), $authRequired, true); + $apiAuth = new ApiAuth($this->createAuthentication($authNotStrict), $authRequired, true); $apiAuth->process($requestWrapped, $responseWrapped); @@ -391,9 +391,9 @@ class Application return $slim; } - protected function createAuth(bool $allowAnyAccess = false) : Auth + protected function createAuthentication(bool $allowAnyAccess = false) : Authentication { - return $this->getInjectableFactory()->createWith(Auth::class, [ + return $this->getInjectableFactory()->createWith(Authentication::class, [ 'allowAnyAccess' => $allowAnyAccess, ]); } diff --git a/application/Espo/Core/Utils/Auth.php b/application/Espo/Core/Authentication/Authentication.php similarity index 96% rename from application/Espo/Core/Utils/Auth.php rename to application/Espo/Core/Authentication/Authentication.php index 310344fc5b..6401d4934e 100644 --- a/application/Espo/Core/Utils/Auth.php +++ b/application/Espo/Core/Authentication/Authentication.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Utils; +namespace Espo\Core\Authentication; use Espo\Core\Exceptions\{ Error, @@ -42,10 +42,10 @@ use Espo\Entities\{ }; use Espo\Core\Authentication\{ - Login, - TwoFA\CodeVerify as TwoFACodeVerify, - Utils\AuthenticationFactory, - TwoFA\Utils\Factory as Auth2FAFactory, + Login\Login, + TwoFactor\Methods\CodeVerify as TwoFACodeVerify, + LoginFactory, + TwoFactor\Factory as TwoFAFactory, }; use Espo\Core\Api\Request; @@ -58,10 +58,12 @@ use Espo\Core\{ ORM\EntityManager, }; +use StdClass; + /** * Handles authentication. The entry point of the auth process. */ -class Auth +class Authentication { const FAILED_ATTEMPTS_PERIOD = '60 seconds'; @@ -79,7 +81,7 @@ class Auth protected $config; protected $metadata; protected $entityManager; - protected $authenticationFactory; + protected $authLoginFactory; protected $auth2FAFactory; public function __construct( @@ -89,8 +91,8 @@ class Auth Config $config, Metadata $metadata, EntityManager $entityManager, - AuthenticationFactory $authenticationFactory, - Auth2FAFactory $auth2FAFactory + LoginFactory $authLoginFactory, + TwoFAFactory $auth2FAFactory ) { $this->allowAnyAccess = $allowAnyAccess; @@ -99,7 +101,7 @@ class Auth $this->config = $config; $this->metadata = $metadata; $this->entityManager = $entityManager; - $this->authenticationFactory = $authenticationFactory; + $this->authLoginFactory = $authLoginFactory; $this->auth2FAFactory = $auth2FAFactory; } @@ -110,7 +112,7 @@ class Auth protected function getAuthenticationImpl(string $method) : Login { - return $this->authenticationFactory->create($method); + return $this->authLoginFactory->create($method); } protected function get2FAImpl(string $method) : TwoFACodeVerify @@ -143,7 +145,7 @@ class Auth */ public function login( ?string $username, ?string $password = null, Request $request, ?string $authenticationMethod = null - ) : ?array { + ) : ?StdClass { $isByTokenOnly = false; if ($authenticationMethod) { @@ -303,7 +305,7 @@ class Auth return null; } } else { - $loginResultData = $twoFAImpl->getLoginData($user2FA); + $loginResultData = (array) $twoFAImpl->getLoginData($user2FA); $secondStepRequired = true; } } @@ -369,7 +371,7 @@ class Auth } if ($secondStepRequired) { - return [ + return (object) [ 'status' => self::STATUS_SECOND_STEP_REQUIRED, 'message' => $loginResultData['message'] ?? null, 'token' => $loginResultData['token'] ?? null, @@ -377,7 +379,7 @@ class Auth ]; } - return [ + return (object) [ 'status' => self::STATUS_SUCCESS, ]; } diff --git a/application/Espo/Core/Authentication/ApiKey.php b/application/Espo/Core/Authentication/Login/ApiKey.php similarity index 98% rename from application/Espo/Core/Authentication/ApiKey.php rename to application/Espo/Core/Authentication/Login/ApiKey.php index 1c1c97ceb0..12f4703412 100644 --- a/application/Espo/Core/Authentication/ApiKey.php +++ b/application/Espo/Core/Authentication/Login/ApiKey.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication; +namespace Espo\Core\Authentication\Login; use Espo\Entities\{ User, diff --git a/application/Espo/Core/Authentication/Espo.php b/application/Espo/Core/Authentication/Login/Espo.php similarity index 98% rename from application/Espo/Core/Authentication/Espo.php rename to application/Espo/Core/Authentication/Login/Espo.php index c341634768..967f34eef4 100644 --- a/application/Espo/Core/Authentication/Espo.php +++ b/application/Espo/Core/Authentication/Login/Espo.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication; +namespace Espo\Core\Authentication\Login; use Espo\Entities\{ User, diff --git a/application/Espo/Core/Authentication/Hmac.php b/application/Espo/Core/Authentication/Login/Hmac.php similarity index 98% rename from application/Espo/Core/Authentication/Hmac.php rename to application/Espo/Core/Authentication/Login/Hmac.php index b4bed03c84..7f237b2c90 100644 --- a/application/Espo/Core/Authentication/Hmac.php +++ b/application/Espo/Core/Authentication/Login/Hmac.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication; +namespace Espo\Core\Authentication\Login; use Espo\Entities\{ User, diff --git a/application/Espo/Core/Authentication/LDAP.php b/application/Espo/Core/Authentication/Login/LDAP.php similarity index 99% rename from application/Espo/Core/Authentication/LDAP.php rename to application/Espo/Core/Authentication/Login/LDAP.php index a98c4670e1..22a2e351de 100644 --- a/application/Espo/Core/Authentication/LDAP.php +++ b/application/Espo/Core/Authentication/Login/LDAP.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication; +namespace Espo\Core\Authentication\Login; use Espo\Core\Exceptions\Error; diff --git a/application/Espo/Core/Authentication/Login.php b/application/Espo/Core/Authentication/Login/Login.php similarity index 83% rename from application/Espo/Core/Authentication/Login.php rename to application/Espo/Core/Authentication/Login/Login.php index a407e308bc..9919802e49 100644 --- a/application/Espo/Core/Authentication/Login.php +++ b/application/Espo/Core/Authentication/Login/Login.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication; +namespace Espo\Core\Authentication\Login; use Espo\Entities\{ User, @@ -36,8 +36,17 @@ use Espo\Entities\{ use Espo\Core\Api\Request; +/** + * Performs credentials checking. For the basic authorization a username & password are used. + * For other authorization methods credentials must be fetched from the request. + */ interface Login { + /** + * Check credentials. + * + * @return User if credentials are correct. NULL otherwise. + */ public function login( ?string $username, ?string $password, diff --git a/application/Espo/Core/Authentication/Utils/AuthenticationFactory.php b/application/Espo/Core/Authentication/LoginFactory.php similarity index 88% rename from application/Espo/Core/Authentication/Utils/AuthenticationFactory.php rename to application/Espo/Core/Authentication/LoginFactory.php index e392e7ca67..93a10426dc 100644 --- a/application/Espo/Core/Authentication/Utils/AuthenticationFactory.php +++ b/application/Espo/Core/Authentication/LoginFactory.php @@ -27,13 +27,13 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\Utils; +namespace Espo\Core\Authentication; use Espo\Core\InjectableFactory; use Espo\Core\Utils\Metadata; -use Espo\Core\Authentication\Login; +use Espo\Core\Authentication\Login\Login; -class AuthenticationFactory +class LoginFactory { protected $injectableFactory; protected $metadata; @@ -51,9 +51,9 @@ class AuthenticationFactory if (!$className) { $sanitizedName = preg_replace('/[^a-zA-Z0-9]+/', '', $method); - $className = "Espo\\Custom\\Core\\Authentication\\" . $sanitizedName; + $className = "Espo\\Custom\\Core\\Authentication\\Login\\" . $sanitizedName; if (!class_exists($className)) { - $className = "Espo\\Core\\Authentication\\" . $sanitizedName; + $className = "Espo\\Core\\Authentication\\Login\\" . $sanitizedName; } } diff --git a/application/Espo/Core/Authentication/TwoFA/Utils/Factory.php b/application/Espo/Core/Authentication/TwoFactor/Factory.php similarity index 92% rename from application/Espo/Core/Authentication/TwoFA/Utils/Factory.php rename to application/Espo/Core/Authentication/TwoFactor/Factory.php index f3fc085109..269da17f8c 100644 --- a/application/Espo/Core/Authentication/TwoFA/Utils/Factory.php +++ b/application/Espo/Core/Authentication/TwoFactor/Factory.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA\Utils; +namespace Espo\Core\Authentication\TwoFactor; use Espo\Core\InjectableFactory; use Espo\Core\Utils\Metadata; @@ -52,9 +52,9 @@ class Factory if (!$className) { $sanitizedName = preg_replace('/[^a-zA-Z0-9]+/', '', $method); - $className = "Espo\\Custom\\Core\\\Authentication\\TwoFA\\" . $sanitizedName; + $className = "Espo\\Custom\\Core\\\Authentication\\TwoFactor\\Methods\\" . $sanitizedName; if (!class_exists($className)) { - $className = "Espo\\Core\\Authentication\\TwoFA\\" . $sanitizedName; + $className = "Espo\\Core\\Authentication\\TwoFactor\\Methods\\" . $sanitizedName; } } diff --git a/application/Espo/Core/Authentication/TwoFA/CodeVerify.php b/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php similarity index 92% rename from application/Espo/Core/Authentication/TwoFA/CodeVerify.php rename to application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php index 8e3ae3fc35..abece44938 100644 --- a/application/Espo/Core/Authentication/TwoFA/CodeVerify.php +++ b/application/Espo/Core/Authentication/TwoFactor/Methods/CodeVerify.php @@ -27,13 +27,15 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA; +namespace Espo\Core\Authentication\TwoFactor\Methods; use Espo\Entities\User; +use StdClass; + interface CodeVerify { public function verifyCode(User $user, string $code) : bool; - public function getLoginData(User $user) : array; + public function getLoginData(User $user) : StdClass; } diff --git a/application/Espo/Core/Authentication/TwoFA/Totp.php b/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php similarity index 91% rename from application/Espo/Core/Authentication/TwoFA/Totp.php rename to application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php index 7b90666d5f..25f2b679c2 100644 --- a/application/Espo/Core/Authentication/TwoFA/Totp.php +++ b/application/Espo/Core/Authentication/TwoFactor/Methods/Totp.php @@ -27,12 +27,14 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA; +namespace Espo\Core\Authentication\TwoFactor\Methods; use Espo\Entities\User; use Espo\ORM\EntityManager; -use Espo\Core\Authentication\TwoFA\Utils\Totp as TotpUtils; +use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils; + +use StdClass; class Totp implements CodeVerify { @@ -60,9 +62,9 @@ class Totp implements CodeVerify return $this->totp->verifyCode($secret, $code); } - public function getLoginData(User $user) : array + public function getLoginData(User $user) : StdClass { - return [ + return (object) [ 'message' => 'enterTotpCode', ]; } diff --git a/application/Espo/Core/Authentication/TwoFA/User/CodeVerify.php b/application/Espo/Core/Authentication/TwoFactor/User/CodeVerify.php similarity index 90% rename from application/Espo/Core/Authentication/TwoFA/User/CodeVerify.php rename to application/Espo/Core/Authentication/TwoFactor/User/CodeVerify.php index becfc84d2f..e0aead22de 100644 --- a/application/Espo/Core/Authentication/TwoFA/User/CodeVerify.php +++ b/application/Espo/Core/Authentication/TwoFactor/User/CodeVerify.php @@ -27,13 +27,15 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA\User; +namespace Espo\Core\Authentication\TwoFactor\User; use Espo\Entities\UserData; +use StdClass; + interface CodeVerify { - public function generateData(UserData $userData, object $data, string $userName) : object; + public function generateData(UserData $userData, StdClass $data, string $userName) : StdClass; public function verify(UserData $userData, string $code) : bool; } diff --git a/application/Espo/Core/Authentication/TwoFA/User/Totp.php b/application/Espo/Core/Authentication/TwoFactor/User/Totp.php similarity index 90% rename from application/Espo/Core/Authentication/TwoFA/User/Totp.php rename to application/Espo/Core/Authentication/TwoFactor/User/Totp.php index 3e9437be00..c86be3b3e4 100644 --- a/application/Espo/Core/Authentication/TwoFA/User/Totp.php +++ b/application/Espo/Core/Authentication/TwoFactor/User/Totp.php @@ -27,12 +27,14 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA\User; +namespace Espo\Core\Authentication\TwoFactor\User; use Espo\Entities\UserData; -use Espo\Core\Authentication\TwoFA\Utils\Totp as TotpUtils; +use Espo\Core\Authentication\TwoFactor\Utils\Totp as TotpUtils; use Espo\Core\Utils\Config; +use StdClass; + class Totp implements CodeVerify { protected $entityManager; @@ -44,7 +46,7 @@ class Totp implements CodeVerify $this->config = $config; } - public function generateData(UserData $userData, object $data, string $userName) : object + public function generateData(UserData $userData, StdClass $data, string $userName) : StdClass { $secret = $this->totp->createSecret(); diff --git a/application/Espo/Core/Authentication/TwoFA/Utils/UserFactory.php b/application/Espo/Core/Authentication/TwoFactor/UserFactory.php similarity index 92% rename from application/Espo/Core/Authentication/TwoFA/Utils/UserFactory.php rename to application/Espo/Core/Authentication/TwoFactor/UserFactory.php index fb9e5483a3..65d31328d4 100644 --- a/application/Espo/Core/Authentication/TwoFA/Utils/UserFactory.php +++ b/application/Espo/Core/Authentication/TwoFactor/UserFactory.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA\Utils; +namespace Espo\Core\Authentication\TwoFactor; use Espo\Core\InjectableFactory; use Espo\Core\Utils\Metadata; @@ -52,9 +52,9 @@ class UserFactory if (!$className) { $sanitizedName = preg_replace('/[^a-zA-Z0-9]+/', '', $method); - $className = "Espo\\Custom\\Core\\Authentication\\TwoFA\\User\\" . $sanitizedName; + $className = "Espo\\Custom\\Core\\Authentication\\TwoFactor\\User\\" . $sanitizedName; if (!class_exists($className)) { - $className = "Espo\\Core\\Authentication\\TwoFA\\User\\" . $sanitizedName; + $className = "Espo\\Core\\Authentication\\TwoFactor\\User\\" . $sanitizedName; } } diff --git a/application/Espo/Core/Authentication/TwoFA/Utils/Totp.php b/application/Espo/Core/Authentication/TwoFactor/Utils/Totp.php similarity index 97% rename from application/Espo/Core/Authentication/TwoFA/Utils/Totp.php rename to application/Espo/Core/Authentication/TwoFactor/Utils/Totp.php index 9f84cc75f0..96d93223c3 100644 --- a/application/Espo/Core/Authentication/TwoFA/Utils/Totp.php +++ b/application/Espo/Core/Authentication/TwoFactor/Utils/Totp.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core\Authentication\TwoFA\Utils; +namespace Espo\Core\Authentication\TwoFactor\Utils; use RobThree\Auth\TwoFactorAuth; diff --git a/application/Espo/Resources/metadata/app/containerServices.json b/application/Espo/Resources/metadata/app/containerServices.json index efd166ccf8..4108059286 100644 --- a/application/Espo/Resources/metadata/app/containerServices.json +++ b/application/Espo/Resources/metadata/app/containerServices.json @@ -80,17 +80,17 @@ "hasher": { "className": "Espo\\Core\\Utils\\Hasher" }, - "authenticationFactory": { - "className": "Espo\\Core\\Authentication\\Utils\\AuthenticationFactory" + "authLoginFactory": { + "className": "Espo\\Core\\Authentication\\LoginFactory" }, "auth2FAFactory": { - "className": "Espo\\Core\\Authentication\\TwoFA\\Utils\\Factory" + "className": "Espo\\Core\\Authentication\\TwoFactor\\Factory" }, "auth2FAUserFactory": { - "className": "Espo\\Core\\Authentication\\TwoFA\\Utils\\UserFactory" + "className": "Espo\\Core\\Authentication\\TwoFactor\\UserFactory" }, "totp": { - "className": "Espo\\Core\\Authentication\\TwoFA\\Utils\\Totp" + "className": "Espo\\Core\\Authentication\\TwoFactor\\Utils\\Totp" }, "emailFilterManager": { "className": "Espo\\Core\\Utils\\EmailFilterManager" diff --git a/application/Espo/Services/UserSecurity.php b/application/Espo/Services/UserSecurity.php index 6138c9b140..2a51e37781 100644 --- a/application/Espo/Services/UserSecurity.php +++ b/application/Espo/Services/UserSecurity.php @@ -44,8 +44,10 @@ use Espo\Core\{ Utils\Config, }; -use Espo\Core\Authentication\Utils\AuthenticationFactory; -use Espo\Core\Authentication\TwoFA\Utils\UserFactory as Auth2FAUserFactory; +use Espo\Core\Authentication\LoginFactory; +use Espo\Core\Authentication\TwoFactor\UserFactory as TwoFactorUserFactory; + +use StdClass; class UserSecurity { @@ -53,7 +55,7 @@ class UserSecurity protected $user; protected $metadata; protected $config; - protected $authenticationFactory; + protected $authLoginFactory; protected $auth2FAUserFactory; public function __construct( @@ -61,18 +63,18 @@ class UserSecurity User $user, Metadata $metadata, Config $config, - AuthenticationFactory $authenticationFactory, - Auth2FAUserFactory $auth2FAUserFactory + LoginFactory $authLoginFactory, + TwoFactorUserFactory $auth2FAUserFactory ) { $this->entityManager = $entityManager; $this->user = $user; $this->metadata = $metadata; $this->config = $config; - $this->authenticationFactory = $authenticationFactory; + $this->authLoginFactory = $authLoginFactory; $this->auth2FAUserFactory = $auth2FAUserFactory; } - public function read(string $id) : object + public function read(string $id) : StdClass { if (!$this->user->isAdmin() && $id !== $this->user->id) throw new Forbidden(); @@ -89,7 +91,7 @@ class UserSecurity ]; } - public function generate2FAData(string $id, object $data) : object + public function generate2FAData(string $id, StdClass $data) : StdClass { if (!$this->user->isAdmin() && $id !== $this->user->id) throw new Forbidden(); @@ -128,7 +130,7 @@ class UserSecurity return $generatedData; } - public function update(string $id, object $data) : object + public function update(string $id, StdClass $data) : StdClass { if (!$this->user->isAdmin() && $id !== $this->user->id) throw new Forbidden(); @@ -204,7 +206,7 @@ class UserSecurity { $method = $this->config->get('authenticationMethod', 'Espo'); - $auth = $this->authenticationFactory->create($method); + $auth = $this->authLoginFactory->create($method); $user = $this->entityManager->getRepository('User')->where([ 'id' => $id,