[Security] refactored remember-me code

This commit is contained in:
Johannes M. Schmitt 2011-03-10 21:27:42 +01:00 committed by Johannes Schmitt
parent 129d7c7c5f
commit 3d97638813
14 changed files with 275 additions and 606 deletions

View File

@ -12,6 +12,8 @@
<parameter key="security.authentication.rememberme.services.persistent.class">Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices</parameter>
<parameter key="security.authentication.rememberme.services.simplehash.class">Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices</parameter>
<parameter key="security.rememberme.response_listener.class">Symfony\Bundle\SecurityBundle\ResponseListener</parameter>
</parameters>
<services>
@ -47,6 +49,10 @@
parent="security.authentication.rememberme.services.abstract"
abstract="true">
</service>
<service id="security.rememberme.response_listener" class="%security.rememberme.response_listener.class%">
<tag name="kernel.listener" method="handle" event="core.response"/>
</service>
</services>
</container>

View File

@ -0,0 +1,24 @@
<?php
namespace Symfony\Bundle\SecurityBundle;
use Symfony\Component\EventDispatcher\EventInterface;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
/**
* Adds remember-me cookies to the Response.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class ResponseListener
{
public function handle(EventInterface $event)
{
$request = $event->get('request');
if (!$request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)) {
return;
}
$event->get('response')->headers->setCookie($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
}

View File

@ -27,7 +27,7 @@ interface AuthenticationManagerInterface
*
* @param TokenInterface $token The TokenInterface instance to authenticate
*
* @return TokenInterface An authenticated TokenInterface instance
* @return TokenInterface An authenticated TokenInterface instance, never null
*
* @throws AuthenticationException if the authentication fails
*/

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
@ -23,7 +22,6 @@ class RememberMeToken extends AbstractToken
{
private $key;
private $providerKey;
private $persistentToken;
/**
* Constructor.
@ -32,7 +30,7 @@ class RememberMeToken extends AbstractToken
* @param string $providerKey
* @param string $key
*/
public function __construct(UserInterface $user, $providerKey, $key, PersistentTokenInterface $persistentToken = null) {
public function __construct(UserInterface $user, $providerKey, $key) {
parent::__construct($user->getRoles());
if (empty($key)) {
@ -45,7 +43,6 @@ class RememberMeToken extends AbstractToken
$this->providerKey = $providerKey;
$this->key = $key;
$this->persistentToken = $persistentToken;
$this->setUser($user);
parent::setAuthenticated(true);
@ -70,11 +67,6 @@ class RememberMeToken extends AbstractToken
return $this->key;
}
public function getPersistentToken()
{
return $this->persistentToken;
}
public function getCredentials()
{
return '';

View File

@ -35,7 +35,6 @@ class RememberMeListener implements ListenerInterface
private $rememberMeServices;
private $authenticationManager;
private $logger;
private $lastState;
private $eventDispatcher;
/**
@ -63,7 +62,6 @@ class RememberMeListener implements ListenerInterface
public function register(EventDispatcherInterface $dispatcher)
{
$dispatcher->connect('core.security', array($this, 'checkCookies'), 0);
$dispatcher->connect('core.response', array($this, 'updateCookies'), 0);
$this->eventDispatcher = $dispatcher;
}
@ -73,7 +71,6 @@ class RememberMeListener implements ListenerInterface
*/
public function unregister(EventDispatcherInterface $dispatcher)
{
$dispatcher->disconnect('core.response', array($this, 'updateCookies'));
}
/**
@ -83,74 +80,36 @@ class RememberMeListener implements ListenerInterface
*/
public function checkCookies(EventInterface $event)
{
$this->lastState = null;
if (null !== $this->securityContext->getToken()) {
return;
}
$request = $event->get('request');
if (null === $token = $this->rememberMeServices->autoLogin($request)) {
return;
}
try {
if (null === $token = $this->rememberMeServices->autoLogin($event->get('request'))) {
return;
$token = $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($token);
if (null !== $this->eventDispatcher) {
$this->eventDispatcher->notify(new Event($this, 'security.interactive_login', array('request' => $request, 'token' => $token)));
}
try {
if (null === $token = $this->authenticationManager->authenticate($token)) {
return;
}
$this->securityContext->setToken($token);
if (null !== $this->eventDispatcher) {
$this->eventDispatcher->notify(new Event($this, 'security.interactive_login', array('request' => $event->get('request'), 'token' => $token)));
}
if (null !== $this->logger) {
$this->logger->debug('SecurityContext populated with remember-me token.');
}
$this->lastState = $token;
} catch (AuthenticationException $failed) {
if (null !== $this->logger) {
$this->logger->debug(
'SecurityContext not populated with remember-me token as the'
.' AuthenticationManager rejected the AuthenticationToken returned'
.' by the RememberMeServices: '.$failed->getMessage()
);
}
$this->lastState = $failed;
}
} catch (AuthenticationException $cookieInvalid) {
$this->lastState = $cookieInvalid;
if (null !== $this->logger) {
$this->logger->debug('The presented cookie was invalid: '.$cookieInvalid->getMessage());
$this->logger->debug('SecurityContext populated with remember-me token.');
}
} catch (AuthenticationException $failed) {
if (null !== $this->logger) {
$this->logger->debug(
'SecurityContext not populated with remember-me token as the'
.' AuthenticationManager rejected the AuthenticationToken returned'
.' by the RememberMeServices: '.$failed->getMessage()
);
}
// silently ignore everything except a cookie theft exception
if ($cookieInvalid instanceof CookieTheftException) {
throw $cookieInvalid;
}
$this->rememberMeServices->loginFail($request);
}
}
/**
* Update cookies
* @param Event $event
*/
public function updateCookies(EventInterface $event, Response $response)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->get('request_type')) {
return $response;
}
if ($this->lastState instanceof TokenInterface) {
$this->rememberMeServices->loginSuccess($event->get('request'), $response, $this->lastState);
} else if ($this->lastState instanceof AuthenticationException) {
$this->rememberMeServices->loginFail($event->get('request'), $response);
}
return $response;
}
}

View File

@ -2,14 +2,19 @@
namespace Symfony\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
/*
@ -26,14 +31,14 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class RememberMeServices implements RememberMeServicesInterface, LogoutHandlerInterface
abstract class AbstractRememberMeServices implements RememberMeServicesInterface, LogoutHandlerInterface
{
const COOKIE_DELIMITER = ':';
protected $options;
protected $logger;
protected $providerKey;
protected $key;
protected $options;
private $providerKey;
private $key;
private $userProviders;
/**
@ -73,6 +78,11 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
return $this->options['remember_me_parameter'];
}
public function getKey()
{
return $this->key;
}
/**
* Implementation of RememberMeServicesInterface. Detects whether a remember-me
* cookie was set, decodes it, and hands it to subclasses for further processing.
@ -91,17 +101,40 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
}
$cookieParts = $this->decodeCookie($cookie);
$token = $this->processAutoLoginCookie($cookieParts, $request);
if (!$token instanceof TokenInterface) {
throw new \RuntimeException('processAutoLoginCookie() must return a TokenInterface implementation.');
try {
$user = $this->processAutoLoginCookie($cookieParts, $request);
if (!$user instanceof UserInterface) {
throw new \RuntimeException('processAutoLoginCookie() must return a UserInterface implementation.');
}
if (null !== $this->logger) {
$this->logger->debug('Remember-me cookie accepted.');
}
return new RememberMeToken($user, $this->providerKey, $this->key);
} catch (CookieTheftException $theft) {
$this->cancelCookie($request);
throw $theft;
} catch (UsernameNotFoundException $notFound) {
if (null !== $this->logger) {
$this->logger->debug('User for remember-me cookie not found.');
}
} catch (UnsupportedUserException $unSupported) {
if (null !== $this->logger) {
$this->logger->debug('User class for remember-me cookie not supported.');
}
} catch (AuthenticationException $invalid) {
if (null !== $this->logger) {
$this->logger->debug('Remember-Me authentication failed: '.$invalid->getMessage());
}
}
if (null !== $this->logger) {
$this->logger->debug('Remember-me cookie accepted.');
}
$this->cancelCookie($request);
return $token;
return null;
}
/**
@ -114,7 +147,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
*/
public function logout(Request $request, Response $response, TokenInterface $token)
{
$this->cancelCookie($response);
$this->cancelCookie($request);
}
/**
@ -122,12 +155,11 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
* an attempted authentication fails.
*
* @param Request $request
* @param Response $response
* @return void
*/
public function loginFail(Request $request, Response $response)
public final function loginFail(Request $request)
{
$this->cancelCookie($response);
$this->cancelCookie($request);
}
/**
@ -141,28 +173,24 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
*/
public final function loginSuccess(Request $request, Response $response, TokenInterface $token)
{
if (!$token instanceof RememberMeToken) {
if (!$token->getUser() instanceof UserInterface) {
if (null !== $this->logger) {
$this->logger->debug('Remember-me ignores token since it does not contain an UserInterface implementation.');
}
return;
}
if (!$this->isRememberMeRequested($request)) {
if (null !== $this->logger) {
$this->logger->debug('Remember-me was not requested.');
}
return;
}
if (!$token->getUser() instanceof UserInterface) {
if (null !== $this->logger) {
$this->logger->debug('Remember-me was requested; setting cookie.');
$this->logger->debug('Remember-me ignores token since it does not contain an UserInterface implementation.');
}
} else if (null !== $this->logger) {
$this->logger->debug('Re-newing remember-me token; setting cookie.');
return;
}
if (!$this->isRememberMeRequested($request)) {
if (null !== $this->logger) {
$this->logger->debug('Remember-me was not requested.');
}
return;
}
if (null !== $this->logger) {
$this->logger->debug('Remember-me was requested; setting cookie.');
}
$this->onLoginSuccess($request, $response, $token);
@ -178,6 +206,10 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
*/
abstract protected function processAutoLoginCookie(array $cookieParts, Request $request);
protected function onLoginFail(Request $request)
{
}
/**
* This is called after a user has been logged in successfully, and has
* requested remember-me capabilities. The implementation usually sets a
@ -190,7 +222,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
*/
abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token);
protected function getUserProvider($class)
protected final function getUserProvider($class)
{
foreach ($this->userProviders as $provider) {
if ($provider->supportsClass($class)) {
@ -198,7 +230,7 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
}
}
throw new \RuntimeException(sprintf('There is no user provider that supports class "%s".', $class));
throw new UnsupportedUserException(sprintf('There is no user provider that supports class "%s".', $class));
}
/**
@ -226,16 +258,16 @@ abstract class RememberMeServices implements RememberMeServicesInterface, Logout
/**
* Deletes the remember-me cookie
*
* @param Response $response
* @param Request $request
* @return void
*/
protected function cancelCookie(Response $response)
protected function cancelCookie(Request $request)
{
if (null !== $this->logger) {
$this->logger->debug(sprintf('Clearing remember-me cookie "%s"', $this->options['name']));
}
$response->headers->clearCookie($this->options['name'], $this->options['path'], $this->options['domain']);
$request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain']));
}
/**

View File

@ -28,7 +28,7 @@ use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class PersistentTokenBasedRememberMeServices extends RememberMeServices
class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
{
private $tokenProvider;
@ -80,9 +80,22 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices
throw new AuthenticationException('The cookie has expired.');
}
$user = $this->getUserProvider($persistentToken->getClass())->loadUserByUsername($persistentToken->getUsername());
$series = $persistentToken->getSeries();
$tokenValue = $this->generateRandomValue();
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
$request->attributes->set(self::COOKIE_ATTR_NAME,
new Cookie(
$this->options['name'],
$this->encodeCookie(array($series, $tokenValue)),
time() + $this->options['lifetime'],
$this->options['path'],
$this->options['domain'],
$this->options['secure'],
$this->options['httponly']
)
);
return new RememberMeToken($user, $this->providerKey, $this->key, $persistentToken);
return $this->getUserProvider($persistentToken->getClass())->loadUserByUsername($persistentToken->getUsername());
}
/**
@ -90,34 +103,23 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices
*/
protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token)
{
if ($token instanceof RememberMeToken) {
if (null === $persistentToken = $token->getPersistentToken()) {
throw new \RuntimeException('RememberMeToken must contain a PersistentTokenInterface implementation when used as login.');
}
$series = $this->generateRandomValue();
$tokenValue = $this->generateRandomValue();
$series = $persistentToken->getSeries();
$tokenValue = $this->generateRandomValue();
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
} else {
$series = $this->generateRandomValue();
$tokenValue = $this->generateRandomValue();
$this->tokenProvider->createNewToken(
new PersistentToken(
get_class($user = $token->getUser()),
$user->getUsername(),
$series,
$tokenValue,
new \DateTime()
)
);
}
$this->tokenProvider->createNewToken(
new PersistentToken(
get_class($user = $token->getUser()),
$user->getUsername(),
$series,
$tokenValue,
new \DateTime()
)
);
$response->headers->setCookie(
new Cookie(
$this->options['name'],
$this->generateCookieValue($series, $tokenValue),
$this->encodeCookie(array($series, $tokenValue)),
time() + $this->options['lifetime'],
$this->options['path'],
$this->options['domain'],
@ -127,18 +129,6 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices
);
}
/**
* Generates the value for the cookie
*
* @param string $series
* @param string $tokenValue
* @return string
*/
protected function generateCookieValue($series, $tokenValue)
{
return $this->encodeCookie(array($series, $tokenValue));
}
/**
* Generates a cryptographically strong random value
*
@ -147,7 +137,7 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices
protected function generateRandomValue()
{
if (function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes(32, $strong);
$bytes = openssl_random_pseudo_bytes(64, $strong);
if (true === $strong && false !== $bytes) {
return base64_encode($bytes);
@ -158,6 +148,6 @@ class PersistentTokenBasedRememberMeServices extends RememberMeServices
$this->logger->warn('Could not produce a cryptographically strong random value. Please install/update the OpenSSL extension.');
}
return base64_encode(hash('sha256', uniqid(mt_rand(), true), true));
return base64_encode(hash('sha512', uniqid(mt_rand(), true), true));
}
}
}

View File

@ -17,50 +17,67 @@ use Symfony\Component\HttpFoundation\Request;
/**
* Interface that needs to be implemented by classes which provide remember-me
* capabilities.
*
*
* We provide two implementations out-of-the-box:
* - TokenBasedRememberMeServices (does not require a TokenProvider)
* - PersistentTokenBasedRememberMeServices (requires a TokenProvider)
*
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface RememberMeServicesInterface
{
/**
* This method will be called whenever the SecurityContext does not contain
* an TokenInterface object and the framework wishes to provide an implementation
* with an opportunity to authenticate the request using remember-me capabilities.
*
* This attribute name can be used by the implementation if it needs to set
* a cookie on the Request when there is no actual Response, yet.
*
* @var string
*/
const COOKIE_ATTR_NAME = '_security_remember_me_cookie';
/**
* This method will be called whenever the SecurityContext does not contain
* an TokenInterface object and the framework wishes to provide an implementation
* with an opportunity to authenticate the request using remember-me capabilities.
*
* No attempt whatsoever is made to determine whether the browser has requested
* remember-me services or presented a valid cookie. Any and all such determinations
* are left to the implementation of this method.
*
* are left to the implementation of this method.
*
* If a browser has presented an unauthorised cookie for whatever reason,
* make sure to throw an AuthenticationException as this will consequentially
* make sure to throw an AuthenticationException as this will consequentially
* result in a call to loginFail() and therefore an invalidation of the cookie.
*
*
* @param Request $request
* @return TokenInterface
*/
function autoLogin(Request $request);
/**
* Called whenever an authentication attempt was made, but the credentials
* supplied by the user were missing or otherwise invalid.
*
* This method needs to take care of invalidating the cookie.
*/
function loginFail(Request $request, Response $response);
/**
* Called whenever authentication attempt is successful (e.g. a form login).
*
* An implementation may always set a remember-me cookie in the Response,
* although this is not recommended.
*
* Instead, implementations should typically look for a request parameter
* Called whenever an interactive authentication attempt was made, but the
* credentials supplied by the user were missing or otherwise invalid.
*
* This method needs to take care of invalidating the cookie.
*
* @param Request $request
* @return void
*/
function loginFail(Request $request);
/**
* Called whenever an interactive authentication attempt is successful
* (e.g. a form login).
*
* An implementation may always set a remember-me cookie in the Response,
* although this is not recommended.
*
* Instead, implementations should typically look for a request parameter
* (such as a HTTP POST parameter) that indicates the browser has explicitly
* requested for the authentication to be remembered.
*
* @param Request $request
* @param Response $response
* @param TokenInterface $token
* @return void
*/
function loginSuccess(Request $request, Response $response, TokenInterface $token);
}

View File

@ -25,7 +25,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class TokenBasedRememberMeServices extends RememberMeServices
class TokenBasedRememberMeServices extends AbstractRememberMeServices
{
/**
* {@inheritDoc}
@ -62,7 +62,7 @@ class TokenBasedRememberMeServices extends RememberMeServices
throw new AuthenticationException('The cookie has expired.');
}
return new RememberMeToken($user, $this->providerKey, $this->key);
return $user;
}
/**
@ -95,10 +95,6 @@ class TokenBasedRememberMeServices extends RememberMeServices
*/
protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token)
{
if ($token instanceof RememberMeToken) {
return;
}
$user = $token->getUser();
$expires = time() + $this->options['lifetime'];
$value = $this->generateCookieValue(get_class($user), $user->getUsername(), $expires, $user->getPassword());
@ -150,6 +146,6 @@ class TokenBasedRememberMeServices extends RememberMeServices
*/
protected function generateCookieHash($class, $username, $expires, $password)
{
return hash('sha256', $class.$username.$expires.$password.$this->key);
return hash('sha256', $class.$username.$expires.$password.$this->getKey());
}
}

View File

@ -60,13 +60,6 @@ class RememberMeTokenTest extends \PHPUnit_Framework_TestCase
);
}
public function testPersistentToken()
{
$token = new RememberMeToken($this->getUser(), 'fookey', 'foo', $persistentToken = $this->getMock('Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface'));
$this->assertSame($persistentToken, $token->getPersistentToken());
}
protected function getUser($roles = array('ROLE_FOO'))
{
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');

View File

@ -21,11 +21,6 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->method('connect')
->with($this->equalTo('core.security'))
;
$dispatcher
->expects($this->at(1))
->method('connect')
->with($this->equalTo('core.response'))
;
$listener->register($dispatcher);
}
@ -45,9 +40,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->method('setToken')
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($this->getEvent()));
$this->assertNull($this->getLastState($listener));
}
public function testCheckCookiesDoesNothingWhenNoCookieIsSet()
@ -74,105 +67,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new Request()))
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($event));
$this->assertNull($this->getLastState($listener));
}
public function testCheckCookiesIgnoresAuthenticationExceptionThrownByTheRememberMeServicesImplementation()
{
list($listener, $context, $service,,) = $this->getListener();
$context
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$exception = new AuthenticationException('cookie invalid.');
$service
->expects($this->once())
->method('autoLogin')
->will($this->throwException($exception))
;
$event = $this->getEvent();
$event
->expects($this->once())
->method('get')
->with('request')
->will($this->returnValue(new Request()))
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($event));
$this->assertSame($exception, $this->getLastState($listener));
}
public function testCheckCookiesThrowsCookieTheftExceptionIfThrownByTheRememberMeServicesImplementation()
{
list($listener, $context, $service,,) = $this->getListener();
$context
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$exception = new CookieTheftException('cookie was stolen.');
$service
->expects($this->once())
->method('autoLogin')
->will($this->throwException($exception))
;
$event = $this->getEvent();
$event
->expects($this->once())
->method('get')
->with('request')
->will($this->returnValue(new Request()))
;
try {
$listener->checkCookies($event);
}
catch (CookieTheftException $theft) {
$this->assertSame($theft, $this->getLastState($listener));
return;
}
$this->fail('Expected CookieTheftException was not thrown.');
}
public function testCheckCookiesAuthenticationManagerDoesNotChangeListenerStateWhenTokenIsNotSupported()
{
list($listener, $context, $service, $manager,) = $this->getListener();
$context
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
;
$event = $this->getEvent();
$event
->expects($this->once())
->method('get')
->with('request')
->will($this->returnValue(new Request()))
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($event));
$this->assertNull($this->getLastState($listener));
}
public function testCheckCookiesIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
@ -191,6 +86,11 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')))
;
$service
->expects($this->once())
->method('loginFail')
;
$exception = new AuthenticationException('Authentication failed.');
$manager
->expects($this->once())
@ -206,9 +106,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new Request()))
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($event));
$this->assertSame($exception, $this->getLastState($listener));
$listener->checkCookies($event);
}
public function testCheckCookies()
@ -248,111 +146,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue(new Request()))
;
$this->assertNull($this->getLastState($listener));
$this->assertNull($listener->checkCookies($event));
$this->assertSame($token, $this->getLastState($listener));
}
public function testUpdateCookiesIgnoresAnythingButMasterRequests()
{
list($listener,,,,) = $this->getListener();
$event = $this->getEvent();
$event
->expects($this->once())
->method('get')
->with($this->equalTo('request_type'))
->will($this->returnValue('foo'))
;
$response = $this->getMock('Symfony\Component\HttpFoundation\Response');
$this->assertSame($response, $listener->updateCookies($event, $response));
}
public function testUpdateCookiesCallsLoginSuccessOnRememberMeServicesImplementationWhenAuthenticationWasSuccessful()
{
list($listener,, $service,,) = $this->getListener();
$request = new Request();
$response = new Response();
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$this->setLastState($listener, $token);
$event = $this->getEvent();
$event
->expects($this->at(0))
->method('get')
->with('request_type')
->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST))
;
$event
->expects($this->at(1))
->method('get')
->with('request')
->will($this->returnValue($request))
;
$service
->expects($this->once())
->method('loginSuccess')
->with($this->equalTo($request), $this->equalTo($response), $this->equalTo($token))
->will($this->returnValue(null))
;
$this->assertSame($response, $listener->updateCookies($event, $response));
}
public function testUpdateCookiesCallsLoginFailOnRememberMeServicesImplementationWhenAuthenticationWasNotSuccessful()
{
list($listener,, $service,,) = $this->getListener();
$request = new Request();
$response = new Response();
$exception = new AuthenticationException('foo');
$this->setLastState($listener, $exception);
$event = $this->getEvent();
$event
->expects($this->at(0))
->method('get')
->with('request_type')
->will($this->returnValue(HttpKernelInterface::MASTER_REQUEST))
;
$event
->expects($this->at(1))
->method('get')
->with('request')
->will($this->returnValue($request))
;
$service
->expects($this->once())
->method('loginFail')
->with($this->equalTo($request), $this->equalTo($response))
->will($this->returnValue(null))
;
$this->assertSame($response, $listener->updateCookies($event, $response));
}
protected function setLastState($listener, $state)
{
$r = new \ReflectionObject($listener);
$p = $r->getProperty('lastState');
$p->setAccessible(true);
$p->setValue($listener, $state);
}
protected function getLastState($listener)
{
$r = new \ReflectionObject($listener);
$p = $r->getProperty('lastState');
$p->setAccessible(true);
return $p->getValue($listener);
$listener->checkCookies($event);
}
protected function getEvent()

View File

@ -2,10 +2,11 @@
namespace Symfony\Tests\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
{
public function testGetRememberMeParameter()
{
@ -14,6 +15,12 @@ class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $service->getRememberMeParameter());
}
public function testGetKey()
{
$service = $this->getService();
$this->assertEquals('fookey', $service->getKey());
}
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo'));
@ -23,9 +30,8 @@ class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \RuntimeException
* @expectedMessage processAutoLoginCookie() must return a TokenInterface implementation.
*/
public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnTokenInterface()
public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface()
{
$service = $this->getService(null, array('name' => 'foo'));
$request = new Request;
@ -46,17 +52,24 @@ class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
$request = new Request();
$request->cookies->set('foo', 'foo');
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array()))
;
$service
->expects($this->once())
->method('processAutoLoginCookie')
->will($this->returnValue($token))
->will($this->returnValue($user))
;
$returnedToken = $service->autoLogin($request);
$this->assertSame($token, $returnedToken);
$this->assertSame($user, $returnedToken->getUser());
$this->assertSame('fookey', $returnedToken->getKey());
$this->assertSame('fookey', $returnedToken->getProviderKey());
}
public function testLogout()
@ -66,24 +79,19 @@ class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
$response = new Response();
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$this->assertFalse($response->headers->hasCookie('foo'));
$service->logout($request, $response, $token);
$this->assertTrue($response->headers->getCookie('foo')->isCleared());
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$this->assertFalse($response->headers->hasCookie('foo'));
$service->loginFail($request);
$service->loginFail($request, $response);
$this->assertTrue($response->headers->getCookie('foo')->isCleared());
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testLoginSuccessIsNotProcessedWhenTokenDoesNotContainUserInterfaceImplementation()
@ -192,34 +200,13 @@ class RememberMeServicesTest extends \PHPUnit_Framework_TestCase
);
}
public function testLoginSuccessRenewsRememberMeCookie()
{
$service = $this->getService();
$token = $this->getMock(
'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken',
array(),
array(),
'NonFunctionalRememberMeTokenMockClass',
false
);
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(null))
;
$service->loginSuccess(new Request(), new Response(), $token);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\RememberMeServices', array(
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', array(
array($userProvider), 'fookey', 'fookey', $options, $logger
));
}

View File

@ -2,6 +2,8 @@
namespace Symfony\Tests\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
@ -21,26 +23,20 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$this->assertNull($service->autoLogin(new Request()));
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedMessage The cookie is invalid.
*/
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$request = new Request;
$request->request->set('foo', 'true');
$request->cookies->set('foo', 'foo');
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\TokenNotFoundException
*/
public function testAutoLoginThrowsExceptionOnNonExistentToken()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$request = new Request;
$request->request->set('foo', 'true');
$request->cookies->set('foo', $this->encodeCookie(array(
@ -56,16 +52,14 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
;
$service->setTokenProvider($tokenProvider);
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testAutoLoginThrowsExceptionOnNonExistentUser()
public function testAutoLoginReturnsNullOnNonExistentUser()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600, 'secure' => false, 'httponly' => false));
$request = new Request;
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
@ -83,13 +77,14 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
->will($this->throwException(new UsernameNotFoundException('user not found')))
;
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testAutoLoginThrowsExceptionOnStolenCookieAndRemovesItFromThePersistentBackend()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true));
$request = new Request;
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
@ -111,20 +106,15 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
try {
$service->autoLogin($request);
} catch (CookieTheftException $theft) {
return;
}
$this->fail('Expected CookieTheftException was not thrown.');
} catch (CookieTheftException $theft) { }
$this->fail('Expected CookieTheftException was not thrown.');
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedMessage The cookie has expired.
*/
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request;
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
@ -133,11 +123,12 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
->expects($this->once())
->method('loadTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(new PersistentToken('fooclass', 'username', 'fooseries', 'newFooValue', new \DateTime('yesterday'))))
->will($this->returnValue(new PersistentToken('fooclass', 'username', 'fooseries', 'foovalue', new \DateTime('yesterday'))))
;
$service->setTokenProvider($tokenProvider);
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testAutoLogin()
@ -157,7 +148,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
->will($this->returnValue($user))
;
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'secure' => false, 'httponly' => false, 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request;
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
@ -173,9 +164,9 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$returnedToken = $service->autoLogin($request);
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $returnedToken);
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface', $returnedToken->getPersistentToken());
$this->assertSame($user, $returnedToken->getUser());
$this->assertEquals('fookey', $returnedToken->getKey());
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testLogout()
@ -195,11 +186,9 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
;
$service->setTokenProvider($tokenProvider);
$this->assertFalse($response->headers->hasCookie('foo'));
$service->logout($request, $response, $token);
$cookie = $response->headers->getCookie('foo');
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foodomain.foo', $cookie->getDomain());
@ -219,10 +208,9 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
;
$service->setTokenProvider($tokenProvider);
$this->assertFalse($response->headers->hasCookie('foo'));
$service->logout($request, $response, $token);
$cookie = $response->headers->getCookie('foo');
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertNull($cookie->getPath());
$this->assertNull($cookie->getDomain());
@ -243,93 +231,19 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
;
$service->setTokenProvider($tokenProvider);
$this->assertFalse($response->headers->hasCookie('foo'));
$service->logout($request, $response, $token);
$this->assertTrue($response->headers->getCookie('foo')->isCleared());
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$this->assertFalse($response->headers->hasCookie('foo'));
$service->loginFail($request, $response);
$this->assertTrue($response->headers->getCookie('foo')->isCleared());
}
public function testLoginSuccessRenewsRememberMeTokenWhenUsedForLogin()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600));
$request = new Request;
$response = new Response;
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array(), array($user, 'fookey', 'fookey'));
$token
->expects($this->once())
->method('getPersistentToken')
->will($this->returnValue(new PersistentToken('fooclass', 'foouser', 'fooseries', 'foovalue', new \DateTime())))
;
$tokenProvider = $this->getMock('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface');
$tokenProvider
->expects($this->once())
->method('updateToken')
->with($this->equalTo('fooseries'))
->will($this->returnValue(null))
;
$service->setTokenProvider($tokenProvider);
$this->assertFalse($response->headers->hasCookie('foo'));
$service->loginSuccess($request, $response, $token);
$cookie = $response->headers->getCookie('foo');
$this->assertFalse($cookie->isCleared());
$this->assertTrue($cookie->isSecure());
$this->assertTrue($cookie->isHttpOnly());
$this->assertTrue($cookie->getExpire() > time() + 3590 && $cookie->getExpire() < time() + 3610);
$this->assertEquals('myfoodomain.foo', $cookie->getDomain());
$this->assertEquals('/foo/path', $cookie->getPath());
}
/**
* @expectedException RuntimeException
* @expectedMessage RememberMeToken must contain a PersistentTokenInterface implementation when used as login.
*/
public function testLoginSuccessThrowsExceptionWhenRememberMeTokenDoesNotContainPersistentTokenImplementation()
{
$service = $this->getService(null, array('always_remember_me' => true, 'name' => 'foo'));
$request = new Request;
$response = new Response;
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', array(), array($user, 'fookey', 'fookey'));
$token
->expects($this->once())
->method('getPersistentToken')
->will($this->returnValue(null))
;
$service->loginSuccess($request, $response, $token);
$this->assertFalse($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
$service->loginFail($request);
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testLoginSuccessSetsCookieWhenLoggedInWithNonRememberMeTokenInterfaceImplementation()

View File

@ -2,6 +2,8 @@
namespace Symfony\Tests\Component\Security\Http\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\Token;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
@ -21,27 +23,21 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertNull($service->autoLogin(new Request()));
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedMessage The cookie is invalid.
*/
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
$request = new Request;
$request->request->set('foo', 'true');
$request->cookies->set('foo', 'foo');
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testAutoLoginThrowsExceptionOnNonExistentUser()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request;
$request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time()+3600, 'foopass'));
@ -51,17 +47,14 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
->will($this->throwException(new UsernameNotFoundException('user not found')))
;
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedMessage The cookie's hash is invalid.
*/
public function testAutoLoginDoesNotAcceptCookieWithInvalidHash()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request;
$request->cookies->set('foo', base64_encode('class:'.base64_encode('foouser').':123456789:fooHash'));
@ -79,17 +72,14 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($user))
;
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @expectedException Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedMessage The cookie has expired.
*/
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$userProvider = $this->getProvider();
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$service = $this->getService($userProvider, array('name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request;
$request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() - 1, 'foopass'));
@ -107,7 +97,8 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($user))
;
$service->autoLogin($request);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLogin()
@ -150,11 +141,9 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$response = new Response();
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$this->assertFalse($response->headers->hasCookie('foo'));
$service->logout($request, $response, $token);
$cookie = $response->headers->getCookie('foo');
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertNull($cookie->getPath());
$this->assertNull($cookie->getDomain());
@ -166,38 +155,14 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$request = new Request();
$response = new Response();
$this->assertFalse($response->headers->hasCookie('foo'));
$service->loginFail($request, $response);
$cookie = $response->headers->getCookie('foo');
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foodomain.foo', $cookie->getDomain());
}
public function testLoginSuccessDoesNotRenewRememberMeToken()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600));
$request = new Request;
$response = new Response;
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$token = new RememberMeToken($user, 'fookey', 'foo');
$this->assertFalse($response->headers->hasCookie('foo'));
$service->loginSuccess($request, $response, $token);
$this->assertFalse($response->headers->hasCookie('foo'));
}
public function testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true));