Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Security] VoterInterface::vote(TokenInterface $token, $subject, array $attributes) #16600

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

Closed
lyrixx opened this issue Nov 19, 2015 · 15 comments
Closed
Labels

Comments

@lyrixx
Copy link
Member

lyrixx commented Nov 19, 2015

Currently, nothing prevent users to use scalar for the $object parameter in VoterInterface::vote(TokenInterface $token, $object, array $attributes).

We already depreciated VoterInterface::supportsAttribute and VoterInterface::supportsClass.

So I propose this new interface:

interface VoterInterface
{
    const ACCESS_GRANTED = 1;
    const ACCESS_ABSTAIN = 0;
    const ACCESS_DENIED = -1;

    /**
     * Returns the vote for the given parameters.
     *
     * This method must return one of the following constants:
     * ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
     *
     * @param TokenInterface $token      A TokenInterface instance
     * @param mixed          $subject     The subject to secure
     * @param array          $attributes An array of attributes associated with the method being invoked
     *
     * @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
     */
    public function vote(TokenInterface $token, $subject, array $attributes);
}
@stof
Copy link
Member

stof commented Nov 19, 2015

@lyrixx this breaks BC for existing voters as they now need to support receiving a scalar or an array though. And there is no way to warn users about it (we don't know whether the internal implementation handles this case properly)

@lyrixx
Copy link
Member Author

lyrixx commented Nov 19, 2015

@stof I disagree with you. This is not a BC break, because nothing change here. It's just PHP doc.

we don't know whether the internal implementation handles this case properly

I do, cause I already use it. Everything works as expected.

@stof
Copy link
Member

stof commented Nov 19, 2015

no it is not phpdoc. It is changing the contract. currently, it is OK for a voter to use get_class on any non-null value, as the contract says it will only receive null or an object (see the AbstractVoter doing it btw).
Passing a string as the subject is currently a mistake of the caller, and it is fine to avoid accounting for caller mistakes (otherwise, you would have to add thousands of defensive checks in Symfony, everywhere we have a non-typehinted argument). If we change the interface, it becomes OK for callers to pass strings, and all implementations must account for it.

Your argument saying that it is just phpdoc is wrong. It would also mean that changing the return value of any method is OK in PHP 5, as we always rely on the phpdoc to define our contracts. And this is clearly false.

I do, cause I already use it. Everything works as expected.

everything works as expected in your voters. This does not mean that it does in all voters existing in all Symfony projects out there. And we actually even know the opposite, as we have a case in Symfony itself where it does not.

@lyrixx
Copy link
Member Author

lyrixx commented Nov 19, 2015

What do you propose to fix this issue?

@stof
Copy link
Member

stof commented Nov 19, 2015

well, the way to fix this would be to make the change only in 3.0, and document the BC break in the upgrade path.

Then, warning about the fact that scalars and arrays are not handled by the implementation cannot be done by Symfony deprecation warnings, so we must rely on people reading the upgrade doc. But a static analyzer could detect the bug in the implementation.

People wanting to write code compatible with both 2.8 and 3.0 should follow 2 rules:

  • make their own voters handle the case of receiving a scalar, to be compatible with 3.0
  • avoid passing non-objects to isGranted() (i.e. respecting the 2.8 contract) (if you are aware of all voters registered in the project are are sure that they are all compatible with receiving scalars, you could decide to break this contract intentionally thanks to the fact that Symfony does not have the check in place explicitly and there is no object typehint in PHP, but this is to be considered as a hack (and static analyzer will tell you are doing things wrong))

@hhamon
Copy link
Contributor

hhamon commented Nov 19, 2015

I would rename the $subject variable to $resource to secure.

@nicolas-grekas
Copy link
Member

$resource is misleading IMHO and can be confused with a php resource. $subject looks just fine.

@hhamon
Copy link
Contributor

hhamon commented Nov 19, 2015

Good point @nicolas-grekas!

@lyrixx
Copy link
Member Author

lyrixx commented Nov 20, 2015

Hmm, I think we all miss something here.

The voter votes on something
\-------/ \---/ \----------/
 Subject   Verb     Object

So it's well an object, but not an object from OOP, but an object from natural language.

as a reminder, The security component was a port of Spring Security Framework, and in Java almost everything is an Object (OOP).

So IMHO, when Fab port the security component, he just made a typo ;)

@nicolas-grekas nicolas-grekas changed the title [Security] VoterInterface::vote(TokenInterface $token, $subject, array $attributes) [Security] VoterInterface::vote(TokenInterface $token, $object, array $attributes) Nov 20, 2015
@nicolas-grekas nicolas-grekas changed the title [Security] VoterInterface::vote(TokenInterface $token, $object, array $attributes) [Security] VoterInterface::vote(TokenInterface $token, $subject, array $attributes) Nov 20, 2015
@lyrixx
Copy link
Member Author

lyrixx commented Nov 30, 2015

@nicolas-grekas Why did you close it?

@xabbuh
Copy link
Member

xabbuh commented Nov 30, 2015

@lyrixx Well, you can now vote on any type with the Voter class that you introduced in #16601. Do you like to see more changes?

@lyrixx
Copy link
Member Author

lyrixx commented Nov 30, 2015

The interface is still wrong, isn't it?

@xabbuh
Copy link
Member

xabbuh commented Nov 30, 2015

see #16754

@derrabus
Copy link
Member

I once failed with a PR on this topic (#13622) and I'd still love to see this change happen. 😃

@xabbuh
Copy link
Member

xabbuh commented Nov 30, 2015

Well, now that we have core code that allows to vote on other data too, imho it doesn't make sense to not update the interface accordingly.

fabpot added a commit that referenced this issue Nov 30, 2015
…(xabbuh)

This PR was merged into the 2.8 branch.

Discussion
----------

[Security] add subject variable to expression context

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #16600
| License       | MIT
| Doc PR        | TODO

Commits
-------

346943e add subject variable to expression context
@fabpot fabpot closed this as completed Nov 30, 2015
fabpot added a commit that referenced this issue Nov 30, 2015
…te() (xabbuh)

This PR was merged into the 3.0-dev branch.

Discussion
----------

[Security] allow arbitrary types in VoterInterface::vote()

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #16600
| License       | MIT
| Doc PR        | TODO

Commits
-------

9054bdf allow arbitrary types in VoterInterface::vote()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants