File tree 4 files changed +56
-6
lines changed
4 files changed +56
-6
lines changed Original file line number Diff line number Diff line change 8
8
final class Security extends Attribute
9
9
{
10
10
/**
11
- * @param array<string>|string|null $handlers
11
+ * @param array<string>|string|null $handlers
12
+ * @param array<string>|null $roles
12
13
* @param class-string<\RuntimeException> $exception
13
14
*/
14
15
public function __construct (
15
- public readonly ?string $ expression = null ,
16
+ public readonly ?string $ expression = null ,
16
17
public array |string |null $ handlers = null ,
17
- public ?string $ message = null ,
18
- public ?string $ exception = null ,
18
+ public ?string $ message = null ,
19
+ public ?string $ exception = null ,
20
+ public ?array $ roles = null ,
19
21
) {
20
22
parent ::__construct ();
21
23
$ this ->setHandlers ($ handlers );
Original file line number Diff line number Diff line change @@ -51,10 +51,25 @@ public function prefix(Instance $instance): Response
51
51
return new Response ();
52
52
}
53
53
54
+ $ rolesExpressions = null ;
55
+ if ($ attribute ->roles !== null ) {
56
+ if ($ attribute ->expression !== null ) {
57
+ throw new \RuntimeException ('You cannot use both roles and expression in the Security attribute. ' );
58
+ }
59
+ $ rolesExpressions = array_map (
60
+ static fn (string $ role ) => "is_granted(' {$ role }') " ,
61
+ $ attribute ->roles
62
+ );
63
+ }
64
+
54
65
$ expression = $ attribute ->expression ;
55
66
if ($ expression === null ) {
56
- $ role = $ this ->guessRoleName ($ instance );
57
- $ expression = "is_granted(' {$ role }') " ;
67
+ if ($ rolesExpressions !== null ) {
68
+ $ expression = implode (' or ' , $ rolesExpressions );
69
+ } else {
70
+ $ role = $ this ->guessRoleName ($ instance );
71
+ $ expression = "is_granted(' {$ role }') " ;
72
+ }
58
73
}
59
74
$ handlers = $ this ->getHandlers (SecurityHandler::class, $ attribute );
60
75
foreach ($ handlers as $ handler ) {
Original file line number Diff line number Diff line change @@ -61,4 +61,19 @@ public function accessDeniedWithMessage(): void
61
61
public function accessDeniedWithException (): void
62
62
{
63
63
}
64
+
65
+ #[Security(roles: ['ROLE_1 ' ])]
66
+ public function rolesParamOne (): void
67
+ {
68
+ }
69
+
70
+ #[Security(roles: ['ROLE_3 ' , 'ROLE_1 ' ])]
71
+ public function rolesParamMultiple (): void
72
+ {
73
+ }
74
+
75
+ #[Security("is_granted('ROLE_1') " , roles: ['ROLE_1 ' , 'ROLE_2 ' ])]
76
+ public function conflict (): void
77
+ {
78
+ }
64
79
}
Original file line number Diff line number Diff line change @@ -111,4 +111,22 @@ public function testAccessDeniedWithException(): void
111
111
$ this ->expectExceptionMessage ('Invalid argument. ' );
112
112
$ this ->proxy ->accessDeniedWithException ();
113
113
}
114
+
115
+ public function testWithRolesParamOne (): void
116
+ {
117
+ $ this ->proxy ->rolesParamOne ();
118
+ $ this ->assertSame (['ROLE_1 ' ], $ this ->handler ->attributes );
119
+ }
120
+
121
+ public function testWithRolesParamMultiple (): void
122
+ {
123
+ $ this ->proxy ->rolesParamMultiple ();
124
+ $ this ->assertSame (['ROLE_3 ' , 'ROLE_1 ' ], $ this ->handler ->attributes );
125
+ }
126
+
127
+ public function testWithRolesAndExpressionShouldThrow (): void
128
+ {
129
+ $ this ->expectException (\RuntimeException::class);
130
+ $ this ->proxy ->conflict ();
131
+ }
114
132
}
You can’t perform that action at this time.
0 commit comments