summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabien Potencier <fabien.potencier@gmail.com>2015-09-30 11:18:13 +0200
committerFabien Potencier <fabien.potencier@gmail.com>2015-09-30 11:18:13 +0200
commitbf2ab7235258e8e35315f080e1a929de7f9517f5 (patch)
treea9061e0dd48d4fee801a4e36ccec315f4dcff86b
parent493704bf17328063a6e566d912e6e063d4c60f8b (diff)
parentd37cee9ea33b5ece6837253a15d83e0740074bba (diff)
downloadsymfony-security-bf2ab7235258e8e35315f080e1a929de7f9517f5.zip
symfony-security-bf2ab7235258e8e35315f080e1a929de7f9517f5.tar.gz
symfony-security-bf2ab7235258e8e35315f080e1a929de7f9517f5.tar.bz2
Merge branch '2.8'
* 2.8: Remove profiler storages deprecate finding deep items in request parameters [CssSelector] updated README [CssSelector] remove ConverterInterface [DependencyInjection] improved a comment for reading fluency [HttpKernel] change a class in tests to avoid depending on SQLite [FrameworkBundle] Fix tests [Bridge\Twig] Fix form lowest version [ci] Display fastest results first when running tests in parallel [Yaml] Improve newline handling in folded scalar blocks
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php3
-rw-r--r--Http/Authentication/DefaultAuthenticationSuccessHandler.php3
-rw-r--r--Http/Firewall/LogoutListener.php3
-rw-r--r--Http/Firewall/SimpleFormAuthenticationListener.php11
-rw-r--r--Http/Firewall/UsernamePasswordFormAuthenticationListener.php11
-rw-r--r--Http/ParameterBagUtils.php96
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php3
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php17
-rw-r--r--Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php14
-rw-r--r--Http/composer.json1
10 files changed, 146 insertions, 16 deletions
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
index f8004d6..3e63992 100644
--- a/Http/Authentication/DefaultAuthenticationFailureHandler.php
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -17,6 +17,7 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Class with the default authentication failure handling logic.
@@ -82,7 +83,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
- if ($failureUrl = $request->get($this->options['failure_path_parameter'], null, true)) {
+ if ($failureUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['failure_path_parameter'])) {
$this->options['failure_path'] = $failureUrl;
}
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
index 5fa7071..078a366 100644
--- a/Http/Authentication/DefaultAuthenticationSuccessHandler.php
+++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Class with the default authentication success handling logic.
@@ -108,7 +109,7 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle
return $this->options['default_target_path'];
}
- if ($targetUrl = $request->get($this->options['target_path_parameter'], null, true)) {
+ if ($targetUrl = ParameterBagUtils::getRequestParameterValue($request, $this->options['target_path_parameter'])) {
return $targetUrl;
}
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index 96f5685..6211ee0 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -24,6 +24,7 @@ use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* LogoutListener logout users.
@@ -98,7 +99,7 @@ class LogoutListener implements ListenerInterface
}
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
throw new LogoutException('Invalid CSRF token.');
diff --git a/Http/Firewall/SimpleFormAuthenticationListener.php b/Http/Firewall/SimpleFormAuthenticationListener.php
index 2729553..36f7bb5 100644
--- a/Http/Firewall/SimpleFormAuthenticationListener.php
+++ b/Http/Firewall/SimpleFormAuthenticationListener.php
@@ -26,6 +26,7 @@ use Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterf
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Psr\Log\LoggerInterface;
@@ -101,7 +102,7 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
protected function attemptAuthentication(Request $request)
{
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
@@ -109,11 +110,11 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
}
if ($this->options['post_only']) {
- $username = trim($request->request->get($this->options['username_parameter'], null, true));
- $password = $request->request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
- $username = trim($request->get($this->options['username_parameter'], null, true));
- $password = $request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
$request->getSession()->set(Security::LAST_USERNAME, $username);
diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 07ab85a..d20ab19 100644
--- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -19,6 +19,7 @@ use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
@@ -76,7 +77,7 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
protected function attemptAuthentication(Request $request)
{
if (null !== $this->csrfTokenManager) {
- $csrfToken = $request->get($this->options['csrf_parameter'], null, true);
+ $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']);
if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['intention'], $csrfToken))) {
throw new InvalidCsrfTokenException('Invalid CSRF token.');
@@ -84,11 +85,11 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
}
if ($this->options['post_only']) {
- $username = trim($request->request->get($this->options['username_parameter'], null, true));
- $password = $request->request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
} else {
- $username = trim($request->get($this->options['username_parameter'], null, true));
- $password = $request->get($this->options['password_parameter'], null, true);
+ $username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
+ $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
}
$request->getSession()->set(Security::LAST_USERNAME, $username);
diff --git a/Http/ParameterBagUtils.php b/Http/ParameterBagUtils.php
new file mode 100644
index 0000000..eed5421
--- /dev/null
+++ b/Http/ParameterBagUtils.php
@@ -0,0 +1,96 @@
+<?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;
+
+use Symfony\Component\HttpFoundation\ParameterBag;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\PropertyAccess\Exception\AccessException;
+use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
+use Symfony\Component\PropertyAccess\PropertyAccess;
+
+/**
+ * @internal
+ */
+final class ParameterBagUtils
+{
+ private static $propertyAccessor;
+
+ /**
+ * Returns a "parameter" value.
+ *
+ * Paths like foo[bar] will be evaluated to find deeper items in nested data structures.
+ *
+ * @param ParameterBag $parameters The parameter bag
+ * @param string $path The key
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException when the given path is malformed
+ */
+ public static function getParameterBagValue(ParameterBag $parameters, $path)
+ {
+ if (false === $pos = strpos($path, '[')) {
+ return $parameters->get($path);
+ }
+
+ $root = substr($path, 0, $pos);
+
+ if (null === $value = $parameters->get($root)) {
+ return;
+ }
+
+ if (null === self::$propertyAccessor) {
+ self::$propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ try {
+ return self::$propertyAccessor->getValue($value, substr($path, $pos));
+ } catch (AccessException $e) {
+ return;
+ }
+ }
+
+ /**
+ * Returns a request "parameter" value.
+ *
+ * Paths like foo[bar] will be evaluated to find deeper items in nested data structures.
+ *
+ * @param Request $request The request
+ * @param string $path The key
+ *
+ * @return mixed
+ *
+ * @throws InvalidArgumentException when the given path is malformed
+ */
+ public static function getRequestParameterValue(Request $request, $path)
+ {
+ if (false === $pos = strpos($path, '[')) {
+ return $request->get($path);
+ }
+
+ $root = substr($path, 0, $pos);
+
+ if (null === $value = $request->get($root)) {
+ return;
+ }
+
+ if (null === self::$propertyAccessor) {
+ self::$propertyAccessor = PropertyAccess::createPropertyAccessor();
+ }
+
+ try {
+ return self::$propertyAccessor->getValue($value, substr($path, $pos));
+ } catch (AccessException $e) {
+ return;
+ }
+ }
+}
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index 765fee9..aa2a50d 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -23,6 +23,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Http\ParameterBagUtils;
/**
* Base class implementing the RememberMeServicesInterface.
@@ -309,7 +310,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return true;
}
- $parameter = $request->get($this->options['remember_me_parameter'], null, true);
+ $parameter = ParameterBagUtils::getRequestParameterValue($request, $this->options['remember_me_parameter']);
if (null === $parameter && null !== $this->logger) {
$this->logger->debug('Did not send remember-me cookie.', array('parameter' => $this->options['remember_me_parameter']));
diff --git a/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
index 82b5533..2ed8872 100644
--- a/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationFailureHandlerTest.php
@@ -145,7 +145,7 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
public function testFailurePathCanBeOverwrittenWithRequest()
{
$this->request->expects($this->once())
- ->method('get')->with('_failure_path', null, true)
+ ->method('get')->with('_failure_path', null, false)
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
@@ -155,12 +155,25 @@ class DefaultAuthenticationFailureHandlerTest extends \PHPUnit_Framework_TestCas
$handler->onAuthenticationFailure($this->request, $this->exception);
}
+ public function testFailurePathCanBeOverwrittenWithNestedAttributeInRequest()
+ {
+ $this->request->expects($this->once())
+ ->method('get')->with('_failure_path', null, false)
+ ->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', null, true)
+ ->method('get')->with('_my_failure_path', null, false)
->will($this->returnValue('/auth/login'));
$this->httpUtils->expects($this->once())
diff --git a/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
index 4d1847d..2c22da6 100644
--- a/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
+++ b/Http/Tests/Authentication/DefaultAuthenticationSuccessHandlerTest.php
@@ -68,6 +68,20 @@ class DefaultAuthenticationSuccessHandlerTest extends \PHPUnit_Framework_TestCas
$this->assertSame($response, $result);
}
+ public function testTargetPathIsPassedAsNestedParameterWithRequest()
+ {
+ $this->request->expects($this->once())
+ ->method('get')->with('_target_path')
+ ->will($this->returnValue(array('value' => '/dashboard')));
+
+ $response = $this->expectRedirectResponse('/dashboard');
+
+ $handler = new DefaultAuthenticationSuccessHandler($this->httpUtils, array('target_path_parameter' => '_target_path[value]'));
+ $result = $handler->onAuthenticationSuccess($this->request, $this->token);
+
+ $this->assertSame($response, $result);
+ }
+
public function testTargetPathParameterIsCustomised()
{
$options = array('target_path_parameter' => '_my_target_path');
diff --git a/Http/composer.json b/Http/composer.json
index 172e0d3..1964802 100644
--- a/Http/composer.json
+++ b/Http/composer.json
@@ -21,6 +21,7 @@
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0"
+ "symfony/property-access": "~2.8|~3.0.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.8|~3.0",