fixes several bugs
This commit is contained in:
parent
a4f05ac7ab
commit
f300edebe4
@ -77,6 +77,9 @@ RC4 to RC5
|
|||||||
Session::getAttributes() -> Session::all()
|
Session::getAttributes() -> Session::all()
|
||||||
Session::setAttributes() -> Session::replace()
|
Session::setAttributes() -> Session::replace()
|
||||||
|
|
||||||
|
* {_locale} is not supported in paths in the access_control section anymore. You can
|
||||||
|
rewrite the paths using a regular expression such as "(?:[a-z]{2})".
|
||||||
|
|
||||||
RC3 to RC4
|
RC3 to RC4
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -34,6 +34,11 @@ class LocalizedController extends ContainerAware
|
|||||||
throw new \RuntimeException('logoutAction() should never be called.');
|
throw new \RuntimeException('logoutAction() should never be called.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function secureAction()
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('secureAction() should never be called.');
|
||||||
|
}
|
||||||
|
|
||||||
public function profileAction()
|
public function profileAction()
|
||||||
{
|
{
|
||||||
return new Response('Profile');
|
return new Response('Profile');
|
||||||
|
@ -1,19 +1,30 @@
|
|||||||
localized_login_path:
|
localized_login_path:
|
||||||
pattern: /{_locale}/login
|
pattern: /{_locale}/login
|
||||||
defaults: { _controller: FormLoginBundle:Localized:login }
|
defaults: { _controller: FormLoginBundle:Localized:login }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_check_path:
|
localized_check_path:
|
||||||
pattern: /{_locale}/login_check
|
pattern: /{_locale}/login_check
|
||||||
defaults: { _controller: FormLoginBundle:Localized:loginCheck }
|
defaults: { _controller: FormLoginBundle:Localized:loginCheck }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_default_target_path:
|
localized_default_target_path:
|
||||||
pattern: /{_locale}/profile
|
pattern: /{_locale}/profile
|
||||||
defaults: { _controller: FormLoginBundle:Localized:profile }
|
defaults: { _controller: FormLoginBundle:Localized:profile }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_logout_path:
|
localized_logout_path:
|
||||||
pattern: /{_locale}/logout
|
pattern: /{_locale}/logout
|
||||||
defaults: { _controller: FormLoginBundle:Localized:logout }
|
defaults: { _controller: FormLoginBundle:Localized:logout }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
localized_logout_target_path:
|
localized_logout_target_path:
|
||||||
pattern: /{_locale}/
|
pattern: /{_locale}/
|
||||||
defaults: { _controller: FormLoginBundle:Localized:homepage }
|
defaults: { _controller: FormLoginBundle:Localized:homepage }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
||||||
|
localized_secure_path:
|
||||||
|
pattern: /{_locale}/secure/
|
||||||
|
defaults: { _controller: FormLoginBundle:Localized:secure }
|
||||||
|
requirements: { _locale: "^[a-z]{2}$" }
|
||||||
|
|
@ -26,6 +26,30 @@ class LocalizedRoutesAsPathTest extends WebTestCase
|
|||||||
$this->assertEquals('Homepage', $client->followRedirect()->text());
|
$this->assertEquals('Homepage', $client->followRedirect()->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLocales
|
||||||
|
*/
|
||||||
|
public function testAccessRestrictedResource($locale)
|
||||||
|
{
|
||||||
|
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml'));
|
||||||
|
$client->insulate();
|
||||||
|
|
||||||
|
$client->request('GET', '/'.$locale.'/secure/');
|
||||||
|
$this->assertRedirect($client->getResponse(), '/'.$locale.'/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getLocales
|
||||||
|
*/
|
||||||
|
public function testAccessRestrictedResourceWithForward($locale)
|
||||||
|
{
|
||||||
|
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml'));
|
||||||
|
$client->insulate();
|
||||||
|
|
||||||
|
$crawler = $client->request('GET', '/'.$locale.'/secure/');
|
||||||
|
$this->assertEquals(1, count($crawler->selectButton('login')), (string) $client->getResponse());
|
||||||
|
}
|
||||||
|
|
||||||
public function getLocales()
|
public function getLocales()
|
||||||
{
|
{
|
||||||
return array(array('en'), array('de'));
|
return array(array('en'), array('de'));
|
||||||
|
@ -13,25 +13,37 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional;
|
|||||||
|
|
||||||
class SecurityRoutingIntegrationTest extends WebTestCase
|
class SecurityRoutingIntegrationTest extends WebTestCase
|
||||||
{
|
{
|
||||||
public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous()
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous($config)
|
||||||
{
|
{
|
||||||
$client = $this->createClient(array('test_case' => 'StandardFormLogin'));
|
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
|
||||||
|
$client->insulate();
|
||||||
$client->request('GET', '/protected_resource');
|
$client->request('GET', '/protected_resource');
|
||||||
|
|
||||||
$this->assertRedirect($client->getResponse(), '/login');
|
$this->assertRedirect($client->getResponse(), '/login');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRoutingErrorIsExposedWhenNotProtected()
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testRoutingErrorIsExposedWhenNotProtected($config)
|
||||||
{
|
{
|
||||||
$client = $this->createClient(array('test_case' => 'StandardFormLogin'));
|
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
|
||||||
|
$client->insulate();
|
||||||
$client->request('GET', '/unprotected_resource');
|
$client->request('GET', '/unprotected_resource');
|
||||||
|
|
||||||
$this->assertEquals(404, $client->getResponse()->getStatusCode());
|
$this->assertEquals(404, $client->getResponse()->getStatusCode(), (string) $client->getResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights()
|
/**
|
||||||
|
* @dataProvider getConfigs
|
||||||
|
*/
|
||||||
|
public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights($config)
|
||||||
{
|
{
|
||||||
$client = $this->createClient(array('test_case' => 'StandardFormLogin'));
|
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
|
||||||
|
$client->insulate();
|
||||||
|
|
||||||
$form = $client->request('GET', '/login')->selectButton('login')->form();
|
$form = $client->request('GET', '/login')->selectButton('login')->form();
|
||||||
$form['_username'] = 'johannes';
|
$form['_username'] = 'johannes';
|
||||||
@ -43,6 +55,11 @@ class SecurityRoutingIntegrationTest extends WebTestCase
|
|||||||
$this->assertNotEquals(404, $client->getResponse()->getStatusCode());
|
$this->assertNotEquals(404, $client->getResponse()->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConfigs()
|
||||||
|
{
|
||||||
|
return array(array('config.yml'), array('routes_as_path.yml'));
|
||||||
|
}
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -18,7 +18,7 @@ class WebTestCase extends BaseWebTestCase
|
|||||||
{
|
{
|
||||||
static public function assertRedirect($response, $location)
|
static public function assertRedirect($response, $location)
|
||||||
{
|
{
|
||||||
self::assertTrue($response->isRedirect());
|
self::assertTrue($response->isRedirect(), 'Response is not a redirect, got status code: '.$response->getStatusCode());
|
||||||
self::assertEquals('http://localhost'.$location, $response->headers->get('Location'));
|
self::assertEquals('http://localhost'.$location, $response->headers->get('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,4 +19,8 @@ security:
|
|||||||
logout:
|
logout:
|
||||||
path: localized_logout_path
|
path: localized_logout_path
|
||||||
target: localized_logout_target_path
|
target: localized_logout_target_path
|
||||||
anonymous: ~
|
anonymous: ~
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
- { path: '^/(?:[a-z]{2})/secure/.*', roles: ROLE_USER }
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
imports:
|
||||||
|
- { resource: ./localized_routes.yml }
|
||||||
|
|
||||||
|
security:
|
||||||
|
firewalls:
|
||||||
|
default:
|
||||||
|
form_login:
|
||||||
|
use_forward: true
|
||||||
|
failure_forward: true
|
@ -100,11 +100,7 @@ class RequestMatcher implements RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->path) {
|
if (null !== $this->path) {
|
||||||
if (null !== $session = $request->getSession()) {
|
$path = str_replace('#', '\\#', $this->path);
|
||||||
$path = strtr($this->path, array('{_locale}' => $session->getLocale(), '#' => '\\#'));
|
|
||||||
} else {
|
|
||||||
$path = str_replace('#', '\\#', $this->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!preg_match('#'.$path.'#', $request->getPathInfo())) {
|
if (!preg_match('#'.$path.'#', $request->getPathInfo())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Security\Http;
|
namespace Symfony\Component\Security\Http;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\SecurityContextInterface;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\Routing\RouterInterface;
|
use Symfony\Component\Routing\RouterInterface;
|
||||||
@ -45,22 +47,10 @@ class HttpUtils
|
|||||||
*/
|
*/
|
||||||
public function createRedirectResponse(Request $request, $path, $status = 302)
|
public function createRedirectResponse(Request $request, $path, $status = 302)
|
||||||
{
|
{
|
||||||
if (0 === strpos($path, '/')) {
|
if ('/' === $path[0]) {
|
||||||
$path = $request->getUriForPath($path);
|
$path = $request->getUriForPath($path);
|
||||||
} elseif (0 !== strpos($path, 'http')) {
|
} elseif (0 !== strpos($path, 'http')) {
|
||||||
// hack (don't have a better solution for now)
|
$this->resetLocale($request);
|
||||||
$context = $this->router->getContext();
|
|
||||||
try {
|
|
||||||
$parameters = $this->router->match($request->getPathInfo());
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($parameters['_locale'])) {
|
|
||||||
$context->setParameter('_locale', $parameters['_locale']);
|
|
||||||
} elseif ($session = $request->getSession()) {
|
|
||||||
$context->setParameter('_locale', $session->getLocale());
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = $this->generateUrl($path, true);
|
$path = $this->generateUrl($path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +68,26 @@ class HttpUtils
|
|||||||
public function createRequest(Request $request, $path)
|
public function createRequest(Request $request, $path)
|
||||||
{
|
{
|
||||||
if ($path && '/' !== $path[0] && 0 !== strpos($path, 'http')) {
|
if ($path && '/' !== $path[0] && 0 !== strpos($path, 'http')) {
|
||||||
|
$this->resetLocale($request);
|
||||||
$path = $this->generateUrl($path, true);
|
$path = $this->generateUrl($path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Request::create($path, 'get', array(), $request->cookies->all(), array(), $request->server->all());
|
$newRequest = Request::create($path, 'get', array(), $request->cookies->all(), array(), $request->server->all());
|
||||||
|
if ($session = $request->getSession()) {
|
||||||
|
$newRequest->setSession($session);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
|
||||||
|
$newRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $request->attributes->get(SecurityContextInterface::AUTHENTICATION_ERROR));
|
||||||
|
}
|
||||||
|
if ($request->attributes->has(SecurityContextInterface::ACCESS_DENIED_ERROR)) {
|
||||||
|
$newRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $request->attributes->get(SecurityContextInterface::ACCESS_DENIED_ERROR));
|
||||||
|
}
|
||||||
|
if ($request->attributes->has(SecurityContextInterface::LAST_USERNAME)) {
|
||||||
|
$newRequest->attributes->set(SecurityContextInterface::LAST_USERNAME, $request->attributes->get(SecurityContextInterface::LAST_USERNAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $newRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +113,27 @@ class HttpUtils
|
|||||||
return $path === $request->getPathInfo();
|
return $path === $request->getPathInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hack (don't have a better solution for now)
|
||||||
|
private function resetLocale(Request $request)
|
||||||
|
{
|
||||||
|
$context = $this->router->getContext();
|
||||||
|
if ($context->getParameter('_locale')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parameters = $this->router->match($request->getPathInfo());
|
||||||
|
|
||||||
|
if (isset($parameters['_locale'])) {
|
||||||
|
$context->setParameter('_locale', $parameters['_locale']);
|
||||||
|
} elseif ($session = $request->getSession()) {
|
||||||
|
$context->setParameter('_locale', $session->getLocale());
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// let's hope user doesn't use the locale in the path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function generateUrl($route, $absolute = false)
|
private function generateUrl($route, $absolute = false)
|
||||||
{
|
{
|
||||||
if (null === $this->router) {
|
if (null === $this->router) {
|
||||||
|
@ -142,7 +142,7 @@ class RequestMatcherTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertFalse($matcher->matches($request));
|
$this->assertFalse($matcher->matches($request));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPathWithLocale()
|
public function testPathWithLocaleIsNotSupported()
|
||||||
{
|
{
|
||||||
$matcher = new RequestMatcher();
|
$matcher = new RequestMatcher();
|
||||||
$request = Request::create('/en/login');
|
$request = Request::create('/en/login');
|
||||||
@ -152,9 +152,6 @@ class RequestMatcherTest extends \PHPUnit_Framework_TestCase
|
|||||||
$request->setSession($session);
|
$request->setSession($session);
|
||||||
|
|
||||||
$matcher->matchPath('^/{_locale}/login$');
|
$matcher->matchPath('^/{_locale}/login$');
|
||||||
$this->assertTrue($matcher->matches($request));
|
|
||||||
|
|
||||||
$session->setLocale('de');
|
|
||||||
$this->assertFalse($matcher->matches($request));
|
$this->assertFalse($matcher->matches($request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,17 @@ class HttpUtilsTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('bar', $subRequest->server->get('Foo'));
|
$this->assertEquals('bar', $subRequest->server->get('Foo'));
|
||||||
|
|
||||||
// route name
|
// route name
|
||||||
|
$utils = new HttpUtils($router = $this->getMockBuilder('Symfony\Component\Routing\Router')->disableOriginalConstructor()->getMock());
|
||||||
|
$router
|
||||||
|
->expects($this->once())
|
||||||
|
->method('generate')
|
||||||
|
->will($this->returnValue('/foo/bar'))
|
||||||
|
;
|
||||||
|
$router
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getContext')
|
||||||
|
->will($this->returnValue($this->getMock('Symfony\Component\Routing\RequestContext')))
|
||||||
|
;
|
||||||
$subRequest = $utils->createRequest($this->getRequest(), 'foobar');
|
$subRequest = $utils->createRequest($this->getRequest(), 'foobar');
|
||||||
$this->assertEquals('/foo/bar', $subRequest->getPathInfo());
|
$this->assertEquals('/foo/bar', $subRequest->getPathInfo());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user