vendor/sulu/sulu/src/Sulu/Bundle/SecurityBundle/EventListener/SuluSecurityListener.php line 43

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of Sulu.
  4. *
  5. * (c) Sulu GmbH
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace Sulu\Bundle\SecurityBundle\EventListener;
  11. use Sulu\Component\Security\Authorization\AccessControl\SecuredObjectControllerInterface;
  12. use Sulu\Component\Security\Authorization\PermissionTypes;
  13. use Sulu\Component\Security\Authorization\SecurityCheckerInterface;
  14. use Sulu\Component\Security\Authorization\SecurityCondition;
  15. use Sulu\Component\Security\SecuredControllerInterface;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  20. /**
  21. * Listens on the kernel.controller event and checks if Sulu allows this action.
  22. */
  23. class SuluSecurityListener implements EventSubscriberInterface
  24. {
  25. public function __construct(private SecurityCheckerInterface $securityChecker)
  26. {
  27. }
  28. public static function getSubscribedEvents(): array
  29. {
  30. return [KernelEvents::CONTROLLER => 'onKernelController'];
  31. }
  32. /**
  33. * Checks if the action is allowed for the current user, and throws an Exception otherwise.
  34. *
  35. * @throws AccessDeniedException
  36. */
  37. public function onKernelController(ControllerEvent $event)
  38. {
  39. $controller = $event->getController();
  40. $action = '__invoke';
  41. if (\is_array($controller)) {
  42. if (isset($controller[1])) {
  43. $action = $controller[1];
  44. }
  45. if (isset($controller[0])) {
  46. $controller = $controller[0];
  47. }
  48. }
  49. if (
  50. !$controller instanceof SecuredControllerInterface
  51. && !$controller instanceof SecuredObjectControllerInterface
  52. ) {
  53. return;
  54. }
  55. $request = $event->getRequest();
  56. // find appropriate permission type for request
  57. $permission = '';
  58. switch ($request->getMethod()) {
  59. case 'GET':
  60. $permission = PermissionTypes::VIEW;
  61. break;
  62. case 'POST':
  63. if (\in_array($action, ['postAction', '__invoke'])) { // means that the ClassResourceInterface has to be used
  64. $permission = PermissionTypes::ADD;
  65. } else {
  66. $permission = PermissionTypes::EDIT;
  67. }
  68. break;
  69. case 'PUT':
  70. case 'PATCH':
  71. $permission = PermissionTypes::EDIT;
  72. break;
  73. case 'DELETE':
  74. $permission = PermissionTypes::DELETE;
  75. break;
  76. }
  77. $securityContext = null;
  78. $locale = $controller->getLocale($request);
  79. $objectType = null;
  80. $objectId = null;
  81. if ($controller instanceof SecuredObjectControllerInterface) {
  82. $objectType = $controller->getSecuredClass();
  83. $objectId = $controller->getSecuredObjectId($request);
  84. }
  85. // check permission
  86. if ($controller instanceof SecuredControllerInterface) {
  87. $securityContext = $controller->getSecurityContext();
  88. }
  89. if (null !== $securityContext) {
  90. $this->securityChecker->checkPermission(
  91. new SecurityCondition($securityContext, $locale, $objectType, $objectId),
  92. $permission
  93. );
  94. }
  95. }
  96. }