Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit c0dd66d

Browse files
committed
Merge branch '2.6' into 2.7
* 2.6: (30 commits) [Translation] fixed JSON loader on PHP 7 when file is empty Fix typo Check instance of FormBuilderInterface instead of FormBuilder [Security] TokenBasedRememberMeServices test to show why encoding username is required [Security] AbstractRememberMeServices::encodeCookie() validates cookie parts fixed typo [console][formater] allow format toString object. [HttpFoundation] Fix baseUrl when script filename is contained in pathInfo Avoid redirection to XHR URIs [HttpFoundation] IpUtils::checkIp4() should allow networks [2.6] Fix HTML escaping of to-source links Fix HTML escaping of to-source links ExceptionHandler: More Encoding Fix the rendering of deprecation log messages [FrameworkBundle] Removed unnecessary parameter in TemplateController [DomCrawler] Throw an exception if a form field path is incomplete. Fixed the indentation in the compiled template for the DumpNode [Console] Delete duplicate test in CommandTest [TwigBundle] Refresh twig paths when resources change. WebProfiler break words ... Conflicts: src/Symfony/Bridge/Twig/composer.json src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig src/Symfony/Component/Debug/ExceptionHandler.php
2 parents 432e908 + c1c3818 commit c0dd66d

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

Http/Firewall/ExceptionListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ private function startAuthentication(Request $request, AuthenticationException $
205205
protected function setTargetPath(Request $request)
206206
{
207207
// session isn't required when using HTTP basic authentication mechanism for example
208-
if ($request->hasSession() && $request->isMethodSafe()) {
208+
if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) {
209209
$request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri());
210210
}
211211
}

Http/RememberMe/AbstractRememberMeServices.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,17 @@ protected function decodeCookie($rawCookie)
268268
* @param array $cookieParts
269269
*
270270
* @return string
271+
*
272+
* @throws \InvalidArgumentException When $cookieParts contain the cookie delimiter. Extending class should either remove or escape it.
271273
*/
272274
protected function encodeCookie(array $cookieParts)
273275
{
276+
foreach ($cookieParts as $cookiePart) {
277+
if (false !== strpos($cookiePart, self::COOKIE_DELIMITER)) {
278+
throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s"', self::COOKIE_DELIMITER));
279+
}
280+
}
281+
274282
return base64_encode(implode(self::COOKIE_DELIMITER, $cookieParts));
275283
}
276284

Http/RememberMe/TokenBasedRememberMeServices.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ protected function onLoginSuccess(Request $request, Response $response, TokenInt
9595
* @param int $expires The Unix timestamp when the cookie expires
9696
* @param string $password The encoded password
9797
*
98-
* @throws \RuntimeException if username contains invalid chars
99-
*
10098
* @return string
10199
*/
102100
protected function generateCookieValue($class, $username, $expires, $password)
103101
{
102+
// $username is encoded because it might contain COOKIE_DELIMITER,
103+
// we assume other values don't
104104
return $this->encodeCookie(array(
105105
$class,
106106
base64_encode($username),
@@ -117,8 +117,6 @@ protected function generateCookieValue($class, $username, $expires, $password)
117117
* @param int $expires The Unix timestamp when the cookie expires
118118
* @param string $password The encoded password
119119
*
120-
* @throws \RuntimeException when the private key is empty
121-
*
122120
* @return string
123121
*/
124122
protected function generateCookieHash($class, $username, $expires, $password)

Http/Tests/RememberMe/AbstractRememberMeServicesTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices;
1718

1819
class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
1920
{
@@ -236,6 +237,30 @@ public function getPositiveRememberMeParameterValues()
236237
);
237238
}
238239

240+
public function testEncodeCookieAndDecodeCookieAreInvertible()
241+
{
242+
$cookieParts = array('aa', 'bb', 'cc');
243+
$service = $this->getService();
244+
245+
$encoded = $this->callProtected($service, 'encodeCookie', array($cookieParts));
246+
$this->assertInternalType('string', $encoded);
247+
248+
$decoded = $this->callProtected($service, 'decodeCookie', array($encoded));
249+
$this->assertSame($cookieParts, $decoded);
250+
}
251+
252+
/**
253+
* @expectedException InvalidArgumentException
254+
* @expectedExceptionMessage cookie delimiter
255+
*/
256+
public function testThereShouldBeNoCookieDelimiterInCookieParts()
257+
{
258+
$cookieParts = array('aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc');
259+
$service = $this->getService();
260+
261+
$this->callProtected($service, 'encodeCookie', array($cookieParts));
262+
}
263+
239264
protected function getService($userProvider = null, $options = array(), $logger = null)
240265
{
241266
if (null === $userProvider) {
@@ -258,4 +283,13 @@ protected function getProvider()
258283

259284
return $provider;
260285
}
286+
287+
private function callProtected($object, $method, array $args)
288+
{
289+
$reflection = new \ReflectionClass(get_class($object));
290+
$reflectionMethod = $reflection->getMethod($method);
291+
$reflectionMethod->setAccessible(true);
292+
293+
return $reflectionMethod->invokeArgs($object, $args);
294+
}
261295
}

Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ public function testAutoLoginDoesNotAcceptAnExpiredCookie()
105105
$this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared());
106106
}
107107

108-
public function testAutoLogin()
108+
/**
109+
* @dataProvider provideUsernamesForAutoLogin
110+
*
111+
* @param string $username
112+
*/
113+
public function testAutoLogin($username)
109114
{
110115
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
111116
$user
@@ -123,13 +128,13 @@ public function testAutoLogin()
123128
$userProvider
124129
->expects($this->once())
125130
->method('loadUserByUsername')
126-
->with($this->equalTo('foouser'))
131+
->with($this->equalTo($username))
127132
->will($this->returnValue($user))
128133
;
129134

130135
$service = $this->getService($userProvider, array('name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600));
131136
$request = new Request();
132-
$request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() + 3600, 'foopass'));
137+
$request->cookies->set('foo', $this->getCookie('fooclass', $username, time() + 3600, 'foopass'));
133138

134139
$returnedToken = $service->autoLogin($request);
135140

@@ -138,6 +143,14 @@ public function testAutoLogin()
138143
$this->assertEquals('fookey', $returnedToken->getKey());
139144
}
140145

146+
public function provideUsernamesForAutoLogin()
147+
{
148+
return array(
149+
array('foouser', 'Simple username'),
150+
array('foo'.TokenBasedRememberMeServices::COOKIE_DELIMITER.'user', 'Username might contain the delimiter'),
151+
);
152+
}
153+
141154
public function testLogout()
142155
{
143156
$service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));

Resources/translations/security.fr.xlf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
</trans-unit>
99
<trans-unit id="2">
1010
<source>Authentication credentials could not be found.</source>
11-
<target>Les droits d'authentification n'ont pas pu être trouvés.</target>
11+
<target>Les identifiants d'authentification n'ont pas pu être trouvés.</target>
1212
</trans-unit>
1313
<trans-unit id="3">
1414
<source>Authentication request could not be processed due to a system problem.</source>
1515
<target>La requête d'authentification n'a pas pu être executée à cause d'un problème système.</target>
1616
</trans-unit>
1717
<trans-unit id="4">
1818
<source>Invalid credentials.</source>
19-
<target>Droits invalides.</target>
19+
<target>Identifiants invalides.</target>
2020
</trans-unit>
2121
<trans-unit id="5">
2222
<source>Cookie has already been used by someone else.</source>
2323
<target>Le cookie a déjà été utilisé par quelqu'un d'autre.</target>
2424
</trans-unit>
2525
<trans-unit id="6">
2626
<source>Not privileged to request the resource.</source>
27-
<target>Pas de privilèges pour accéder à la ressource.</target>
27+
<target>Privilèges insuffisants pour accéder à la ressource.</target>
2828
</trans-unit>
2929
<trans-unit id="7">
3030
<source>Invalid CSRF token.</source>
@@ -40,23 +40,23 @@
4040
</trans-unit>
4141
<trans-unit id="10">
4242
<source>No session available, it either timed out or cookies are not enabled.</source>
43-
<target>Pas de session disponible, celle-ci a expiré ou les cookies ne sont pas activés.</target>
43+
<target>Aucune session disponible, celle-ci a expiré ou les cookies ne sont pas activés.</target>
4444
</trans-unit>
4545
<trans-unit id="11">
4646
<source>No token could be found.</source>
4747
<target>Aucun jeton n'a pu être trouvé.</target>
4848
</trans-unit>
4949
<trans-unit id="12">
5050
<source>Username could not be found.</source>
51-
<target>Le nom d'utilisateur ne peut pas être trouvé.</target>
51+
<target>Le nom d'utilisateur n'a pas pu être trouvé.</target>
5252
</trans-unit>
5353
<trans-unit id="13">
5454
<source>Account has expired.</source>
5555
<target>Le compte a expiré.</target>
5656
</trans-unit>
5757
<trans-unit id="14">
5858
<source>Credentials have expired.</source>
59-
<target>Les droits ont expirés.</target>
59+
<target>Les identifiants ont expiré.</target>
6060
</trans-unit>
6161
<trans-unit id="15">
6262
<source>Account is disabled.</source>

0 commit comments

Comments
 (0)