Merge branch '2.3' into 2.6

* 2.3:
  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
  [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
  Fix HTML escaping of to-source links
  [FrameworkBundle] Removed unnecessary parameter in TemplateController
  [DomCrawler] Throw an exception if a form field path is incomplete.
  [Console] Delete duplicate test in CommandTest
  [TwigBundle] Refresh twig paths when resources change.
  WebProfiler break words
  fixed typo
  Update README.md
  [HttpKernel] Handle an array vary header in the http cache store
  [Security][Translation] fixes #14584
  [Framework] added test for Router commands.
  Handled bearer authorization header in REDIRECT_ form

Conflicts:
	src/Symfony/Component/Debug/ExceptionHandler.php
This commit is contained in:
Fabien Potencier 2015-05-22 16:53:08 +02:00
commit dd744c9f53
31 changed files with 385 additions and 45 deletions

View File

@ -33,8 +33,8 @@ work for you:
Installation
------------
The best way to install Symfony is to download the Symfony Standard Edition
available at <https://symfony.com/download>.
The best way to install Symfony is to use the [official Symfony Installer][7].
It allows you to start a new project based on the version you want.
Documentation
-------------
@ -64,3 +64,4 @@ Information on how to run the Symfony test suite can be found in the
[4]: https://symfony.com/doc/current/contributing/code/patches.html#check-list
[5]: https://symfony.com/doc/current/contributing/code/patches.html#make-a-pull-request
[6]: https://symfony.com/doc/master/contributing/code/tests.html
[7]: https://symfony.com/doc/current/book/installation.html#installing-the-symfony-installer

View File

@ -49,7 +49,7 @@ class CodeExtension extends \Twig_Extension
new \Twig_SimpleFilter('file_excerpt', array($this, 'fileExcerpt'), array('is_safe' => array('html'))),
new \Twig_SimpleFilter('format_file', array($this, 'formatFile'), array('is_safe' => array('html'))),
new \Twig_SimpleFilter('format_file_from_text', array($this, 'formatFileFromText'), array('is_safe' => array('html'))),
new \Twig_SimpleFilter('file_link', array($this, 'getFileLink'), array('is_safe' => array('html'))),
new \Twig_SimpleFilter('file_link', array($this, 'getFileLink')),
);
}

View File

@ -47,7 +47,7 @@ class TemplateController extends ContainerAware
if ($private) {
$response->setPrivate();
} elseif ($private === false || (null === $private && ($maxAge || $sharedAge))) {
$response->setPublic($private);
$response->setPublic();
}
return $response;

View File

@ -52,6 +52,7 @@ build: 56
background-color: #FFFFFF;
border: 1px solid #dfdfdf;
padding: 40px 50px;
word-break: break-all;
}
.sf-reset h2 {
font-size: 16px;

View File

@ -154,24 +154,25 @@ class CodeHelper extends Helper
*/
public function formatFile($file, $line, $text = null)
{
if (PHP_VERSION_ID >= 50400) {
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
} else {
$flags = ENT_QUOTES;
}
if (null === $text) {
$file = trim($file);
$fileStr = $file;
if (0 === strpos($fileStr, $this->rootDir)) {
$fileStr = str_replace($this->rootDir, '', str_replace('\\', '/', $fileStr));
$fileStr = sprintf('<abbr title="%s">kernel.root_dir</abbr>/%s', $this->rootDir, $fileStr);
$fileStr = htmlspecialchars($fileStr, $flags, $this->charset);
$fileStr = sprintf('<abbr title="%s">kernel.root_dir</abbr>/%s', htmlspecialchars($this->rootDir, $flags, $this->charset), $fileStr);
}
$text = "$fileStr at line $line";
$text = sprintf('%s at line %d', $fileStr, $line);
}
if (false !== $link = $this->getFileLink($file, $line)) {
if (PHP_VERSION_ID >= 50400) {
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
} else {
$flags = ENT_QUOTES;
}
return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text);
}

View File

@ -0,0 +1,89 @@
<?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\Bundle\FrameworkBundle\Tests\Command;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class RouterDebugCommandTest extends \PHPUnit_Framework_TestCase
{
public function testDebugAllRoutes()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array('name' => null));
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertContains('[router] Current routes', $tester->getDisplay());
}
public function testDebugSingleRoute()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array('name' => 'foo'));
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertContains('[router] Route "foo"', $tester->getDisplay());
}
/**
* @expectedException \InvalidArgumentException
*/
public function testDebugInvalidRoute()
{
$this->createCommandTester()->execute(array('name' => 'test'));
}
/**
* @return CommandTester
*/
private function createCommandTester()
{
$application = new Application();
$command = new RouterDebugCommand();
$command->setContainer($this->getContainer());
$application->add($command);
return new CommandTester($application->find('router:debug'));
}
private function getContainer()
{
$routeCollection = new RouteCollection();
$routeCollection->add('foo', new Route('foo'));
$router = $this->getMock('Symfony\Component\Routing\RouterInterface');
$router
->expects($this->atLeastOnce())
->method('getRouteCollection')
->will($this->returnValue($routeCollection))
;
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->once())
->method('has')
->with('router')
->will($this->returnValue(true))
;
$container
->expects($this->atLeastOnce())
->method('get')
->with('router')
->will($this->returnValue($router))
;
return $container;
}
}

View File

@ -0,0 +1,93 @@
<?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\Bundle\FrameworkBundle\Tests\Command;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Bundle\FrameworkBundle\Command\RouterMatchCommand;
use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RequestContext;
class RouterMatchCommandTest extends \PHPUnit_Framework_TestCase
{
public function testWithMatchPath()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array('path_info' => '/foo', 'foo'));
$this->assertEquals(0, $ret, 'Returns 0 in case of success');
$this->assertContains('[router] Route "foo"', $tester->getDisplay());
}
public function testWithNotMatchPath()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(array('path_info' => '/test', 'foo'));
$this->assertEquals(1, $ret, 'Returns 1 in case of failure');
$this->assertContains('None of the routes match the path "/test"', $tester->getDisplay());
}
/**
* @return CommandTester
*/
private function createCommandTester()
{
$application = new Application();
$command = new RouterMatchCommand();
$command->setContainer($this->getContainer());
$application->add($command);
$command = new RouterDebugCommand();
$command->setContainer($this->getContainer());
$application->add($command);
return new CommandTester($application->find('router:match'));
}
private function getContainer()
{
$routeCollection = new RouteCollection();
$routeCollection->add('foo', new Route('foo'));
$requestContext = new RequestContext();
$router = $this->getMock('Symfony\Component\Routing\RouterInterface');
$router
->expects($this->any())
->method('getRouteCollection')
->will($this->returnValue($routeCollection))
;
$router
->expects($this->any())
->method('getContext')
->will($this->returnValue($requestContext))
;
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->once())
->method('has')
->with('router')
->will($this->returnValue(true))
;
$container
->expects($this->atLeastOnce())
->method('get')
->with('router')
->will($this->returnValue($router))
;
return $container;
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\TwigBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Resource\DirectoryResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
@ -66,22 +67,26 @@ class TwigExtension extends Extension
} else {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, $namespace));
}
$container->addResource(new DirectoryResource($path));
}
// register bundles as Twig namespaces
foreach ($container->getParameter('kernel.bundles') as $bundle => $class) {
if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$bundle.'/views')) {
$this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $bundle);
$container->addResource(new DirectoryResource($dir));
}
$reflection = new \ReflectionClass($class);
if (is_dir($dir = dirname($reflection->getFilename()).'/Resources/views')) {
$this->addTwigPath($twigFilesystemLoaderDefinition, $dir, $bundle);
$container->addResource(new DirectoryResource($dir));
}
}
if (is_dir($dir = $container->getParameter('kernel.root_dir').'/Resources/views')) {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir));
$container->addResource(new DirectoryResource($dir));
}
if (!empty($config['globals'])) {

View File

@ -142,6 +142,7 @@ class OutputFormatter implements OutputFormatterInterface
*/
public function format($message)
{
$message = (string) $message;
$offset = 0;
$output = '';
$tagRegex = '[a-z][a-z0-9_=;-]*';

View File

@ -167,15 +167,6 @@ class CommandTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
}
public function testGet()
{
$application = new Application();
$command = new \TestCommand();
$command->setApplication($application);
$formatterHelper = new FormatterHelper();
$this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->__get() returns the correct helper');
}
public function testMergeApplicationDefinition()
{
$application1 = new Application();

View File

@ -166,6 +166,14 @@ class OutputFormatterTest extends \PHPUnit_Framework_TestCase
$this->assertEquals("\033[37;41msome error\033[39;49m".$long, $formatter->format('<error>some error</error>'.$long));
}
public function testFormatToStringObject()
{
$formatter = new OutputFormatter(false);
$this->assertEquals(
'some info', $formatter->format(new TableCell())
);
}
public function testNotDecoratedFormatter()
{
$formatter = new OutputFormatter(false);
@ -255,3 +263,11 @@ EOF
));
}
}
class TableCell
{
public function __toString()
{
return '<info>some info</info>';
}
}

View File

@ -124,13 +124,15 @@ class FormFieldRegistry
public function set($name, $value)
{
$target = &$this->get($name);
if (!is_array($value) || $target instanceof Field\ChoiceFormField) {
if ((!is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) {
$target->setValue($value);
} else {
} elseif (is_array($value)) {
$fields = self::create($name, $value);
foreach ($fields->all() as $k => $v) {
$this->set($k, $v);
}
} else {
throw new \InvalidArgumentException(sprintf('Cannot set value on a compound field "%s".', $name));
}
}

View File

@ -807,6 +807,31 @@ class FormTest extends \PHPUnit_Framework_TestCase
));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Cannot set value on a compound field "foo[bar]".
*/
public function testFormRegistrySetValueOnCompoundField()
{
$registry = new FormFieldRegistry();
$registry->add($this->getFormFieldMock('foo[bar][baz]'));
$registry->set('foo[bar]', 'fbb');
}
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Unreachable field "0"
*/
public function testFormRegistrySetArrayOnNotCompoundField()
{
$registry = new FormFieldRegistry();
$registry->add($this->getFormFieldMock('bar'));
$registry->set('bar', array('baz'));
}
public function testDifferentFieldTypesWithSameName()
{
$dom = new \DOMDocument();

View File

@ -62,7 +62,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
}
if ($child instanceof self) {
if ($child instanceof FormBuilderInterface) {
$this->children[$child->getName()] = $child;
// In case an unresolved child with the same name exists
@ -72,7 +72,7 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
}
if (!is_string($child) && !is_int($child)) {
throw new UnexpectedTypeException($child, 'string, integer or Symfony\Component\Form\FormBuilder');
throw new UnexpectedTypeException($child, 'string, integer or Symfony\Component\Form\FormBuilderInterface');
}
if (null !== $type && !is_string($type) && !$type instanceof FormTypeInterface) {

View File

@ -11,7 +11,9 @@
namespace Symfony\Component\Form\Tests;
use Symfony\Component\Form\ButtonBuilder;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\SubmitButtonBuilder;
class FormBuilderTest extends \PHPUnit_Framework_TestCase
{
@ -154,6 +156,12 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase
$this->builder->create('foo');
}
public function testAddButton()
{
$this->builder->add(new ButtonBuilder('reset'));
$this->builder->add(new SubmitButtonBuilder('submit'));
}
public function testGetUnknown()
{
$this->setExpectedException('Symfony\Component\Form\Exception\InvalidArgumentException', 'The child with the name "foo" does not exist.');

View File

@ -62,6 +62,10 @@ class IpUtils
public static function checkIp4($requestIp, $ip)
{
if (false !== strpos($ip, '/')) {
if ('0.0.0.0/0' === $ip) {
return true;
}
list($address, $netmask) = explode('/', $ip, 2);
if ($netmask < 1 || $netmask > 32) {

View File

@ -1760,7 +1760,7 @@ class Request
return $prefix;
}
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl).'/')) {
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, rtrim(dirname($baseUrl), '/').'/')) {
// directory portion of $baseUrl matches
return rtrim($prefix, '/');
}

View File

@ -75,6 +75,13 @@ class ServerBag extends ParameterBag
// In some circumstances PHP_AUTH_DIGEST needs to be set
$headers['PHP_AUTH_DIGEST'] = $authorizationHeader;
$this->parameters['PHP_AUTH_DIGEST'] = $authorizationHeader;
} elseif (0 === stripos($authorizationHeader, 'bearer ')) {
/*
* XXX: Since there is no PHP_AUTH_BEARER in PHP predefined variables,
* I'll just set $headers['AUTHORIZATION'] here.
* http://php.net/manual/en/reserved.variables.server.php
*/
$headers['AUTHORIZATION'] = $authorizationHeader;
}
}
}

View File

@ -34,6 +34,9 @@ class IpUtilsTest extends \PHPUnit_Framework_TestCase
array(true, '192.168.1.1', array('1.2.3.4/1', '192.168.1.0/24')),
array(true, '192.168.1.1', array('192.168.1.0/24', '1.2.3.4/1')),
array(false, '192.168.1.1', array('1.2.3.4/1', '4.3.2.1/1')),
array(true, '1.2.3.4', '0.0.0.0/0'),
array(false, '1.2.3.4', '256.256.256/0'),
array(false, '1.2.3.4', '192.168.1.0/0'),
);
}

View File

@ -1345,6 +1345,26 @@ class RequestTest extends \PHPUnit_Framework_TestCase
public function getBaseUrlData()
{
return array(
array(
'/fruit/strawberry/1234index.php/blah',
array(
'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/fruit/index.php',
'SCRIPT_NAME' => '/fruit/index.php',
'PHP_SELF' => '/fruit/index.php',
),
'/fruit',
'/strawberry/1234index.php/blah',
),
array(
'/fruit/strawberry/1234index.php/blah',
array(
'SCRIPT_FILENAME' => 'E:/Sites/cc-new/public_html/index.php',
'SCRIPT_NAME' => '/index.php',
'PHP_SELF' => '/index.php',
),
'',
'/fruit/strawberry/1234index.php/blah',
),
array(
'/foo%20bar/',
array(

View File

@ -141,4 +141,14 @@ class ServerBagTest extends \PHPUnit_Framework_TestCase
'AUTHORIZATION' => $headerContent,
), $bag->getHeaders());
}
public function testOAuthBearerAuthWithRedirect()
{
$headerContent = 'Bearer L-yLEOr9zhmUYRkzN1jwwxwQ-PBNiKDc8dgfB4hTfvo';
$bag = new ServerBag(array('REDIRECT_HTTP_AUTHORIZATION' => $headerContent));
$this->assertEquals(array(
'AUTHORIZATION' => $headerContent,
), $bag->getHeaders());
}
}

View File

@ -127,7 +127,7 @@ class Store implements StoreInterface
// find a cached entry that matches the request.
$match = null;
foreach ($entries as $entry) {
if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? $entry[1]['vary'][0] : '', $request->headers->all(), $entry[0])) {
if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? implode(', ', $entry[1]['vary']) : '', $request->headers->all(), $entry[0])) {
$match = $entry;
break;

View File

@ -168,6 +168,16 @@ class StoreTest extends \PHPUnit_Framework_TestCase
$this->assertNull($this->store->lookup($req2));
}
public function testDoesNotReturnEntriesThatSlightlyVaryWithLookup()
{
$req1 = Request::create('/test', 'get', array(), array(), array(), array('HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'));
$req2 = Request::create('/test', 'get', array(), array(), array(), array('HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bam'));
$res = new Response('test', 200, array('Vary' => array('Foo', 'Bar')));
$this->store->write($req1, $res);
$this->assertNull($this->store->lookup($req2));
}
public function testStoresMultipleResponsesForEachVaryCombination()
{
$req1 = Request::create('/test', 'get', array(), array(), array(), array('HTTP_FOO' => 'Foo', 'HTTP_BAR' => 'Bar'));

View File

@ -119,7 +119,7 @@ class IntlDateFormatter
/**
* @var bool
*/
private $unitializedTimeZoneId = false;
private $uninitializedTimeZoneId = false;
/**
* @var string
@ -371,7 +371,7 @@ class IntlDateFormatter
*/
public function getTimeZoneId()
{
if (!$this->unitializedTimeZoneId) {
if (!$this->uninitializedTimeZoneId) {
return $this->timeZoneId;
}
@ -551,7 +551,7 @@ class IntlDateFormatter
$timeZoneId = getenv('TZ') ?: 'UTC';
}
$this->unitializedTimeZoneId = true;
$this->uninitializedTimeZoneId = true;
}
// Backup original passed time zone

View File

@ -201,7 +201,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());
}
}

View File

@ -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));
}

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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));

View File

@ -8,7 +8,7 @@
</trans-unit>
<trans-unit id="2">
<source>Authentication credentials could not be found.</source>
<target>Les droits d'authentification n'ont pas pu être trouvés.</target>
<target>Les identifiants d'authentification n'ont pas pu être trouvés.</target>
</trans-unit>
<trans-unit id="3">
<source>Authentication request could not be processed due to a system problem.</source>
@ -16,7 +16,7 @@
</trans-unit>
<trans-unit id="4">
<source>Invalid credentials.</source>
<target>Droits invalides.</target>
<target>Identifiants invalides.</target>
</trans-unit>
<trans-unit id="5">
<source>Cookie has already been used by someone else.</source>
@ -24,7 +24,7 @@
</trans-unit>
<trans-unit id="6">
<source>Not privileged to request the resource.</source>
<target>Pas de privilèges pour accéder à la ressource.</target>
<target>Privilèges insuffisants pour accéder à la ressource.</target>
</trans-unit>
<trans-unit id="7">
<source>Invalid CSRF token.</source>
@ -40,7 +40,7 @@
</trans-unit>
<trans-unit id="10">
<source>No session available, it either timed out or cookies are not enabled.</source>
<target>Pas de session disponible, celle-ci a expiré ou les cookies ne sont pas activés.</target>
<target>Aucune session disponible, celle-ci a expiré ou les cookies ne sont pas activés.</target>
</trans-unit>
<trans-unit id="11">
<source>No token could be found.</source>
@ -48,7 +48,7 @@
</trans-unit>
<trans-unit id="12">
<source>Username could not be found.</source>
<target>Le nom d'utilisateur ne peut pas être trouvé.</target>
<target>Le nom d'utilisateur n'a pas pu être trouvé.</target>
</trans-unit>
<trans-unit id="13">
<source>Account has expired.</source>
@ -56,7 +56,7 @@
</trans-unit>
<trans-unit id="14">
<source>Credentials have expired.</source>
<target>Les droits ont expirés.</target>
<target>Les identifiants ont expiré.</target>
</trans-unit>
<trans-unit id="15">
<source>Account is disabled.</source>

View File

@ -1,7 +1,7 @@
Serializer Component
====================
With the Serializer component its possible to handle serializing data structures,
With the Serializer component it's possible to handle serializing data structures,
including object graphs, into array structures or other formats like XML and JSON.
It can also handle deserializing XML and JSON back to object graphs.