custom/plugins/SwagPlatformSecurity/src/Fixes/NEXT15675/SecurityFix.php line 73

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Swag\Security\Fixes\NEXT15675;
  3. use Shopware\Core\Content\ImportExport\Aggregate\ImportExportFile\ImportExportFileEntity;
  4. use Shopware\Core\Content\ImportExport\Exception\FileNotFoundException;
  5. use Shopware\Core\Content\ImportExport\Exception\InvalidFileAccessTokenException;
  6. use Shopware\Core\Content\ImportExport\Service\ImportExportService as CoreImportExportService;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Swag\Security\Components\AbstractSecurityFix;
  11. use Symfony\Component\DependencyInjection\ContainerBuilder;
  12. use Symfony\Component\DependencyInjection\Definition;
  13. use Symfony\Component\DependencyInjection\Reference;
  14. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  17. class SecurityFix extends AbstractSecurityFix
  18. {
  19.     /**
  20.      * @var EntityRepositoryInterface $fileRepository
  21.      */
  22.     private $fileRepository;
  23.     /**
  24.      * @var EventDispatcherInterface $eventDispatcher
  25.      */
  26.     private $eventDispatcher;
  27.     public function __construct(EntityRepositoryInterface $fileRepositoryEventDispatcherInterface $eventDispatcher)
  28.     {
  29.         $this->fileRepository $fileRepository;
  30.         $this->eventDispatcher $eventDispatcher;
  31.     }
  32.     public static function getTicket(): string
  33.     {
  34.         return 'NEXT-15675';
  35.     }
  36.     public static function getMaxVersion(): ?string
  37.     {
  38.         return '6.4.3.1';
  39.     }
  40.     public static function getMinVersion(): string
  41.     {
  42.         return '6.1.5';
  43.     }
  44.     public static function getSubscribedEvents(): array
  45.     {
  46.         return [
  47.             KernelEvents::CONTROLLER_ARGUMENTS => 'onControllerArguments'
  48.         ];
  49.     }
  50.     public static function buildContainer(ContainerBuilder $container): void
  51.     {
  52.         $coreImportExportService $container->getDefinition(CoreImportExportService::class);
  53.         $def = new Definition(ImportExportService::class);
  54.         $def->setDecoratedService(CoreImportExportService::class);
  55.         $def->setArguments([$coreImportExportService->getArguments(), new Reference('import_export_file.repository')]);
  56.         $def->addTag('swag.security.fix', ['ticket' => \Swag\Security\Fixes\NEXT15675\SecurityFix::class]);
  57.         $container
  58.             ->setDefinition(ImportExportService::class, $def);
  59.     }
  60.     public function onControllerArguments(ControllerArgumentsEvent $event)
  61.     {
  62.         $request $event->getRequest();
  63.         $route $request->attributes->get('_route''');
  64.         if ($route !== 'api.action.import_export.file.download') {
  65.             return;
  66.         }
  67.         $fileId = (string) $request->query->get('fileId''');
  68.         /** @var ImportExportFileEntity $file */
  69.         $file $this->fileRepository->search(new Criteria([$fileId]), Context::createDefaultContext())->first();
  70.         if ($file === null) {
  71.             throw new FileNotFoundException($fileId);
  72.         }
  73.         if ($file->getAccessToken() === ImportExportService::PLACEHOLDER_EMPTY_ACCESS_TOKEN) {
  74.             throw new InvalidFileAccessTokenException();
  75.         }
  76.         if ($file->getUpdatedAt() === null) {
  77.             throw new InvalidFileAccessTokenException();
  78.         }
  79.         $diff time() - $file->getUpdatedAt()->getTimestamp();
  80.         if ($diff 300) {
  81.             throw new InvalidFileAccessTokenException();
  82.         }
  83.         $executed false;
  84.         $this->eventDispatcher->addListener(KernelEvents::TERMINATE, function () use($fileId, &$executed) {
  85.             if ($executed) {
  86.                 return;
  87.             }
  88.             $this->fileRepository->update([
  89.                 [
  90.                     'id' => $fileId,
  91.                     'accessToken' => ImportExportService::PLACEHOLDER_EMPTY_ACCESS_TOKEN
  92.                 ]
  93.             ], Context::createDefaultContext());
  94.             $executed true;
  95.         });
  96.     }
  97. }