1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the API Platform project. |
5
|
|
|
* |
6
|
|
|
* (c) Kévin Dunglas <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
declare(strict_types=1); |
13
|
|
|
|
14
|
|
|
namespace ApiPlatform\Core\Security; |
15
|
|
|
|
16
|
|
|
use ApiPlatform\Core\Util\ClassInfoTrait; |
17
|
|
|
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; |
18
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; |
19
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
20
|
|
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; |
21
|
|
|
use Symfony\Component\Security\Core\Role\Role; |
22
|
|
|
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Checks if the logged user has sufficient permissions to access the given resource. |
26
|
|
|
* |
27
|
|
|
* @author Kévin Dunglas <[email protected]> |
28
|
|
|
*/ |
29
|
|
|
final class ResourceAccessChecker implements ResourceAccessCheckerInterface |
30
|
|
|
{ |
31
|
|
|
use ClassInfoTrait; |
32
|
|
|
|
33
|
|
|
private $expressionLanguage; |
34
|
|
|
private $authenticationTrustResolver; |
35
|
|
|
private $roleHierarchy; |
36
|
|
|
private $tokenStorage; |
37
|
|
|
private $authorizationChecker; |
38
|
|
|
|
39
|
|
|
public function __construct(ExpressionLanguage $expressionLanguage = null, AuthenticationTrustResolverInterface $authenticationTrustResolver = null, RoleHierarchyInterface $roleHierarchy = null, TokenStorageInterface $tokenStorage = null, AuthorizationCheckerInterface $authorizationChecker = null) |
40
|
|
|
{ |
41
|
|
|
$this->expressionLanguage = $expressionLanguage; |
42
|
|
|
$this->authenticationTrustResolver = $authenticationTrustResolver; |
43
|
|
|
$this->roleHierarchy = $roleHierarchy; |
44
|
|
|
$this->tokenStorage = $tokenStorage; |
45
|
|
|
$this->authorizationChecker = $authorizationChecker; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
public function isGranted(string $resourceClass, string $expression, array $extraVariables = []): bool |
49
|
|
|
{ |
50
|
|
|
if (null === $this->tokenStorage || null === $this->authenticationTrustResolver) { |
51
|
|
|
throw new \LogicException('The "symfony/security" library must be installed to use the "access_control" attribute.'); |
52
|
|
|
} |
53
|
|
|
if (null === $token = $this->tokenStorage->getToken()) { |
54
|
|
|
throw new \LogicException('The current token must be set to use the "access_control" attribute (is the URL behind a firewall?).'); |
55
|
|
|
} |
56
|
|
|
if (null === $this->expressionLanguage) { |
57
|
|
|
throw new \LogicException('The "symfony/expression-language" library must be installed to use the "access_control".'); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
return (bool) $this->expressionLanguage->evaluate($expression, array_merge($extraVariables, $this->getVariables($token))); |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @copyright Fabien Potencier <[email protected]> |
65
|
|
|
* |
66
|
|
|
* @see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php |
67
|
|
|
*/ |
68
|
|
|
private function getVariables(TokenInterface $token): array |
69
|
|
|
{ |
70
|
|
|
return [ |
71
|
|
|
'token' => $token, |
72
|
|
|
'user' => $token->getUser(), |
73
|
|
|
'roles' => $this->getEffectiveRoles($token), |
74
|
|
|
'trust_resolver' => $this->authenticationTrustResolver, |
75
|
|
|
// needed for the is_granted expression function |
76
|
|
|
'auth_checker' => $this->authorizationChecker, |
77
|
|
|
]; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @return string[] |
82
|
|
|
*/ |
83
|
|
|
private function getEffectiveRoles(TokenInterface $token): array |
84
|
|
|
{ |
85
|
|
|
if (null === $this->roleHierarchy) { |
86
|
|
|
return method_exists($token, 'getRoleNames') ? $token->getRoleNames() : array_map('strval', $token->getRoles()); |
|
|
|
|
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
if (method_exists($this->roleHierarchy, 'getReachableRoleNames')) { |
90
|
|
|
return $this->roleHierarchy->getReachableRoleNames($token->getRoleNames()); |
|
|
|
|
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
return array_map(function (Role $role): string { |
94
|
|
|
return $role->getRole(); |
95
|
|
|
}, $this->roleHierarchy->getReachableRoles($token->getRoles())); |
|
|
|
|
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.