Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\AccessMap;
class AccessMapTest extends TestCase
{
public function testReturnsFirstMatchedPattern()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$requestMatcher1 = $this->getRequestMatcher($request, false);
$requestMatcher2 = $this->getRequestMatcher($request, true);
$map = new AccessMap();
$map->add($requestMatcher1, array('ROLE_ADMIN'), 'http');
$map->add($requestMatcher2, array('ROLE_USER'), 'https');
$this->assertSame(array(array('ROLE_USER'), 'https'), $map->getPatterns($request));
}
public function testReturnsEmptyPatternIfNoneMatched()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$requestMatcher = $this->getRequestMatcher($request, false);
$map = new AccessMap();
$map->add($requestMatcher, array('ROLE_USER'), 'https');
$this->assertSame(array(null, null), $map->getPatterns($request));
}
private function getRequestMatcher($request, $matches)
{
$requestMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcherInterface')->getMock();
$requestMatcher->expects($this->once())
->method('matches')->with($request)
->will($this->returnValue($matches));
return $requestMatcher;
}
}

View File

@@ -0,0 +1,190 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Authentication;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class DefaultAuthenticationFailureHandlerTest extends TestCase
{
private $httpKernel;
private $httpUtils;
private $logger;
private $request;
private $session;
private $exception;
protected function setUp()
{
$this->httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$this->httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$this->request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$this->request->expects($this->any())->method('getSession')->will($this->returnValue($this->session));
$this->exception = $this->getMockBuilder('Symfony\Component\Security\Core\Exception\AuthenticationException')->setMethods(array('getMessage'))->getMock();
}
public function testForward()
{
$options = array('failure_forward' => true);
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($subRequest));
$response = new Response();
$this->httpKernel->expects($this->once())
->method('handle')->with($subRequest, HttpKernelInterface::SUB_REQUEST)
->will($this->returnValue($response));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$result = $handler->onAuthenticationFailure($this->request, $this->exception);
$this->assertSame($response, $result);
}
public function testRedirect()
{
$response = new Response();
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/login')
->will($this->returnValue($response));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$result = $handler->onAuthenticationFailure($this->request, $this->exception);
$this->assertSame($response, $result);
}
public function testExceptionIsPersistedInSession()
{
$this->session->expects($this->once())
->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testExceptionIsPassedInRequestOnForward()
{
$options = array('failure_forward' => true);
$subRequest = $this->getRequest();
$subRequest->attributes->expects($this->once())
->method('set')->with(Security::AUTHENTICATION_ERROR, $this->exception);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($subRequest));
$this->session->expects($this->never())->method('set');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testRedirectIsLogged()
{
$this->logger
->expects($this->once())
->method('debug')
->with('Authentication failure, redirect triggered.', array('failure_path' => '/login'));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testForwardIsLogged()
{
$options = array('failure_forward' => true);
$this->httpUtils->expects($this->once())
->method('createRequest')->with($this->request, '/login')
->will($this->returnValue($this->getRequest()));
$this->logger
->expects($this->once())
->method('debug')
->with('Authentication failure, forward triggered.', array('failure_path' => '/login'));
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testFailurePathCanBeOverwritten()
{
$options = array('failure_path' => '/auth/login');
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testFailurePathCanBeOverwrittenWithRequest()
{
$this->request->expects($this->once())
->method('get')->with('_failure_path')
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array(), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testFailurePathCanBeOverwrittenWithNestedAttributeInRequest()
{
$this->request->expects($this->once())
->method('get')->with('_failure_path')
->will($this->returnValue(array('value' => '/auth/login')));
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, array('failure_path_parameter' => '_failure_path[value]'), $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
public function testFailurePathParameterCanBeOverwritten()
{
$options = array('failure_path_parameter' => '_my_failure_path');
$this->request->expects($this->once())
->method('get')->with('_my_failure_path')
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
->method('createRedirectResponse')->with($this->request, '/auth/login');
$handler = new DefaultAuthenticationFailureHandler($this->httpKernel, $this->httpUtils, $options, $this->logger);
$handler->onAuthenticationFailure($this->request, $this->exception);
}
private function getRequest()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->attributes = $this->getMockBuilder('Symfony\Component\HttpFoundation\ParameterBag')->getMock();
return $request;
}
}

View File

@@ -0,0 +1,103 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Authentication;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\HttpUtils;
class DefaultAuthenticationSuccessHandlerTest extends TestCase
{
/**
* @dataProvider getRequestRedirections
*/
public function testRequestRedirections(Request $request, $options, $redirectedUrl)
{
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
$urlGenerator->expects($this->any())->method('generate')->will($this->returnValue('http://localhost/login'));
$httpUtils = new HttpUtils($urlGenerator);
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$handler = new DefaultAuthenticationSuccessHandler($httpUtils, $options);
if ($request->hasSession()) {
$handler->setProviderKey('admin');
}
$this->assertSame('http://localhost'.$redirectedUrl, $handler->onAuthenticationSuccess($request, $token)->getTargetUrl());
}
public function getRequestRedirections()
{
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session->expects($this->once())->method('get')->with('_security.admin.target_path')->will($this->returnValue('/admin/dashboard'));
$session->expects($this->once())->method('remove')->with('_security.admin.target_path');
$requestWithSession = Request::create('/');
$requestWithSession->setSession($session);
return array(
'default' => array(
Request::create('/'),
array(),
'/',
),
'forced target path' => array(
Request::create('/'),
array('always_use_default_target_path' => true, 'default_target_path' => '/dashboard'),
'/dashboard',
),
'target path as query string' => array(
Request::create('/?_target_path=/dashboard'),
array(),
'/dashboard',
),
'target path name as query string is customized' => array(
Request::create('/?_my_target_path=/dashboard'),
array('target_path_parameter' => '_my_target_path'),
'/dashboard',
),
'target path name as query string is customized and nested' => array(
Request::create('/?_target_path[value]=/dashboard'),
array('target_path_parameter' => '_target_path[value]'),
'/dashboard',
),
'target path in session' => array(
$requestWithSession,
array(),
'/admin/dashboard',
),
'target path as referer' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/dashboard')),
array('use_referer' => true),
'/dashboard',
),
'target path as referer is ignored if not configured' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/dashboard')),
array(),
'/',
),
'target path should be different than login URL' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login')),
array('use_referer' => true, 'login_path' => '/login'),
'/',
),
'target path should be different than login URL (query string does not matter)' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login?t=1&p=2')),
array('use_referer' => true, 'login_path' => '/login'),
'/',
),
'target path should be different than login URL (login_path as a route)' => array(
Request::create('/', 'GET', array(), array(), array(), array('HTTP_REFERER' => 'http://localhost/login?t=1&p=2')),
array('use_referer' => true, 'login_path' => 'login_route'),
'/',
),
);
}
}

View File

@@ -0,0 +1,196 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Authentication\SimpleAuthenticationHandler;
class SimpleAuthenticationHandlerTest extends TestCase
{
private $successHandler;
private $failureHandler;
private $request;
private $token;
private $authenticationException;
private $response;
protected function setUp()
{
$this->successHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface')->getMock();
$this->failureHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface')->getMock();
$this->request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$this->token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
// No methods are invoked on the exception; we just assert on its class
$this->authenticationException = new AuthenticationException();
$this->response = new Response();
}
public function testOnAuthenticationSuccessFallsBackToDefaultHandlerIfSimpleIsNotASuccessHandler()
{
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock();
$this->successHandler->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
$this->assertSame($this->response, $result);
}
public function testOnAuthenticationSuccessCallsSimpleAuthenticator()
{
$this->successHandler->expects($this->never())
->method('onAuthenticationSuccess');
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
$this->assertSame($this->response, $result);
}
/**
* @expectedException \UnexpectedValueException
* @expectedExceptionMessage onAuthenticationSuccess method must return null to use the default success handler, or a Response object
*/
public function testOnAuthenticationSuccessThrowsAnExceptionIfNonResponseIsReturned()
{
$this->successHandler->expects($this->never())
->method('onAuthenticationSuccess');
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue(new \stdClass()));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$handler->onAuthenticationSuccess($this->request, $this->token);
}
public function testOnAuthenticationSuccessFallsBackToDefaultHandlerIfNullIsReturned()
{
$this->successHandler->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue($this->response));
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestSuccessHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationSuccess')
->with($this->request, $this->token)
->will($this->returnValue(null));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationSuccess($this->request, $this->token);
$this->assertSame($this->response, $result);
}
public function testOnAuthenticationFailureFallsBackToDefaultHandlerIfSimpleIsNotAFailureHandler()
{
$authenticator = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\SimpleAuthenticatorInterface')->getMock();
$this->failureHandler->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
$this->assertSame($this->response, $result);
}
public function testOnAuthenticationFailureCallsSimpleAuthenticator()
{
$this->failureHandler->expects($this->never())
->method('onAuthenticationFailure');
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
$this->assertSame($this->response, $result);
}
/**
* @expectedException \UnexpectedValueException
* @expectedExceptionMessage onAuthenticationFailure method must return null to use the default failure handler, or a Response object
*/
public function testOnAuthenticationFailureThrowsAnExceptionIfNonResponseIsReturned()
{
$this->failureHandler->expects($this->never())
->method('onAuthenticationFailure');
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue(new \stdClass()));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$handler->onAuthenticationFailure($this->request, $this->authenticationException);
}
public function testOnAuthenticationFailureFallsBackToDefaultHandlerIfNullIsReturned()
{
$this->failureHandler->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue($this->response));
$authenticator = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Tests\TestFailureHandlerInterface');
$authenticator->expects($this->once())
->method('onAuthenticationFailure')
->with($this->request, $this->authenticationException)
->will($this->returnValue(null));
$handler = new SimpleAuthenticationHandler($authenticator, $this->successHandler, $this->failureHandler);
$result = $handler->onAuthenticationFailure($this->request, $this->authenticationException);
$this->assertSame($this->response, $result);
}
}
interface TestSuccessHandlerInterface extends AuthenticationSuccessHandlerInterface, SimpleAuthenticatorInterface
{
}
interface TestFailureHandlerInterface extends AuthenticationFailureHandlerInterface, SimpleAuthenticatorInterface
{
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class BasicAuthenticationEntryPointTest extends TestCase
{
public function testStart()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$authException = new AuthenticationException('The exception message');
$entryPoint = new BasicAuthenticationEntryPoint('TheRealmName');
$response = $entryPoint->start($request, $authException);
$this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
$this->assertEquals(401, $response->getStatusCode());
}
public function testStartWithoutAuthException()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$entryPoint = new BasicAuthenticationEntryPoint('TheRealmName');
$response = $entryPoint->start($request);
$this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
$this->assertEquals(401, $response->getStatusCode());
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
class DigestAuthenticationEntryPointTest extends TestCase
{
public function testStart()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$authenticationException = new AuthenticationException('TheAuthenticationExceptionMessage');
$entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request, $authenticationException);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
public function testStartWithNoException()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
public function testStartWithNonceExpiredException()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$nonceExpiredException = new NonceExpiredException('TheNonceExpiredExceptionMessage');
$entryPoint = new DigestAuthenticationEntryPoint('TheRealmName', 'TheSecret');
$response = $entryPoint->start($request, $nonceExpiredException);
$this->assertEquals(401, $response->getStatusCode());
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}", stale="true"$/', $response->headers->get('WWW-Authenticate'));
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class FormAuthenticationEntryPointTest extends TestCase
{
public function testStart()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$response = new Response();
$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils
->expects($this->once())
->method('createRedirectResponse')
->with($this->equalTo($request), $this->equalTo('/the/login/path'))
->will($this->returnValue($response))
;
$entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', false);
$this->assertEquals($response, $entryPoint->start($request));
}
public function testStartWithUseForward()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$subRequest = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$response = new Response('', 200);
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils
->expects($this->once())
->method('createRequest')
->with($this->equalTo($request), $this->equalTo('/the/login/path'))
->will($this->returnValue($subRequest))
;
$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$httpKernel
->expects($this->once())
->method('handle')
->with($this->equalTo($subRequest), $this->equalTo(HttpKernelInterface::SUB_REQUEST))
->will($this->returnValue($response))
;
$entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', true);
$entryPointResponse = $entryPoint->start($request);
$this->assertEquals($response, $entryPointResponse);
$this->assertEquals(401, $entryPointResponse->headers->get('X-Status-Code'));
}
}

View File

@@ -0,0 +1,65 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\EntryPoint;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint;
use Symfony\Component\HttpFoundation\Request;
class RetryAuthenticationEntryPointTest extends TestCase
{
/**
* @dataProvider dataForStart
*/
public function testStart($httpPort, $httpsPort, $request, $expectedUrl)
{
$entryPoint = new RetryAuthenticationEntryPoint($httpPort, $httpsPort);
$response = $entryPoint->start($request);
$this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
$this->assertEquals($expectedUrl, $response->headers->get('Location'));
}
public function dataForStart()
{
if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
return array(array());
}
return array(
array(
80,
443,
Request::create('http://localhost/foo/bar?baz=bat'),
'https://localhost/foo/bar?baz=bat',
),
array(
80,
443,
Request::create('https://localhost/foo/bar?baz=bat'),
'http://localhost/foo/bar?baz=bat',
),
array(
80,
123,
Request::create('http://localhost/foo/bar?baz=bat'),
'https://localhost:123/foo/bar?baz=bat',
),
array(
8080,
443,
Request::create('https://localhost/foo/bar?baz=bat'),
'http://localhost:8080/foo/bar?baz=bat',
),
);
}
}

View File

@@ -0,0 +1,253 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
class AbstractPreAuthenticatedListenerTest extends TestCase
{
public function testHandleWithValidValues()
{
$userCredentials = array('TheUser', 'TheCredentials');
$request = new Request(array(), array(), array(), array(), array(), array());
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->returnValue($token))
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWhenAuthenticationFails()
{
$userCredentials = array('TheUser', 'TheCredentials');
$request = new Request(array(), array(), array(), array(), array(), array());
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$exception = new AuthenticationException('Authentication failed.');
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWhenAuthenticationFailsWithDifferentToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO'));
$request = new Request(array(), array(), array(), array(), array(), array());
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$exception = new AuthenticationException('Authentication failed.');
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWithASimilarAuthenticatedToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$request = new Request(array(), array(), array(), array(), array(), array());
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->never())
->method('authenticate')
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWithAnInvalidSimilarToken()
{
$userCredentials = array('TheUser', 'TheCredentials');
$request = new Request(array(), array(), array(), array(), array(), array());
$token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo(null))
;
$exception = new AuthenticationException('Authentication failed.');
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken'))
->will($this->throwException($exception))
;
$listener = $this->getMockForAbstractClass('Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener', array(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
));
$listener
->expects($this->once())
->method('getPreAuthenticatedData')
->will($this->returnValue($userCredentials));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
}

View File

@@ -0,0 +1,209 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Firewall\AccessListener;
class AccessListenerTest extends TestCase
{
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array('foo' => 'bar'), null)))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(true))
;
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
$accessDecisionManager
->expects($this->once())
->method('decide')
->with($this->equalTo($token), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request))
->will($this->returnValue(false))
;
$listener = new AccessListener(
$tokenStorage,
$accessDecisionManager,
$accessMap,
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWhenTheTokenIsNotAuthenticated()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array('foo' => 'bar'), null)))
;
$notAuthenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$notAuthenticatedToken
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(false))
;
$authenticatedToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$authenticatedToken
->expects($this->any())
->method('isAuthenticated')
->will($this->returnValue(true))
;
$authManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authManager
->expects($this->once())
->method('authenticate')
->with($this->equalTo($notAuthenticatedToken))
->will($this->returnValue($authenticatedToken))
;
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($notAuthenticatedToken))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($authenticatedToken))
;
$accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
$accessDecisionManager
->expects($this->once())
->method('decide')
->with($this->equalTo($authenticatedToken), $this->equalTo(array('foo' => 'bar')), $this->equalTo($request))
->will($this->returnValue(true))
;
$listener = new AccessListener(
$tokenStorage,
$accessDecisionManager,
$accessMap,
$authManager
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWhenThereIsNoAccessMapEntryMatchingTheRequest()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(null, null)))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->never())
->method('isAuthenticated')
;
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$listener = new AccessListener(
$tokenStorage,
$this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock(),
$accessMap,
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testHandleWhenTheSecurityTokenStorageHasNoToken()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$listener = new AccessListener(
$tokenStorage,
$this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$listener->handle($event);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener;
class AnonymousAuthenticationListenerTest extends TestCase
{
public function testHandleWithTokenStorageHavingAToken()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->never())
->method('authenticate')
;
$listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager);
$listener->handle($this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock());
}
public function testHandleWithTokenStorageHavingNoToken()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$anonymousToken = new AnonymousToken('TheSecret', 'anon.', array());
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->callback(function ($token) {
return 'TheSecret' === $token->getSecret();
}))
->will($this->returnValue($anonymousToken))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($anonymousToken)
;
$listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager);
$listener->handle($this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock());
}
public function testHandledEventIsLogged()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger->expects($this->once())
->method('info')
->with('Populated the TokenStorage with an anonymous Token.')
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', $logger, $authenticationManager);
$listener->handle($this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock());
}
}

View File

@@ -0,0 +1,250 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener;
use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager;
class BasicAuthenticationListenerTest extends TestCase
{
public function testHandleWithValidUsernameAndPasswordServerParameters()
{
$request = new Request(array(), array(), array(), array(), array(), array(
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken'))
->will($this->returnValue($token))
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
$this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWhenAuthenticationFails()
{
$request = new Request(array(), array(), array(), array(), array(), array(
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue(null))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$response = new Response();
$authenticationEntryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$authenticationEntryPoint
->expects($this->any())
->method('start')
->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException'))
->will($this->returnValue($response))
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
new AuthenticationProviderManager(array($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock())),
'TheProviderKey',
$authenticationEntryPoint
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->once())
->method('setResponse')
->with($this->equalTo($response))
;
$listener->handle($event);
}
public function testHandleWithNoUsernameServerParameter()
{
$request = new Request();
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->never())
->method('getToken')
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
'TheProviderKey',
$this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testHandleWithASimilarAuthenticatedToken()
{
$request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_USER' => 'TheUsername'));
$token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', array('ROLE_FOO'));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$authenticationManager
->expects($this->never())
->method('authenticate')
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
$this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock()
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $providerKey must not be empty
*/
public function testItRequiresProviderKey()
{
new BasicAuthenticationListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
'',
$this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock()
);
}
public function testHandleWithADifferentAuthenticatedToken()
{
$request = new Request(array(), array(), array(), array(), array(), array(
'PHP_AUTH_USER' => 'TheUsername',
'PHP_AUTH_PW' => 'ThePassword',
));
$token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', array('ROLE_FOO'));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->any())
->method('getToken')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$response = new Response();
$authenticationEntryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$authenticationEntryPoint
->expects($this->any())
->method('start')
->with($this->equalTo($request), $this->isInstanceOf('Symfony\Component\Security\Core\Exception\AuthenticationException'))
->will($this->returnValue($response))
;
$listener = new BasicAuthenticationListener(
$tokenStorage,
new AuthenticationProviderManager(array($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface')->getMock())),
'TheProviderKey',
$authenticationEntryPoint
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->once())
->method('setResponse')
->with($this->equalTo($response))
;
$listener->handle($event);
}
}

View File

@@ -0,0 +1,181 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Firewall\ChannelListener;
use Symfony\Component\HttpFoundation\Response;
class ChannelListenerTest extends TestCase
{
public function testHandleWithNotSecuredRequestAndHttpChannel()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(false))
;
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'http')))
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint
->expects($this->never())
->method('start')
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->never())
->method('setResponse')
;
$listener = new ChannelListener($accessMap, $entryPoint);
$listener->handle($event);
}
public function testHandleWithSecuredRequestAndHttpsChannel()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(true))
;
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'https')))
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint
->expects($this->never())
->method('start')
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->never())
->method('setResponse')
;
$listener = new ChannelListener($accessMap, $entryPoint);
$listener->handle($event);
}
public function testHandleWithNotSecuredRequestAndHttpsChannel()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(false))
;
$response = new Response();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'https')))
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint
->expects($this->once())
->method('start')
->with($this->equalTo($request))
->will($this->returnValue($response))
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->once())
->method('setResponse')
->with($this->equalTo($response))
;
$listener = new ChannelListener($accessMap, $entryPoint);
$listener->handle($event);
}
public function testHandleWithSecuredRequestAndHttpChannel()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$request
->expects($this->any())
->method('isSecure')
->will($this->returnValue(true))
;
$response = new Response();
$accessMap = $this->getMockBuilder('Symfony\Component\Security\Http\AccessMapInterface')->getMock();
$accessMap
->expects($this->any())
->method('getPatterns')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), 'http')))
;
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint
->expects($this->once())
->method('start')
->with($this->equalTo($request))
->will($this->returnValue($response))
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$event
->expects($this->once())
->method('setResponse')
->with($this->equalTo($response))
;
$listener = new ChannelListener($accessMap, $entryPoint);
$listener->handle($event);
}
}

View File

@@ -0,0 +1,380 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Firewall\ContextListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
class ContextListenerTest extends TestCase
{
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $contextKey must not be empty
*/
public function testItRequiresContextKey()
{
new ContextListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
array(),
''
);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage User provider "stdClass" must implement "Symfony\Component\Security\Core\User\UserProviderInterface
*/
public function testUserProvidersNeedToImplementAnInterface()
{
new ContextListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
array(new \stdClass()),
'key123'
);
}
public function testOnKernelResponseWillAddSession()
{
$session = $this->runSessionOnKernelResponse(
new UsernamePasswordToken('test1', 'pass1', 'phpunit'),
null
);
$token = unserialize($session->get('_security_session'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $token);
$this->assertEquals('test1', $token->getUsername());
}
public function testOnKernelResponseWillReplaceSession()
{
$session = $this->runSessionOnKernelResponse(
new UsernamePasswordToken('test1', 'pass1', 'phpunit'),
'C:10:"serialized"'
);
$token = unserialize($session->get('_security_session'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $token);
$this->assertEquals('test1', $token->getUsername());
}
public function testOnKernelResponseWillRemoveSession()
{
$session = $this->runSessionOnKernelResponse(
null,
'C:10:"serialized"'
);
$this->assertFalse($session->has('_security_session'));
}
public function testOnKernelResponseWillRemoveSessionOnAnonymousToken()
{
$session = $this->runSessionOnKernelResponse(new AnonymousToken('secret', 'anon.'), 'C:10:"serialized"');
$this->assertFalse($session->has('_security_session'));
}
public function testOnKernelResponseWithoutSession()
{
$tokenStorage = new TokenStorage();
$tokenStorage->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
$request = new Request();
$session = new Session(new MockArraySessionStorage());
$request->setSession($session);
$event = new FilterResponseEvent(
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$request,
HttpKernelInterface::MASTER_REQUEST,
new Response()
);
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertTrue($session->isStarted());
}
public function testOnKernelResponseWithoutSessionNorToken()
{
$request = new Request();
$session = new Session(new MockArraySessionStorage());
$request->setSession($session);
$event = new FilterResponseEvent(
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$request,
HttpKernelInterface::MASTER_REQUEST,
new Response()
);
$listener = new ContextListener(new TokenStorage(), array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
$this->assertFalse($session->isStarted());
}
/**
* @dataProvider provideInvalidToken
*/
public function testInvalidTokenInSession($token)
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
$request->expects($this->any())
->method('hasPreviousSession')
->will($this->returnValue(true));
$request->expects($this->any())
->method('getSession')
->will($this->returnValue($session));
$session->expects($this->any())
->method('get')
->with('_security_key123')
->will($this->returnValue($token));
$tokenStorage->expects($this->once())
->method('setToken')
->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123');
$listener->handle($event);
}
public function provideInvalidToken()
{
return array(
array(serialize(new \__PHP_Incomplete_Class())),
array(serialize(null)),
array(null),
);
}
public function testHandleAddsKernelResponseListener()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$event->expects($this->any())
->method('isMasterRequest')
->will($this->returnValue(true));
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock()));
$dispatcher->expects($this->once())
->method('addListener')
->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse'));
$listener->handle($event);
}
public function testOnKernelResponseListenerRemovesItself()
{
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')
->disableOriginalConstructor()
->getMock();
$listener = new ContextListener($tokenStorage, array(), 'key123', null, $dispatcher);
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->expects($this->any())
->method('hasSession')
->will($this->returnValue(true));
$event->expects($this->any())
->method('isMasterRequest')
->will($this->returnValue(true));
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request));
$dispatcher->expects($this->once())
->method('removeListener')
->with(KernelEvents::RESPONSE, array($listener, 'onKernelResponse'));
$listener->onKernelResponse($event);
}
public function testHandleRemovesTokenIfNoPreviousSessionWasFound()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$request->expects($this->any())->method('hasPreviousSession')->will($this->returnValue(false));
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->once())->method('setToken')->with(null);
$listener = new ContextListener($tokenStorage, array(), 'key123');
$listener->handle($event);
}
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
{
$tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, array(new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)));
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
}
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
{
$tokenStorage = new TokenStorage();
$this->handleEventWithPreviousSession($tokenStorage, array(new NotSupportingUserProvider(), new SupportingUserProvider()));
$this->assertNull($tokenStorage->getToken());
}
/**
* @expectedException \RuntimeException
*/
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
{
$this->handleEventWithPreviousSession(new TokenStorage(), array(new NotSupportingUserProvider(), new NotSupportingUserProvider()));
}
protected function runSessionOnKernelResponse($newToken, $original = null)
{
$session = new Session(new MockArraySessionStorage());
if ($original !== null) {
$session->set('_security_session', $original);
}
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($newToken);
$request = new Request();
$request->setSession($session);
$request->cookies->set('MOCKSESSID', true);
$event = new FilterResponseEvent(
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$request,
HttpKernelInterface::MASTER_REQUEST,
new Response()
);
$listener = new ContextListener($tokenStorage, array(), 'session', null, new EventDispatcher());
$listener->onKernelResponse($event);
return $session;
}
private function handleEventWithPreviousSession(TokenStorageInterface $tokenStorage, array $userProviders)
{
$session = new Session(new MockArraySessionStorage());
$session->set('_security_context_key', serialize(new UsernamePasswordToken(new User('foo', 'bar'), '', 'context_key')));
$request = new Request();
$request->setSession($session);
$request->cookies->set('MOCKSESSID', true);
$listener = new ContextListener($tokenStorage, $userProviders, 'context_key');
$listener->handle(new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
}
}
class NotSupportingUserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
throw new UsernameNotFoundException();
}
public function refreshUser(UserInterface $user)
{
throw new UnsupportedUserException();
}
public function supportsClass($class)
{
return false;
}
}
class SupportingUserProvider implements UserProviderInterface
{
private $refreshedUser;
public function __construct(User $refreshedUser = null)
{
$this->refreshedUser = $refreshedUser;
}
public function loadUserByUsername($username)
{
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof User) {
throw new UnsupportedUserException();
}
if (null === $this->refreshedUser) {
throw new UsernameNotFoundException();
}
return $this->refreshedUser;
}
public function supportsClass($class)
{
return 'Symfony\Component\Security\Core\User\User' === $class;
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
use Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener;
class DigestAuthenticationListenerTest extends TestCase
{
public function testHandleWithValidDigest()
{
$time = microtime(true) + 1000;
$secret = 'ThisIsASecret';
$nonce = base64_encode($time.':'.md5($time.':'.$secret));
$username = 'user';
$password = 'password';
$realm = 'Welcome, robot!';
$cnonce = 'MDIwODkz';
$nc = '00000001';
$qop = 'auth';
$uri = '/path/info?p1=5&p2=5';
$serverDigest = $this->calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, 'GET', $uri);
$digestData =
'username="'.$username.'", realm="'.$realm.'", nonce="'.$nonce.'", '.
'uri="'.$uri.'", cnonce="'.$cnonce.'", nc='.$nc.', qop="'.$qop.'", '.
'response="'.$serverDigest.'"'
;
$request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_DIGEST' => $digestData));
$entryPoint = new DigestAuthenticationEntryPoint($realm, $secret);
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user->method('getPassword')->willReturn($password);
$providerKey = 'TheProviderKey';
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo(new UsernamePasswordToken($user, $password, $providerKey)))
;
$userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$userProvider->method('loadUserByUsername')->willReturn($user);
$listener = new DigestAuthenticationListener($tokenStorage, $userProvider, $providerKey, $entryPoint);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
private function calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, $method, $uri)
{
$response = md5(
md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri)
);
return sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"',
$username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response
);
}
}

View File

@@ -0,0 +1,185 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Firewall\DigestData;
class DigestDataTest extends TestCase
{
public function testGetResponse()
{
$digestAuth = new DigestData(
'username="user", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('b52938fc9e6d7c01be7702ece9031b42', $digestAuth->getResponse());
}
public function testGetUsername()
{
$digestAuth = new DigestData(
'username="user", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('user', $digestAuth->getUsername());
}
public function testGetUsernameWithQuote()
{
$digestAuth = new DigestData(
'username="\"user\"", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('"user"', $digestAuth->getUsername());
}
public function testGetUsernameWithQuoteAndEscape()
{
$digestAuth = new DigestData(
'username="\"u\\\\\"ser\"", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('"u\\"ser"', $digestAuth->getUsername());
}
public function testGetUsernameWithSingleQuote()
{
$digestAuth = new DigestData(
'username="\"u\'ser\"", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('"u\'ser"', $digestAuth->getUsername());
}
public function testGetUsernameWithSingleQuoteAndEscape()
{
$digestAuth = new DigestData(
'username="\"u\\\'ser\"", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('"u\\\'ser"', $digestAuth->getUsername());
}
public function testGetUsernameWithEscape()
{
$digestAuth = new DigestData(
'username="\"u\\ser\"", realm="Welcome, robot!", '.
'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$this->assertEquals('"u\\ser"', $digestAuth->getUsername());
}
/**
* @group time-sensitive
*/
public function testValidateAndDecode()
{
$time = microtime(true);
$key = 'ThisIsAKey';
$nonce = base64_encode($time.':'.md5($time.':'.$key));
$digestAuth = new DigestData(
'username="user", realm="Welcome, robot!", nonce="'.$nonce.'", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$digestAuth->validateAndDecode($key, 'Welcome, robot!');
sleep(1);
$this->assertTrue($digestAuth->isNonceExpired());
}
public function testCalculateServerDigest()
{
$this->calculateServerDigest('user', 'Welcome, robot!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
}
public function testCalculateServerDigestWithQuote()
{
$this->calculateServerDigest('\"user\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
}
public function testCalculateServerDigestWithQuoteAndEscape()
{
$this->calculateServerDigest('\"u\\\\\"ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
}
public function testCalculateServerDigestEscape()
{
$this->calculateServerDigest('\"u\\ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
$this->calculateServerDigest('\"u\\ser\\\\\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
}
public function testIsNonceExpired()
{
$time = microtime(true) + 10;
$key = 'ThisIsAKey';
$nonce = base64_encode($time.':'.md5($time.':'.$key));
$digestAuth = new DigestData(
'username="user", realm="Welcome, robot!", nonce="'.$nonce.'", '.
'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", '.
'response="b52938fc9e6d7c01be7702ece9031b42"'
);
$digestAuth->validateAndDecode($key, 'Welcome, robot!');
$this->assertFalse($digestAuth->isNonceExpired());
}
protected function setUp()
{
class_exists('Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener', true);
}
private function calculateServerDigest($username, $realm, $password, $key, $nc, $cnonce, $qop, $method, $uri)
{
$time = microtime(true);
$nonce = base64_encode($time.':'.md5($time.':'.$key));
$response = md5(
md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri)
);
$digest = sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"',
$username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response
);
$digestAuth = new DigestData($digest);
$this->assertEquals($digestAuth->getResponse(), $digestAuth->calculateServerDigest($password, $method));
}
}

View File

@@ -0,0 +1,199 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
use Symfony\Component\Security\Http\HttpUtils;
class ExceptionListenerTest extends TestCase
{
/**
* @dataProvider getAuthenticationExceptionProvider
*/
public function testAuthenticationExceptionWithoutEntryPoint(\Exception $exception, \Exception $eventException = null)
{
$event = $this->createEvent($exception);
$listener = $this->createExceptionListener();
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException());
}
/**
* @dataProvider getAuthenticationExceptionProvider
*/
public function testAuthenticationExceptionWithEntryPoint(\Exception $exception, \Exception $eventException = null)
{
$event = $this->createEvent($exception = new AuthenticationException());
$listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint());
$listener->onKernelException($event);
$this->assertEquals('OK', $event->getResponse()->getContent());
$this->assertSame($exception, $event->getException());
}
public function getAuthenticationExceptionProvider()
{
return array(
array(new AuthenticationException()),
array(new \LogicException('random', 0, $e = new AuthenticationException()), $e),
array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AuthenticationException())), $e),
array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AccessDeniedException())), $e),
array(new AuthenticationException('random', 0, new \LogicException())),
);
}
public function testExceptionWhenEntryPointReturnsBadValue()
{
$event = $this->createEvent(new AuthenticationException());
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint->expects($this->once())->method('start')->will($this->returnValue('NOT A RESPONSE'));
$listener = $this->createExceptionListener(null, null, null, $entryPoint);
$listener->onKernelException($event);
// the exception has been replaced by our LogicException
$this->assertInstanceOf('LogicException', $event->getException());
$this->assertStringEndsWith('start() method must return a Response object (string returned)', $event->getException()->getMessage());
}
/**
* @dataProvider getAccessDeniedExceptionProvider
*/
public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
{
$event = $this->createEvent($exception);
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true));
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
/**
* @dataProvider getAccessDeniedExceptionProvider
*/
public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
$event = $this->createEvent($exception, $kernel);
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error');
$listener->onKernelException($event);
$this->assertEquals('error', $event->getResponse()->getContent());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
/**
* @dataProvider getAccessDeniedExceptionProvider
*/
public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
{
$event = $this->createEvent($exception);
$accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock();
$accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
$listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler);
$listener->onKernelException($event);
$this->assertEquals('error', $event->getResponse()->getContent());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
/**
* @dataProvider getAccessDeniedExceptionProvider
*/
public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \Exception $eventException = null)
{
$event = $this->createEvent($exception);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()));
$listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint());
$listener->onKernelException($event);
$this->assertEquals('OK', $event->getResponse()->getContent());
$this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
}
public function getAccessDeniedExceptionProvider()
{
return array(
array(new AccessDeniedException()),
array(new \LogicException('random', 0, $e = new AccessDeniedException()), $e),
array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AccessDeniedException())), $e),
array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AuthenticationException())), $e),
array(new AccessDeniedException('random', new \LogicException())),
);
}
private function createEntryPoint()
{
$entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock();
$entryPoint->expects($this->once())->method('start')->will($this->returnValue(new Response('OK')));
return $entryPoint;
}
private function createTrustResolver($fullFledged)
{
$trustResolver = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock();
$trustResolver->expects($this->once())->method('isFullFledged')->will($this->returnValue($fullFledged));
return $trustResolver;
}
private function createEvent(\Exception $exception, $kernel = null)
{
if (null === $kernel) {
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
}
return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
}
private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
{
return new ExceptionListener(
$tokenStorage ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
$trustResolver ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock(),
$httpUtils ?: $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock(),
'key',
$authenticationEntryPoint,
$errorPage,
$accessDeniedHandler
);
}
}

View File

@@ -0,0 +1,236 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\LogoutListener;
class LogoutListenerTest extends TestCase
{
public function testHandleUnmatchedPath()
{
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener();
list($event, $request) = $this->getGetResponseEvent();
$event->expects($this->never())
->method('setResponse');
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(false));
$listener->handle($event);
}
public function testHandleMatchedPathWithSuccessHandlerAndCsrfValidation()
{
$successHandler = $this->getSuccessHandler();
$tokenManager = $this->getTokenManager();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler, $tokenManager);
list($event, $request) = $this->getGetResponseEvent();
$request->query->set('_csrf_token', 'token');
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
$tokenManager->expects($this->once())
->method('isTokenValid')
->will($this->returnValue(true));
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue($response = new Response()));
$tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
$handler = $this->getHandler();
$handler->expects($this->once())
->method('logout')
->with($request, $response, $token);
$tokenStorage->expects($this->once())
->method('setToken')
->with(null);
$event->expects($this->once())
->method('setResponse')
->with($response);
$listener->addHandler($handler);
$listener->handle($event);
}
public function testHandleMatchedPathWithoutSuccessHandlerAndCsrfValidation()
{
$successHandler = $this->getSuccessHandler();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue($response = new Response()));
$tokenStorage->expects($this->once())
->method('getToken')
->will($this->returnValue($token = $this->getToken()));
$handler = $this->getHandler();
$handler->expects($this->once())
->method('logout')
->with($request, $response, $token);
$tokenStorage->expects($this->once())
->method('setToken')
->with(null);
$event->expects($this->once())
->method('setResponse')
->with($response);
$listener->addHandler($handler);
$listener->handle($event);
}
/**
* @expectedException \RuntimeException
*/
public function testSuccessHandlerReturnsNonResponse()
{
$successHandler = $this->getSuccessHandler();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
$successHandler->expects($this->once())
->method('onLogoutSuccess')
->with($request)
->will($this->returnValue(null));
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\LogoutException
*/
public function testCsrfValidationFails()
{
$tokenManager = $this->getTokenManager();
list($listener, $tokenStorage, $httpUtils, $options) = $this->getListener(null, $tokenManager);
list($event, $request) = $this->getGetResponseEvent();
$request->query->set('_csrf_token', 'token');
$httpUtils->expects($this->once())
->method('checkRequestPath')
->with($request, $options['logout_path'])
->will($this->returnValue(true));
$tokenManager->expects($this->once())
->method('isTokenValid')
->will($this->returnValue(false));
$listener->handle($event);
}
private function getTokenManager()
{
return $this->getMockBuilder('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface')->getMock();
}
private function getTokenStorage()
{
return $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
}
private function getGetResponseEvent()
{
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
->getMock();
$event->expects($this->any())
->method('getRequest')
->will($this->returnValue($request = new Request()));
return array($event, $request);
}
private function getHandler()
{
return $this->getMockBuilder('Symfony\Component\Security\Http\Logout\LogoutHandlerInterface')->getMock();
}
private function getHttpUtils()
{
return $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')
->disableOriginalConstructor()
->getMock();
}
private function getListener($successHandler = null, $tokenManager = null)
{
$listener = new LogoutListener(
$tokenStorage = $this->getTokenStorage(),
$httpUtils = $this->getHttpUtils(),
$successHandler ?: $this->getSuccessHandler(),
$options = array(
'csrf_parameter' => '_csrf_token',
'csrf_token_id' => 'logout',
'logout_path' => '/logout',
'target_url' => '/',
),
$tokenManager
);
return array($listener, $tokenStorage, $httpUtils, $options);
}
private function getSuccessHandler()
{
return $this->getMockBuilder('Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface')->getMock();
}
private function getToken()
{
return $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
}
}

View File

@@ -0,0 +1,416 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Firewall\RememberMeListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\SecurityEvents;
class RememberMeListenerTest extends TestCase
{
public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage()
{
list($listener, $tokenStorage) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
;
$tokenStorage
->expects($this->never())
->method('setToken')
;
$this->assertNull($listener->handle($this->getGetResponseEvent()));
}
public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet()
{
list($listener, $tokenStorage, $service) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue(null))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
;
$this->assertNull($listener->handle($event));
}
public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
;
$service
->expects($this->once())
->method('loginFail')
;
$exception = new AuthenticationException('Authentication failed.');
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
;
$listener->handle($event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException
* @expectedExceptionMessage Authentication failed.
*/
public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener(false, false);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock()))
;
$service
->expects($this->once())
->method('loginFail')
;
$exception = new AuthenticationException('Authentication failed.');
$manager
->expects($this->once())
->method('authenticate')
->will($this->throwException($exception))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
;
$listener->handle($event);
}
public function testOnCoreSecurity()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
;
$listener->handle($event);
}
public function testSessionStrategy()
{
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
;
$session = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session
->expects($this->once())
->method('isStarted')
->will($this->returnValue(true))
;
$request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')->getMock();
$request
->expects($this->once())
->method('hasSession')
->will($this->returnValue(true))
;
$request
->expects($this->once())
->method('getSession')
->will($this->returnValue($session))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
;
$sessionStrategy
->expects($this->once())
->method('onAuthentication')
->will($this->returnValue(null))
;
$listener->handle($event);
}
public function testSessionIsMigratedByDefault()
{
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
;
$session = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session
->expects($this->once())
->method('isStarted')
->will($this->returnValue(true))
;
$session
->expects($this->once())
->method('migrate')
;
$request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')->getMock();
$request
->expects($this->any())
->method('hasSession')
->will($this->returnValue(true))
;
$request
->expects($this->any())
->method('getSession')
->will($this->returnValue($session))
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent()
{
list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true);
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service
->expects($this->once())
->method('autoLogin')
->will($this->returnValue($token))
;
$tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($token))
;
$manager
->expects($this->once())
->method('authenticate')
->will($this->returnValue($token))
;
$event = $this->getGetResponseEvent();
$request = new Request();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue($request))
;
$dispatcher
->expects($this->once())
->method('dispatch')
->with(
SecurityEvents::INTERACTIVE_LOGIN,
$this->isInstanceOf('Symfony\Component\Security\Http\Event\InteractiveLoginEvent')
)
;
$listener->handle($event);
}
protected function getGetResponseEvent()
{
return $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
}
protected function getFilterResponseEvent()
{
return $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')->disableOriginalConstructor()->getMock();
}
protected function getListener($withDispatcher = false, $catchExceptions = true, $withSessionStrategy = false)
{
$listener = new RememberMeListener(
$tokenStorage = $this->getTokenStorage(),
$service = $this->getService(),
$manager = $this->getManager(),
$logger = $this->getLogger(),
$dispatcher = ($withDispatcher ? $this->getDispatcher() : null),
$catchExceptions,
$sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null)
);
return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy);
}
protected function getLogger()
{
return $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
}
protected function getManager()
{
return $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
}
protected function getService()
{
return $this->getMockBuilder('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface')->getMock();
}
protected function getTokenStorage()
{
return $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
}
protected function getDispatcher()
{
return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
}
private function getSessionStrategy()
{
return $this->getMockBuilder('\Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock();
}
}

View File

@@ -0,0 +1,92 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Firewall\RemoteUserAuthenticationListener;
class RemoteUserAuthenticationListenerTest extends TestCase
{
public function testGetPreAuthenticatedData()
{
$serverVars = array(
'REMOTE_USER' => 'TheUser',
);
$request = new Request(array(), array(), array(), array(), array(), $serverVars);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new RemoteUserAuthenticationListener(
$tokenStorage,
$authenticationManager,
'TheProviderKey'
);
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array('TheUser', null));
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testGetPreAuthenticatedDataNoUser()
{
$request = new Request(array(), array(), array(), array(), array(), array());
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new RemoteUserAuthenticationListener(
$tokenStorage,
$authenticationManager,
'TheProviderKey'
);
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
}
public function testGetPreAuthenticatedDataWithDifferentKeys()
{
$userCredentials = array('TheUser', null);
$request = new Request(array(), array(), array(), array(), array(), array(
'TheUserKey' => 'TheUser',
));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new RemoteUserAuthenticationListener(
$tokenStorage,
$authenticationManager,
'TheProviderKey',
'TheUserKey'
);
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, $userCredentials);
}
}

View File

@@ -0,0 +1,129 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener;
use Symfony\Component\Security\Http\SecurityEvents;
class SimplePreAuthenticationListenerTest extends TestCase
{
private $authenticationManager;
private $dispatcher;
private $event;
private $logger;
private $request;
private $tokenStorage;
private $token;
public function testHandle()
{
$this->tokenStorage
->expects($this->once())
->method('setToken')
->with($this->equalTo($this->token))
;
$this->authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->equalTo($this->token))
->will($this->returnValue($this->token))
;
$simpleAuthenticator = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface')->getMock();
$simpleAuthenticator
->expects($this->once())
->method('createToken')
->with($this->equalTo($this->request), $this->equalTo('secured_area'))
->will($this->returnValue($this->token))
;
$loginEvent = new InteractiveLoginEvent($this->request, $this->token);
$this->dispatcher
->expects($this->once())
->method('dispatch')
->with($this->equalTo(SecurityEvents::INTERACTIVE_LOGIN), $this->equalTo($loginEvent))
;
$listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher);
$listener->handle($this->event);
}
public function testHandlecatchAuthenticationException()
{
$exception = new AuthenticationException('Authentication failed.');
$this->authenticationManager
->expects($this->once())
->method('authenticate')
->with($this->equalTo($this->token))
->will($this->throwException($exception))
;
$this->tokenStorage->expects($this->once())
->method('setToken')
->with($this->equalTo(null))
;
$simpleAuthenticator = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface')->getMock();
$simpleAuthenticator
->expects($this->once())
->method('createToken')
->with($this->equalTo($this->request), $this->equalTo('secured_area'))
->will($this->returnValue($this->token))
;
$listener = new SimplePreAuthenticationListener($this->tokenStorage, $this->authenticationManager, 'secured_area', $simpleAuthenticator, $this->logger, $this->dispatcher);
$listener->handle($this->event);
}
protected function setUp()
{
$this->authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')
->disableOriginalConstructor()
->getMock()
;
$this->dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$this->request = new Request(array(), array(), array(), array(), array(), array());
$this->event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$this->event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($this->request))
;
$this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$this->token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
}
protected function tearDown()
{
$this->authenticationManager = null;
$this->dispatcher = null;
$this->event = null;
$this->logger = null;
$this->request = null;
$this->tokenStorage = null;
$this->token = null;
}
}

View File

@@ -0,0 +1,230 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Http\Event\SwitchUserEvent;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
use Symfony\Component\Security\Http\SecurityEvents;
class SwitchUserListenerTest extends TestCase
{
private $tokenStorage;
private $userProvider;
private $userChecker;
private $accessDecisionManager;
private $request;
private $event;
protected function setUp()
{
$this->tokenStorage = new TokenStorage();
$this->userProvider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$this->userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
$this->accessDecisionManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')->getMock();
$this->request = new Request();
$this->event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $this->request, HttpKernelInterface::MASTER_REQUEST);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage $providerKey must not be empty
*/
public function testProviderKeyIsRequired()
{
new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, '', $this->accessDecisionManager);
}
public function testEventIsIgnoredIfUsernameIsNotPassedWithTheRequest()
{
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertNull($this->event->getResponse());
$this->assertNull($this->tokenStorage->getToken());
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testExitUserThrowsAuthenticationExceptionIfNoCurrentToken()
{
$this->tokenStorage->setToken(null);
$this->request->query->set('_switch_user', '_exit');
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testExitUserThrowsAuthenticationExceptionIfOriginalTokenCannotBeFound()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', '_exit');
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
public function testExitUserUpdatesToken()
{
$originalToken = new UsernamePasswordToken('username', '', 'key', array());
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$this->request->query->set('_switch_user', '_exit');
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame(array(), $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $this->event->getResponse());
$this->assertSame($this->request->getUri(), $this->event->getResponse()->getTargetUrl());
$this->assertSame($originalToken, $this->tokenStorage->getToken());
}
public function testExitUserDispatchesEventWithRefreshedUser()
{
$originalUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$refreshedUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$this
->userProvider
->expects($this->any())
->method('refreshUser')
->with($originalUser)
->willReturn($refreshedUser);
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$this->request->query->set('_switch_user', '_exit');
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
->expects($this->once())
->method('dispatch')
->with(SecurityEvents::SWITCH_USER, $this->callback(function (SwitchUserEvent $event) use ($refreshedUser) {
return $event->getTargetUser() === $refreshedUser;
}))
;
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
$listener->handle($this->event);
}
public function testExitUserDoesNotDispatchEventWithStringUser()
{
$originalUser = 'anon.';
$this
->userProvider
->expects($this->never())
->method('refreshUser');
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken))));
$this->request->query->set('_switch_user', '_exit');
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher
->expects($this->never())
->method('dispatch')
;
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher);
$listener->handle($this->event);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testSwitchUserIsDisallowed()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(false));
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
}
public function testSwitchUser()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$user = new User('username', 'password', array());
$this->tokenStorage->setToken($token);
$this->request->query->set('_switch_user', 'kuba');
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(true));
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('kuba')
->will($this->returnValue($user));
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame(array(), $this->request->query->all());
$this->assertSame('', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
}
public function testSwitchUserKeepsOtherQueryStringParameters()
{
$token = new UsernamePasswordToken('username', '', 'key', array('ROLE_FOO'));
$user = new User('username', 'password', array());
$this->tokenStorage->setToken($token);
$this->request->query->replace(array(
'_switch_user' => 'kuba',
'page' => 3,
'section' => 2,
));
$this->accessDecisionManager->expects($this->once())
->method('decide')->with($token, array('ROLE_ALLOWED_TO_SWITCH'))
->will($this->returnValue(true));
$this->userProvider->expects($this->once())
->method('loadUserByUsername')->with('kuba')
->will($this->returnValue($user));
$this->userChecker->expects($this->once())
->method('checkPostAuth')->with($user);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame('page=3&section=2', $this->request->server->get('QUERY_STRING'));
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $this->tokenStorage->getToken());
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Tests\Http\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
use Symfony\Component\Security\Core\Security;
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
{
/**
* @dataProvider getUsernameForLength
*/
public function testHandleWhenUsernameLength($username, $ok)
{
$request = Request::create('/login_check', 'POST', array('_username' => $username));
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils
->expects($this->any())
->method('checkRequestPath')
->will($this->returnValue(true))
;
$failureHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface')->getMock();
$failureHandler
->expects($ok ? $this->never() : $this->once())
->method('onAuthenticationFailure')
->will($this->returnValue(new Response()))
;
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')->disableOriginalConstructor()->getMock();
$authenticationManager
->expects($ok ? $this->once() : $this->never())
->method('authenticate')
->will($this->returnValue(new Response()))
;
$listener = new UsernamePasswordFormAuthenticationListener(
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(),
$authenticationManager,
$this->getMockBuilder('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock(),
$httpUtils,
'TheProviderKey',
$this->getMockBuilder('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface')->getMock(),
$failureHandler,
array('require_previous_session' => false)
);
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
$event
->expects($this->any())
->method('getRequest')
->will($this->returnValue($request))
;
$listener->handle($event);
}
public function getUsernameForLength()
{
return array(
array(str_repeat('x', Security::MAX_USERNAME_LENGTH + 1), false),
array(str_repeat('x', Security::MAX_USERNAME_LENGTH - 1), true),
);
}
}

View File

@@ -0,0 +1,124 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Firewall;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener;
class X509AuthenticationListenerTest extends TestCase
{
/**
* @dataProvider dataProviderGetPreAuthenticatedData
*/
public function testGetPreAuthenticatedData($user, $credentials)
{
$serverVars = array();
if ('' !== $user) {
$serverVars['SSL_CLIENT_S_DN_Email'] = $user;
}
if ('' !== $credentials) {
$serverVars['SSL_CLIENT_S_DN'] = $credentials;
}
$request = new Request(array(), array(), array(), array(), array(), $serverVars);
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array($user, $credentials));
}
public static function dataProviderGetPreAuthenticatedData()
{
return array(
'validValues' => array('TheUser', 'TheCredentials'),
'noCredentials' => array('TheUser', ''),
);
}
/**
* @dataProvider dataProviderGetPreAuthenticatedDataNoUser
*/
public function testGetPreAuthenticatedDataNoUser($emailAddress)
{
$credentials = 'CN=Sample certificate DN/emailAddress='.$emailAddress;
$request = new Request(array(), array(), array(), array(), array(), array('SSL_CLIENT_S_DN' => $credentials));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, array($emailAddress, $credentials));
}
public static function dataProviderGetPreAuthenticatedDataNoUser()
{
return array(
'basicEmailAddress' => array('cert@example.com'),
'emailAddressWithPlusSign' => array('cert+something@example.com'),
);
}
/**
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testGetPreAuthenticatedDataNoData()
{
$request = new Request(array(), array(), array(), array(), array(), array());
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
}
public function testGetPreAuthenticatedDataWithDifferentKeys()
{
$userCredentials = array('TheUser', 'TheCredentials');
$request = new Request(array(), array(), array(), array(), array(), array(
'TheUserKey' => 'TheUser',
'TheCredentialsKey' => 'TheCredentials',
));
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
$authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock();
$listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey');
$method = new \ReflectionMethod($listener, 'getPreAuthenticatedData');
$method->setAccessible(true);
$result = $method->invokeArgs($listener, array($request));
$this->assertSame($result, $userCredentials);
}
}

View File

@@ -0,0 +1,118 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\FirewallMap;
use Symfony\Component\HttpFoundation\Request;
class FirewallMapTest extends TestCase
{
public function testGetListeners()
{
$map = new FirewallMap();
$request = new Request();
$notMatchingMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$notMatchingMatcher
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$matchingMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$matchingMatcher
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(true))
;
$theListener = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$theException = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ExceptionListener')->disableOriginalConstructor()->getMock();
$map->add($matchingMatcher, array($theListener), $theException);
$tooLateMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$tooLateMatcher
->expects($this->never())
->method('matches')
;
$map->add($tooLateMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array($theListener), $listeners);
$this->assertEquals($theException, $exception);
}
public function testGetListenersWithAnEntryHavingNoRequestMatcher()
{
$map = new FirewallMap();
$request = new Request();
$notMatchingMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$notMatchingMatcher
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
$theListener = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$theException = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ExceptionListener')->disableOriginalConstructor()->getMock();
$map->add(null, array($theListener), $theException);
$tooLateMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$tooLateMatcher
->expects($this->never())
->method('matches')
;
$map->add($tooLateMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array($theListener), $listeners);
$this->assertEquals($theException, $exception);
}
public function testGetListenersWithNoMatchingEntry()
{
$map = new FirewallMap();
$request = new Request();
$notMatchingMatcher = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestMatcher')->getMock();
$notMatchingMatcher
->expects($this->once())
->method('matches')
->with($this->equalTo($request))
->will($this->returnValue(false))
;
$map->add($notMatchingMatcher, array($this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock()));
list($listeners, $exception) = $map->getListeners($request);
$this->assertEquals(array(), $listeners);
$this->assertNull($exception);
}
}

View File

@@ -0,0 +1,110 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\Firewall;
class FirewallTest extends TestCase
{
public function testOnKernelRequestRegistersExceptionListener()
{
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$listener = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ExceptionListener')->disableOriginalConstructor()->getMock();
$listener
->expects($this->once())
->method('register')
->with($this->equalTo($dispatcher))
;
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock();
$map = $this->getMockBuilder('Symfony\Component\Security\Http\FirewallMapInterface')->getMock();
$map
->expects($this->once())
->method('getListeners')
->with($this->equalTo($request))
->will($this->returnValue(array(array(), $listener)))
;
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$firewall = new Firewall($map, $dispatcher);
$firewall->onKernelRequest($event);
}
public function testOnKernelRequestStopsWhenThereIsAResponse()
{
$response = new Response();
$first = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$first
->expects($this->once())
->method('handle')
;
$second = $this->getMockBuilder('Symfony\Component\Security\Http\Firewall\ListenerInterface')->getMock();
$second
->expects($this->never())
->method('handle')
;
$map = $this->getMockBuilder('Symfony\Component\Security\Http\FirewallMapInterface')->getMock();
$map
->expects($this->once())
->method('getListeners')
->will($this->returnValue(array(array($first, $second), null)))
;
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->setMethods(array('hasResponse'))
->setConstructorArgs(array(
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->disableOriginalConstructor()->disableOriginalClone()->getMock(),
HttpKernelInterface::MASTER_REQUEST,
))
->getMock()
;
$event
->expects($this->once())
->method('hasResponse')
->will($this->returnValue(true))
;
$firewall = new Firewall($map, $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock());
$firewall->onKernelRequest($event);
}
public function testOnKernelRequestWithSubRequest()
{
$map = $this->getMockBuilder('Symfony\Component\Security\Http\FirewallMapInterface')->getMock();
$map
->expects($this->never())
->method('getListeners')
;
$event = new GetResponseEvent(
$this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(),
$this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock(),
HttpKernelInterface::SUB_REQUEST
);
$firewall = new Firewall($map, $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock());
$firewall->onKernelRequest($event);
$this->assertFalse($event->hasResponse());
}
}

View File

@@ -0,0 +1,313 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\HttpUtils;
class HttpUtilsTest extends TestCase
{
public function testCreateRedirectResponseWithPath()
{
$utils = new HttpUtils($this->getUrlGenerator());
$response = $utils->createRedirectResponse($this->getRequest(), '/foobar');
$this->assertTrue($response->isRedirect('http://localhost/foobar'));
$this->assertEquals(302, $response->getStatusCode());
}
public function testCreateRedirectResponseWithAbsoluteUrl()
{
$utils = new HttpUtils($this->getUrlGenerator());
$response = $utils->createRedirectResponse($this->getRequest(), 'http://symfony.com/');
$this->assertTrue($response->isRedirect('http://symfony.com/'));
}
public function testCreateRedirectResponseWithDomainRegexp()
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://symfony\.com$#i');
$response = $utils->createRedirectResponse($this->getRequest(), 'http://symfony.com/blog');
$this->assertTrue($response->isRedirect('http://symfony.com/blog'));
}
public function testCreateRedirectResponseWithRequestsDomain()
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');
$response = $utils->createRedirectResponse($this->getRequest(), 'http://localhost/blog');
$this->assertTrue($response->isRedirect('http://localhost/blog'));
}
public function testCreateRedirectResponseWithBadRequestsDomain()
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');
$response = $utils->createRedirectResponse($this->getRequest(), 'http://pirate.net/foo');
$this->assertTrue($response->isRedirect('http://localhost/'));
}
public function testCreateRedirectResponseWithProtocolRelativeTarget()
{
$utils = new HttpUtils($this->getUrlGenerator(), null, '#^https?://%s$#i');
$response = $utils->createRedirectResponse($this->getRequest(), '//evil.com/do-bad-things');
$this->assertTrue($response->isRedirect('http://localhost//evil.com/do-bad-things'), 'Protocol-relative redirection should not be supported for security reasons');
}
public function testCreateRedirectResponseWithRouteName()
{
$utils = new HttpUtils($urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock());
$urlGenerator
->expects($this->any())
->method('generate')
->with('foobar', array(), UrlGeneratorInterface::ABSOLUTE_URL)
->will($this->returnValue('http://localhost/foo/bar'))
;
$urlGenerator
->expects($this->any())
->method('getContext')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock()))
;
$response = $utils->createRedirectResponse($this->getRequest(), 'foobar');
$this->assertTrue($response->isRedirect('http://localhost/foo/bar'));
}
public function testCreateRequestWithPath()
{
$request = $this->getRequest();
$request->server->set('Foo', 'bar');
$utils = new HttpUtils($this->getUrlGenerator());
$subRequest = $utils->createRequest($request, '/foobar');
$this->assertEquals('GET', $subRequest->getMethod());
$this->assertEquals('/foobar', $subRequest->getPathInfo());
$this->assertEquals('bar', $subRequest->server->get('Foo'));
}
public function testCreateRequestWithRouteName()
{
$utils = new HttpUtils($urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock());
$urlGenerator
->expects($this->once())
->method('generate')
->will($this->returnValue('/foo/bar'))
;
$urlGenerator
->expects($this->any())
->method('getContext')
->will($this->returnValue($this->getMockBuilder('Symfony\Component\Routing\RequestContext')->getMock()))
;
$subRequest = $utils->createRequest($this->getRequest(), 'foobar');
$this->assertEquals('/foo/bar', $subRequest->getPathInfo());
}
public function testCreateRequestWithAbsoluteUrl()
{
$utils = new HttpUtils($this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock());
$subRequest = $utils->createRequest($this->getRequest(), 'http://symfony.com/');
$this->assertEquals('/', $subRequest->getPathInfo());
}
public function testCreateRequestPassesSessionToTheNewRequest()
{
$request = $this->getRequest();
$request->setSession($session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
$utils = new HttpUtils($this->getUrlGenerator());
$subRequest = $utils->createRequest($request, '/foobar');
$this->assertSame($session, $subRequest->getSession());
}
/**
* @dataProvider provideSecurityContextAttributes
*/
public function testCreateRequestPassesSecurityContextAttributesToTheNewRequest($attribute)
{
$request = $this->getRequest();
$request->attributes->set($attribute, 'foo');
$utils = new HttpUtils($this->getUrlGenerator());
$subRequest = $utils->createRequest($request, '/foobar');
$this->assertSame('foo', $subRequest->attributes->get($attribute));
}
public function provideSecurityContextAttributes()
{
return array(
array(Security::AUTHENTICATION_ERROR),
array(Security::ACCESS_DENIED_ERROR),
array(Security::LAST_USERNAME),
);
}
public function testCheckRequestPath()
{
$utils = new HttpUtils($this->getUrlGenerator());
$this->assertTrue($utils->checkRequestPath($this->getRequest(), '/'));
$this->assertFalse($utils->checkRequestPath($this->getRequest(), '/foo'));
$this->assertTrue($utils->checkRequestPath($this->getRequest('/foo%20bar'), '/foo bar'));
// Plus must not decoded to space
$this->assertTrue($utils->checkRequestPath($this->getRequest('/foo+bar'), '/foo+bar'));
// Checking unicode
$this->assertTrue($utils->checkRequestPath($this->getRequest('/'.urlencode('вход')), '/вход'));
}
public function testCheckRequestPathWithUrlMatcherAndResourceNotFound()
{
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('match')
->with('/')
->will($this->throwException(new ResourceNotFoundException()))
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertFalse($utils->checkRequestPath($this->getRequest(), 'foobar'));
}
public function testCheckRequestPathWithUrlMatcherAndMethodNotAllowed()
{
$request = $this->getRequest();
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('matchRequest')
->with($request)
->will($this->throwException(new MethodNotAllowedException(array())))
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertFalse($utils->checkRequestPath($request, 'foobar'));
}
public function testCheckRequestPathWithUrlMatcherAndResourceFoundByUrl()
{
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('match')
->with('/foo/bar')
->will($this->returnValue(array('_route' => 'foobar')))
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertTrue($utils->checkRequestPath($this->getRequest('/foo/bar'), 'foobar'));
}
public function testCheckRequestPathWithUrlMatcherAndResourceFoundByRequest()
{
$request = $this->getRequest();
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('matchRequest')
->with($request)
->will($this->returnValue(array('_route' => 'foobar')))
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertTrue($utils->checkRequestPath($request, 'foobar'));
}
/**
* @expectedException \RuntimeException
*/
public function testCheckRequestPathWithUrlMatcherLoadingException()
{
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('match')
->will($this->throwException(new \RuntimeException()))
;
$utils = new HttpUtils(null, $urlMatcher);
$utils->checkRequestPath($this->getRequest(), 'foobar');
}
public function testCheckPathWithoutRouteParam()
{
$urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface')->getMock();
$urlMatcher
->expects($this->any())
->method('match')
->willReturn(array('_controller' => 'PathController'))
;
$utils = new HttpUtils(null, $urlMatcher);
$this->assertFalse($utils->checkRequestPath($this->getRequest(), 'path/index.html'));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Matcher must either implement UrlMatcherInterface or RequestMatcherInterface
*/
public function testUrlMatcher()
{
new HttpUtils($this->getUrlGenerator(), new \stdClass());
}
public function testGenerateUriRemovesQueryString()
{
$utils = new HttpUtils($this->getUrlGenerator('/foo/bar'));
$this->assertEquals('/foo/bar', $utils->generateUri(new Request(), 'route_name'));
$utils = new HttpUtils($this->getUrlGenerator('/foo/bar?param=value'));
$this->assertEquals('/foo/bar', $utils->generateUri(new Request(), 'route_name'));
}
/**
* @expectedException \LogicException
* @expectedExceptionMessage You must provide a UrlGeneratorInterface instance to be able to use routes.
*/
public function testUrlGeneratorIsRequiredToGenerateUrl()
{
$utils = new HttpUtils();
$utils->generateUri(new Request(), 'route_name');
}
private function getUrlGenerator($generatedUrl = '/foo/bar')
{
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
$urlGenerator
->expects($this->any())
->method('generate')
->will($this->returnValue($generatedUrl))
;
return $urlGenerator;
}
private function getRequest($path = '/')
{
return Request::create($path, 'get');
}
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Logout\CookieClearingLogoutHandler;
class CookieClearingLogoutHandlerTest extends TestCase
{
public function testLogout()
{
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$handler = new CookieClearingLogoutHandler(array('foo' => array('path' => '/foo', 'domain' => 'foo.foo'), 'foo2' => array('path' => null, 'domain' => null)));
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
$handler->logout($request, $response, $token);
$cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$this->assertCount(2, $cookies);
$cookie = $cookies['foo.foo']['/foo']['foo'];
$this->assertEquals('foo', $cookie->getName());
$this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foo.foo', $cookie->getDomain());
$this->assertTrue($cookie->isCleared());
$cookie = $cookies['']['/']['foo2'];
$this->assertStringStartsWith('foo2', $cookie->getName());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
$this->assertTrue($cookie->isCleared());
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
class DefaultLogoutSuccessHandlerTest extends TestCase
{
public function testLogout()
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$response = new Response();
$httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock();
$httpUtils->expects($this->once())
->method('createRedirectResponse')
->with($request, '/dashboard')
->will($this->returnValue($response));
$handler = new DefaultLogoutSuccessHandler($httpUtils, '/dashboard');
$result = $handler->onLogoutSuccess($request);
$this->assertSame($response, $result);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Logout;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Logout\SessionLogoutHandler;
class SessionLogoutHandlerTest extends TestCase
{
public function testLogout()
{
$handler = new SessionLogoutHandler();
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
$response = new Response();
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')->disableOriginalConstructor()->getMock();
$request
->expects($this->once())
->method('getSession')
->will($this->returnValue($session))
;
$session
->expects($this->once())
->method('invalidate')
;
$handler->logout($request, $response, $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock());
}
}

View File

@@ -0,0 +1,313 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices;
class AbstractRememberMeServicesTest extends TestCase
{
public function testGetRememberMeParameter()
{
$service = $this->getService(null, array('remember_me_parameter' => 'foo'));
$this->assertEquals('foo', $service->getRememberMeParameter());
}
public function testGetSecret()
{
$service = $this->getService();
$this->assertEquals('foosecret', $service->getSecret());
}
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$this->assertNull($service->autoLogin(new Request()));
}
/**
* @expectedException \RuntimeException
*/
public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$request->cookies->set('foo', 'foo');
$service
->expects($this->once())
->method('processAutoLoginCookie')
->will($this->returnValue(null))
;
$service->autoLogin($request);
}
public function testAutoLogin()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$request->cookies->set('foo', 'foo');
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array()))
;
$service
->expects($this->once())
->method('processAutoLoginCookie')
->will($this->returnValue($user))
;
$returnedToken = $service->autoLogin($request);
$this->assertSame($user, $returnedToken->getUser());
$this->assertSame('foosecret', $returnedToken->getSecret());
$this->assertSame('fookey', $returnedToken->getProviderKey());
}
/**
* @dataProvider provideOptionsForLogout
*/
public function testLogout(array $options)
{
$service = $this->getService(null, $options);
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service->logout($request, $response, $token);
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Cookie', $cookie);
$this->assertTrue($cookie->isCleared());
$this->assertSame($options['name'], $cookie->getName());
$this->assertSame($options['path'], $cookie->getPath());
$this->assertSame($options['domain'], $cookie->getDomain());
$this->assertSame($options['secure'], $cookie->isSecure());
$this->assertSame($options['httponly'], $cookie->isHttpOnly());
}
public function provideOptionsForLogout()
{
return array(
array(array('name' => 'foo', 'path' => '/', 'domain' => null, 'secure' => false, 'httponly' => true)),
array(array('name' => 'foo', 'path' => '/bar', 'domain' => 'baz.com', 'secure' => true, 'httponly' => false)),
);
}
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$service->loginFail($request);
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testLoginSuccessIsNotProcessedWhenTokenDoesNotContainUserInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue('foo'))
;
$service
->expects($this->never())
->method('onLoginSuccess')
;
$this->assertFalse($request->request->has('foo'));
$service->loginSuccess($request, $response, $token);
}
public function testLoginSuccessIsNotProcessedWhenRememberMeIsNotRequested()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
;
$service
->expects($this->never())
->method('onLoginSuccess')
->will($this->returnValue(null))
;
$this->assertFalse($request->request->has('foo'));
$service->loginSuccess($request, $response, $token);
}
public function testLoginSuccessWhenRememberMeAlwaysIsTrue()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(null))
;
$service->loginSuccess($request, $response, $token);
}
/**
* @dataProvider getPositiveRememberMeParameterValues
*/
public function testLoginSuccessWhenRememberMeParameterWithPathIsPositive($value)
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]', 'path' => null, 'domain' => null));
$request = new Request();
$request->request->set('foo', array('bar' => $value));
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(true))
;
$service->loginSuccess($request, $response, $token);
}
/**
* @dataProvider getPositiveRememberMeParameterValues
*/
public function testLoginSuccessWhenRememberMeParameterIsPositive($value)
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$request->request->set('foo', $value);
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue($account))
;
$service
->expects($this->once())
->method('onLoginSuccess')
->will($this->returnValue(true))
;
$service->loginSuccess($request, $response, $token);
}
public function getPositiveRememberMeParameterValues()
{
return array(
array('true'),
array('1'),
array('on'),
array('yes'),
array(true),
);
}
public function testEncodeCookieAndDecodeCookieAreInvertible()
{
$cookieParts = array('aa', 'bb', 'cc');
$service = $this->getService();
$encoded = $this->callProtected($service, 'encodeCookie', array($cookieParts));
$this->assertInternalType('string', $encoded);
$decoded = $this->callProtected($service, 'decodeCookie', array($encoded));
$this->assertSame($cookieParts, $decoded);
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage cookie delimiter
*/
public function testThereShouldBeNoCookieDelimiterInCookieParts()
{
$cookieParts = array('aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc');
$service = $this->getService();
$this->callProtected($service, 'encodeCookie', array($cookieParts));
}
protected function getService($userProvider = null, $options = array(), $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
return $this->getMockForAbstractClass('Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', array(
array($userProvider), 'foosecret', 'fookey', $options, $logger,
));
}
protected function getProvider()
{
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
;
return $provider;
}
private function callProtected($object, $method, array $args)
{
$reflection = new \ReflectionClass(get_class($object));
$reflectionMethod = $reflection->getMethod($method);
$reflectionMethod->setAccessible(true);
return $reflectionMethod->invokeArgs($object, $args);
}
}

View File

@@ -0,0 +1,339 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
class PersistentTokenBasedRememberMeServicesTest extends TestCase
{
public static function setUpBeforeClass()
{
try {
random_bytes(1);
} catch (\Exception $e) {
self::markTestSkipped($e->getMessage());
}
}
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo'));
$this->assertNull($service->autoLogin(new Request()));
}
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$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');
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLoginThrowsExceptionOnNonExistentToken()
{
$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(
$series = 'fooseries',
$tokenValue = 'foovalue',
)));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->throwException(new TokenNotFoundException('Token not found.')))
;
$service->setTokenProvider($tokenProvider);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLoginReturnsNullOnNonExistentUser()
{
$userProvider = $this->getProvider();
$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')));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->returnValue(new PersistentToken('fooclass', 'fooname', 'fooseries', 'foovalue', new \DateTime())))
;
$service->setTokenProvider($tokenProvider);
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
;
$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', 'path' => null, 'domain' => null, 'always_remember_me' => true));
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$service->setTokenProvider($tokenProvider);
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->will($this->returnValue(new PersistentToken('fooclass', 'foouser', 'fooseries', 'anotherFooValue', new \DateTime())))
;
$tokenProvider
->expects($this->once())
->method('deleteTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(null))
;
try {
$service->autoLogin($request);
$this->fail('Expected CookieTheftException was not thrown.');
} catch (CookieTheftException $e) {
}
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$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')));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(new PersistentToken('fooclass', 'username', 'fooseries', 'foovalue', new \DateTime('yesterday'))))
;
$service->setTokenProvider($tokenProvider);
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testAutoLogin()
{
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$userProvider = $this->getProvider();
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
;
$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')));
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('loadTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(new PersistentToken('fooclass', 'foouser', 'fooseries', 'foovalue', new \DateTime())))
;
$service->setTokenProvider($tokenProvider);
$returnedToken = $service->autoLogin($request);
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $returnedToken);
$this->assertSame($user, $returnedToken->getUser());
$this->assertEquals('foosecret', $returnedToken->getSecret());
$this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME));
}
public function testLogout()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo', 'secure' => true, 'httponly' => false));
$request = new Request();
$request->cookies->set('foo', $this->encodeCookie(array('fooseries', 'foovalue')));
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('deleteTokenBySeries')
->with($this->equalTo('fooseries'))
->will($this->returnValue(null))
;
$service->setTokenProvider($tokenProvider);
$service->logout($request, $response, $token);
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertEquals('/foo', $cookie->getPath());
$this->assertEquals('foodomain.foo', $cookie->getDomain());
$this->assertTrue($cookie->isSecure());
$this->assertFalse($cookie->isHttpOnly());
}
public function testLogoutSimplyIgnoresNonSetRequestCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->never())
->method('deleteTokenBySeries')
;
$service->setTokenProvider($tokenProvider);
$service->logout($request, $response, $token);
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
}
public function testLogoutSimplyIgnoresInvalidCookie()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$request->cookies->set('foo', 'somefoovalue');
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->never())
->method('deleteTokenBySeries')
;
$service->setTokenProvider($tokenProvider);
$service->logout($request, $response, $token);
$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();
$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()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600, 'always_remember_me' => true));
$request = new Request();
$response = new Response();
$account = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$account
->expects($this->once())
->method('getUsername')
->will($this->returnValue('foo'))
;
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->any())
->method('getUser')
->will($this->returnValue($account))
;
$tokenProvider = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface')->getMock();
$tokenProvider
->expects($this->once())
->method('createNewToken')
;
$service->setTokenProvider($tokenProvider);
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
$service->loginSuccess($request, $response, $token);
$cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$cookie = $cookies['myfoodomain.foo']['/foo/path']['foo'];
$this->assertFalse($cookie->isCleared());
$this->assertTrue($cookie->isSecure());
$this->assertTrue($cookie->isHttpOnly());
$this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610);
$this->assertEquals('myfoodomain.foo', $cookie->getDomain());
$this->assertEquals('/foo/path', $cookie->getPath());
}
protected function encodeCookie(array $parts)
{
$service = $this->getService();
$r = new \ReflectionMethod($service, 'encodeCookie');
$r->setAccessible(true);
return $r->invoke($service, $parts);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
return new PersistentTokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
}
protected function getProvider()
{
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
;
return $provider;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\RememberMe\ResponseListener;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\KernelEvents;
class ResponseListenerTest extends TestCase
{
public function testRememberMeCookieIsSentWithResponse()
{
$cookie = new Cookie('rememberme');
$request = $this->getRequest(array(
RememberMeServicesInterface::COOKIE_ATTR_NAME => $cookie,
));
$response = $this->getResponse();
$response->headers->expects($this->once())->method('setCookie')->with($cookie);
$listener = new ResponseListener();
$listener->onKernelResponse($this->getEvent($request, $response));
}
public function testRememberMeCookieIsNotSendWithResponseForSubRequests()
{
$cookie = new Cookie('rememberme');
$request = $this->getRequest(array(
RememberMeServicesInterface::COOKIE_ATTR_NAME => $cookie,
));
$response = $this->getResponse();
$response->headers->expects($this->never())->method('setCookie');
$listener = new ResponseListener();
$listener->onKernelResponse($this->getEvent($request, $response, HttpKernelInterface::SUB_REQUEST));
}
public function testRememberMeCookieIsNotSendWithResponse()
{
$request = $this->getRequest();
$response = $this->getResponse();
$response->headers->expects($this->never())->method('setCookie');
$listener = new ResponseListener();
$listener->onKernelResponse($this->getEvent($request, $response));
}
public function testItSubscribesToTheOnKernelResponseEvent()
{
$listener = new ResponseListener();
$this->assertSame(array(KernelEvents::RESPONSE => 'onKernelResponse'), ResponseListener::getSubscribedEvents());
}
private function getRequest(array $attributes = array())
{
$request = new Request();
foreach ($attributes as $name => $value) {
$request->attributes->set($name, $value);
}
return $request;
}
private function getResponse()
{
$response = new Response();
$response->headers = $this->getMockBuilder('Symfony\Component\HttpFoundation\ResponseHeaderBag')->getMock();
return $response;
}
private function getEvent($request, $response, $type = HttpKernelInterface::MASTER_REQUEST)
{
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\FilterResponseEvent')
->disableOriginalConstructor()
->getMock();
$event->expects($this->any())->method('getRequest')->will($this->returnValue($request));
$event->expects($this->any())->method('isMasterRequest')->will($this->returnValue($type === HttpKernelInterface::MASTER_REQUEST));
$event->expects($this->any())->method('getResponse')->will($this->returnValue($response));
return $event;
}
}

View File

@@ -0,0 +1,285 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\RememberMe;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
class TokenBasedRememberMeServicesTest extends TestCase
{
public function testAutoLoginReturnsNullWhenNoCookie()
{
$service = $this->getService(null, array('name' => 'foo'));
$this->assertNull($service->autoLogin(new Request()));
}
public function testAutoLoginThrowsExceptionOnInvalidCookie()
{
$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');
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLoginThrowsExceptionOnNonExistentUser()
{
$userProvider = $this->getProvider();
$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'));
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->will($this->throwException(new UsernameNotFoundException('user not found')))
;
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLoginDoesNotAcceptCookieWithInvalidHash()
{
$userProvider = $this->getProvider();
$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'));
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
;
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
;
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
public function testAutoLoginDoesNotAcceptAnExpiredCookie()
{
$userProvider = $this->getProvider();
$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'));
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
;
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo('foouser'))
->will($this->returnValue($user))
;
$this->assertNull($service->autoLogin($request));
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
/**
* @dataProvider provideUsernamesForAutoLogin
*
* @param string $username
*/
public function testAutoLogin($username)
{
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
;
$userProvider = $this->getProvider();
$userProvider
->expects($this->once())
->method('loadUserByUsername')
->with($this->equalTo($username))
->will($this->returnValue($user))
;
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
$request = new Request();
$request->cookies->set('foo', $this->getCookie('fooclass', $username, time() + 3600, 'foopass'));
$returnedToken = $service->autoLogin($request);
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $returnedToken);
$this->assertSame($user, $returnedToken->getUser());
$this->assertEquals('foosecret', $returnedToken->getSecret());
}
public function provideUsernamesForAutoLogin()
{
return array(
array('foouser', 'Simple username'),
array('foo'.TokenBasedRememberMeServices::COOKIE_DELIMITER.'user', 'Username might contain the delimiter'),
);
}
public function testLogout()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null, 'secure' => true, 'httponly' => false));
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$service->logout($request, $response, $token);
$cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME);
$this->assertTrue($cookie->isCleared());
$this->assertEquals('/', $cookie->getPath());
$this->assertNull($cookie->getDomain());
$this->assertTrue($cookie->isSecure());
$this->assertFalse($cookie->isHttpOnly());
}
public function testLoginFail()
{
$service = $this->getService(null, array('name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo'));
$request = new Request();
$service->loginFail($request);
$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 testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImplementation()
{
$service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('getUser')
->will($this->returnValue('foo'))
;
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
$service->loginSuccess($request, $response, $token);
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
}
public function testLoginSuccess()
{
$service = $this->getService(null, array('name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'lifetime' => 3600, 'always_remember_me' => true));
$request = new Request();
$response = new Response();
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user
->expects($this->once())
->method('getPassword')
->will($this->returnValue('foopass'))
;
$user
->expects($this->once())
->method('getUsername')
->will($this->returnValue('foouser'))
;
$token
->expects($this->atLeastOnce())
->method('getUser')
->will($this->returnValue($user))
;
$cookies = $response->headers->getCookies();
$this->assertCount(0, $cookies);
$service->loginSuccess($request, $response, $token);
$cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY);
$cookie = $cookies['myfoodomain.foo']['/foo/path']['foo'];
$this->assertFalse($cookie->isCleared());
$this->assertTrue($cookie->isSecure());
$this->assertTrue($cookie->isHttpOnly());
$this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610);
$this->assertEquals('myfoodomain.foo', $cookie->getDomain());
$this->assertEquals('/foo/path', $cookie->getPath());
}
protected function getCookie($class, $username, $expires, $password)
{
$service = $this->getService();
$r = new \ReflectionMethod($service, 'generateCookieValue');
$r->setAccessible(true);
return $r->invoke($service, $class, $username, $expires, $password);
}
protected function encodeCookie(array $parts)
{
$service = $this->getService();
$r = new \ReflectionMethod($service, 'encodeCookie');
$r->setAccessible(true);
return $r->invoke($service, $parts);
}
protected function getService($userProvider = null, $options = array(), $logger = null)
{
if (null === $userProvider) {
$userProvider = $this->getProvider();
}
$service = new TokenBasedRememberMeServices(array($userProvider), 'foosecret', 'fookey', $options, $logger);
return $service;
}
protected function getProvider()
{
$provider = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserProviderInterface')->getMock();
$provider
->expects($this->any())
->method('supportsClass')
->will($this->returnValue(true))
;
return $provider;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Tests\Session;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
class SessionAuthenticationStrategyTest extends TestCase
{
public function testSessionIsNotChanged()
{
$request = $this->getRequest();
$request->expects($this->never())->method('getSession');
$strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE);
$strategy->onAuthentication($request, $this->getToken());
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Invalid session authentication strategy "foo"
*/
public function testUnsupportedStrategy()
{
$request = $this->getRequest();
$request->expects($this->never())->method('getSession');
$strategy = new SessionAuthenticationStrategy('foo');
$strategy->onAuthentication($request, $this->getToken());
}
public function testSessionIsMigrated()
{
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session->expects($this->once())->method('migrate')->with($this->equalTo(true));
$strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE);
$strategy->onAuthentication($this->getRequest($session), $this->getToken());
}
public function testSessionIsInvalidated()
{
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock();
$session->expects($this->once())->method('invalidate');
$strategy = new SessionAuthenticationStrategy(SessionAuthenticationStrategy::INVALIDATE);
$strategy->onAuthentication($this->getRequest($session), $this->getToken());
}
private function getRequest($session = null)
{
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
if (null !== $session) {
$request->expects($this->any())->method('getSession')->will($this->returnValue($session));
}
return $request;
}
private function getToken()
{
return $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Symfony\Component\Security\Http\Tests\Util;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class TargetPathTraitTest extends TestCase
{
public function testSetTargetPath()
{
$obj = new TestClassWithTargetPathTrait();
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
->getMock();
$session->expects($this->once())
->method('set')
->with('_security.firewall_name.target_path', '/foo');
$obj->doSetTargetPath($session, 'firewall_name', '/foo');
}
public function testGetTargetPath()
{
$obj = new TestClassWithTargetPathTrait();
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
->getMock();
$session->expects($this->once())
->method('get')
->with('_security.cool_firewall.target_path')
->willReturn('/bar');
$actualUri = $obj->doGetTargetPath($session, 'cool_firewall');
$this->assertEquals(
'/bar',
$actualUri
);
}
public function testRemoveTargetPath()
{
$obj = new TestClassWithTargetPathTrait();
$session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')
->getMock();
$session->expects($this->once())
->method('remove')
->with('_security.best_firewall.target_path');
$obj->doRemoveTargetPath($session, 'best_firewall');
}
}
class TestClassWithTargetPathTrait
{
use TargetPathTrait;
public function doSetTargetPath(SessionInterface $session, $providerKey, $uri)
{
$this->saveTargetPath($session, $providerKey, $uri);
}
public function doGetTargetPath(SessionInterface $session, $providerKey)
{
return $this->getTargetPath($session, $providerKey);
}
public function doRemoveTargetPath(SessionInterface $session, $providerKey)
{
$this->removeTargetPath($session, $providerKey);
}
}