From e32fcc0aa3e7b8217fb84292cf83bc72a70137b5 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Sun, 27 Sep 2015 23:02:53 +0200 Subject: [PATCH 1/6] Added UserLoaderInterface for loading users through Doctrine. --- .../Security/User/EntityUserProvider.php | 11 ++++- .../Security/User/UserLoaderInterface.php | 45 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index b34b9bdec4a67..3b5091f0ab400 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -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) { + if (!$this->repository instanceof UserProviderInterface) { + throw new \InvalidArgumentException(sprintf( + 'The Doctrine repository "%s" must implement UserLoaderInterface.', + get_class($this->repository) + )); + } + + @trigger_error('Implementing loadUserByUsername from Symfony\Component\Security\Core\User\UserProviderInterface is deprecated since version 2.8 and will be removed in 3.0. Implement the Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED); } $user = $this->repository->loadUserByUsername($username); diff --git a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php new file mode 100644 index 0000000000000..b7ebceeada8bd --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Security\User; + +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; + +/** + * Represents a class that loads UserInterface objects from Doctrine source for the authentication system. + * + * This interface is meant to facilitate the loading of a User from Doctrine source using a custom method. + * If you want to implement your own logic of retrieving the user from Doctrine your repository should implement this + * interface. + * + * @see UserInterface + * + * @author Fabien Potencier + */ +interface UserLoaderInterface +{ + /** + * Loads the user for the given username. + * + * This method must throw UsernameNotFoundException if the user is not + * found. + * + * @param string $username The username + * + * @return UserInterface + * + * @see UsernameNotFoundException + * + * @throws UsernameNotFoundException if the user is not found + */ + public function loadUserByUsername($username); +} From 414fd1660b8e836f2347b041f0f1d83f1a4b5fb2 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Wed, 30 Sep 2015 23:05:21 +0200 Subject: [PATCH 2/6] Change of author and formatting fix. --- .../Bridge/Doctrine/Security/User/EntityUserProvider.php | 5 +---- .../Bridge/Doctrine/Security/User/UserLoaderInterface.php | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 3b5091f0ab400..8b5540ef9c7ac 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -56,10 +56,7 @@ public function loadUserByUsername($username) } else { 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) - )); + throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserLoaderInterface.', get_class($this->repository))); } @trigger_error('Implementing loadUserByUsername from Symfony\Component\Security\Core\User\UserProviderInterface is deprecated since version 2.8 and will be removed in 3.0. Implement the Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED); diff --git a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php index b7ebceeada8bd..e6a8e3e1a6329 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -23,7 +23,7 @@ * * @see UserInterface * - * @author Fabien Potencier + * @author Michal Trojanowski */ interface UserLoaderInterface { From e463cc2dad7dec399b423aba9df253f5bde3ee47 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Wed, 30 Sep 2015 23:48:34 +0200 Subject: [PATCH 3/6] Added namespace to exception message. --- .../Bridge/Doctrine/Security/User/EntityUserProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 8b5540ef9c7ac..692aae0127508 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -56,7 +56,7 @@ public function loadUserByUsername($username) } else { 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))); + throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface.', get_class($this->repository))); } @trigger_error('Implementing loadUserByUsername from Symfony\Component\Security\Core\User\UserProviderInterface is deprecated since version 2.8 and will be removed in 3.0. Implement the Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED); From 6bdfd0b39433a5a452d9400c23cd67f8a09dde64 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Tue, 13 Oct 2015 08:54:33 +0200 Subject: [PATCH 4/6] The interface should not throw UsernameNotFoundException anymore. --- .../Doctrine/Security/User/UserLoaderInterface.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php index e6a8e3e1a6329..452939fa7934a 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -12,7 +12,6 @@ namespace Symfony\Bridge\Doctrine\Security\User; use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; /** * Represents a class that loads UserInterface objects from Doctrine source for the authentication system. @@ -30,16 +29,11 @@ interface UserLoaderInterface /** * Loads the user for the given username. * - * This method must throw UsernameNotFoundException if the user is not - * found. + * This method must return null if the user is not found. * * @param string $username The username * - * @return UserInterface - * - * @see UsernameNotFoundException - * - * @throws UsernameNotFoundException if the user is not found + * @return UserInterface|null */ public function loadUserByUsername($username); } From 1466957ec4dc2b4fbb72bf22851d35b6140a1dc3 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Tue, 13 Oct 2015 08:57:16 +0200 Subject: [PATCH 5/6] Removed unnecessary @see annotation. --- .../Component/Security/Core/User/UserProviderInterface.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php index d17e3b704d981..146ed65ad303d 100644 --- a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php +++ b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php @@ -43,8 +43,6 @@ interface UserProviderInterface * * @return UserInterface * - * @see UsernameNotFoundException - * * @throws UsernameNotFoundException if the user is not found */ public function loadUserByUsername($username); From 1b8f21906e7c46b8d46278b9de457e6ae94176c4 Mon Sep 17 00:00:00 2001 From: Michal Trojanowski Date: Tue, 13 Oct 2015 09:55:39 +0200 Subject: [PATCH 6/6] Added new unit tests for EntityUserProvider. --- .../Security/User/EntityUserProviderTest.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php index 8c179cd31f246..0b5292d4a671e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php @@ -89,6 +89,39 @@ public function testSupportProxy() $this->assertTrue($provider->supportsClass(get_class($user2))); } + public function testLoadUserByUserNameShouldLoadUserWhenProperInterfaceProvided() + { + $repository = $this->getMock('\Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface'); + $repository->expects($this->once()) + ->method('loadUserByUsername') + ->with('name') + ->willReturn( + $this->getMock('\Symfony\Component\Security\Core\User\UserInterface') + ); + + $provider = new EntityUserProvider( + $this->getManager($this->getObjectManager($repository)), + 'Symfony\Bridge\Doctrine\Tests\Fixtures\User' + ); + + $provider->loadUserByUsername('name'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testLoadUserByUserNameShouldDeclineInvalidInterface() + { + $repository = $this->getMock('\Symfony\Component\Security\Core\User\AdvancedUserInterface'); + + $provider = new EntityUserProvider( + $this->getManager($this->getObjectManager($repository)), + 'Symfony\Bridge\Doctrine\Tests\Fixtures\User' + ); + + $provider->loadUserByUsername('name'); + } + private function getManager($em, $name = null) { $manager = $this->getMock('Doctrine\Common\Persistence\ManagerRegistry'); @@ -100,6 +133,18 @@ private function getManager($em, $name = null) return $manager; } + private function getObjectManager($repository) + { + $em = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager') + ->setMethods(array('getClassMetadata', 'getRepository')) + ->getMockForAbstractClass(); + $em->expects($this->any()) + ->method('getRepository') + ->willReturn($repository); + + return $em; + } + private function createSchema($em) { $schemaTool = new SchemaTool($em);