login consent app sql
This commit is contained in:
188
vendor/symfony/security-core/Authorization/AccessDecisionManager.php
vendored
Normal file
188
vendor/symfony/security-core/Authorization/AccessDecisionManager.php
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Strategy\AccessDecisionStrategyInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Strategy\AffirmativeStrategy;
|
||||
use Symfony\Component\Security\Core\Authorization\Strategy\ConsensusStrategy;
|
||||
use Symfony\Component\Security\Core\Authorization\Strategy\PriorityStrategy;
|
||||
use Symfony\Component\Security\Core\Authorization\Strategy\UnanimousStrategy;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\CacheableVoterInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* AccessDecisionManager is the base class for all access decision managers
|
||||
* that use decision voters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since Symfony 5.4
|
||||
*/
|
||||
class AccessDecisionManager implements AccessDecisionManagerInterface
|
||||
{
|
||||
/**
|
||||
* @deprecated use {@see AffirmativeStrategy} instead
|
||||
*/
|
||||
public const STRATEGY_AFFIRMATIVE = 'affirmative';
|
||||
|
||||
/**
|
||||
* @deprecated use {@see ConsensusStrategy} instead
|
||||
*/
|
||||
public const STRATEGY_CONSENSUS = 'consensus';
|
||||
|
||||
/**
|
||||
* @deprecated use {@see UnanimousStrategy} instead
|
||||
*/
|
||||
public const STRATEGY_UNANIMOUS = 'unanimous';
|
||||
|
||||
/**
|
||||
* @deprecated use {@see PriorityStrategy} instead
|
||||
*/
|
||||
public const STRATEGY_PRIORITY = 'priority';
|
||||
|
||||
private const VALID_VOTES = [
|
||||
VoterInterface::ACCESS_GRANTED => true,
|
||||
VoterInterface::ACCESS_DENIED => true,
|
||||
VoterInterface::ACCESS_ABSTAIN => true,
|
||||
];
|
||||
|
||||
private $voters;
|
||||
private $votersCacheAttributes;
|
||||
private $votersCacheObject;
|
||||
private $strategy;
|
||||
|
||||
/**
|
||||
* @param iterable<mixed, VoterInterface> $voters An array or an iterator of VoterInterface instances
|
||||
* @param AccessDecisionStrategyInterface|null $strategy The vote strategy
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(iterable $voters = [], /* AccessDecisionStrategyInterface */ $strategy = null)
|
||||
{
|
||||
$this->voters = $voters;
|
||||
if (\is_string($strategy)) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'Passing the access decision strategy as a string is deprecated, pass an instance of "%s" instead.', AccessDecisionStrategyInterface::class);
|
||||
$allowIfAllAbstainDecisions = 3 <= \func_num_args() && func_get_arg(2);
|
||||
$allowIfEqualGrantedDeniedDecisions = 4 > \func_num_args() || func_get_arg(3);
|
||||
|
||||
$strategy = $this->createStrategy($strategy, $allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions);
|
||||
} elseif (null !== $strategy && !$strategy instanceof AccessDecisionStrategyInterface) {
|
||||
throw new \TypeError(sprintf('"%s": Parameter #2 ($strategy) is expected to be an instance of "%s" or null, "%s" given.', __METHOD__, AccessDecisionStrategyInterface::class, get_debug_type($strategy)));
|
||||
}
|
||||
|
||||
$this->strategy = $strategy ?? new AffirmativeStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $allowMultipleAttributes Whether to allow passing multiple values to the $attributes array
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decide(TokenInterface $token, array $attributes, $object = null/*, bool $allowMultipleAttributes = false*/)
|
||||
{
|
||||
$allowMultipleAttributes = 3 < \func_num_args() && func_get_arg(3);
|
||||
|
||||
// Special case for AccessListener, do not remove the right side of the condition before 6.0
|
||||
if (\count($attributes) > 1 && !$allowMultipleAttributes) {
|
||||
throw new InvalidArgumentException(sprintf('Passing more than one Security attribute to "%s()" is not supported.', __METHOD__));
|
||||
}
|
||||
|
||||
return $this->strategy->decide(
|
||||
$this->collectResults($token, $attributes, $object)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $object
|
||||
*
|
||||
* @return \Traversable<int, int>
|
||||
*/
|
||||
private function collectResults(TokenInterface $token, array $attributes, $object): \Traversable
|
||||
{
|
||||
foreach ($this->getVoters($attributes, $object) as $voter) {
|
||||
$result = $voter->vote($token, $object, $attributes);
|
||||
if (!\is_int($result) || !(self::VALID_VOTES[$result] ?? false)) {
|
||||
trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class);
|
||||
}
|
||||
|
||||
yield $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException if the $strategy is invalid
|
||||
*/
|
||||
private function createStrategy(string $strategy, bool $allowIfAllAbstainDecisions, bool $allowIfEqualGrantedDeniedDecisions): AccessDecisionStrategyInterface
|
||||
{
|
||||
switch ($strategy) {
|
||||
case self::STRATEGY_AFFIRMATIVE:
|
||||
return new AffirmativeStrategy($allowIfAllAbstainDecisions);
|
||||
case self::STRATEGY_CONSENSUS:
|
||||
return new ConsensusStrategy($allowIfAllAbstainDecisions, $allowIfEqualGrantedDeniedDecisions);
|
||||
case self::STRATEGY_UNANIMOUS:
|
||||
return new UnanimousStrategy($allowIfAllAbstainDecisions);
|
||||
case self::STRATEGY_PRIORITY:
|
||||
return new PriorityStrategy($allowIfAllAbstainDecisions);
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<mixed, VoterInterface>
|
||||
*/
|
||||
private function getVoters(array $attributes, $object = null): iterable
|
||||
{
|
||||
$keyAttributes = [];
|
||||
foreach ($attributes as $attribute) {
|
||||
$keyAttributes[] = \is_string($attribute) ? $attribute : null;
|
||||
}
|
||||
// use `get_class` to handle anonymous classes
|
||||
$keyObject = \is_object($object) ? \get_class($object) : get_debug_type($object);
|
||||
foreach ($this->voters as $key => $voter) {
|
||||
if (!$voter instanceof CacheableVoterInterface) {
|
||||
yield $voter;
|
||||
continue;
|
||||
}
|
||||
|
||||
$supports = true;
|
||||
// The voter supports the attributes if it supports at least one attribute of the list
|
||||
foreach ($keyAttributes as $keyAttribute) {
|
||||
if (null === $keyAttribute) {
|
||||
$supports = true;
|
||||
} elseif (!isset($this->votersCacheAttributes[$keyAttribute][$key])) {
|
||||
$this->votersCacheAttributes[$keyAttribute][$key] = $supports = $voter->supportsAttribute($keyAttribute);
|
||||
} else {
|
||||
$supports = $this->votersCacheAttributes[$keyAttribute][$key];
|
||||
}
|
||||
if ($supports) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$supports) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($this->votersCacheObject[$keyObject][$key])) {
|
||||
$this->votersCacheObject[$keyObject][$key] = $supports = $voter->supportsType($keyObject);
|
||||
} else {
|
||||
$supports = $this->votersCacheObject[$keyObject][$key];
|
||||
}
|
||||
if (!$supports) {
|
||||
continue;
|
||||
}
|
||||
yield $voter;
|
||||
}
|
||||
}
|
||||
}
|
32
vendor/symfony/security-core/Authorization/AccessDecisionManagerInterface.php
vendored
Normal file
32
vendor/symfony/security-core/Authorization/AccessDecisionManagerInterface.php
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* AccessDecisionManagerInterface makes authorization decisions.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface AccessDecisionManagerInterface
|
||||
{
|
||||
/**
|
||||
* Decides whether the access is possible or not.
|
||||
*
|
||||
* @param array $attributes An array of attributes associated with the method being invoked
|
||||
* @param mixed $object The object to secure
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function decide(TokenInterface $token, array $attributes, $object = null);
|
||||
}
|
91
vendor/symfony/security-core/Authorization/AuthorizationChecker.php
vendored
Normal file
91
vendor/symfony/security-core/Authorization/AuthorizationChecker.php
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
|
||||
|
||||
/**
|
||||
* AuthorizationChecker is the main authorization point of the Security component.
|
||||
*
|
||||
* It gives access to the token representing the current user authentication.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AuthorizationChecker implements AuthorizationCheckerInterface
|
||||
{
|
||||
private $tokenStorage;
|
||||
private $accessDecisionManager;
|
||||
private $authenticationManager;
|
||||
private $alwaysAuthenticate;
|
||||
private $exceptionOnNoToken;
|
||||
|
||||
public function __construct(TokenStorageInterface $tokenStorage, /*AccessDecisionManagerInterface*/ $accessDecisionManager, /*bool*/ $alwaysAuthenticate = false, /*bool*/ $exceptionOnNoToken = true)
|
||||
{
|
||||
if ($accessDecisionManager instanceof AuthenticationManagerInterface) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'The $autenticationManager argument of "%s" is deprecated.', __METHOD__);
|
||||
|
||||
$this->authenticationManager = $accessDecisionManager;
|
||||
$accessDecisionManager = $alwaysAuthenticate;
|
||||
$alwaysAuthenticate = $exceptionOnNoToken;
|
||||
$exceptionOnNoToken = \func_num_args() > 4 ? func_get_arg(4) : true;
|
||||
}
|
||||
|
||||
if (false !== $alwaysAuthenticate) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 4th argument of "%s" to "false" is deprecated.', __METHOD__);
|
||||
}
|
||||
if (false !== $exceptionOnNoToken) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 5th argument of "%s" to "false" is deprecated.', __METHOD__);
|
||||
}
|
||||
|
||||
if (!$accessDecisionManager instanceof AccessDecisionManagerInterface) {
|
||||
throw new \TypeError(sprintf('Argument 2 of "%s" must be instance of "%s", "%s" given.', __METHOD__, AccessDecisionManagerInterface::class, get_debug_type($accessDecisionManager)));
|
||||
}
|
||||
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
$this->accessDecisionManager = $accessDecisionManager;
|
||||
$this->alwaysAuthenticate = $alwaysAuthenticate;
|
||||
$this->exceptionOnNoToken = $exceptionOnNoToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token and $exceptionOnNoToken is set to true
|
||||
*/
|
||||
final public function isGranted($attribute, $subject = null): bool
|
||||
{
|
||||
$token = $this->tokenStorage->getToken();
|
||||
|
||||
if (!$token || !$token->getUser()) {
|
||||
if ($this->exceptionOnNoToken) {
|
||||
throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
|
||||
}
|
||||
|
||||
$token = new NullToken();
|
||||
} else {
|
||||
$authenticated = true;
|
||||
// @deprecated since Symfony 5.4
|
||||
if ($this->alwaysAuthenticate || !$authenticated = $token->isAuthenticated(false)) {
|
||||
if (!($authenticated ?? true)) {
|
||||
trigger_deprecation('symfony/core', '5.4', 'Returning false from "%s()" is deprecated, return null from "getUser()" instead.');
|
||||
}
|
||||
$this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->accessDecisionManager->decide($token, [$attribute], $subject);
|
||||
}
|
||||
}
|
30
vendor/symfony/security-core/Authorization/AuthorizationCheckerInterface.php
vendored
Normal file
30
vendor/symfony/security-core/Authorization/AuthorizationCheckerInterface.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
/**
|
||||
* The AuthorizationCheckerInterface.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface AuthorizationCheckerInterface
|
||||
{
|
||||
/**
|
||||
* Checks if the attribute is granted against the current authentication token and optionally supplied subject.
|
||||
*
|
||||
* @param mixed $attribute A single attribute to vote on (can be of any type, string and instance of Expression are supported by the core)
|
||||
* @param mixed $subject
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGranted($attribute, $subject = null);
|
||||
}
|
43
vendor/symfony/security-core/Authorization/ExpressionLanguage.php
vendored
Normal file
43
vendor/symfony/security-core/Authorization/ExpressionLanguage.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
|
||||
|
||||
if (!class_exists(BaseExpressionLanguage::class)) {
|
||||
throw new \LogicException(sprintf('The "%s" class requires the "ExpressionLanguage" component. Try running "composer require symfony/expression-language".', ExpressionLanguage::class));
|
||||
} else {
|
||||
// Help opcache.preload discover always-needed symbols
|
||||
class_exists(ExpressionLanguageProvider::class);
|
||||
|
||||
/**
|
||||
* Adds some function to the default ExpressionLanguage.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see ExpressionLanguageProvider
|
||||
*/
|
||||
class ExpressionLanguage extends BaseExpressionLanguage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(CacheItemPoolInterface $cache = null, array $providers = [])
|
||||
{
|
||||
// prepend the default provider to let users override it easily
|
||||
array_unshift($providers, new ExpressionLanguageProvider());
|
||||
|
||||
parent::__construct($cache, $providers);
|
||||
}
|
||||
}
|
||||
}
|
62
vendor/symfony/security-core/Authorization/ExpressionLanguageProvider.php
vendored
Normal file
62
vendor/symfony/security-core/Authorization/ExpressionLanguageProvider.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
|
||||
|
||||
/**
|
||||
* Define some ExpressionLanguage functions.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
|
||||
{
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new ExpressionFunction('is_anonymous', function () {
|
||||
return 'trigger_deprecation("symfony/security-core", "5.4", "The \"is_anonymous()\" expression function is deprecated.") || ($token && $auth_checker->isGranted("IS_ANONYMOUS"))';
|
||||
}, function (array $variables) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'The "is_anonymous()" expression function is deprecated.');
|
||||
|
||||
return $variables['token'] && $variables['auth_checker']->isGranted('IS_ANONYMOUS');
|
||||
}),
|
||||
|
||||
// @deprecated remove the ternary and always use IS_AUTHENTICATED in 6.0
|
||||
new ExpressionFunction('is_authenticated', function () {
|
||||
return 'defined("'.AuthenticatedVoter::class.'::IS_AUTHENTICATED") ? $auth_checker->isGranted("IS_AUTHENTICATED") : ($token && !$auth_checker->isGranted("IS_ANONYMOUS"))';
|
||||
}, function (array $variables) {
|
||||
return \defined(AuthenticatedVoter::class.'::IS_AUTHENTICATED') ? $variables['auth_checker']->isGranted('IS_AUTHENTICATED') : ($variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS'));
|
||||
}),
|
||||
|
||||
new ExpressionFunction('is_fully_authenticated', function () {
|
||||
return '$token && $auth_checker->isGranted("IS_AUTHENTICATED_FULLY")';
|
||||
}, function (array $variables) {
|
||||
return $variables['token'] && $variables['auth_checker']->isGranted('IS_AUTHENTICATED_FULLY');
|
||||
}),
|
||||
|
||||
new ExpressionFunction('is_granted', function ($attributes, $object = 'null') {
|
||||
return sprintf('$auth_checker->isGranted(%s, %s)', $attributes, $object);
|
||||
}, function (array $variables, $attributes, $object = null) {
|
||||
return $variables['auth_checker']->isGranted($attributes, $object);
|
||||
}),
|
||||
|
||||
new ExpressionFunction('is_remember_me', function () {
|
||||
return '$token && $auth_checker->isGranted("IS_REMEMBERED")';
|
||||
}, function (array $variables) {
|
||||
return $variables['token'] && $variables['auth_checker']->isGranted('IS_REMEMBERED');
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
25
vendor/symfony/security-core/Authorization/Strategy/AccessDecisionStrategyInterface.php
vendored
Normal file
25
vendor/symfony/security-core/Authorization/Strategy/AccessDecisionStrategyInterface.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Strategy;
|
||||
|
||||
/**
|
||||
* A strategy for turning a stream of votes into a final decision.
|
||||
*
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
interface AccessDecisionStrategyInterface
|
||||
{
|
||||
/**
|
||||
* @param \Traversable<int> $results
|
||||
*/
|
||||
public function decide(\Traversable $results): bool;
|
||||
}
|
64
vendor/symfony/security-core/Authorization/Strategy/AffirmativeStrategy.php
vendored
Normal file
64
vendor/symfony/security-core/Authorization/Strategy/AffirmativeStrategy.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Strategy;
|
||||
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Grants access if any voter returns an affirmative response.
|
||||
*
|
||||
* If all voters abstained from voting, the decision will be based on the
|
||||
* allowIfAllAbstainDecisions property value (defaults to false).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
final class AffirmativeStrategy implements AccessDecisionStrategyInterface, \Stringable
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $allowIfAllAbstainDecisions;
|
||||
|
||||
public function __construct(bool $allowIfAllAbstainDecisions = false)
|
||||
{
|
||||
$this->allowIfAllAbstainDecisions = $allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decide(\Traversable $results): bool
|
||||
{
|
||||
$deny = 0;
|
||||
foreach ($results as $result) {
|
||||
if (VoterInterface::ACCESS_GRANTED === $result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (VoterInterface::ACCESS_DENIED === $result) {
|
||||
++$deny;
|
||||
}
|
||||
}
|
||||
|
||||
if ($deny > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'affirmative';
|
||||
}
|
||||
}
|
75
vendor/symfony/security-core/Authorization/Strategy/ConsensusStrategy.php
vendored
Normal file
75
vendor/symfony/security-core/Authorization/Strategy/ConsensusStrategy.php
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Strategy;
|
||||
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Grants access if there is consensus of granted against denied responses.
|
||||
*
|
||||
* Consensus means majority-rule (ignoring abstains) rather than unanimous
|
||||
* agreement (ignoring abstains). If you require unanimity, see
|
||||
* UnanimousBased.
|
||||
*
|
||||
* If there were an equal number of grant and deny votes, the decision will
|
||||
* be based on the allowIfEqualGrantedDeniedDecisions property value
|
||||
* (defaults to true).
|
||||
*
|
||||
* If all voters abstained from voting, the decision will be based on the
|
||||
* allowIfAllAbstainDecisions property value (defaults to false).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
final class ConsensusStrategy implements AccessDecisionStrategyInterface, \Stringable
|
||||
{
|
||||
private $allowIfAllAbstainDecisions;
|
||||
private $allowIfEqualGrantedDeniedDecisions;
|
||||
|
||||
public function __construct(bool $allowIfAllAbstainDecisions = false, bool $allowIfEqualGrantedDeniedDecisions = true)
|
||||
{
|
||||
$this->allowIfAllAbstainDecisions = $allowIfAllAbstainDecisions;
|
||||
$this->allowIfEqualGrantedDeniedDecisions = $allowIfEqualGrantedDeniedDecisions;
|
||||
}
|
||||
|
||||
public function decide(\Traversable $results): bool
|
||||
{
|
||||
$grant = 0;
|
||||
$deny = 0;
|
||||
foreach ($results as $result) {
|
||||
if (VoterInterface::ACCESS_GRANTED === $result) {
|
||||
++$grant;
|
||||
} elseif (VoterInterface::ACCESS_DENIED === $result) {
|
||||
++$deny;
|
||||
}
|
||||
}
|
||||
|
||||
if ($grant > $deny) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($deny > $grant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($grant > 0) {
|
||||
return $this->allowIfEqualGrantedDeniedDecisions;
|
||||
}
|
||||
|
||||
return $this->allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'consensus';
|
||||
}
|
||||
}
|
57
vendor/symfony/security-core/Authorization/Strategy/PriorityStrategy.php
vendored
Normal file
57
vendor/symfony/security-core/Authorization/Strategy/PriorityStrategy.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Strategy;
|
||||
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Grant or deny access depending on the first voter that does not abstain.
|
||||
* The priority of voters can be used to overrule a decision.
|
||||
*
|
||||
* If all voters abstained from voting, the decision will be based on the
|
||||
* allowIfAllAbstainDecisions property value (defaults to false).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
final class PriorityStrategy implements AccessDecisionStrategyInterface, \Stringable
|
||||
{
|
||||
private $allowIfAllAbstainDecisions;
|
||||
|
||||
public function __construct(bool $allowIfAllAbstainDecisions = false)
|
||||
{
|
||||
$this->allowIfAllAbstainDecisions = $allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decide(\Traversable $results): bool
|
||||
{
|
||||
foreach ($results as $result) {
|
||||
if (VoterInterface::ACCESS_GRANTED === $result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (VoterInterface::ACCESS_DENIED === $result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'priority';
|
||||
}
|
||||
}
|
62
vendor/symfony/security-core/Authorization/Strategy/UnanimousStrategy.php
vendored
Normal file
62
vendor/symfony/security-core/Authorization/Strategy/UnanimousStrategy.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Strategy;
|
||||
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Grants access if only grant (or abstain) votes were received.
|
||||
*
|
||||
* If all voters abstained from voting, the decision will be based on the
|
||||
* allowIfAllAbstainDecisions property value (defaults to false).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Alexander M. Turek <me@derrabus.de>
|
||||
*/
|
||||
final class UnanimousStrategy implements AccessDecisionStrategyInterface, \Stringable
|
||||
{
|
||||
private $allowIfAllAbstainDecisions;
|
||||
|
||||
public function __construct(bool $allowIfAllAbstainDecisions = false)
|
||||
{
|
||||
$this->allowIfAllAbstainDecisions = $allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decide(\Traversable $results): bool
|
||||
{
|
||||
$grant = 0;
|
||||
foreach ($results as $result) {
|
||||
if (VoterInterface::ACCESS_DENIED === $result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VoterInterface::ACCESS_GRANTED === $result) {
|
||||
++$grant;
|
||||
}
|
||||
}
|
||||
|
||||
// no deny votes
|
||||
if ($grant > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->allowIfAllAbstainDecisions;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'unanimous';
|
||||
}
|
||||
}
|
117
vendor/symfony/security-core/Authorization/TraceableAccessDecisionManager.php
vendored
Normal file
117
vendor/symfony/security-core/Authorization/TraceableAccessDecisionManager.php
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* Decorates the original AccessDecisionManager class to log information
|
||||
* about the security voters and the decisions made by them.
|
||||
*
|
||||
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TraceableAccessDecisionManager implements AccessDecisionManagerInterface
|
||||
{
|
||||
private $manager;
|
||||
private $strategy;
|
||||
/** @var iterable<mixed, VoterInterface> */
|
||||
private $voters = [];
|
||||
private $decisionLog = []; // All decision logs
|
||||
private $currentLog = []; // Logs being filled in
|
||||
|
||||
public function __construct(AccessDecisionManagerInterface $manager)
|
||||
{
|
||||
$this->manager = $manager;
|
||||
|
||||
if ($this->manager instanceof AccessDecisionManager) {
|
||||
// The strategy and voters are stored in a private properties of the decorated service
|
||||
$reflection = new \ReflectionProperty(AccessDecisionManager::class, 'strategy');
|
||||
$reflection->setAccessible(true);
|
||||
$this->strategy = $reflection->getValue($manager);
|
||||
$reflection = new \ReflectionProperty(AccessDecisionManager::class, 'voters');
|
||||
$reflection->setAccessible(true);
|
||||
$this->voters = $reflection->getValue($manager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param bool $allowMultipleAttributes Whether to allow passing multiple values to the $attributes array
|
||||
*/
|
||||
public function decide(TokenInterface $token, array $attributes, $object = null/*, bool $allowMultipleAttributes = false*/): bool
|
||||
{
|
||||
$currentDecisionLog = [
|
||||
'attributes' => $attributes,
|
||||
'object' => $object,
|
||||
'voterDetails' => [],
|
||||
];
|
||||
|
||||
$this->currentLog[] = &$currentDecisionLog;
|
||||
|
||||
$result = $this->manager->decide($token, $attributes, $object, 3 < \func_num_args() && func_get_arg(3));
|
||||
|
||||
$currentDecisionLog['result'] = $result;
|
||||
|
||||
$this->decisionLog[] = array_pop($this->currentLog); // Using a stack since decide can be called by voters
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds voter vote and class to the voter details.
|
||||
*
|
||||
* @param array $attributes attributes used for the vote
|
||||
* @param int $vote vote of the voter
|
||||
*/
|
||||
public function addVoterVote(VoterInterface $voter, array $attributes, int $vote)
|
||||
{
|
||||
$currentLogIndex = \count($this->currentLog) - 1;
|
||||
$this->currentLog[$currentLogIndex]['voterDetails'][] = [
|
||||
'voter' => $voter,
|
||||
'attributes' => $attributes,
|
||||
'vote' => $vote,
|
||||
];
|
||||
}
|
||||
|
||||
public function getStrategy(): string
|
||||
{
|
||||
if (null === $this->strategy) {
|
||||
return '-';
|
||||
}
|
||||
if (method_exists($this->strategy, '__toString')) {
|
||||
return (string) $this->strategy;
|
||||
}
|
||||
|
||||
return get_debug_type($this->strategy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<mixed, VoterInterface>
|
||||
*/
|
||||
public function getVoters(): iterable
|
||||
{
|
||||
return $this->voters;
|
||||
}
|
||||
|
||||
public function getDecisionLog(): array
|
||||
{
|
||||
return $this->decisionLog;
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists(DebugAccessDecisionManager::class, false)) {
|
||||
class_alias(TraceableAccessDecisionManager::class, DebugAccessDecisionManager::class);
|
||||
}
|
138
vendor/symfony/security-core/Authorization/Voter/AuthenticatedVoter.php
vendored
Normal file
138
vendor/symfony/security-core/Authorization/Voter/AuthenticatedVoter.php
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* AuthenticatedVoter votes if an attribute like IS_AUTHENTICATED_FULLY,
|
||||
* IS_AUTHENTICATED_REMEMBERED, IS_AUTHENTICATED is present.
|
||||
*
|
||||
* This list is most restrictive to least restrictive checking.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AuthenticatedVoter implements CacheableVoterInterface
|
||||
{
|
||||
public const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY';
|
||||
public const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED';
|
||||
/**
|
||||
* @deprecated since Symfony 5.4
|
||||
*/
|
||||
public const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY';
|
||||
/**
|
||||
* @deprecated since Symfony 5.4
|
||||
*/
|
||||
public const IS_ANONYMOUS = 'IS_ANONYMOUS';
|
||||
public const IS_AUTHENTICATED = 'IS_AUTHENTICATED';
|
||||
public const IS_IMPERSONATOR = 'IS_IMPERSONATOR';
|
||||
public const IS_REMEMBERED = 'IS_REMEMBERED';
|
||||
public const PUBLIC_ACCESS = 'PUBLIC_ACCESS';
|
||||
|
||||
private $authenticationTrustResolver;
|
||||
|
||||
public function __construct(AuthenticationTrustResolverInterface $authenticationTrustResolver)
|
||||
{
|
||||
$this->authenticationTrustResolver = $authenticationTrustResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function vote(TokenInterface $token, $subject, array $attributes)
|
||||
{
|
||||
if ($attributes === [self::PUBLIC_ACCESS]) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
foreach ($attributes as $attribute) {
|
||||
if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute
|
||||
&& self::IS_AUTHENTICATED_REMEMBERED !== $attribute
|
||||
&& self::IS_AUTHENTICATED_ANONYMOUSLY !== $attribute
|
||||
&& self::IS_AUTHENTICATED !== $attribute
|
||||
&& self::IS_ANONYMOUS !== $attribute
|
||||
&& self::IS_IMPERSONATOR !== $attribute
|
||||
&& self::IS_REMEMBERED !== $attribute)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
|
||||
if (self::IS_AUTHENTICATED_FULLY === $attribute
|
||||
&& $this->authenticationTrustResolver->isFullFledged($token)) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (self::IS_AUTHENTICATED_REMEMBERED === $attribute
|
||||
&& ($this->authenticationTrustResolver->isRememberMe($token)
|
||||
|| $this->authenticationTrustResolver->isFullFledged($token))) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute
|
||||
&& ($this->authenticationTrustResolver->isAnonymous($token)
|
||||
|| $this->authenticationTrustResolver->isRememberMe($token)
|
||||
|| $this->authenticationTrustResolver->isFullFledged($token))) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'The "IS_AUTHENTICATED_ANONYMOUSLY" security attribute is deprecated, use "PUBLIC_ACCESS" for public resources, otherwise use "IS_AUTHENTICATED" or "IS_AUTHENTICATED_FULLY" instead if you want to check if the request is (fully) authenticated.');
|
||||
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
// @deprecated $this->authenticationTrustResolver must implement isAuthenticated() in 6.0
|
||||
if (self::IS_AUTHENTICATED === $attribute
|
||||
&& (method_exists($this->authenticationTrustResolver, 'isAuthenticated')
|
||||
? $this->authenticationTrustResolver->isAuthenticated($token)
|
||||
: ($token && $token->getUser()))) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (self::IS_REMEMBERED === $attribute && $this->authenticationTrustResolver->isRememberMe($token)) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (self::IS_ANONYMOUS === $attribute && $this->authenticationTrustResolver->isAnonymous($token)) {
|
||||
trigger_deprecation('symfony/security-core', '5.4', 'The "IS_ANONYMOUSLY" security attribute is deprecated, anonymous no longer exists in version 6.');
|
||||
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
|
||||
if (self::IS_IMPERSONATOR === $attribute && $token instanceof SwitchUserToken) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsAttribute(string $attribute): bool
|
||||
{
|
||||
return \in_array($attribute, [
|
||||
self::IS_AUTHENTICATED_FULLY,
|
||||
self::IS_AUTHENTICATED_REMEMBERED,
|
||||
self::IS_AUTHENTICATED_ANONYMOUSLY,
|
||||
self::IS_AUTHENTICATED,
|
||||
self::IS_ANONYMOUS,
|
||||
self::IS_IMPERSONATOR,
|
||||
self::IS_REMEMBERED,
|
||||
self::PUBLIC_ACCESS,
|
||||
], true);
|
||||
}
|
||||
|
||||
public function supportsType(string $subjectType): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
30
vendor/symfony/security-core/Authorization/Voter/CacheableVoterInterface.php
vendored
Normal file
30
vendor/symfony/security-core/Authorization/Voter/CacheableVoterInterface.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
/**
|
||||
* Let voters expose the attributes and types they care about.
|
||||
*
|
||||
* By returning false to either `supportsAttribute` or `supportsType`, the
|
||||
* voter will never be called for the specified attribute or subject.
|
||||
*
|
||||
* @author Jérémy Derussé <jeremy@derusse.com>
|
||||
*/
|
||||
interface CacheableVoterInterface extends VoterInterface
|
||||
{
|
||||
public function supportsAttribute(string $attribute): bool;
|
||||
|
||||
/**
|
||||
* @param string $subjectType The type of the subject inferred by `get_class` or `get_debug_type`
|
||||
*/
|
||||
public function supportsType(string $subjectType): bool;
|
||||
}
|
104
vendor/symfony/security-core/Authorization/Voter/ExpressionVoter.php
vendored
Normal file
104
vendor/symfony/security-core/Authorization/Voter/ExpressionVoter.php
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
|
||||
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
||||
|
||||
/**
|
||||
* ExpressionVoter votes based on the evaluation of an expression.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExpressionVoter implements CacheableVoterInterface
|
||||
{
|
||||
private $expressionLanguage;
|
||||
private $trustResolver;
|
||||
private $authChecker;
|
||||
private $roleHierarchy;
|
||||
|
||||
public function __construct(ExpressionLanguage $expressionLanguage, AuthenticationTrustResolverInterface $trustResolver, AuthorizationCheckerInterface $authChecker, RoleHierarchyInterface $roleHierarchy = null)
|
||||
{
|
||||
$this->expressionLanguage = $expressionLanguage;
|
||||
$this->trustResolver = $trustResolver;
|
||||
$this->authChecker = $authChecker;
|
||||
$this->roleHierarchy = $roleHierarchy;
|
||||
}
|
||||
|
||||
public function supportsAttribute(string $attribute): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function supportsType(string $subjectType): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function vote(TokenInterface $token, $subject, array $attributes)
|
||||
{
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
$variables = null;
|
||||
foreach ($attributes as $attribute) {
|
||||
if (!$attribute instanceof Expression) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $variables) {
|
||||
$variables = $this->getVariables($token, $subject);
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
if ($this->expressionLanguage->evaluate($attribute, $variables)) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getVariables(TokenInterface $token, $subject): array
|
||||
{
|
||||
$roleNames = $token->getRoleNames();
|
||||
|
||||
if (null !== $this->roleHierarchy) {
|
||||
$roleNames = $this->roleHierarchy->getReachableRoleNames($roleNames);
|
||||
}
|
||||
|
||||
$variables = [
|
||||
'token' => $token,
|
||||
'user' => $token->getUser(),
|
||||
'object' => $subject,
|
||||
'subject' => $subject,
|
||||
'role_names' => $roleNames,
|
||||
'trust_resolver' => $this->trustResolver,
|
||||
'auth_checker' => $this->authChecker,
|
||||
];
|
||||
|
||||
// this is mainly to propose a better experience when the expression is used
|
||||
// in an access control rule, as the developer does not know that it's going
|
||||
// to be handled by this voter
|
||||
if ($subject instanceof Request) {
|
||||
$variables['request'] = $subject;
|
||||
}
|
||||
|
||||
return $variables;
|
||||
}
|
||||
}
|
41
vendor/symfony/security-core/Authorization/Voter/RoleHierarchyVoter.php
vendored
Normal file
41
vendor/symfony/security-core/Authorization/Voter/RoleHierarchyVoter.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
||||
|
||||
/**
|
||||
* RoleHierarchyVoter uses a RoleHierarchy to determine the roles granted to
|
||||
* the user before voting.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RoleHierarchyVoter extends RoleVoter
|
||||
{
|
||||
private $roleHierarchy;
|
||||
|
||||
public function __construct(RoleHierarchyInterface $roleHierarchy, string $prefix = 'ROLE_')
|
||||
{
|
||||
$this->roleHierarchy = $roleHierarchy;
|
||||
|
||||
parent::__construct($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function extractRoles(TokenInterface $token)
|
||||
{
|
||||
return $this->roleHierarchy->getReachableRoleNames($token->getRoleNames());
|
||||
}
|
||||
}
|
72
vendor/symfony/security-core/Authorization/Voter/RoleVoter.php
vendored
Normal file
72
vendor/symfony/security-core/Authorization/Voter/RoleVoter.php
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* RoleVoter votes if any attribute starts with a given prefix.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RoleVoter implements CacheableVoterInterface
|
||||
{
|
||||
private $prefix;
|
||||
|
||||
public function __construct(string $prefix = 'ROLE_')
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function vote(TokenInterface $token, $subject, array $attributes)
|
||||
{
|
||||
$result = VoterInterface::ACCESS_ABSTAIN;
|
||||
$roles = $this->extractRoles($token);
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if (!\is_string($attribute) || !str_starts_with($attribute, $this->prefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('ROLE_PREVIOUS_ADMIN' === $attribute) {
|
||||
trigger_deprecation('symfony/security-core', '5.1', 'The ROLE_PREVIOUS_ADMIN role is deprecated and will be removed in version 6.0, use the IS_IMPERSONATOR attribute instead.');
|
||||
}
|
||||
|
||||
$result = VoterInterface::ACCESS_DENIED;
|
||||
foreach ($roles as $role) {
|
||||
if ($attribute === $role) {
|
||||
return VoterInterface::ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function supportsAttribute(string $attribute): bool
|
||||
{
|
||||
return str_starts_with($attribute, $this->prefix);
|
||||
}
|
||||
|
||||
public function supportsType(string $subjectType): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function extractRoles(TokenInterface $token)
|
||||
{
|
||||
return $token->getRoleNames();
|
||||
}
|
||||
}
|
59
vendor/symfony/security-core/Authorization/Voter/TraceableVoter.php
vendored
Normal file
59
vendor/symfony/security-core/Authorization/Voter/TraceableVoter.php
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Event\VoteEvent;
|
||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Decorates voter classes to send result events.
|
||||
*
|
||||
* @author Laurent VOULLEMIER <laurent.voullemier@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TraceableVoter implements CacheableVoterInterface
|
||||
{
|
||||
private $voter;
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct(VoterInterface $voter, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->voter = $voter;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
public function vote(TokenInterface $token, $subject, array $attributes): int
|
||||
{
|
||||
$result = $this->voter->vote($token, $subject, $attributes);
|
||||
|
||||
$this->eventDispatcher->dispatch(new VoteEvent($this->voter, $subject, $attributes, $result), 'debug.security.authorization.vote');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getDecoratedVoter(): VoterInterface
|
||||
{
|
||||
return $this->voter;
|
||||
}
|
||||
|
||||
public function supportsAttribute(string $attribute): bool
|
||||
{
|
||||
return !$this->voter instanceof CacheableVoterInterface || $this->voter->supportsAttribute($attribute);
|
||||
}
|
||||
|
||||
public function supportsType(string $subjectType): bool
|
||||
{
|
||||
return !$this->voter instanceof CacheableVoterInterface || $this->voter->supportsType($subjectType);
|
||||
}
|
||||
}
|
101
vendor/symfony/security-core/Authorization/Voter/Voter.php
vendored
Normal file
101
vendor/symfony/security-core/Authorization/Voter/Voter.php
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* Voter is an abstract default implementation of a voter.
|
||||
*
|
||||
* @author Roman Marintšenko <inoryy@gmail.com>
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*/
|
||||
abstract class Voter implements VoterInterface, CacheableVoterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function vote(TokenInterface $token, $subject, array $attributes)
|
||||
{
|
||||
// abstain vote by default in case none of the attributes are supported
|
||||
$vote = self::ACCESS_ABSTAIN;
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
if (!$this->supports($attribute, $subject)) {
|
||||
continue;
|
||||
}
|
||||
} catch (\TypeError $e) {
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (0 === strpos($e->getMessage(), 'Argument 1 passed to')
|
||||
&& false !== strpos($e->getMessage(), '::supports() must be of the type string')) {
|
||||
continue;
|
||||
}
|
||||
} elseif (false !== strpos($e->getMessage(), 'supports(): Argument #1')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// as soon as at least one attribute is supported, default is to deny access
|
||||
$vote = self::ACCESS_DENIED;
|
||||
|
||||
if ($this->voteOnAttribute($attribute, $subject, $token)) {
|
||||
// grant access as soon as at least one attribute returns a positive response
|
||||
return self::ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return $vote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return false if your voter doesn't support the given attribute. Symfony will cache
|
||||
* that decision and won't call your voter again for that attribute.
|
||||
*/
|
||||
public function supportsAttribute(string $attribute): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return false if your voter doesn't support the given subject type. Symfony will cache
|
||||
* that decision and won't call your voter again for that subject type.
|
||||
*
|
||||
* @param string $subjectType The type of the subject inferred by `get_class()` or `get_debug_type()`
|
||||
*/
|
||||
public function supportsType(string $subjectType): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the attribute and subject are supported by this voter.
|
||||
*
|
||||
* @param string $attribute An attribute
|
||||
* @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function supports(string $attribute, $subject);
|
||||
|
||||
/**
|
||||
* Perform a single access check operation on a given attribute, subject and token.
|
||||
* It is safe to assume that $attribute and $subject already passed the "supports()" method check.
|
||||
*
|
||||
* @param mixed $subject
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token);
|
||||
}
|
39
vendor/symfony/security-core/Authorization/Voter/VoterInterface.php
vendored
Normal file
39
vendor/symfony/security-core/Authorization/Voter/VoterInterface.php
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Security\Core\Authorization\Voter;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* VoterInterface is the interface implemented by all voters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface VoterInterface
|
||||
{
|
||||
public const ACCESS_GRANTED = 1;
|
||||
public const ACCESS_ABSTAIN = 0;
|
||||
public const ACCESS_DENIED = -1;
|
||||
|
||||
/**
|
||||
* Returns the vote for the given parameters.
|
||||
*
|
||||
* This method must return one of the following constants:
|
||||
* ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
|
||||
*
|
||||
* @param mixed $subject The subject to secure
|
||||
* @param array $attributes An array of attributes associated with the method being invoked
|
||||
*
|
||||
* @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
|
||||
*/
|
||||
public function vote(TokenInterface $token, $subject, array $attributes);
|
||||
}
|
Reference in New Issue
Block a user