vendor/pimcore/pimcore/bundles/AdminBundle/Controller/AdminController.php line 262

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\Controller;
  15. use Pimcore\Bundle\AdminBundle\HttpFoundation\JsonResponse;
  16. use Pimcore\Bundle\AdminBundle\Security\User\TokenStorageUserResolver;
  17. use Pimcore\Bundle\AdminBundle\Security\User\User as UserProxy;
  18. use Pimcore\Controller\Controller;
  19. use Pimcore\Extension\Bundle\PimcoreBundleManager;
  20. use Pimcore\Logger;
  21. use Pimcore\Model\User;
  22. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  23. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  24. use Symfony\Component\Serializer\Encoder\DecoderInterface;
  25. use Symfony\Component\Serializer\SerializerInterface;
  26. use Symfony\Component\Translation\Exception\InvalidArgumentException;
  27. use Symfony\Contracts\Translation\TranslatorInterface;
  28. abstract class AdminController extends Controller implements AdminControllerInterface
  29. {
  30.     /**
  31.      * @var TokenStorageUserResolver
  32.      */
  33.     protected $tokenResolver;
  34.     /**
  35.      * @var TranslatorInterface
  36.      */
  37.     protected $translator;
  38.     /**
  39.      * @var PimcoreBundleManager
  40.      */
  41.     protected $bundleManager;
  42.     /**
  43.      * @return string[]
  44.      */
  45.     public static function getSubscribedServices()// : array
  46.     {
  47.         $services parent::getSubscribedServices();
  48.         $services['translator'] = TranslatorInterface::class;
  49.         $services[TokenStorageUserResolver::class] = TokenStorageUserResolver::class;
  50.         $services[PimcoreBundleManager::class] = PimcoreBundleManager::class;
  51.         $services['pimcore_admin.serializer'] = '?Pimcore\\Admin\\Serializer';
  52.         return $services;
  53.     }
  54.     /**
  55.      * {@inheritdoc}
  56.      */
  57.     public function needsSessionDoubleAuthenticationCheck()
  58.     {
  59.         return true;
  60.     }
  61.     /**
  62.      * {@inheritdoc}
  63.      */
  64.     public function needsStorageDoubleAuthenticationCheck()
  65.     {
  66.         return true;
  67.     }
  68.     public function getTranslator()
  69.     {
  70.         return $this->container->get('translator');
  71.     }
  72.     public function getBundleManager()
  73.     {
  74.         return $this->container->get(PimcoreBundleManager::class);
  75.     }
  76.     public function getTokenResolver()
  77.     {
  78.         return $this->container->get(TokenStorageUserResolver::class);
  79.     }
  80.     /**
  81.      * Get user from user proxy object which is registered on security component
  82.      *
  83.      * @param bool $proxyUser Return the proxy user (UserInterface) instead of the pimcore model
  84.      *
  85.      * @return UserProxy|User|null
  86.      */
  87.     protected function getAdminUser($proxyUser false)
  88.     {
  89.         if ($proxyUser) {
  90.             return $this->getTokenResolver()->getUserProxy();
  91.         }
  92.         return $this->getTokenResolver()->getUser();
  93.     }
  94.     /**
  95.      * Check user permission
  96.      *
  97.      * @param string $permission
  98.      *
  99.      * @throws AccessDeniedHttpException
  100.      */
  101.     protected function checkPermission($permission)
  102.     {
  103.         if (!$this->getAdminUser() || !$this->getAdminUser()->isAllowed($permission)) {
  104.             Logger::error(
  105.                 'User {user} attempted to access {permission}, but has no permission to do so',
  106.                 [
  107.                     'user' => $this->getAdminUser()?->getName(),
  108.                     'permission' => $permission,
  109.                 ]
  110.             );
  111.             throw $this->createAccessDeniedHttpException();
  112.         }
  113.     }
  114.     /**
  115.      * @param string $message
  116.      * @param \Throwable|null $previous
  117.      * @param int $code
  118.      * @param array $headers
  119.      *
  120.      * @return AccessDeniedHttpException
  121.      */
  122.     protected function createAccessDeniedHttpException(string $message 'Access Denied.'\Throwable $previous nullint $code 0, array $headers = []): AccessDeniedHttpException
  123.     {
  124.         // $headers parameter not supported by Symfony 3.4
  125.         return new AccessDeniedHttpException($message$previous$code$headers);
  126.     }
  127.     /**
  128.      * @param string[] $permissions
  129.      */
  130.     protected function checkPermissionsHasOneOf(array $permissions)
  131.     {
  132.         $allowed false;
  133.         $permission null;
  134.         foreach ($permissions as $permission) {
  135.             if ($this->getAdminUser()->isAllowed($permission)) {
  136.                 $allowed true;
  137.                 break;
  138.             }
  139.         }
  140.         if (!$this->getAdminUser() || !$allowed) {
  141.             Logger::error(
  142.                 'User {user} attempted to access {permission}, but has no permission to do so',
  143.                 [
  144.                     'user' => $this->getAdminUser()->getName(),
  145.                     'permission' => $permission,
  146.                 ]
  147.             );
  148.             throw new AccessDeniedHttpException('Attempt to access ' $permission ', but has no permission to do so.');
  149.         }
  150.     }
  151.     /**
  152.      * Check permission against all controller actions. Can optionally exclude a list of actions.
  153.      *
  154.      * @param ControllerEvent $event
  155.      * @param string $permission
  156.      * @param array $unrestrictedActions
  157.      */
  158.     protected function checkActionPermission(ControllerEvent $eventstring $permission, array $unrestrictedActions = [])
  159.     {
  160.         $actionName null;
  161.         $controller $event->getController();
  162.         if (is_array($controller) && count($controller) === && is_string($controller[1])) {
  163.             $actionName $controller[1];
  164.         }
  165.         if (null === $actionName || !in_array($actionName$unrestrictedActions)) {
  166.             $this->checkPermission($permission);
  167.         }
  168.     }
  169.     /**
  170.      * Encodes data into JSON string
  171.      *
  172.      * @param mixed $data    The data to be encoded
  173.      * @param array $context Context to pass to serializer when using serializer component
  174.      * @param int $options   Options passed to json_encode
  175.      * @param bool $useAdminSerializer
  176.      *
  177.      * @TODO check if $useAdminSerializer still required?
  178.      *
  179.      * @return string
  180.      */
  181.     protected function encodeJson($data, array $context = [], $options JsonResponse::DEFAULT_ENCODING_OPTIONSbool $useAdminSerializer true)
  182.     {
  183.         /** @var SerializerInterface $serializer */
  184.         $serializer null;
  185.         if ($useAdminSerializer) {
  186.             $serializer $this->container->get('pimcore_admin.serializer');
  187.         } else {
  188.             $serializer $this->container->get('serializer');
  189.         }
  190.         return $serializer->serialize($data'json'array_merge([
  191.             'json_encode_options' => $options,
  192.         ], $context));
  193.     }
  194.     /**
  195.      * Decodes a JSON string into an array/object
  196.      *
  197.      * @param mixed $json       The data to be decoded
  198.      * @param bool $associative Whether to decode into associative array or object
  199.      * @param array $context    Context to pass to serializer when using serializer component
  200.      * @param bool $useAdminSerializer
  201.      *
  202.      * @return mixed
  203.      */
  204.     protected function decodeJson($json$associative true, array $context = [], bool $useAdminSerializer true)
  205.     {
  206.         /** @var SerializerInterface|DecoderInterface $serializer */
  207.         $serializer null;
  208.         if ($useAdminSerializer) {
  209.             $serializer $this->container->get('pimcore_admin.serializer');
  210.         } else {
  211.             $serializer $this->container->get('serializer');
  212.         }
  213.         if ($associative) {
  214.             $context['json_decode_associative'] = true;
  215.         }
  216.         return $serializer->decode($json'json'$context);
  217.     }
  218.     /**
  219.      * Returns a JsonResponse that uses the admin serializer
  220.      *
  221.      * @param mixed $data    The response data
  222.      * @param int $status    The status code to use for the Response
  223.      * @param array $headers Array of extra headers to add
  224.      * @param array $context Context to pass to serializer when using serializer component
  225.      * @param bool $useAdminSerializer
  226.      *
  227.      * @return JsonResponse
  228.      */
  229.     protected function adminJson($data$status 200$headers = [], $context = [], bool $useAdminSerializer true)
  230.     {
  231.         $json $this->encodeJson($data$contextJsonResponse::DEFAULT_ENCODING_OPTIONS$useAdminSerializer);
  232.         return new JsonResponse($json$status$headerstrue);
  233.     }
  234.     /**
  235.      * Translates the given message.
  236.      *
  237.      * @param string $id The message id (may also be an object that can be cast to string)
  238.      * @param array $parameters An array of parameters for the message
  239.      * @param string|null $domain The domain for the message or null to use the default
  240.      * @param string|null $locale The locale or null to use the default
  241.      *
  242.      * @return string The translated string
  243.      *
  244.      * @throws InvalidArgumentException If the locale contains invalid characters
  245.      */
  246.     public function trans($id, array $parameters = [], $domain 'admin'$locale null)
  247.     {
  248.         return $this->getTranslator()->trans($id$parameters$domain$locale);
  249.     }
  250. }