vendor/symfony/security-core/Authorization/Voter/AuthenticatedVoter.php line 27

  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Core\Authorization\Voter;
  11. use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\OfflineTokenInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
  14. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  15. use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
  16. /**
  17. * AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY,
  18. * IS_AUTHENTICATED_REMEMBERED, IS_AUTHENTICATED is present.
  19. *
  20. * This list is most restrictive to least restrictive checking.
  21. *
  22. * @author Fabien Potencier <fabien@symfony.com>
  23. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  24. */
  25. class AuthenticatedVoter implements CacheableVoterInterface
  26. {
  27. public const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY';
  28. public const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED';
  29. public const IS_AUTHENTICATED = 'IS_AUTHENTICATED';
  30. public const IS_IMPERSONATOR = 'IS_IMPERSONATOR';
  31. public const IS_REMEMBERED = 'IS_REMEMBERED';
  32. public const PUBLIC_ACCESS = 'PUBLIC_ACCESS';
  33. public function __construct(
  34. private AuthenticationTrustResolverInterface $authenticationTrustResolver,
  35. ) {
  36. }
  37. /**
  38. * @param Vote|null $vote Should be used to explain the vote
  39. */
  40. public function vote(TokenInterface $token, mixed $subject, array $attributes/* , ?Vote $vote = null */): int
  41. {
  42. $vote = 3 < \func_num_args() ? func_get_arg(3) : null;
  43. if ($attributes === [self::PUBLIC_ACCESS]) {
  44. $vote?->addReason('Access is public.');
  45. return VoterInterface::ACCESS_GRANTED;
  46. }
  47. $result = VoterInterface::ACCESS_ABSTAIN;
  48. foreach ($attributes as $attribute) {
  49. if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute
  50. && self::IS_AUTHENTICATED_REMEMBERED !== $attribute
  51. && self::IS_AUTHENTICATED !== $attribute
  52. && self::IS_IMPERSONATOR !== $attribute
  53. && self::IS_REMEMBERED !== $attribute)) {
  54. continue;
  55. }
  56. if ($token instanceof OfflineTokenInterface) {
  57. throw new InvalidArgumentException('Cannot decide on authentication attributes when an offline token is used.');
  58. }
  59. $result = VoterInterface::ACCESS_DENIED;
  60. if ((self::IS_AUTHENTICATED_FULLY === $attribute || self::IS_AUTHENTICATED_REMEMBERED === $attribute)
  61. && $this->authenticationTrustResolver->isFullFledged($token)
  62. ) {
  63. $vote?->addReason('The user is fully authenticated.');
  64. return VoterInterface::ACCESS_GRANTED;
  65. }
  66. if (self::IS_AUTHENTICATED_REMEMBERED === $attribute
  67. && $this->authenticationTrustResolver->isRememberMe($token)
  68. ) {
  69. $vote?->addReason('The user is remembered.');
  70. return VoterInterface::ACCESS_GRANTED;
  71. }
  72. if (self::IS_AUTHENTICATED === $attribute && $this->authenticationTrustResolver->isAuthenticated($token)) {
  73. $vote?->addReason('The user is authenticated.');
  74. return VoterInterface::ACCESS_GRANTED;
  75. }
  76. if (self::IS_REMEMBERED === $attribute && $this->authenticationTrustResolver->isRememberMe($token)) {
  77. $vote?->addReason('The user is remembered.');
  78. return VoterInterface::ACCESS_GRANTED;
  79. }
  80. if (self::IS_IMPERSONATOR === $attribute && $token instanceof SwitchUserToken) {
  81. $vote?->addReason('The user is impersonating another user.');
  82. return VoterInterface::ACCESS_GRANTED;
  83. }
  84. }
  85. if (VoterInterface::ACCESS_DENIED === $result) {
  86. $vote?->addReason('The user is not appropriately authenticated.');
  87. }
  88. return $result;
  89. }
  90. public function supportsAttribute(string $attribute): bool
  91. {
  92. return \in_array($attribute, [
  93. self::IS_AUTHENTICATED_FULLY,
  94. self::IS_AUTHENTICATED_REMEMBERED,
  95. self::IS_AUTHENTICATED,
  96. self::IS_IMPERSONATOR,
  97. self::IS_REMEMBERED,
  98. self::PUBLIC_ACCESS,
  99. ], true);
  100. }
  101. public function supportsType(string $subjectType): bool
  102. {
  103. return true;
  104. }
  105. }