11
11
12
12
namespace Symfony \Component \Security \Core \Authorization ;
13
13
14
+ use Symfony \Component \Security \Core \Authorization \Strategy \AffirmativeVoteStrategy ;
15
+ use Symfony \Component \Security \Core \Authorization \Strategy \ConsensusVoteStrategy ;
16
+ use Symfony \Component \Security \Core \Authorization \Strategy \UnanimousVoteStrategy ;
17
+ use Symfony \Component \Security \Core \Authorization \Strategy \VoteStrategyInterface ;
14
18
use Symfony \Component \Security \Core \Authorization \Voter \VoterInterface ;
15
19
use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
16
20
@@ -28,30 +32,34 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
28
32
29
33
private $ voters ;
30
34
private $ strategy ;
31
- private $ allowIfAllAbstainDecisions ;
32
- private $ allowIfEqualGrantedDeniedDecisions ;
35
+ private $ voteStrategy ;
33
36
34
37
/**
35
38
* Constructor.
36
39
*
37
- * @param VoterInterface[] $voters An array of VoterInterface instances
38
- * @param string $strategy The vote strategy
39
- * @param bool $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not
40
- * @param bool $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals
40
+ * @param VoterInterface[] $voters An array of VoterInterface instances
41
+ * @param string|VoteStrategyInterface $strategy The vote strategy
42
+ * @param bool $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not
43
+ * @param bool $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals
41
44
*
42
45
* @throws \InvalidArgumentException
43
46
*/
44
47
public function __construct (array $ voters = array (), $ strategy = self ::STRATEGY_AFFIRMATIVE , $ allowIfAllAbstainDecisions = false , $ allowIfEqualGrantedDeniedDecisions = true )
45
48
{
46
- $ strategyMethod = 'decide ' .ucfirst ($ strategy );
47
- if (!is_callable (array ($ this , $ strategyMethod ))) {
48
- throw new \InvalidArgumentException (sprintf ('The strategy "%s" is not supported. ' , $ strategy ));
49
- }
50
-
51
49
$ this ->voters = $ voters ;
52
- $ this ->strategy = $ strategyMethod ;
53
- $ this ->allowIfAllAbstainDecisions = (bool ) $ allowIfAllAbstainDecisions ;
54
- $ this ->allowIfEqualGrantedDeniedDecisions = (bool ) $ allowIfEqualGrantedDeniedDecisions ;
50
+ $ this ->strategy = $ strategy ;
51
+
52
+ if ($ strategy instanceof VoteStrategyInterface) {
53
+ $ this ->voteStrategy = $ strategy ;
54
+ } elseif (self ::STRATEGY_AFFIRMATIVE === $ strategy ) {
55
+ $ this ->voteStrategy = new AffirmativeVoteStrategy ($ allowIfAllAbstainDecisions );
56
+ } elseif (self ::STRATEGY_CONSENSUS === $ strategy ) {
57
+ $ this ->voteStrategy = new ConsensusVoteStrategy ($ allowIfAllAbstainDecisions , $ allowIfEqualGrantedDeniedDecisions );
58
+ } elseif (self ::STRATEGY_UNANIMOUS === $ strategy ) {
59
+ $ this ->voteStrategy = new UnanimousVoteStrategy ($ allowIfAllAbstainDecisions );
60
+ } else {
61
+ throw new \InvalidArgumentException ('The vote strategy must be one of "affirmative", "consensus", "unanimous", or an instance of Symfony\Component\Security\Core\Authorization\Strategy\VoteStrategyInterface. ' );
62
+ }
55
63
}
56
64
57
65
/**
@@ -69,123 +77,6 @@ public function setVoters(array $voters)
69
77
*/
70
78
public function decide (TokenInterface $ token , array $ attributes , $ object = null )
71
79
{
72
- return $ this ->{$ this ->strategy }($ token , $ attributes , $ object );
73
- }
74
-
75
- /**
76
- * Grants access if any voter returns an affirmative response.
77
- *
78
- * If all voters abstained from voting, the decision will be based on the
79
- * allowIfAllAbstainDecisions property value (defaults to false).
80
- */
81
- private function decideAffirmative (TokenInterface $ token , array $ attributes , $ object = null )
82
- {
83
- $ deny = 0 ;
84
- foreach ($ this ->voters as $ voter ) {
85
- $ result = $ voter ->vote ($ token , $ object , $ attributes );
86
- switch ($ result ) {
87
- case VoterInterface::ACCESS_GRANTED :
88
- return true ;
89
-
90
- case VoterInterface::ACCESS_DENIED :
91
- ++$ deny ;
92
-
93
- break ;
94
-
95
- default :
96
- break ;
97
- }
98
- }
99
-
100
- if ($ deny > 0 ) {
101
- return false ;
102
- }
103
-
104
- return $ this ->allowIfAllAbstainDecisions ;
105
- }
106
-
107
- /**
108
- * Grants access if there is consensus of granted against denied responses.
109
- *
110
- * Consensus means majority-rule (ignoring abstains) rather than unanimous
111
- * agreement (ignoring abstains). If you require unanimity, see
112
- * UnanimousBased.
113
- *
114
- * If there were an equal number of grant and deny votes, the decision will
115
- * be based on the allowIfEqualGrantedDeniedDecisions property value
116
- * (defaults to true).
117
- *
118
- * If all voters abstained from voting, the decision will be based on the
119
- * allowIfAllAbstainDecisions property value (defaults to false).
120
- */
121
- private function decideConsensus (TokenInterface $ token , array $ attributes , $ object = null )
122
- {
123
- $ grant = 0 ;
124
- $ deny = 0 ;
125
- foreach ($ this ->voters as $ voter ) {
126
- $ result = $ voter ->vote ($ token , $ object , $ attributes );
127
-
128
- switch ($ result ) {
129
- case VoterInterface::ACCESS_GRANTED :
130
- ++$ grant ;
131
-
132
- break ;
133
-
134
- case VoterInterface::ACCESS_DENIED :
135
- ++$ deny ;
136
-
137
- break ;
138
- }
139
- }
140
-
141
- if ($ grant > $ deny ) {
142
- return true ;
143
- }
144
-
145
- if ($ deny > $ grant ) {
146
- return false ;
147
- }
148
-
149
- if ($ grant > 0 ) {
150
- return $ this ->allowIfEqualGrantedDeniedDecisions ;
151
- }
152
-
153
- return $ this ->allowIfAllAbstainDecisions ;
154
- }
155
-
156
- /**
157
- * Grants access if only grant (or abstain) votes were received.
158
- *
159
- * If all voters abstained from voting, the decision will be based on the
160
- * allowIfAllAbstainDecisions property value (defaults to false).
161
- */
162
- private function decideUnanimous (TokenInterface $ token , array $ attributes , $ object = null )
163
- {
164
- $ grant = 0 ;
165
- foreach ($ attributes as $ attribute ) {
166
- foreach ($ this ->voters as $ voter ) {
167
- $ result = $ voter ->vote ($ token , $ object , array ($ attribute ));
168
-
169
- switch ($ result ) {
170
- case VoterInterface::ACCESS_GRANTED :
171
- ++$ grant ;
172
-
173
- break ;
174
-
175
- case VoterInterface::ACCESS_DENIED :
176
- return false ;
177
-
178
- default :
179
- break ;
180
- }
181
- }
182
- }
183
-
184
- // no deny votes
185
- if ($ grant > 0 ) {
186
- return true ;
187
- }
188
-
189
- return $ this ->allowIfAllAbstainDecisions ;
80
+ return $ this ->voteStrategy ->decide ($ this ->voters , $ token , $ attributes , $ object );
190
81
}
191
82
}
0 commit comments