diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index b34b9bdec4..692aae0127 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -54,8 +54,12 @@ class EntityUserProvider implements UserProviderInterface 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 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); } $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 0000000000..452939fa79 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -0,0 +1,39 @@ + + * + * 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; + +/** + * 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 Michal Trojanowski + */ +interface UserLoaderInterface +{ + /** + * Loads the user for the given username. + * + * This method must return null if the user is not found. + * + * @param string $username The username + * + * @return UserInterface|null + */ + public function loadUserByUsername($username); +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php index 8c179cd31f..0b5292d4a6 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 @@ class EntityUserProviderTest extends \PHPUnit_Framework_TestCase $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 @@ class EntityUserProviderTest extends \PHPUnit_Framework_TestCase 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); diff --git a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php index d17e3b704d..146ed65ad3 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);