src/Core/Framework/Api/OAuth/ScopeRepository.php line 83

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Api\OAuth;
  3. use Doctrine\DBAL\Connection;
  4. use League\OAuth2\Server\Entities\ClientEntityInterface;
  5. use League\OAuth2\Server\Entities\ScopeEntityInterface;
  6. use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
  7. use Shopware\Core\Framework\Api\OAuth\Client\ApiClient;
  8. use Shopware\Core\Framework\Api\OAuth\Scope\AdminScope;
  9. use Shopware\Core\Framework\Api\OAuth\Scope\UserVerifiedScope;
  10. use Shopware\Core\Framework\Api\OAuth\Scope\WriteScope;
  11. use Shopware\Core\Framework\Log\Package;
  12. #[Package('core')]
  13. class ScopeRepository implements ScopeRepositoryInterface
  14. {
  15.     /**
  16.      * @var ScopeEntityInterface[]
  17.      */
  18.     private readonly array $scopes;
  19.     /**
  20.      * @internal
  21.      *
  22.      * @param ScopeEntityInterface[] $scopes
  23.      */
  24.     public function __construct(iterable $scopes, private readonly Connection $connection)
  25.     {
  26.         $scopeIndex = [];
  27.         foreach ($scopes as $scope) {
  28.             $scopeIndex[$scope->getIdentifier()] = $scope;
  29.         }
  30.         $this->scopes $scopeIndex;
  31.     }
  32.     /**
  33.      * {@inheritdoc}
  34.      */
  35.     public function getScopeEntityByIdentifier($identifier): ?ScopeEntityInterface
  36.     {
  37.         return $this->scopes[$identifier] ?? null;
  38.     }
  39.     /**
  40.      * {@inheritdoc}
  41.      */
  42.     public function finalizeScopes(
  43.         array $scopes,
  44.         $grantType,
  45.         ClientEntityInterface $clientEntity,
  46.         $userIdentifier null
  47.     ): array {
  48.         $hasWrite false;
  49.         if ($grantType === 'password') {
  50.             $hasWrite true;
  51.         }
  52.         if ($grantType !== 'password') {
  53.             $scopes $this->removeScope($scopesUserVerifiedScope::class);
  54.         }
  55.         if ($grantType === 'client_credentials' && $clientEntity instanceof ApiClient && $clientEntity->getWriteAccess()) {
  56.             $hasWrite true;
  57.         }
  58.         if (!$hasWrite) {
  59.             $scopes $this->removeScope($scopesWriteScope::class);
  60.         }
  61.         if ($hasWrite) {
  62.             $scopes[] = new WriteScope();
  63.         }
  64.         $isAdmin $this->connection->createQueryBuilder()
  65.             ->select('admin')
  66.             ->from('user')
  67.             ->where('id = UNHEX(:accessKey)')
  68.             ->setParameter('accessKey'$userIdentifier)
  69.             ->setMaxResults(1)
  70.             ->executeQuery()
  71.             ->fetchOne();
  72.         if ($isAdmin) {
  73.             $scopes[] = new AdminScope();
  74.         }
  75.         return $this->uniqueScopes($scopes);
  76.     }
  77.     private function uniqueScopes(array $scopes): array
  78.     {
  79.         $uniqueScopes = [];
  80.         /** @var ScopeEntityInterface $scope */
  81.         foreach ($scopes as $scope) {
  82.             $uniqueScopes[$scope->getIdentifier()] = $scope;
  83.         }
  84.         return array_values($uniqueScopes);
  85.     }
  86.     private function removeScope(array $scopesstring $class): array
  87.     {
  88.         foreach ($scopes as $index => $scope) {
  89.             if ($scope instanceof $class) {
  90.                 unset($scopes[$index]);
  91.             }
  92.         }
  93.         return $scopes;
  94.     }
  95. }