diff --git a/src/Authorization/AbstractAuthorizationService.php b/src/Authorization/AbstractAuthorizationService.php index 7507f98853ab84fce2fd63cc193f378a47d4a5d7..9911ced147eb8cf86e580bb8cd677f4b505420be 100644 --- a/src/Authorization/AbstractAuthorizationService.php +++ b/src/Authorization/AbstractAuthorizationService.php @@ -10,7 +10,7 @@ use Symfony\Component\HttpFoundation\Response; abstract class AbstractAuthorizationService { - /** @var UserAuthorizationChecker */ + /** @var AuthorizationExpressionChecker */ private $userAuthorizationChecker; /** @var AuthorizationUser|null */ @@ -18,8 +18,9 @@ abstract class AbstractAuthorizationService public function __construct(UserSessionInterface $userSession, AuthorizationDataProviderProvider $authorizationDataProviderProvider) { - $this->userAuthorizationChecker = new UserAuthorizationChecker($userSession->getUserIdentifier(), $authorizationDataProviderProvider); - $this->currentAuthorizationUser = new AuthorizationUser($this->userAuthorizationChecker); + $muxer = new AuthorizationDataMuxer($authorizationDataProviderProvider->getAuthorizationDataProviders()); + $this->userAuthorizationChecker = new AuthorizationExpressionChecker($muxer); + $this->currentAuthorizationUser = new AuthorizationUser($userSession->getUserIdentifier(), $this->userAuthorizationChecker); } public function setConfig(array $config) diff --git a/src/Authorization/AuthorizationDataMuxer.php b/src/Authorization/AuthorizationDataMuxer.php new file mode 100644 index 0000000000000000000000000000000000000000..475b79c63662b9c1836835cb434cf5acb2251f7b --- /dev/null +++ b/src/Authorization/AuthorizationDataMuxer.php @@ -0,0 +1,72 @@ +<?php + +declare(strict_types=1); + +namespace Dbp\Relay\CoreBundle\Authorization; + +class AuthorizationDataMuxer +{ + /** @var iterable */ + private $authorizationDataProviders; + + /** @var array */ + private $customAttributes; + + /** + * @param iterable<AuthorizationDataProviderInterface> $authorizationDataProviders + */ + public function __construct(iterable $authorizationDataProviders) + { + $this->authorizationDataProviders = $authorizationDataProviders; + $this->customAttributes = []; + } + + private function loadUserAttributesFromAuthorizationProvider(?string $userIdentifier, AuthorizationDataProviderInterface $authorizationDataProvider): void + { + $userAttributes = []; + + if ($userIdentifier !== null) { + $userAttributes = $authorizationDataProvider->getUserAttributes($userIdentifier); + } + + foreach ($authorizationDataProvider->getAvailableAttributes() as $availableAttribute) { + $this->customAttributes[$availableAttribute] = $userAttributes[$availableAttribute] ?? null; + } + } + + /** + * @param mixed|null $defaultValue + * + * @return mixed|null + * + * @throws AuthorizationException + */ + public function getCustomAttribute(?string $userIdentifier, string $attributeName, $defaultValue = null) + { + if (array_key_exists($attributeName, $this->customAttributes) === false) { + $this->loadCustomAttribute($userIdentifier, $attributeName); + } + + return $this->customAttributes[$attributeName] ?? $defaultValue; + } + + /** + * @throws AuthorizationException + */ + private function loadCustomAttribute(?string $userIdentifier, string $attributeName): void + { + $wasFound = false; + foreach ($this->authorizationDataProviders as $authorizationDataProvider) { + $availableAttributes = $authorizationDataProvider->getAvailableAttributes(); + if (in_array($attributeName, $availableAttributes, true)) { + $this->loadUserAttributesFromAuthorizationProvider($userIdentifier, $authorizationDataProvider); + $wasFound = true; + break; + } + } + + if ($wasFound === false) { + throw new AuthorizationException(sprintf('custom attribute \'%s\' undefined', $attributeName), AuthorizationException::ATTRIBUTE_UNDEFINED); + } + } +} diff --git a/src/Authorization/UserAuthorizationChecker.php b/src/Authorization/AuthorizationExpressionChecker.php similarity index 60% rename from src/Authorization/UserAuthorizationChecker.php rename to src/Authorization/AuthorizationExpressionChecker.php index ba961d690af8aeb59e236b00fbdb97e98c2d5610..1eb373488eea7484eb4b01a90400344e81581169 100644 --- a/src/Authorization/UserAuthorizationChecker.php +++ b/src/Authorization/AuthorizationExpressionChecker.php @@ -5,27 +5,17 @@ declare(strict_types=1); namespace Dbp\Relay\CoreBundle\Authorization; use Dbp\Relay\CoreBundle\Authorization\ExpressionLanguage\ExpressionLanguage; -use Dbp\Relay\CoreBundle\Helpers\Tools; -class UserAuthorizationChecker +class AuthorizationExpressionChecker { public const RIGHTS_CONFIG_ATTRIBUTE = 'rights'; public const ATTRIBUTES_CONFIG_ATTRIBUTE = 'attributes'; private const MAX_NUM_CALLS = 16; - /** @var ?string */ - private $currentUserIdentifier; - - /** @var iterable */ - private $authorizationDataProviders; - /** @var ExpressionLanguage */ private $expressionLanguage; - /** @var array */ - private $customAttributes; - /** @var array */ private $rightExpressions; @@ -35,16 +25,16 @@ class UserAuthorizationChecker /** @var int */ private $callCounter; - public function __construct(?string $userIdentifier, AuthorizationDataProviderProvider $authorizationDataProviderProvider) + /** @var AuthorizationDataMuxer */ + private $dataMux; + + public function __construct(AuthorizationDataMuxer $dataMux) { - $this->currentUserIdentifier = $userIdentifier; - $this->authorizationDataProviders = $authorizationDataProviderProvider->getAuthorizationDataProviders(); $this->expressionLanguage = new ExpressionLanguage(); - $this->customAttributes = []; - $this->rightExpressions = []; $this->attributeExpressions = []; + $this->dataMux = $dataMux; } public function setConfig(array $config) @@ -58,11 +48,6 @@ class UserAuthorizationChecker $this->callCounter = 0; } - public function getCurrentUserIdentifier(): ?string - { - return $this->currentUserIdentifier; - } - /** * @param mixed|null $defaultValue * @@ -92,11 +77,7 @@ class UserAuthorizationChecker */ public function getCustomAttribute(AuthorizationUser $currentAuthorizationUser, string $attributeName, $defaultValue = null) { - if (array_key_exists($attributeName, $this->customAttributes) === false) { - $this->loadCustomAttribute($attributeName); - } - - return $this->customAttributes[$attributeName] ?? $defaultValue; + return $this->dataMux->getCustomAttribute($currentAuthorizationUser->getIdentifier(), $attributeName, $defaultValue); } /** @@ -127,39 +108,6 @@ class UserAuthorizationChecker } } - /** - * @throws AuthorizationException - */ - private function loadCustomAttribute(string $attributeName): void - { - $wasFound = false; - foreach ($this->authorizationDataProviders as $authorizationDataProvider) { - $availableAttributes = $authorizationDataProvider->getAvailableAttributes(); - if (in_array($attributeName, $availableAttributes, true)) { - $this->loadUserAttributesFromAuthorizationProvider($authorizationDataProvider); - $wasFound = true; - break; - } - } - - if ($wasFound === false) { - throw new AuthorizationException(sprintf('custom attribute \'%s\' undefined', $attributeName), AuthorizationException::ATTRIBUTE_UNDEFINED); - } - } - - private function loadUserAttributesFromAuthorizationProvider(AuthorizationDataProviderInterface $authorizationDataProvider): void - { - $userAttributes = []; - - if (Tools::isNullOrEmpty($this->currentUserIdentifier) === false) { - $userAttributes = $authorizationDataProvider->getUserAttributes($this->currentUserIdentifier); - } - - foreach ($authorizationDataProvider->getAvailableAttributes() as $availableAttribute) { - $this->customAttributes[$availableAttribute] = $userAttributes[$availableAttribute] ?? null; - } - } - /** * @throws AuthorizationException */ diff --git a/src/Authorization/AuthorizationUser.php b/src/Authorization/AuthorizationUser.php index 9bdf451bb209969ec7bc39c27051b13699669b48..2fafe5efc218df8327e5ddb1bfc640f2eb06463f 100644 --- a/src/Authorization/AuthorizationUser.php +++ b/src/Authorization/AuthorizationUser.php @@ -9,17 +9,23 @@ namespace Dbp\Relay\CoreBundle\Authorization; */ class AuthorizationUser { - /** @var UserAuthorizationChecker */ + /** @var AuthorizationExpressionChecker */ private $authorizationChecker; - public function __construct(UserAuthorizationChecker $authorizationChecker) + /** + * @var string|null + */ + private $identifier; + + public function __construct(?string $identifier, AuthorizationExpressionChecker $authorizationChecker) { $this->authorizationChecker = $authorizationChecker; + $this->identifier = $identifier; } public function getIdentifier(): ?string { - return $this->authorizationChecker->getCurrentUserIdentifier(); + return $this->identifier; } /**