Skip to content

Added UserLoaderInterface for loading users through Doctrine. #15947

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

Conversation

mtrojanowski
Copy link
Contributor

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets #11157
License MIT
Doc PR symfony/symfony-docs#4543

Based on the @weaverryan and @stof propositions from this discussion I created a new interface in the Doctrine Bridge which can be used to more easily implement a repository capable of returning a User.

}

if ($this->repository instanceof UserProviderInterface) {
@trigger_error('Implementing loadUserByUsername from Symfony\Component\Security\Core\User\UserProviderInterface is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if the deprecation message is right here. Also what should be the Symfony version stated in this message? And if this behaviour will in fact be deprecated should I add a phpdoc comment with deprecation notice next to the loadUserByUsername method in UserProviderInterface?

Copy link
Member

Choose a reason for hiding this comment

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

This should be triggered only if the class does not implement UserLoaderInterface, to be able to implement both interfaces in case you need to keep BC with older versions

@weaverryan
Copy link
Member

There's also logic down in refreshUser that that can call out to the entity repository, and it feels a little inconsistent to have a new interface for just the loadUserByUsername() method. But, in practice, that's the only of the 3 that needs to be overridden. So I think it's ok.

@linaori
Copy link
Contributor

linaori commented Sep 28, 2015

Maybe we can bring up this issue as a discussion again: #5678

@stof
Copy link
Member

stof commented Sep 28, 2015

@weaverryan the whole point is that you should not change the way the user is refreshed. Refreshing is done by primary key on purpose, to avoid a security issue in case your username is mutable. this is precisely why we provide a dedicated new way

@stof
Copy link
Member

stof commented Sep 28, 2015

This should go in the 2.8 branch when merging though. It is a new feature.

* method is asked to load the UserInterface object for the given username
* (via loadUserByUsername) so that the rest of the process can continue.
*
* Internally, a user provider can load users from any source (databases,
Copy link
Member

Choose a reason for hiding this comment

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

this description is wrong. The UserLoaderInterface is meant to load objects from Doctrine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed the description of the interface. I hope now it's more appropriate.

@mtrojanowski mtrojanowski force-pushed the simplify-user-provider-interface branch 2 times, most recently from 36ac3e4 to e2cc24d Compare September 28, 2015 21:32
@@ -54,8 +54,15 @@ public function loadUserByUsername($username)
if (null !== $this->property) {
$user = $this->repository->findOneBy(array($this->property => $username));
} else {
if (!$this->repository instanceof UserProviderInterface) {
throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository)));
if (!$this->repository instanceof UserLoaderInterface) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I rephrased the clause a bit as the deprecation warning should be thrown if the UserLoaderInterface is not being implemented.

@mtrojanowski
Copy link
Contributor Author

@stof If it's not a problem I will close this PR and open another one for the 2.8 branch once we decide that all the changes here are ok.

@stof
Copy link
Member

stof commented Sep 29, 2015

@mtrojanowski not really needed as we can switch branch with our merging tool

@mtrojanowski mtrojanowski force-pushed the simplify-user-provider-interface branch from 65b9708 to e32fcc0 Compare September 29, 2015 20:34
@mtrojanowski
Copy link
Contributor Author

@stof Great :) Do you think anything else need to be fixed here?

throw new \InvalidArgumentException(sprintf(
'The Doctrine repository "%s" must implement UserLoaderInterface.',
get_class($this->repository)
));
Copy link
Member

Choose a reason for hiding this comment

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

this should be kept on one line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository)));
if (!$this->repository instanceof UserLoaderInterface) {
if (!$this->repository instanceof UserProviderInterface) {
throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserLoaderInterface.', get_class($this->repository)));
Copy link
Member

Choose a reason for hiding this comment

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

I think you should include the namespace in the interface name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@fabpot
Copy link
Member

fabpot commented Oct 7, 2015

👍 ping @symfony/deciders

*
* @see UsernameNotFoundException
*
* @throws UsernameNotFoundException if the user is not found
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering whether we should ask people to throw this exception themselves, or just return UserInterface|null. the EntityUserProvider already handles the case of null anyway, and this would be more in line with the way Doctrine return values work (this would allow to implement it as a findOneBy() call for instance)

Copy link
Member

Choose a reason for hiding this comment

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

Good idea.

Copy link
Member

Choose a reason for hiding this comment

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

This one should be removed.

@fabpot
Copy link
Member

fabpot commented Oct 11, 2015

@mtrojanowski Can you add some tests?

*
* @param string $username The username
*
* @return UserInterface
Copy link
Member

Choose a reason for hiding this comment

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

Should be @return UserInterface|null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

@fabpot
Copy link
Member

fabpot commented Oct 13, 2015

@mtrojanowski Looks good now, can you add some tests for this new feature?

@fabpot
Copy link
Member

fabpot commented Oct 13, 2015

You should also add a note in the CHANGELOG file of the Doctrine Bridge.

@mtrojanowski
Copy link
Contributor Author

@fabpot I added some tests for the EntityUserProvider that check if proper interface is being used. I will also add a note to CHANGELOG.

@fabpot
Copy link
Member

fabpot commented Oct 16, 2015

Thank you @mtrojanowski.

@fabpot fabpot closed this Oct 16, 2015
fabpot added a commit that referenced this pull request Oct 16, 2015
…ctrine. (mtrojanowski)

This PR was submitted for the 2.7 branch but it was merged into the 2.8 branch instead (closes #15947).

Discussion
----------

Added UserLoaderInterface for loading users through Doctrine.

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #11157
| License       | MIT
| Doc PR        | symfony/symfony-docs#4543

Based on the @weaverryan and @stof propositions from [this](#12733 (comment)) discussion I created a new interface in the Doctrine Bridge which can be used to more easily implement a repository capable of returning a User.

Commits
-------

a8d3d12 Added UserLoaderInterface for loading users through Doctrine.
@fabpot fabpot mentioned this pull request Nov 16, 2015
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.

7 participants