[Security] added unit tests to some authenticated providers (code coverage is more than 96% for the Security component now)

This commit is contained in:
Fabien Potencier 2010-10-31 15:41:15 +01:00
parent 52e03e8885
commit ec417578ca
4 changed files with 349 additions and 15 deletions

View File

@ -55,12 +55,10 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
*/
protected function checkAuthentication(AccountInterface $account, UsernamePasswordToken $token)
{
if (null === $token->getCredentials()) {
if (!$presentedPassword = (string) $token->getCredentials()) {
throw new BadCredentialsException('Bad credentials');
}
$presentedPassword = (string) $token->getCredentials();
if (!$this->passwordEncoder->isPasswordValid($account->getPassword(), $presentedPassword, $account->getSalt())) {
throw new BadCredentialsException('Bad credentials');
}
@ -80,8 +78,8 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
throw new AuthenticationServiceException($repositoryProblem->getMessage(), $token, 0, $repositoryProblem);
}
if (null === $user) {
throw new AuthenticationServiceException('UserProvider returned null.');
if (!$user instanceof AccountInterface) {
throw new AuthenticationServiceException('The user provider must return an AccountInterface object.');
}
return $user;

View File

@ -7,6 +7,7 @@ use Symfony\Component\Security\User\AccountCheckerInterface;
use Symfony\Component\Security\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Exception\AuthenticationException;
use Symfony\Component\Security\Exception\BadCredentialsException;
use Symfony\Component\Security\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Authentication\Token\TokenInterface;
@ -62,17 +63,12 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
throw $notFound;
}
if (null === $user) {
throw new \LogicException('The retrieveUser() methods returned null which should not be possible.');
}
try {
$this->accountChecker->checkPreAuth($user);
$this->checkAuthentication($user, $token);
} catch (AuthenticationException $e) {
throw $e;
if (!$user instanceof AccountInterface) {
throw new AuthenticationServiceException('The retrieveUser() methods must return an AccountInterface object.');
}
$this->accountChecker->checkPreAuth($user);
$this->checkAuthentication($user, $token);
$this->accountChecker->checkPostAuth($user);
return new UsernamePasswordToken($user, $token->getCredentials(), $user->getRoles());
@ -92,7 +88,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
* @param string $username The username to retrieve
* @param UsernamePasswordToken $token The Token
*
* @return mixed The user
* @return AccountInterface The user
*
* @throws AuthenticationException if the credentials could not be validated
*/

View File

@ -0,0 +1,166 @@
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\Security\Authentication\Provider;
use Symfony\Component\Security\Authentication\Provider\DaoAuthenticationProvider;
class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException Symfony\Component\Security\Exception\AuthenticationServiceException
*/
public function testRetrieveUserWhenProviderDoesNotReturnAnAccountInterface()
{
$provider = $this->getProvider('fabien');
$method = new \ReflectionMethod($provider, 'retrieveUser');
$method->setAccessible(true);
$method->invoke($provider, 'fabien', $this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\UsernameNotFoundException
*/
public function testRetrieveUserWhenUsernameIsNotFound()
{
$userProvider = $this->getMock('Symfony\Component\Security\User\UserProviderInterface');
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\UsernameNotFoundException', null, array(), '', false)))
;
$provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface'));
$method = new \ReflectionMethod($provider, 'retrieveUser');
$method->setAccessible(true);
$method->invoke($provider, 'fabien', $this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\AuthenticationServiceException
*/
public function testRetrieveUserWhenAnExceptionOccurs()
{
$userProvider = $this->getMock('Symfony\Component\Security\User\UserProviderInterface');
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException($this->getMock('RuntimeException', null, array(), '', false)))
;
$provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface'));
$method = new \ReflectionMethod($provider, 'retrieveUser');
$method->setAccessible(true);
$method->invoke($provider, 'fabien', $this->getSupportedToken());
}
public function testRetrieveUser()
{
$user = $this->getMock('Symfony\Component\Security\User\AccountInterface');
$userProvider = $this->getMock('Symfony\Component\Security\User\UserProviderInterface');
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->returnValue($user))
;
$provider = new DaoAuthenticationProvider($userProvider, $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface'));
$method = new \ReflectionMethod($provider, 'retrieveUser');
$method->setAccessible(true);
$this->assertSame($user, $method->invoke($provider, 'fabien', $this->getSupportedToken()));
}
/**
* @expectedException Symfony\Component\Security\Exception\BadCredentialsException
*/
public function testCheckAuthenticationWhenCredentialsAreEmpty()
{
$provider = $this->getProvider();
$method = new \ReflectionMethod($provider, 'checkAuthentication');
$method->setAccessible(true);
$token = $this->getSupportedToken();
$token->expects($this->once())
->method('getCredentials')
->will($this->returnValue(''))
;
$method->invoke($provider, $this->getMock('Symfony\Component\Security\User\AccountInterface'), $token);
}
/**
* @expectedException Symfony\Component\Security\Exception\BadCredentialsException
*/
public function testCheckAuthenticationWhenCredentialsAreNotValid()
{
$encoder = $this->getMock('Symfony\Component\Security\Encoder\PasswordEncoderInterface');
$encoder->expects($this->once())
->method('isPasswordValid')
->will($this->returnValue(false))
;
$provider = $this->getProvider(false, false, $encoder);
$method = new \ReflectionMethod($provider, 'checkAuthentication');
$method->setAccessible(true);
$token = $this->getSupportedToken();
$token->expects($this->once())
->method('getCredentials')
->will($this->returnValue('foo'))
;
$method->invoke($provider, $this->getMock('Symfony\Component\Security\User\AccountInterface'), $token);
}
public function testCheckAuthentication()
{
$encoder = $this->getMock('Symfony\Component\Security\Encoder\PasswordEncoderInterface');
$encoder->expects($this->once())
->method('isPasswordValid')
->will($this->returnValue(true))
;
$provider = $this->getProvider(false, false, $encoder);
$method = new \ReflectionMethod($provider, 'checkAuthentication');
$method->setAccessible(true);
$token = $this->getSupportedToken();
$token->expects($this->once())
->method('getCredentials')
->will($this->returnValue('foo'))
;
$method->invoke($provider, $this->getMock('Symfony\Component\Security\User\AccountInterface'), $token);
}
protected function getSupportedToken()
{
return $this->getMock('Symfony\Component\Security\Authentication\Token\UsernamePasswordToken', array('getCredentials'), array(), '', false);
}
protected function getProvider($user = false, $userChecker = false, $passwordEncoder = null)
{
$userProvider = $this->getMock('Symfony\Component\Security\User\UserProviderInterface');
if (false !== $user) {
$userProvider->expects($this->once())
->method('loadUserByUsername')
->will($this->returnValue($user))
;
}
if (false === $userChecker) {
$userChecker = $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface');
}
return new DaoAuthenticationProvider($userProvider, $userChecker, $passwordEncoder);
}
}

View File

@ -0,0 +1,174 @@
<?php
/*
* This file is part of the Symfony package.
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\Security\Authentication\Provider;
use Symfony\Component\Security\Authentication\Provider\UserAuthenticationProvider;
use Symfony\Component\Security\Role\Role;
class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
{
public function testSupports()
{
$provider = $this->getProvider();
$this->assertTrue($provider->supports($this->getSupportedToken()));
$this->assertFalse($provider->supports($this->getMock('Symfony\Component\Security\Authentication\Token\TokenInterface')));
}
public function testAuthenticateWhenTokenIsNotSupported()
{
$provider = $this->getProvider();
$this->assertNull($provider->authenticate($this->getMock('Symfony\Component\Security\Authentication\Token\TokenInterface')));
}
/**
* @expectedException Symfony\Component\Security\Exception\UsernameNotFoundException
*/
public function testAuthenticateWhenUsernameIsNotFound()
{
$provider = $this->getProvider(false, false);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\UsernameNotFoundException', null, array(), '', false)))
;
$provider->authenticate($this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\BadCredentialsException
*/
public function testAuthenticateWhenUsernameIsNotFoundAndHideIsTrue()
{
$provider = $this->getProvider(false, true);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\UsernameNotFoundException', null, array(), '', false)))
;
$provider->authenticate($this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\AuthenticationServiceException
*/
public function testAuthenticateWhenProviderDoesNotReturnAnAccountInterface()
{
$provider = $this->getProvider(false, true);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue(null))
;
$provider->authenticate($this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\CredentialsExpiredException
*/
public function testAuthenticateWhenPreChecksFails()
{
$userChecker = $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface');
$userChecker->expects($this->once())
->method('checkPreAuth')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\CredentialsExpiredException', null, array(), '', false)))
;
$provider = $this->getProvider($userChecker);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue($this->getMock('Symfony\Component\Security\User\AccountInterface')))
;
$provider->authenticate($this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\AccountExpiredException
*/
public function testAuthenticateWhenPostChecksFails()
{
$userChecker = $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface');
$userChecker->expects($this->once())
->method('checkPostAuth')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\AccountExpiredException', null, array(), '', false)))
;
$provider = $this->getProvider($userChecker);
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue($this->getMock('Symfony\Component\Security\User\AccountInterface')))
;
$provider->authenticate($this->getSupportedToken());
}
/**
* @expectedException Symfony\Component\Security\Exception\BadCredentialsException
*/
public function testAuthenticateWhenPostCheckAuthenticationFails()
{
$provider = $this->getProvider();
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue($this->getMock('Symfony\Component\Security\User\AccountInterface')))
;
$provider->expects($this->once())
->method('checkAuthentication')
->will($this->throwException($this->getMock('Symfony\Component\Security\Exception\BadCredentialsException', null, array(), '', false)))
;
$provider->authenticate($this->getSupportedToken());
}
public function testAuthenticate()
{
$user = $this->getMock('Symfony\Component\Security\User\AccountInterface');
$user->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$provider = $this->getProvider();
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue($user))
;
$token = $this->getSupportedToken();
$token->expects($this->once())
->method('getCredentials')
->will($this->returnValue('foo'))
;
$authToken = $provider->authenticate($token);
$this->assertInstanceOf('Symfony\Component\Security\Authentication\Token\UsernamePasswordToken', $authToken);
$this->assertSame($user, $authToken->getUser());
$this->assertEquals(array(new Role('ROLE_FOO')), $authToken->getRoles());
$this->assertEquals('foo', $authToken->getCredentials());
}
protected function getSupportedToken()
{
return $this->getMock('Symfony\Component\Security\Authentication\Token\UsernamePasswordToken', array('getCredentials'), array(), '', false);
}
protected function getProvider($userChecker = false, $hide = true)
{
if (false === $userChecker) {
$userChecker = $this->getMock('Symfony\Component\Security\User\AccountCheckerInterface');
}
return $this->getMockForAbstractClass('Symfony\Component\Security\Authentication\Provider\UserAuthenticationProvider', array($userChecker, $hide));
}
}