src/Core/Framework/Store/Api/StoreController.php line 85

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Store\Api;
  3. use GuzzleHttp\Exception\ClientException;
  4. use Shopware\Core\Framework\Api\Context\AdminApiSource;
  5. use Shopware\Core\Framework\Api\Context\Exception\InvalidContextSourceException;
  6. use Shopware\Core\Framework\Api\Context\Exception\InvalidContextSourceUserException;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\Log\Package;
  11. use Shopware\Core\Framework\Store\Exception\StoreApiException;
  12. use Shopware\Core\Framework\Store\Exception\StoreInvalidCredentialsException;
  13. use Shopware\Core\Framework\Store\Exception\StoreTokenMissingException;
  14. use Shopware\Core\Framework\Store\Services\AbstractExtensionDataProvider;
  15. use Shopware\Core\Framework\Store\Services\StoreClient;
  16. use Shopware\Core\System\User\UserEntity;
  17. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  18. use Symfony\Component\HttpFoundation\JsonResponse;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\Response;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. /**
  23.  * @internal
  24.  */
  25. #[Route(defaults: ['_routeScope' => ['api']])]
  26. #[Package('merchant-services')]
  27. class StoreController extends AbstractController
  28. {
  29.     public function __construct(private readonly StoreClient $storeClient, private readonly EntityRepository $userRepository, private readonly AbstractExtensionDataProvider $extensionDataProvider)
  30.     {
  31.     }
  32.     #[Route(path'/api/_action/store/login'name'api.custom.store.login'methods: ['POST'])]
  33.     public function login(Request $requestContext $context): JsonResponse
  34.     {
  35.         $shopwareId $request->request->get('shopwareId');
  36.         $password $request->request->get('password');
  37.         if (!\is_string($shopwareId) || !\is_string($password)) {
  38.             throw new StoreInvalidCredentialsException();
  39.         }
  40.         try {
  41.             $this->storeClient->loginWithShopwareId($shopwareId$password$context);
  42.         } catch (ClientException $exception) {
  43.             throw new StoreApiException($exception);
  44.         }
  45.         return new JsonResponse();
  46.     }
  47.     #[Route(path'/api/_action/store/checklogin'name'api.custom.store.checklogin'methods: ['POST'])]
  48.     public function checkLogin(Context $context): Response
  49.     {
  50.         try {
  51.             // Throws StoreTokenMissingException if no token is present
  52.             $this->getUserStoreToken($context);
  53.             $userInfo $this->storeClient->userInfo($context);
  54.             return new JsonResponse([
  55.                 'userInfo' => $userInfo,
  56.             ]);
  57.         } catch (StoreTokenMissingException|ClientException) {
  58.             return new JsonResponse([
  59.                 'userInfo' => null,
  60.             ]);
  61.         }
  62.     }
  63.     #[Route(path'/api/_action/store/logout'name'api.custom.store.logout'methods: ['POST'])]
  64.     public function logout(Context $context): Response
  65.     {
  66.         $context->scope(Context::SYSTEM_SCOPE, function ($context): void {
  67.             $this->userRepository->update([['id' => $context->getSource()->getUserId(), 'storeToken' => null]], $context);
  68.         });
  69.         return new Response();
  70.     }
  71.     #[Route(path'/api/_action/store/updates'name'api.custom.store.updates'methods: ['GET'])]
  72.     public function getUpdateList(Context $context): JsonResponse
  73.     {
  74.         $extensions $this->extensionDataProvider->getInstalledExtensions($contextfalse);
  75.         try {
  76.             $updatesList $this->storeClient->getExtensionUpdateList($extensions$context);
  77.         } catch (ClientException $exception) {
  78.             throw new StoreApiException($exception);
  79.         }
  80.         return new JsonResponse([
  81.             'items' => $updatesList,
  82.             'total' => \count($updatesList),
  83.         ]);
  84.     }
  85.     #[Route(path'/api/_action/store/license-violations'name'api.custom.store.license-violations'methods: ['POST'])]
  86.     public function getLicenseViolations(Request $requestContext $context): JsonResponse
  87.     {
  88.         $extensions $this->extensionDataProvider->getInstalledExtensions($contextfalse);
  89.         $indexedExtensions = [];
  90.         foreach ($extensions as $extension) {
  91.             $name $extension->getName();
  92.             $indexedExtensions[$name] = [
  93.                 'name' => $name,
  94.                 'version' => $extension->getVersion(),
  95.                 'active' => $extension->getActive(),
  96.             ];
  97.         }
  98.         try {
  99.             $violations $this->storeClient->getLicenseViolations($context$indexedExtensions$request->getHost());
  100.         } catch (ClientException $exception) {
  101.             throw new StoreApiException($exception);
  102.         }
  103.         return new JsonResponse([
  104.             'items' => $violations,
  105.             'total' => \count($violations),
  106.         ]);
  107.     }
  108.     #[Route(path'/api/_action/store/plugin/search'name'api.action.store.plugin.search'methods: ['POST'])]
  109.     public function searchPlugins(Request $requestContext $context): Response
  110.     {
  111.         $extensions $this->extensionDataProvider->getInstalledExtensions($contextfalse);
  112.         try {
  113.             $this->storeClient->checkForViolations($context$extensions$request->getHost());
  114.         } catch (\Exception) {
  115.         }
  116.         return new JsonResponse([
  117.             'total' => $extensions->count(),
  118.             'items' => $extensions,
  119.         ]);
  120.     }
  121.     protected function getUserStoreToken(Context $context): string
  122.     {
  123.         $contextSource $context->getSource();
  124.         if (!$contextSource instanceof AdminApiSource) {
  125.             throw new InvalidContextSourceException(AdminApiSource::class, $contextSource::class);
  126.         }
  127.         $userId $contextSource->getUserId();
  128.         if ($userId === null) {
  129.             throw new InvalidContextSourceUserException($contextSource::class);
  130.         }
  131.         /** @var UserEntity|null $user */
  132.         $user $this->userRepository->search(new Criteria([$userId]), $context)->first();
  133.         if ($user === null) {
  134.             throw new StoreTokenMissingException();
  135.         }
  136.         $storeToken $user->getStoreToken();
  137.         if ($storeToken === null) {
  138.             throw new StoreTokenMissingException();
  139.         }
  140.         return $storeToken;
  141.     }
  142. }