Skip to content

Commit 7212e07

Browse files
committed
Refactor access control system to use token-based requester.
Replaced reliance on `TokenStorageInterface` with requester tokens directly passed via `AccessRequest` objects. Introduced `MetadataBag` for improved metadata handling and marked several classes as `final`. Updated tests and strategies accordingly to simplify the architecture and enhance maintainability.
1 parent 8a5587d commit 7212e07

19 files changed

+119
-99
lines changed

src/Symfony/Component/AccessControl/AccessControlManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
* @experimental
1414
*/
15-
class AccessControlManager implements AccessControlManagerInterface
15+
final class AccessControlManager implements AccessControlManagerInterface
1616
{
1717
private readonly string $defaultStrategy;
1818

src/Symfony/Component/AccessControl/AccessRequest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,18 @@
44

55
use Symfony\Component\ExpressionLanguage\Expression;
66
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
7+
use Symfony\Component\Security\Core\User\UserInterface;
78

89
/**
910
* @experimental
1011
*/
1112
readonly class AccessRequest
1213
{
13-
/**
14-
* @param array<array-key, mixed> $metadata
15-
*/
1614
public function __construct(
15+
public null|TokenInterface $requester,
1716
public mixed $attribute,
1817
public mixed $subject = null,
19-
public array $metadata = [],
18+
public MetadataBag $metadata = new MetadataBag(),
2019
public bool $allowIfAllAbstainOrTie = false,
2120
) {
2221
}

src/Symfony/Component/AccessControl/Attribute/AccessPolicy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
readonly class AccessPolicy
1919
{
2020
/**
21-
* @param array<array-key, mixed> $
21+
* @param array<array-key, mixed> $metadata
2222
*/
2323
public function __construct(
2424
public mixed $attribute,

src/Symfony/Component/AccessControl/Attribute/All.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @experimental
1616
*/
1717
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION)]
18-
readonly class All
18+
final readonly class All
1919
{
2020
/**
2121
* @param list<AccessPolicy> $accessPolicies

src/Symfony/Component/AccessControl/Attribute/AtLeastOneOf.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @experimental
1616
*/
1717
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION)]
18-
readonly class AtLeastOneOf
18+
final readonly class AtLeastOneOf
1919
{
2020
/**
2121
* @param list<AccessPolicy> $accessPolicies

src/Symfony/Component/AccessControl/Exception/InvalidStrategyException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* @experimental
77
*/
8-
class InvalidStrategyException extends \RuntimeException
8+
final class InvalidStrategyException extends \RuntimeException
99
{
1010

1111
}

src/Symfony/Component/AccessControl/Listener/AccessPolicyListener.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
use Symfony\Component\AccessControl\AccessControlManager;
77
use Symfony\Component\AccessControl\Attribute\AccessPolicy;
88
use Symfony\Component\AccessControl\DecisionVote;
9+
use Symfony\Component\AccessControl\MetadataBag;
910
use Symfony\Component\Console\ConsoleEvents;
1011
use Symfony\Component\Console\Event\ConsoleCommandEvent;
1112
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1213
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
1314
use Symfony\Component\HttpKernel\Exception\HttpException;
1415
use Symfony\Component\HttpKernel\KernelEvents;
16+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1517
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
1618

1719
/**
@@ -20,6 +22,7 @@
2022
final readonly class AccessPolicyListener implements EventSubscriberInterface
2123
{
2224
public function __construct(
25+
private TokenStorageInterface $tokenStorage,
2326
private AccessControlManager $accessControlManager,
2427
) {
2528
}
@@ -73,12 +76,13 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo
7376
private function processAttribute(AccessPolicy $attribute, array $metadata): void
7477
{
7578
$accessRequest = new AccessRequest(
79+
$this->tokenStorage->getToken(),
7680
$attribute->attribute,
7781
$attribute->subject,
78-
[
82+
new MetadataBag([
7983
...$attribute->metadata,
8084
...$metadata,
81-
],
85+
]),
8286
$attribute->allowIfAllAbstain
8387
);
8488
$accessDecision = $this->accessControlManager->decide($accessRequest, $attribute->strategy);

src/Symfony/Component/AccessControl/Listener/AllListener.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
use Symfony\Component\AccessControl\AccessControlManager;
77
use Symfony\Component\AccessControl\Attribute\All;
88
use Symfony\Component\AccessControl\DecisionVote;
9+
use Symfony\Component\AccessControl\MetadataBag;
910
use Symfony\Component\Console\ConsoleEvents;
1011
use Symfony\Component\Console\Event\ConsoleCommandEvent;
1112
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1213
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
1314
use Symfony\Component\HttpKernel\Exception\HttpException;
1415
use Symfony\Component\HttpKernel\KernelEvents;
16+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1517
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
1618

1719
/**
@@ -20,6 +22,7 @@
2022
final readonly class AllListener implements EventSubscriberInterface
2123
{
2224
public function __construct(
25+
private TokenStorageInterface $tokenStorage,
2326
private AccessControlManager $accessControlManager,
2427
) {
2528
}
@@ -74,12 +77,13 @@ private function processAttribute(All $attribute, array $metadata): void
7477
{
7578
foreach ($attribute->accessPolicies as $accessPolicy) {
7679
$accessRequest = new AccessRequest(
80+
$this->tokenStorage->getToken(),
7781
$accessPolicy->attribute,
7882
$accessPolicy->subject,
79-
[
83+
new MetadataBag([
8084
...$accessPolicy->metadata,
8185
...$metadata,
82-
],
86+
]),
8387
$accessPolicy->allowIfAllAbstain
8488
);
8589
$accessDecision = $this->accessControlManager->decide($accessRequest, $accessPolicy->strategy);

src/Symfony/Component/AccessControl/Listener/AtLeastOneOfListener.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
use Symfony\Component\AccessControl\AccessControlManager;
77
use Symfony\Component\AccessControl\Attribute\All;
88
use Symfony\Component\AccessControl\DecisionVote;
9+
use Symfony\Component\AccessControl\MetadataBag;
910
use Symfony\Component\Console\ConsoleEvents;
1011
use Symfony\Component\Console\Event\ConsoleCommandEvent;
1112
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1213
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
1314
use Symfony\Component\HttpKernel\Exception\HttpException;
1415
use Symfony\Component\HttpKernel\KernelEvents;
16+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1517
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
1618

1719
/**
@@ -20,6 +22,7 @@
2022
final readonly class AtLeastOneOfListener implements EventSubscriberInterface
2123
{
2224
public function __construct(
25+
private TokenStorageInterface $tokenStorage,
2326
private AccessControlManager $accessControlManager,
2427
) {
2528
}
@@ -74,12 +77,13 @@ private function processAttribute(All $attribute, array $metadata): void
7477
{
7578
foreach ($attribute->accessPolicies as $accessPolicy) {
7679
$accessRequest = new AccessRequest(
80+
$this->tokenStorage->getToken(),
7781
$accessPolicy->attribute,
7882
$accessPolicy->subject,
79-
[
83+
new MetadataBag([
8084
...$accessPolicy->metadata,
8185
...$metadata,
82-
],
86+
]),
8387
$accessPolicy->allowIfAllAbstain
8488
);
8589
$accessDecision = $this->accessControlManager->decide($accessRequest, $accessPolicy->strategy);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Symfony\Component\AccessControl;
4+
5+
/**
6+
* @experimental
7+
*/
8+
final readonly class MetadataBag implements \IteratorAggregate, \Countable
9+
{
10+
/**
11+
* @param array<string, mixed> $parameters
12+
*/
13+
public function __construct(
14+
private array $parameters = [],
15+
) {
16+
}
17+
18+
/**
19+
* Returns the parameter keys.
20+
*/
21+
public function keys(): array
22+
{
23+
return array_keys($this->parameters);
24+
}
25+
26+
public function get(string $key, mixed $default = null): mixed
27+
{
28+
return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
29+
}
30+
31+
/**
32+
* Returns true if the parameter is defined.
33+
*/
34+
public function has(string $key): bool
35+
{
36+
return \array_key_exists($key, $this->parameters);
37+
}
38+
39+
/**
40+
* Returns an iterator for parameters.
41+
*
42+
* @return \ArrayIterator<string, mixed>
43+
*/
44+
public function getIterator(): \ArrayIterator
45+
{
46+
return new \ArrayIterator($this->parameters);
47+
}
48+
49+
/**
50+
* Returns the number of parameters.
51+
*/
52+
public function count(): int
53+
{
54+
return \count($this->parameters);
55+
}
56+
}

0 commit comments

Comments
 (0)