8000 [Security][SecurityBundle] Add messages and score on votes by eltharin · Pull Request #58107 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security][SecurityBundle] Add messages and score on votes #58107

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 8000 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

Closed
wants to merge 12 commits into from

Conversation

eltharin
Copy link
Contributor
@eltharin eltharin commented Aug 27, 2024
Q A
Branch? 7.3
Bug fix? no
New feature? yes
Deprecations? no
Issues Fix #27995, #26343, #35592, #43147
License MIT

This PR continue the work started by @maidmaid and @noniagriconomie in #35592, continued by @yellow1912 in #43147 continued by @alamirault in #46493.

I rebase on 7.2 and remove deprecation as suggested by nicolas-grekas for not causing backward compatiblity breaks.

It allow to have informations about AccessDecisionManager and Voters (And understand why we have an AccessDeniedException with clear infos).
170878112-f93f8d90-97b7-42f8-8494-603d6b2019e2

I add possibility to respond a voter with a score and create a Scoring strategy, looks like consensus but with ponderation.

@eltharin eltharin requested a review from chalasr as a code owner August 27, 2024 17:38
@carsonbot carsonbot added this to the 7.2 milestone Aug 27, 2024
@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from 5a4fbe1 to fc77e53 Compare August 27, 2024 17:49
@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch 8 times, most recently from 6e67169 to 71d7744 Compare August 27, 2024 21:41
@94noni
Copy link
Contributor
94noni commented Aug 28, 2024

@eltharin hi 👋🏻

nice to see that you are willing to take over this amount of work, incremented overtime by different coders and reviewers :)

i am still interested in such feature even though now I rarely use voter, still thinking that this can be a great addition in core (like workflow transition blocker message is available)

to be honest, I think I would probable split this in 2 separates PRs, just to ease review and reduce the friction already existing around such feature, as it needs to arrive on a simple/BC/evolutive/maintainable way in core

  • add the feature of a voter message (main issue feature that seem to have lot of traction over the year regarding all PRs reactions)
  • add the feature of a new decision strategy alone (perhaps even before the voter message)

in any way, I will add a reminder to make a review on this PR as well :)

( PS: @noniagriconomie is one old account of mine no more used since )

@eltharin
Copy link
Contributor Author

@94noni

you and other are the firsts to thank for the start of this work,

For the 2 PR's I thought about it but it's absolutlly linked, both needs Vote Object so getVote function so GetDecision functions,

Remove first or second feature but keep other one will only touch few files compared with all files changed.

At start, i saw your PR's without really needed, but when I wrote myine for scoring, I saw I made the same work as you, so I included your work in these to not have conflict when one will be accepted.

As it's a big update to add all these functions in symfony core I add a new benefit to this to have more chance to see this PR passed :)

@eltharin eltharin requested a review from OskarStark August 29, 2024 07:56
@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from 46b15e0 to e9f63ce Compare August 30, 2024 08:51
@kevinpapst
Copy link

Did anyone ever run performance checks on these changes? Considering that Voters can be called hundreds of times per request, any overhead created by hundreds of new Vote() instances or checks for existing methods should imo be avoided (e.g. add new interfaces so I can opt-in to the new approach, instead of forcing the code upon everyone).

@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from e9f63ce to 278f259 Compare September 9, 2024 06:25
@@ -40,29 +43,38 @@ public function __construct(

public function decide(\Traversable $results): bool
{
return $this->getDecision(new \ArrayIterator(array_map(fn ($vote) => new Vote($vote), iterator_to_array($results))))->isGranted();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps create a trait to avoid copy/past such internal ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of requiring an array of Vote, it might be more convenient to allow an array of Vote|int?
this would make the implementation trivial

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem is for those who have custom classes, if someone made a custom strategy with decide function witch take only booleans, tomorrow we will pass Vote object and booleans IT will fail,
To avoid BC, we are obliged to have two functions,
Same for Voter with vote/getVote

@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from 278f259 to 84f75b9 Compare September 9, 2024 10:29
@eltharin
Copy link
Contributor Author
eltharin commented Sep 10, 2024

Did anyone ever run performance checks on these changes? Considering that Voters can be called hundreds of times per request, any overhead created by hundreds of new Vote() instances or checks for existing methods should imo be avoided (e.g. add new interfaces so I can opt-in to the new approach, instead of forcing the code upon everyone).

I look with Symfony Profiler, with 3000 voters With 7.2 actual version VoteListener take 120MiB in 8ms with this PR, 118MiB for 8.4ms.
I don't made more performance test with a performance tool

@eltharin
Copy link
Contributor Author

friendly ping @chalasr as default reviewer

@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from 2f1bc20 to 8d38717 Compare February 11, 2025 11:08
@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch 2 times, most recently from fe4a1c6 to 793b302 Compare February 11, 2025 11:31
@eltharin eltharin force-pushed the add_messages_and_score_on_votes branch from 793b302 to 17cbdf8 Compare February 11, 2025 11:44
nicolas-grekas

This comment was marked as outdated.

@eltharin

This comment was marked as resolved.

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Feb 12, 2025

I think I nailed it: instead of passing by reference, we can pass pre-constructed objects.
Here is a patch that implements what I mean. (see last commit there for my specific contribution)
Note that I didn't update tests and that I removed the message on the AccessDecision object as I see it of low value.

@nicolas-grekas
Copy link
Member

I removed the message on the AccessDecision object as I see it of low value.

BTW, this makes me realize that the AccessDecision object is never used in the end. We pass it around, we collect votes in it, and we trash it. The profiler doesn't need that object. Maybe we can remove this part?

@eltharin
Copy link
Contributor Author

AccessDecision Object is send to Profiler AND Exception to retreive why this reason with votes.
I kept "int" votes and objects votes in this object to see whitch voter respond in int and whitch respond in object.
And I keep in mind my ScoringStragy need (witch I'll put in PR later or in a personal bundle) but with your solution it can be impossible to do that.
That's what I want with a VoteInterface instead directly Vote that if some more crazier than me (yes it can be possible) want more attributes in a vote It can have it own VoteObject with Own strategy.
I think your last commit lost very much of that

@nicolas-grekas
Copy link
Member

I'm sorry I don't understand your comment. What did my approach lose? The only thing I removed from a feature pov is adding a reason to the access decision itself.

@eltharin
Copy link
Contributor Author
eltharin commented Feb 12, 2025

sorry I miss something in your code...
Don't see you put Vote Object in adm

@eltharin
Copy link
Contributor Author

for allowMultipleAttributes argument, it's not from my PR, I just put it into comments in interface to rember it but It already been there.

@eltharin
Copy link
Contributor Author

And in the strategy we don't have Vote Object ?
Can't we keep accessdecision in second argument of decide and get Vote Object by end($accessDecision->votes) ?

@nicolas-grekas
Copy link
Member

Don't see you put Vote Object in adm

I don't get what this means sorry.

allowMultipleAttributes argument

this argument is an implementation detail, it shouldn't become an API. I moved it to the AccessDecision object but I suppose it can be kept as an argument, after the added $accessDecision. I'll see how this idea fits on by PR.

And in the strategy we don't have Vote Object ?
Can't we keep accessdecision in second argument of decide and get Vote Object by end($accessDecision->votes) ?

No, because it's not needed to achieve the purpose of this PR.
Why would we do this if we can make everything work without?
Said another way: what would this provide that'd not be possible with my approach?

@eltharin
Copy link
Contributor Author

What I say is the argument allowMultipleAttributes already exist now, it's not me who create it.

No, because it's not needed to achieve the purpose of this PR.

purpose is to open Vote process, by creating a VoteInterface, it allow developer to integrate a custom configuration with its own properties to have a custom strategy using it.

I don't think to make all thoses changes "just" to print some message is very useful...

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Feb 13, 2025

I'm going to submit my patch as a separate PR, with only the "reason" feature. That's what people are asking for in all linked PRs/issues so many others do think it would be useful.

Then, I'll invite you to submit the scoring strategy as a separate and follow up PR. At the moment, I don't get what you want to achieve on this topic so having it split will help understand where we want to go, and why.

@nicolas-grekas
Copy link
Member

Follow up PR at #59771
I'm closing here as I'm quite convinced my approach works and fully accounts for BC issues.
As mentioned in my previous comment, I'll let you submit the scoring strategy as a separate PR.
Thanks a lot for helping this move forward!

@eltharin
Copy link
Contributor Author

I agree your approach works, I just said with a small patch (post below) we improve DX from "add a message in a vote" to make a full customizable Vote Process. I really think it's a shame to stop work for so little benefic

Now for your PR, I think it can be a BC when Dev create a custom AccesManager copying decide function (with existing $allowMultipleAttributes argument, they receive message :
App\Security\MyCustomAccessDecisionManager::decide(): Argument #4 ($allowMultipleAttributes) must be of type bool, Symfony\Component\Security\Core\Authorization\AccessDecision given

@eltharin
Copy link
Contributor Author

patch.patch

@nicolas-grekas
Copy link
Member
nicolas-grekas commented Feb 14, 2025

MyCustomAccessDecisionManager::decide(): Argument #4 ($allowMultipleAttributes)

Let's resolve this once for all: this argument is not part of any abstract API. It's only part of the concrete (Traceable)AccessDecisionManager, and if you extend it, BC is kept.

About your patch:

  • I realized the by-ref approach I suggested doesn't work with fun_get_args(), so it's not BC.
  • I removed the final modifier on AccessDecision and Vote to open things a bit for extensibility.
  • I've yet to see why a strategy would need to get the $accessDecision. The challenge is on you, in a follow up PR ;)

@eltharin
Copy link
Contributor Author

OK.
please for my culture,
this line :
$vote = 3 < \func_num_args() ? func_get_arg(3) : new Vote();
is used to avoid create $vote argument that whould have caused BC ?

@nicolas-grekas
Copy link
Member

Absolutely

fabpot added a commit that referenced this pull request Feb 17, 2025
…e (nicolas-grekas)

This PR was merged into the 7.3 branch.

Discussion
----------

[Security] Add ability for voters to explain their vote

| Q             | A
| ------------- | ---
| Branch?       | 7.3
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #27995, #26343, #35592, #43147
| License       | MIT

This PR takes over #58107, which itself took over from #46493, etc.

It takes the only approach I could think of that would preserve BC.

The visible tip of what this achieves is:

![image](https://github.com/user-attachments/assets/67bd0678-868f-40ed-b2c6-3b1f10ffe101)

![image](https://github.com/user-attachments/assets/715814d8-e4de-47f0-aa0e-c412092389ff)

Internally, this provides a new access audit log infrastructure that relies on new `AccessDecision` and `Vote` objects.

Note that I didn't add (nor fix) tests for now. I'll borrow (and credit) from #58107 / #46493 as much as possible.

Commits
-------

c6eb9ae [Security] Add ability for voters to explain their vote
@eltharin
Copy link
Contributor Author
* I've yet to see why a strategy would need to get the $accessDecision. The challenge is on you, in a follow up PR ;)

Here is : #60085

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Security][DX] Be able to know why exactly SecurityVoter returns false
7 participants
0