summaryrefslogtreecommitdiffstats
path: root/Http
diff options
context:
space:
mode:
authorFabien Potencier <fabien.potencier@gmail.com>2015-06-04 22:21:09 +0200
committerFabien Potencier <fabien.potencier@gmail.com>2015-06-04 22:21:09 +0200
commitbb21b1a293e2da693a6f7ccf90f04db5005a5b82 (patch)
treee75c41ee81f43f0ab791145c008ecead0aa3e7de /Http
parent3c6c556ba36d68e6c05b8be761d35fb919825509 (diff)
parent3cc16dfd5f68148e6a691809325c26bf0ed5b672 (diff)
downloadsymfony-security-bb21b1a293e2da693a6f7ccf90f04db5005a5b82.zip
symfony-security-bb21b1a293e2da693a6f7ccf90f04db5005a5b82.tar.gz
symfony-security-bb21b1a293e2da693a6f7ccf90f04db5005a5b82.tar.bz2
Merge branch '2.7' into 2.8
* 2.7: (95 commits) [DependencyInjection] provide better error message when using deprecated configuration options [console][TableCell] get cell width without decoration. Improve the config validation in TwigBundle [VarDumper] Changed tooltip to expand-all keybinding in OS X [Bridge\PhpUnit] Fix composer installed phpunit detection [VarDumper] Fix generic casters calling order [2.7][SecurityBundle] Remove SecurityContext from Compile [WebProfilerBundle][logger] added missing deprecation message. Fix profiler CSS [Security][Acl] enforce string identifiers [FrameworkBundle] make `templating.helper.router` service available again for BC reasons [BrowserKit] Fix bug when uri starts with http. bumped Symfony version to 2.7.1 updated VERSION for 2.7.0 updated CHANGELOG for 2.7.0 bumped Symfony version to 2.6.10 updated VERSION for 2.6.9 updated CHANGELOG for 2.6.9 fixed tests bumped Symfony version to 2.3.31 ... Conflicts: src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig src/Symfony/Component/HttpKernel/Kernel.php src/Symfony/Component/Translation/Loader/JsonFileLoader.php
Diffstat (limited to 'Http')
-rw-r--r--Http/Firewall/ExceptionListener.php2
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php8
-rw-r--r--Http/RememberMe/PersistentTokenBasedRememberMeServices.php1
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php6
-rw-r--r--Http/Tests/RememberMe/AbstractRememberMeServicesTest.php34
-rw-r--r--Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php19
6 files changed, 61 insertions, 9 deletions
diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php
index 213a837..6d1f27d 100644
--- a/Http/Firewall/ExceptionListener.php
+++ b/Http/Firewall/ExceptionListener.php
@@ -205,7 +205,7 @@ class ExceptionListener
protected function setTargetPath(Request $request)
{
// session isn't required when using HTTP basic authentication mechanism for example
- if ($request->hasSession() && $request->isMethodSafe()) {
+ if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) {
$request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri());
}
}
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index 3ac584a..5df82fa 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -268,9 +268,17 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param array $cookieParts
*
* @return string
+ *
+ * @throws \InvalidArgumentException When $cookieParts contain the cookie delimiter. Extending class should either remove or escape it.
*/
protected function encodeCookie(array $cookieParts)
{
+ foreach ($cookieParts as $cookiePart) {
+ if (false !== strpos($cookiePart, self::COOKIE_DELIMITER)) {
+ throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s"', self::COOKIE_DELIMITER));
+ }
+ }
+
return base64_encode(implode(self::COOKIE_DELIMITER, $cookieParts));
}
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index f800668..4fb7e09 100644
--- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -98,7 +98,6 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
throw new AuthenticationException('The cookie has expired.');
}
- $series = $persistentToken->getSeries();
$tokenValue = base64_encode($this->secureRandom->nextBytes(64));
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
$request->attributes->set(self::COOKIE_ATTR_NAME,
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index 3fe39ac..65bac0a 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -95,12 +95,12 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
- * @throws \RuntimeException if username contains invalid chars
- *
* @return string
*/
protected function generateCookieValue($class, $username, $expires, $password)
{
+ // $username is encoded because it might contain COOKIE_DELIMITER,
+ // we assume other values don't
return $this->encodeCookie(array(
$class,
base64_encode($username),
@@ -117,8 +117,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
- * @throws \RuntimeException when the private key is empty
- *
* @return string
*/
protected function generateCookieHash($class, $username, $expires, $password)
diff --git a/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
index c3d9260..2225b6c 100644
--- a/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Http\Tests\RememberMe;
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 \PHPUnit_Framework_TestCase
{
@@ -236,6 +237,30 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
);
}
+ 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) {
@@ -258,4 +283,13 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
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);
+ }
}
diff --git a/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
index 9801bc8..8383cec 100644
--- a/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
+++ b/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php
@@ -105,7 +105,12 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
}
- public function testAutoLogin()
+ /**
+ * @dataProvider provideUsernamesForAutoLogin
+ *
+ * @param string $username
+ */
+ public function testAutoLogin($username)
{
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
$user
@@ -123,13 +128,13 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$userProvider
->expects($this->once())
->method('loadUserByUsername')
- ->with($this->equalTo('foouser'))
+ ->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', 'foouser', time() + 3600, 'foopass'));
+ $request->cookies->set('foo', $this->getCookie('fooclass', $username, time() + 3600, 'foopass'));
$returnedToken = $service->autoLogin($request);
@@ -138,6 +143,14 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('fookey', $returnedToken->getKey());
}
+ 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));