-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Use IteratorArgument for voters #21437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -81,7 +88,7 @@ public function getStrategy() | |||
} | |||
|
|||
/** | |||
* @return array | |||
* @return iterable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically, this is a BC break if the calling code passes it to a function requiring an array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but this class is marked as internal, so the BC break should be ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iterable|VoterInterface[]
for helping IDE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would IDEs support the iterable<VoterInterface>
syntax from PSR-5 ?
What is the benefit of this change ? |
The benefits are :
|
*/ | ||
public function setVoters(array $voters) | ||
{ | ||
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Pass the voters to the constructor instead.', __METHOD__), E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we gain anything by deprecating this method? Does it hurt to keep it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the type of the $voters
argument from array
to iterable
would be a BC break so this would mean having a different argument type for the constructor parameter and this method.
👍 |
@@ -45,7 +46,7 @@ public function process(ContainerBuilder $container) | |||
throw new LogicException('No security voters found. You need to tag at least one with "security.voter"'); | |||
} | |||
|
|||
$adm = $container->getDefinition($container->hasDefinition('debug.security.access.decision_manager') ? 'debug.security.access.decision_manager' : 'security.access.decision_manager'); | |||
$adm->addMethodCall('setVoters', array(array_values($voters))); | |||
$adm = $container->getDefinition('security.access.decision_manager'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this change break the DebugAccessDecisionManager
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated it to grab the voters properties from the AccessDecisionManager
in the same way it is doing it for the strategy : https://github.com/symfony/symfony/pull/21437/files#diff-76aa9de2473eccdc05075961beaed023R42
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But now the debug.security.access.decision_manager
service will not be aware of the available voters, will it (see #18566 for more context)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The voters will be injected into the security.access.decision_manager
service that will then be injected into the debug.security.access.decision_manager
service that will grab the voters so everything should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But then these lines will never be executed: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Authorization/TraceableAccessDecisionManager.php#L62-L70 So getVoters()
would always return an empty list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It tried different solutions to fix this problems but either they break BC in a worse way or introduce a risk that the voters list shown in the profiler is different than the one used by the access decision manager.
Or maybe someone else has solution to fix this problem.
Maybe this would be ok keeping it like this, the only thing broken would be getting an empty voter list in the profiler when using such an implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC we explicitly have this handling because there were issue otherwise when you were, for example, using the JMSSecurityExtraBundle which ships with its own RememberingAccessDecisionManager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the conclusion here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did someone test the changes from this PR in a real project to ensure that the profiler still works as expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My opinion here would be to keep it like this and accept that you lose the list of voters in the profiler in some cases (you already lose the configured strategy in those cases).
The alternatives are IMO not worth it. One of them would be to pass the list of voters to the DebugAccessDecisionManager
independently, but that would introduce the possibility that the list shown in the profiler is not the same as the one used by the AccessDecisionManager
(if someone modify it in another compile pass). And the other possibilities I could think of would either have worst BC breaks or introduce possible differences in behavior between prod and dev environments.
* @param string $strategy The vote strategy | ||
* @param bool $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not | ||
* @param bool $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals | ||
* @param iterable $voters An iterator of VoterInterface instances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a BC break, we should accept iterable|VoterInterface[]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iterable
is equivalent to array|\Traversable
so we still accept arrays as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iterable|VoterInterface[]
would still allow IDEs to provide type hints
I did not look at the exact logic: in |
5a25337
to
58797f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
926a51c
to
a4b574e
Compare
@jvasseur can you please rebase? there are failures related to this PR isn't it? |
Rebased and fix the test failure that was related to the changes in this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changelog/upgrade files should mention this
👍 |
A quick rebase to ensure that tests are all-right would be good as well. |
e012064
to
794a1b7
Compare
@fabpot rebased on current master. Remaining test failures are unrelated to this PR. |
So did someone try this PR in a real project and made sure that this will not break the security profiler? |
I did try it on a real project and everything was working. But since I made some changes to the PR since then I will try to do it again when I have some free time. |
CHANGELOG/UPGRADE-* still need an update. |
ping @jvasseur |
Note added to CHANGELOG/UPGRADE. |
@@ -258,6 +258,8 @@ Security | |||
* The `LogoutUrlGenerator::registerListener()` method will expect a 6th `$context = null` argument in 4.0. | |||
Define the argument when overriding this method. | |||
|
|||
* The `AccessDecisionManager::setVoters()` has been deprecated. Pass the voters to the constructor instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
corresponding entry missing from UPGRADE-4.0.md (the ... has been removed. ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Thank you @jvasseur. |
This PR was merged into the 3.3-dev branch. Discussion ---------- [Security] Use IteratorArgument for voters | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | License | MIT Use an IteratorArgument for injecting voters into the AccessDecisionManager. Commits ------- 4ec80b1 Use IteratorArgument for voters
Use an IteratorArgument for injecting voters into the AccessDecisionManager.