summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Acl/Domain/ObjectIdentity.php4
-rw-r--r--Acl/Tests/Domain/EntryTest.php2
-rw-r--r--Acl/Tests/Domain/ObjectIdentityTest.php24
-rw-r--r--Core/Authorization/AccessDecisionManager.php16
-rw-r--r--Core/Tests/Authorization/AccessDecisionManagerTest.php8
-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
-rw-r--r--Resources/translations/security.fr.xlf12
12 files changed, 104 insertions, 32 deletions
diff --git a/Acl/Domain/ObjectIdentity.php b/Acl/Domain/ObjectIdentity.php
index 907b1d8..fc5b9c6 100644
--- a/Acl/Domain/ObjectIdentity.php
+++ b/Acl/Domain/ObjectIdentity.php
@@ -36,7 +36,7 @@ final class ObjectIdentity implements ObjectIdentityInterface
*/
public function __construct($identifier, $type)
{
- if (empty($identifier)) {
+ if ('' === $identifier) {
throw new \InvalidArgumentException('$identifier cannot be empty.');
}
if (empty($type)) {
@@ -66,7 +66,7 @@ final class ObjectIdentity implements ObjectIdentityInterface
if ($domainObject instanceof DomainObjectInterface) {
return new self($domainObject->getObjectIdentifier(), ClassUtils::getRealClass($domainObject));
} elseif (method_exists($domainObject, 'getId')) {
- return new self($domainObject->getId(), ClassUtils::getRealClass($domainObject));
+ return new self((string) $domainObject->getId(), ClassUtils::getRealClass($domainObject));
}
} catch (\InvalidArgumentException $invalid) {
throw new InvalidDomainObjectException($invalid->getMessage(), 0, $invalid);
diff --git a/Acl/Tests/Domain/EntryTest.php b/Acl/Tests/Domain/EntryTest.php
index 6a2aac0..ab8e481 100644
--- a/Acl/Tests/Domain/EntryTest.php
+++ b/Acl/Tests/Domain/EntryTest.php
@@ -36,7 +36,7 @@ class EntryTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($ace->isAuditSuccess());
$ace->setAuditSuccess(false);
$this->assertFalse($ace->isAuditSuccess());
- $ace->setAuditsuccess(true);
+ $ace->setAuditSuccess(true);
$this->assertTrue($ace->isAuditSuccess());
}
diff --git a/Acl/Tests/Domain/ObjectIdentityTest.php b/Acl/Tests/Domain/ObjectIdentityTest.php
index 4eab7b2..325bb91 100644
--- a/Acl/Tests/Domain/ObjectIdentityTest.php
+++ b/Acl/Tests/Domain/ObjectIdentityTest.php
@@ -64,6 +64,26 @@ namespace Symfony\Component\Security\Acl\Tests\Domain
$this->assertEquals('Symfony\Component\Security\Acl\Tests\Domain\TestDomainObject', $id->getType());
}
+ public function testFromDomainObjectWithoutInterfaceEnforcesStringIdentifier()
+ {
+ $domainObject = new TestDomainObject();
+ $domainObject->id = 1;
+ $id = ObjectIdentity::fromDomainObject($domainObject);
+
+ $this->assertSame('1', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ }
+
+ public function testFromDomainObjectWithoutInterfaceAllowsZeroAsIdentifier()
+ {
+ $domainObject = new TestDomainObject();
+ $domainObject->id = '0';
+ $id = ObjectIdentity::fromDomainObject($domainObject);
+
+ $this->assertSame('0', $id->getIdentifier());
+ $this->assertEquals('Symfony\Component\Security\Tests\Acl\Domain\TestDomainObject', $id->getType());
+ }
+
/**
* @dataProvider getCompareData
*/
@@ -89,6 +109,8 @@ namespace Symfony\Component\Security\Acl\Tests\Domain
class TestDomainObject
{
+ public $id = 'getId()';
+
public function getObjectIdentifier()
{
return 'getObjectIdentifier()';
@@ -96,7 +118,7 @@ namespace Symfony\Component\Security\Acl\Tests\Domain
public function getId()
{
- return 'getId()';
+ return $this->id;
}
}
}
diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php
index b8b6a77..61debe3 100644
--- a/Core/Authorization/AccessDecisionManager.php
+++ b/Core/Authorization/AccessDecisionManager.php
@@ -41,12 +41,8 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
*
* @throws \InvalidArgumentException
*/
- public function __construct(array $voters, $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
+ public function __construct(array $voters = array(), $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
{
- if (!$voters) {
- throw new \InvalidArgumentException('You must at least add one voter.');
- }
-
$strategyMethod = 'decide'.ucfirst($strategy);
if (!is_callable(array($this, $strategyMethod))) {
throw new \InvalidArgumentException(sprintf('The strategy "%s" is not supported.', $strategy));
@@ -59,6 +55,16 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
}
/**
+ * Configures the voters.
+ *
+ * @param VoterInterface[] $voters An array of VoterInterface instances
+ */
+ public function setVoters(array $voters)
+ {
+ $this->voters = $voters;
+ }
+
+ /**
* {@inheritdoc}
*/
public function decide(TokenInterface $token, array $attributes, $object = null)
diff --git a/Core/Tests/Authorization/AccessDecisionManagerTest.php b/Core/Tests/Authorization/AccessDecisionManagerTest.php
index 3c970d1..bd876c7 100644
--- a/Core/Tests/Authorization/AccessDecisionManagerTest.php
+++ b/Core/Tests/Authorization/AccessDecisionManagerTest.php
@@ -49,14 +49,6 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \InvalidArgumentException
*/
- public function testSetVotersEmpty()
- {
- $manager = new AccessDecisionManager(array());
- }
-
- /**
- * @expectedException \InvalidArgumentException
- */
public function testSetUnsupportedStrategy()
{
new AccessDecisionManager(array($this->getVoter(VoterInterface::ACCESS_GRANTED)), 'fooBar');
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));
diff --git a/Resources/translations/security.fr.xlf b/Resources/translations/security.fr.xlf
index f3965d3..5a77c6e 100644
--- a/Resources/translations/security.fr.xlf
+++ b/Resources/translations/security.fr.xlf
@@ -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>