ModuleVoter.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Security\Voter;
  4. use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
  5. use App\Entity\Access\Access;
  6. use App\Entity\Organization\Organization;
  7. use App\Service\Security\Module;
  8. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  9. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  10. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  11. /**
  12. * Class ModuleVoter : permet d'assurer que la resource appelée est comprise dans l'un des modules de la structure
  13. * @package App\Security
  14. */
  15. class ModuleVoter extends Voter
  16. {
  17. const HAVING_MODULE = 'IS_HAVING_MODULE';
  18. public function __construct(private Module $module, private ResourceMetadataFactoryInterface $resourceMetadataFactory)
  19. { }
  20. protected function supports(string $attribute, $subject): bool
  21. {
  22. if (!in_array($attribute, [self::HAVING_MODULE])) {
  23. return false;
  24. }
  25. return true;
  26. }
  27. /**
  28. * @param string $attribute
  29. * @param mixed $subject
  30. * @param TokenInterface $token
  31. * @return bool
  32. * @throws \ApiPlatform\Core\Exception\ResourceClassNotFoundException
  33. */
  34. protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
  35. {
  36. if (!$subject->attributes->get('_api_resource_class') || !$resourceMetadata = $this->resourceMetadataFactory->create($subject->attributes->get('_api_resource_class'))) {
  37. throw new AccessDeniedHttpException(sprintf('Missing resource class'));
  38. }
  39. $module = $this->module->getModuleByResourceName($resourceMetadata->getShortName());
  40. //Check if there is a module for this entity : eq configuration problem
  41. if (null === $module) {
  42. throw new AccessDeniedHttpException(sprintf('There are no module for the entity (%s) !', $resourceMetadata->getShortName()));
  43. }
  44. /** @var Access $currentAccess */
  45. $currentAccess = $token->getUser();
  46. /** @var Organization $organization */
  47. $organization = $currentAccess->getOrganization();
  48. return $this->isOrganizationHaveThisModule($organization, $module);
  49. }
  50. /**
  51. * Test si l'organisation possède le module parmis les modules possédés via le produit souscrit, les options souscrites
  52. * ou les modules possédées via des conditions particulières (isCmf par exemple)
  53. *
  54. * @param Organization $organization
  55. * @param string $module
  56. * @return bool
  57. */
  58. private function isOrganizationHaveThisModule(Organization $organization, string $module): bool{
  59. $organizationModules = $this->module->getOrganizationModules($organization);
  60. return in_array($module, $organizationModules);
  61. }
  62. }