summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Acl/Dbal/AclProvider.php13
-rw-r--r--Acl/Dbal/MutableAclProvider.php127
-rw-r--r--Acl/Domain/AclCollectionCache.php1
-rw-r--r--Acl/Model/AclInterface.php2
-rw-r--r--Acl/Model/AclProviderInterface.php2
-rw-r--r--Core/Authentication/RememberMe/PersistentToken.php2
-rw-r--r--Core/Authentication/RememberMe/TokenProviderInterface.php2
-rw-r--r--Core/Authentication/Token/AbstractToken.php9
-rw-r--r--Core/Authentication/Token/AnonymousToken.php2
-rw-r--r--Core/Authentication/Token/UsernamePasswordToken.php2
-rw-r--r--Core/Encoder/BCryptPasswordEncoder.php9
-rw-r--r--Core/Encoder/BasePasswordEncoder.php12
-rw-r--r--Core/Encoder/MessageDigestPasswordEncoder.php8
-rw-r--r--Core/Encoder/Pbkdf2PasswordEncoder.php8
-rw-r--r--Core/Encoder/PlaintextPasswordEncoder.php10
-rw-r--r--Core/User/InMemoryUserProvider.php2
-rw-r--r--Core/User/UserInterface.php4
-rw-r--r--Http/AccessMap.php3
-rw-r--r--Http/Authentication/AuthenticationFailureHandlerInterface.php1
-rw-r--r--Http/Authentication/AuthenticationSuccessHandlerInterface.php1
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php2
-rw-r--r--Http/Authorization/AccessDeniedHandlerInterface.php1
-rw-r--r--Http/EntryPoint/AuthenticationEntryPointInterface.php1
-rw-r--r--Http/EntryPoint/BasicAuthenticationEntryPoint.php3
-rw-r--r--Http/EntryPoint/DigestAuthenticationEntryPoint.php9
-rw-r--r--Http/EntryPoint/FormAuthenticationEntryPoint.php2
-rw-r--r--Http/EntryPoint/RetryAuthenticationEntryPoint.php3
-rw-r--r--Http/Event/InteractiveLoginEvent.php6
-rw-r--r--Http/Event/SwitchUserEvent.php12
-rw-r--r--Http/Firewall.php3
-rw-r--r--Http/Firewall/AbstractPreAuthenticatedListener.php2
-rw-r--r--Http/Firewall/AccessListener.php5
-rw-r--r--Http/Firewall/ContextListener.php7
-rw-r--r--Http/Firewall/ExceptionListener.php125
-rw-r--r--Http/Firewall/LogoutListener.php5
-rw-r--r--Http/Firewall/RememberMeListener.php2
-rw-r--r--Http/Firewall/X509AuthenticationListener.php3
-rw-r--r--Http/FirewallMap.php8
-rw-r--r--Http/FirewallMapInterface.php2
-rw-r--r--Http/HttpUtils.php12
-rw-r--r--Http/Logout/LogoutSuccessHandlerInterface.php1
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php11
-rw-r--r--Http/RememberMe/ResponseListener.php6
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php4
-rw-r--r--README.md2
-rw-r--r--Resources/translations/security.ja.xlf71
-rw-r--r--Tests/Acl/Dbal/MutableAclProviderTest.php50
-rw-r--r--Tests/Core/Authentication/AuthenticationProviderManagerTest.php2
-rw-r--r--Tests/Core/Authentication/Token/AbstractTokenTest.php41
-rw-r--r--Tests/Core/Authentication/Token/RememerMeTokenTest.php2
-rw-r--r--Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php2
-rw-r--r--Tests/Core/Authorization/AccessDecisionManagerTest.php2
-rw-r--r--Tests/Core/Encoder/BCryptPasswordEncoderTest.php17
-rw-r--r--Tests/Core/Encoder/BasePasswordEncoderTest.php18
-rw-r--r--Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php19
-rw-r--r--Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php19
-rw-r--r--Tests/Core/Encoder/PlaintextPasswordEncoderTest.php17
-rw-r--r--Tests/Core/User/InMemoryProviderTest.php2
-rw-r--r--Tests/Core/User/UserTest.php2
-rw-r--r--Tests/Core/Util/SecureRandomTest.php2
-rw-r--r--Tests/Http/Firewall/ExceptionListenerTest.php189
-rw-r--r--Tests/Http/Firewall/LogoutListenerTest.php2
-rw-r--r--Tests/Http/Firewall/X509AuthenticationListenerTest.php2
-rw-r--r--Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php1
64 files changed, 780 insertions, 137 deletions
diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php
index 822a160..1d1cb16 100644
--- a/Acl/Dbal/AclProvider.php
+++ b/Acl/Dbal/AclProvider.php
@@ -165,8 +165,17 @@ class AclProvider implements AclProviderInterface
// Is it time to load the current batch?
if ((self::MAX_BATCH_SIZE === count($currentBatch) || ($i + 1) === $c) && count($currentBatch) > 0) {
- $loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
-
+ try {
+ $loadedBatch = $this->lookupObjectIdentities($currentBatch, $sids, $oidLookup);
+ } catch (AclNotFoundException $aclNotFoundexception) {
+ if ($result->count()) {
+ $partialResultException = new NotAllAclsFoundException('The provider could not find ACLs for all object identities.');
+ $partialResultException->setPartialResult($result);
+ throw $partialResultException;
+ } else {
+ throw $aclNotFoundexception;
+ }
+ }
foreach ($loadedBatch as $loadedOid) {
$loadedAcl = $loadedBatch->offsetGet($loadedOid);
diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php
index 0ac4fa7..29d3cfd 100644
--- a/Acl/Dbal/MutableAclProvider.php
+++ b/Acl/Dbal/MutableAclProvider.php
@@ -252,6 +252,22 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
}
}
+ // check properties for deleted, and created ACEs, and perform deletions
+ // we need to perfom deletions before updating existing ACEs, in order to
+ // preserve uniqueness of the order field
+ if (isset($propertyChanges['classAces'])) {
+ $this->updateOldAceProperty('classAces', $propertyChanges['classAces']);
+ }
+ if (isset($propertyChanges['classFieldAces'])) {
+ $this->updateOldFieldAceProperty('classFieldAces', $propertyChanges['classFieldAces']);
+ }
+ if (isset($propertyChanges['objectAces'])) {
+ $this->updateOldAceProperty('objectAces', $propertyChanges['objectAces']);
+ }
+ if (isset($propertyChanges['objectFieldAces'])) {
+ $this->updateOldFieldAceProperty('objectFieldAces', $propertyChanges['objectFieldAces']);
+ }
+
// this includes only updates of existing ACEs, but neither the creation, nor
// the deletion of ACEs; these are tracked by changes to the ACL's respective
// properties (classAces, classFieldAces, objectAces, objectFieldAces)
@@ -259,20 +275,20 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
$this->updateAces($propertyChanges['aces']);
}
- // check properties for deleted, and created ACEs
+ // check properties for deleted, and created ACEs, and perform creations
if (isset($propertyChanges['classAces'])) {
- $this->updateAceProperty('classAces', $propertyChanges['classAces']);
+ $this->updateNewAceProperty('classAces', $propertyChanges['classAces']);
$sharedPropertyChanges['classAces'] = $propertyChanges['classAces'];
}
if (isset($propertyChanges['classFieldAces'])) {
- $this->updateFieldAceProperty('classFieldAces', $propertyChanges['classFieldAces']);
+ $this->updateNewFieldAceProperty('classFieldAces', $propertyChanges['classFieldAces']);
$sharedPropertyChanges['classFieldAces'] = $propertyChanges['classFieldAces'];
}
if (isset($propertyChanges['objectAces'])) {
- $this->updateAceProperty('objectAces', $propertyChanges['objectAces']);
+ $this->updateNewAceProperty('objectAces', $propertyChanges['objectAces']);
}
if (isset($propertyChanges['objectFieldAces'])) {
- $this->updateFieldAceProperty('objectFieldAces', $propertyChanges['objectFieldAces']);
+ $this->updateNewFieldAceProperty('objectFieldAces', $propertyChanges['objectFieldAces']);
}
// if there have been changes to shared properties, we need to synchronize other
@@ -740,12 +756,12 @@ QUERY;
}
/**
- * This processes changes on an ACE related property (classFieldAces, or objectFieldAces).
+ * This processes new entries changes on an ACE related property (classFieldAces, or objectFieldAces).
*
* @param string $name
* @param array $changes
*/
- private function updateFieldAceProperty($name, array $changes)
+ private function updateNewFieldAceProperty($name, array $changes)
{
$sids = new \SplObjectStorage();
$classIds = new \SplObjectStorage();
@@ -782,9 +798,29 @@ QUERY;
}
}
}
+ }
+
+ /**
+ * This process old entries changes on an ACE related property (classFieldAces, or objectFieldAces).
+ *
+ * @param string $name
+ * @param array $changes
+ */
+ private function updateOldFieldAceProperty($ane, array $changes)
+ {
+ $currentIds = array();
+ foreach ($changes[1] as $field => $new) {
+ for ($i = 0, $c = count($new); $i < $c; $i++) {
+ $ace = $new[$i];
+
+ if (null !== $ace->getId()) {
+ $currentIds[$ace->getId()] = true;
+ }
+ }
+ }
foreach ($changes[0] as $old) {
- for ($i=0,$c=count($old); $i<$c; $i++) {
+ for ($i = 0, $c = count($old); $i < $c; $i++) {
$ace = $old[$i];
if (!isset($currentIds[$ace->getId()])) {
@@ -796,12 +832,12 @@ QUERY;
}
/**
- * This processes changes on an ACE related property (classAces, or objectAces).
+ * This processes new entries changes on an ACE related property (classAces, or objectAces).
*
* @param string $name
* @param array $changes
*/
- private function updateAceProperty($name, array $changes)
+ private function updateNewAceProperty($name, array $changes)
{
list($old, $new) = $changes;
@@ -838,8 +874,28 @@ QUERY;
$currentIds[$ace->getId()] = true;
}
}
+ }
- for ($i=0,$c=count($old); $i<$c; $i++) {
+ /**
+ * This processes old entries changes on an ACE related property (classAces, or objectAces).
+ *
+ * @param string $name
+ * @param array $changes
+ */
+ private function updateOldAceProperty($name, array $changes)
+ {
+ list($old, $new) = $changes;
+ $currentIds = array();
+
+ for ($i=0,$c=count($new); $i<$c; $i++) {
+ $ace = $new[$i];
+
+ if (null !== $ace->getId()) {
+ $currentIds[$ace->getId()] = true;
+ }
+ }
+
+ for ($i = 0, $c = count($old); $i < $c; $i++) {
$ace = $old[$i];
if (!isset($currentIds[$ace->getId()])) {
@@ -857,26 +913,41 @@ QUERY;
private function updateAces(\SplObjectStorage $aces)
{
foreach ($aces as $ace) {
- $propertyChanges = $aces->offsetGet($ace);
- $sets = array();
+ $this->updateAce($aces, $ace);
+ }
+ }
- if (isset($propertyChanges['mask'])) {
- $sets[] = sprintf('mask = %d', $propertyChanges['mask'][1]);
- }
- if (isset($propertyChanges['strategy'])) {
- $sets[] = sprintf('granting_strategy = %s', $this->connection->quote($propertyChanges['strategy']));
- }
- if (isset($propertyChanges['aceOrder'])) {
- $sets[] = sprintf('ace_order = %d', $propertyChanges['aceOrder'][1]);
- }
- if (isset($propertyChanges['auditSuccess'])) {
- $sets[] = sprintf('audit_success = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditSuccess'][1]));
- }
- if (isset($propertyChanges['auditFailure'])) {
- $sets[] = sprintf('audit_failure = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditFailure'][1]));
+ private function updateAce(\SplObjectStorage $aces, $ace)
+ {
+ $propertyChanges = $aces->offsetGet($ace);
+ $sets = array();
+
+ if (isset($propertyChanges['aceOrder'])
+ && $propertyChanges['aceOrder'][1] > $propertyChanges['aceOrder'][0]
+ && $propertyChanges == $aces->offsetGet($ace)) {
+ $aces->next();
+ if ($aces->valid()) {
+ $this->updateAce($aces, $aces->current());
+ }
}
- $this->connection->executeQuery($this->getUpdateAccessControlEntrySql($ace->getId(), $sets));
+ if (isset($propertyChanges['mask'])) {
+ $sets[] = sprintf('mask = %d', $propertyChanges['mask'][1]);
}
+ if (isset($propertyChanges['strategy'])) {
+ $sets[] = sprintf('granting_strategy = %s', $this->connection->quote($propertyChanges['strategy']));
+ }
+ if (isset($propertyChanges['aceOrder'])) {
+ $sets[] = sprintf('ace_order = %d', $propertyChanges['aceOrder'][1]);
+ }
+ if (isset($propertyChanges['auditSuccess'])) {
+ $sets[] = sprintf('audit_success = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditSuccess'][1]));
+ }
+ if (isset($propertyChanges['auditFailure'])) {
+ $sets[] = sprintf('audit_failure = %s', $this->connection->getDatabasePlatform()->convertBooleans($propertyChanges['auditFailure'][1]));
+ }
+
+ $this->connection->executeQuery($this->getUpdateAccessControlEntrySql($ace->getId(), $sets));
}
+
}
diff --git a/Acl/Domain/AclCollectionCache.php b/Acl/Domain/AclCollectionCache.php
index d3a4b37..5dfef08 100644
--- a/Acl/Domain/AclCollectionCache.php
+++ b/Acl/Domain/AclCollectionCache.php
@@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Acl\Domain;
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
use Symfony\Component\Security\Acl\Model\ObjectIdentityRetrievalStrategyInterface;
use Symfony\Component\Security\Acl\Model\SecurityIdentityRetrievalStrategyInterface;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* This service caches ACLs for an entire collection of objects.
diff --git a/Acl/Model/AclInterface.php b/Acl/Model/AclInterface.php
index fffe591..02bbd00 100644
--- a/Acl/Model/AclInterface.php
+++ b/Acl/Model/AclInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Acl\Model;
+use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
+
/**
* This interface represents an access control list (ACL) for a domain object.
* Each domain object can have exactly one associated ACL.
diff --git a/Acl/Model/AclProviderInterface.php b/Acl/Model/AclProviderInterface.php
index 4be49bf..615cf14 100644
--- a/Acl/Model/AclProviderInterface.php
+++ b/Acl/Model/AclProviderInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Acl\Model;
+use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
+
/**
* Provides a common interface for retrieving ACLs.
*
diff --git a/Core/Authentication/RememberMe/PersistentToken.php b/Core/Authentication/RememberMe/PersistentToken.php
index f3f6858..8919be9 100644
--- a/Core/Authentication/RememberMe/PersistentToken.php
+++ b/Core/Authentication/RememberMe/PersistentToken.php
@@ -100,7 +100,7 @@ final class PersistentToken implements PersistentTokenInterface
/**
* Returns the time the token was last used
*
- * @return DateTime
+ * @return \DateTime
*/
public function getLastUsed()
{
diff --git a/Core/Authentication/RememberMe/TokenProviderInterface.php b/Core/Authentication/RememberMe/TokenProviderInterface.php
index 44bf4b0..93ed8d3 100644
--- a/Core/Authentication/RememberMe/TokenProviderInterface.php
+++ b/Core/Authentication/RememberMe/TokenProviderInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\RememberMe;
+use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
+
/**
* Interface for TokenProviders
*
diff --git a/Core/Authentication/Token/AbstractToken.php b/Core/Authentication/Token/AbstractToken.php
index 1d65819..b994733 100644
--- a/Core/Authentication/Token/AbstractToken.php
+++ b/Core/Authentication/Token/AbstractToken.php
@@ -146,7 +146,14 @@ abstract class AbstractToken implements TokenInterface
*/
public function serialize()
{
- return serialize(array($this->user, $this->authenticated, $this->roles, $this->attributes));
+ return serialize(
+ array(
+ is_object($this->user) ? clone $this->user : $this->user,
+ $this->authenticated,
+ $this->roles,
+ $this->attributes
+ )
+ );
}
/**
diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php
index 9b0a084..cabb6d5 100644
--- a/Core/Authentication/Token/AnonymousToken.php
+++ b/Core/Authentication/Token/AnonymousToken.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+
/**
* AnonymousToken represents an anonymous token.
*
diff --git a/Core/Authentication/Token/UsernamePasswordToken.php b/Core/Authentication/Token/UsernamePasswordToken.php
index d6e3998..3854242 100644
--- a/Core/Authentication/Token/UsernamePasswordToken.php
+++ b/Core/Authentication/Token/UsernamePasswordToken.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+
/**
* UsernamePasswordToken implements a username and password token.
*
diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php
index a355421..fc79021 100644
--- a/Core/Encoder/BCryptPasswordEncoder.php
+++ b/Core/Encoder/BCryptPasswordEncoder.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Encoder;
use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
/**
* @author Elnur Abdurrakhimov <elnur@elnur.pro>
@@ -42,7 +43,7 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
throw new \InvalidArgumentException('Cost must be in the range of 4-31.');
}
- $this->cost = sprintf('%02d', $cost);
+ $this->cost = $cost;
}
/**
@@ -64,6 +65,10 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
*/
public function encodePassword($raw, $salt)
{
+ if ($this->isPasswordTooLong($raw)) {
+ throw new BadCredentialsException('Invalid password.');
+ }
+
$options = array('cost' => $this->cost);
if ($salt) {
@@ -78,6 +83,6 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
*/
public function isPasswordValid($encoded, $raw, $salt)
{
- return password_verify($raw, $encoded);
+ return !$this->isPasswordTooLong($raw) && password_verify($raw, $encoded);
}
}
diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php
index c26c9ce..b83eb30 100644
--- a/Core/Encoder/BasePasswordEncoder.php
+++ b/Core/Encoder/BasePasswordEncoder.php
@@ -20,6 +20,8 @@ use Symfony\Component\Security\Core\Util\StringUtils;
*/
abstract class BasePasswordEncoder implements PasswordEncoderInterface
{
+ const MAX_PASSWORD_LENGTH = 4096;
+
/**
* Demerges a merge password and salt string.
*
@@ -83,4 +85,14 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
{
return StringUtils::equals($password1, $password2);
}
+
+ /**
+ * Checks if the password is too long.
+ *
+ * @return Boolean true if the password is too long, false otherwise
+ */
+ protected function isPasswordTooLong($password)
+ {
+ return strlen($password) > self::MAX_PASSWORD_LENGTH;
+ }
}
diff --git a/Core/Encoder/MessageDigestPasswordEncoder.php b/Core/Encoder/MessageDigestPasswordEncoder.php
index a8bd553..a7e5546 100644
--- a/Core/Encoder/MessageDigestPasswordEncoder.php
+++ b/Core/Encoder/MessageDigestPasswordEncoder.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Encoder;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+
/**
* MessageDigestPasswordEncoder uses a message digest algorithm.
*
@@ -41,6 +43,10 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder
*/
public function encodePassword($raw, $salt)
{
+ if ($this->isPasswordTooLong($raw)) {
+ throw new BadCredentialsException('Invalid password.');
+ }
+
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
@@ -61,6 +67,6 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder
*/
public function isPasswordValid($encoded, $raw, $salt)
{
- return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
+ return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
}
diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php
index 4f37ba3..8a5a958 100644
--- a/Core/Encoder/Pbkdf2PasswordEncoder.php
+++ b/Core/Encoder/Pbkdf2PasswordEncoder.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Encoder;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+
/**
* Pbkdf2PasswordEncoder uses the PBKDF2 (Password-Based Key Derivation Function 2).
*
@@ -54,6 +56,10 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
*/
public function encodePassword($raw, $salt)
{
+ if ($this->isPasswordTooLong($raw)) {
+ throw new BadCredentialsException('Invalid password.');
+ }
+
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
@@ -72,7 +78,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
*/
public function isPasswordValid($encoded, $raw, $salt)
{
- return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
+ return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0)
diff --git a/Core/Encoder/PlaintextPasswordEncoder.php b/Core/Encoder/PlaintextPasswordEncoder.php
index c21f3cd..22f3da4 100644
--- a/Core/Encoder/PlaintextPasswordEncoder.php
+++ b/Core/Encoder/PlaintextPasswordEncoder.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Encoder;
+use Symfony\Component\Security\Core\Exception\BadCredentialsException;
+
/**
* PlaintextPasswordEncoder does not do any encoding.
*
@@ -35,6 +37,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder
*/
public function encodePassword($raw, $salt)
{
+ if ($this->isPasswordTooLong($raw)) {
+ throw new BadCredentialsException('Invalid password.');
+ }
+
return $this->mergePasswordAndSalt($raw, $salt);
}
@@ -43,6 +49,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder
*/
public function isPasswordValid($encoded, $raw, $salt)
{
+ if ($this->isPasswordTooLong($raw)) {
+ return false;
+ }
+
$pass2 = $this->mergePasswordAndSalt($raw, $salt);
if (!$this->ignorePasswordCase) {
diff --git a/Core/User/InMemoryUserProvider.php b/Core/User/InMemoryUserProvider.php
index e87f80c..074c21e 100644
--- a/Core/User/InMemoryUserProvider.php
+++ b/Core/User/InMemoryUserProvider.php
@@ -56,7 +56,7 @@ class InMemoryUserProvider implements UserProviderInterface
public function createUser(UserInterface $user)
{
if (isset($this->users[strtolower($user->getUsername())])) {
- throw new \LogicException('Another user with the same username already exist.');
+ throw new \LogicException('Another user with the same username already exists.');
}
$this->users[strtolower($user->getUsername())] = $user;
diff --git a/Core/User/UserInterface.php b/Core/User/UserInterface.php
index f5bbde2..1b52dab 100644
--- a/Core/User/UserInterface.php
+++ b/Core/User/UserInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\User;
+use Symfony\Component\Security\Core\Role\Role;
+
/**
* Represents the interface that all user classes must implement.
*
@@ -80,8 +82,6 @@ interface UserInterface
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
- *
- * @return void
*/
public function eraseCredentials();
}
diff --git a/Http/AccessMap.php b/Http/AccessMap.php
index de78e15..051a8c2 100644
--- a/Http/AccessMap.php
+++ b/Http/AccessMap.php
@@ -36,6 +36,9 @@ class AccessMap implements AccessMapInterface
$this->map[] = array($requestMatcher, $roles, $channel);
}
+ /**
+ * {@inheritDoc}
+ */
public function getPatterns(Request $request)
{
foreach ($this->map as $elements) {
diff --git a/Http/Authentication/AuthenticationFailureHandlerInterface.php b/Http/Authentication/AuthenticationFailureHandlerInterface.php
index 8dbd29a..e2d375e 100644
--- a/Http/Authentication/AuthenticationFailureHandlerInterface.php
+++ b/Http/Authentication/AuthenticationFailureHandlerInterface.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
/**
* Interface for custom authentication failure handlers.
diff --git a/Http/Authentication/AuthenticationSuccessHandlerInterface.php b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
index 5c08e73..9ec64b4 100644
--- a/Http/Authentication/AuthenticationSuccessHandlerInterface.php
+++ b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Authentication;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
/**
* Interface for a custom authentication success handler
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
index 64f84f0..70dcd1e 100644
--- a/Http/Authentication/DefaultAuthenticationFailureHandler.php
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -64,7 +64,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
{
if ($failureUrl = $request->get($this->options['failure_path_parameter'], null, true)) {
$this->options['failure_path'] = $failureUrl;
- }
+ }
if (null === $this->options['failure_path']) {
$this->options['failure_path'] = $this->options['login_path'];
diff --git a/Http/Authorization/AccessDeniedHandlerInterface.php b/Http/Authorization/AccessDeniedHandlerInterface.php
index a10a5d0..a5ea9db 100644
--- a/Http/Authorization/AccessDeniedHandlerInterface.php
+++ b/Http/Authorization/AccessDeniedHandlerInterface.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Http\Authorization;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
diff --git a/Http/EntryPoint/AuthenticationEntryPointInterface.php b/Http/EntryPoint/AuthenticationEntryPointInterface.php
index d190fc7..0d7595d 100644
--- a/Http/EntryPoint/AuthenticationEntryPointInterface.php
+++ b/Http/EntryPoint/AuthenticationEntryPointInterface.php
@@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\EntryPoint;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
/**
* AuthenticationEntryPointInterface is the interface used to start the
diff --git a/Http/EntryPoint/BasicAuthenticationEntryPoint.php b/Http/EntryPoint/BasicAuthenticationEntryPoint.php
index 44ece5e..e03de7d 100644
--- a/Http/EntryPoint/BasicAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/BasicAuthenticationEntryPoint.php
@@ -30,6 +30,9 @@ class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
$this->realmName = $realmName;
}
+ /**
+ * {@inheritdoc}
+ */
public function start(Request $request, AuthenticationException $authException = null)
{
$response = new Response();
diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
index 1131b58..4029d79 100644
--- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
@@ -38,6 +38,9 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
$this->logger = $logger;
}
+ /**
+ * {@inheritdoc}
+ */
public function start(Request $request, AuthenticationException $authException = null)
{
$expiryTime = microtime(true) + $this->nonceValiditySeconds * 1000;
@@ -62,11 +65,17 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
return $response;
}
+ /**
+ * @return string
+ */
public function getKey()
{
return $this->key;
}
+ /**
+ * @return string
+ */
public function getRealmName()
{
return $this->realmName;
diff --git a/Http/EntryPoint/FormAuthenticationEntryPoint.php b/Http/EntryPoint/FormAuthenticationEntryPoint.php
index 3eaae82..45a7ea9 100644
--- a/Http/EntryPoint/FormAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/FormAuthenticationEntryPoint.php
@@ -30,7 +30,7 @@ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface
private $httpUtils;
/**
- * Constructor
+ * Constructor.
*
* @param HttpKernelInterface $kernel
* @param HttpUtils $httpUtils An HttpUtils instance
diff --git a/Http/EntryPoint/RetryAuthenticationEntryPoint.php b/Http/EntryPoint/RetryAuthenticationEntryPoint.php
index 532601a..091e0ee 100644
--- a/Http/EntryPoint/RetryAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/RetryAuthenticationEntryPoint.php
@@ -34,6 +34,9 @@ class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface
$this->httpsPort = $httpsPort;
}
+ /**
+ * {@inheritdoc}
+ */
public function start(Request $request, AuthenticationException $authException = null)
{
$scheme = $request->isSecure() ? 'http' : 'https';
diff --git a/Http/Event/InteractiveLoginEvent.php b/Http/Event/InteractiveLoginEvent.php
index 2225d92..575352c 100644
--- a/Http/Event/InteractiveLoginEvent.php
+++ b/Http/Event/InteractiveLoginEvent.php
@@ -15,10 +15,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+/**
+ * InteractiveLoginEvent
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
class InteractiveLoginEvent extends Event
{
private $request;
-
private $authenticationToken;
/**
diff --git a/Http/Event/SwitchUserEvent.php b/Http/Event/SwitchUserEvent.php
index 4a7dcaf..a553154 100644
--- a/Http/Event/SwitchUserEvent.php
+++ b/Http/Event/SwitchUserEvent.php
@@ -15,10 +15,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\EventDispatcher\Event;
+/**
+ * SwitchUserEvent
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
class SwitchUserEvent extends Event
{
private $request;
-
private $targetUser;
public function __construct(Request $request, UserInterface $targetUser)
@@ -27,11 +31,17 @@ class SwitchUserEvent extends Event
$this->targetUser = $targetUser;
}
+ /**
+ * @return Request
+ */
public function getRequest()
{
return $this->request;
}
+ /**
+ * @return UserInterface
+ */
public function getTargetUser()
{
return $this->targetUser;
diff --git a/Http/Firewall.php b/Http/Firewall.php
index 31c1da5..4f1cf30 100644
--- a/Http/Firewall.php
+++ b/Http/Firewall.php
@@ -71,6 +71,9 @@ class Firewall implements EventSubscriberInterface
}
}
+ /**
+ * {@inheritDoc}
+ */
public static function getSubscribedEvents()
{
return array(KernelEvents::REQUEST => array('onKernelRequest', 8));
diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php
index fdc2e8c..94ae901 100644
--- a/Http/Firewall/AbstractPreAuthenticatedListener.php
+++ b/Http/Firewall/AbstractPreAuthenticatedListener.php
@@ -97,7 +97,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
/**
* Clears a PreAuthenticatedToken for this provider (if present)
- *
+ *
* @param AuthenticationException $exception
*/
private function clearToken(AuthenticationException $exception)
diff --git a/Http/Firewall/AccessListener.php b/Http/Firewall/AccessListener.php
index c3894ef..9349012 100644
--- a/Http/Firewall/AccessListener.php
+++ b/Http/Firewall/AccessListener.php
@@ -15,7 +15,6 @@ use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
-use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
@@ -31,15 +30,13 @@ class AccessListener implements ListenerInterface
private $accessDecisionManager;
private $map;
private $authManager;
- private $logger;
- public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager, LoggerInterface $logger = null)
+ public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager)
{
$this->context = $context;
$this->accessDecisionManager = $accessDecisionManager;
$this->map = $map;
$this->authManager = $authManager;
- $this->logger = $logger;
}
/**
diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php
index 81ccbdc..60ab3df 100644
--- a/Http/Firewall/ContextListener.php
+++ b/Http/Firewall/ContextListener.php
@@ -156,10 +156,11 @@ class ContextListener implements ListenerInterface
foreach ($this->userProviders as $provider) {
try {
- $token->setUser($provider->refreshUser($user));
+ $refreshedUser = $provider->refreshUser($user);
+ $token->setUser($refreshedUser);
if (null !== $this->logger) {
- $this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $user->getUsername()));
+ $this->logger->debug(sprintf('Username "%s" was reloaded from user provider.', $refreshedUser->getUsername()));
}
return $token;
@@ -167,7 +168,7 @@ class ContextListener implements ListenerInterface
// let's try the next user provider
} catch (UsernameNotFoundException $notFound) {
if (null !== $this->logger) {
- $this->logger->warning(sprintf('Username "%s" could not be found.', $user->getUsername()));
+ $this->logger->warning(sprintf('Username "%s" could not be found.', $notFound->getUsername()));
}
return null;
diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php
index abbb460..e7e2989 100644
--- a/Http/Firewall/ExceptionListener.php
+++ b/Http/Firewall/ExceptionListener.php
@@ -81,86 +81,92 @@ class ExceptionListener
$event->getDispatcher()->removeListener(KernelEvents::EXCEPTION, array($this, 'onKernelException'));
$exception = $event->getException();
- $request = $event->getRequest();
+ do {
+ if ($exception instanceof AuthenticationException) {
+ return $this->handleAuthenticationException($event, $exception);
+ } elseif ($exception instanceof AccessDeniedException) {
+ return $this->handleAccessDeniedException($event, $exception);
+ } elseif ($exception instanceof LogoutException) {
+ return $this->handleLogoutException($event, $exception);
+ }
+ } while (null !== $exception = $exception->getPrevious());
+ }
+
+ private function handleAuthenticationException(GetResponseForExceptionEvent $event, AuthenticationException $exception)
+ {
+ if (null !== $this->logger) {
+ $this->logger->info(sprintf('Authentication exception occurred; redirecting to authentication entry point (%s)', $exception->getMessage()));
+ }
- // determine the actual cause for the exception
- while (null !== $previous = $exception->getPrevious()) {
- $exception = $previous;
+ try {
+ $event->setResponse($this->startAuthentication($event->getRequest(), $exception));
+ } catch (\Exception $e) {
+ $event->setException($e);
}
+ }
- if ($exception instanceof AuthenticationException) {
+ private function handleAccessDeniedException(GetResponseForExceptionEvent $event, AccessDeniedException $exception)
+ {
+ $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
+
+ $token = $this->context->getToken();
+ if (!$this->authenticationTrustResolver->isFullFledged($token)) {
if (null !== $this->logger) {
- $this->logger->info(sprintf('Authentication exception occurred; redirecting to authentication entry point (%s)', $exception->getMessage()));
+ $this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
}
try {
- $response = $this->startAuthentication($request, $exception);
+ $insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
+ $insufficientAuthenticationException->setToken($token);
+
+ $event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
} catch (\Exception $e) {
$event->setException($e);
-
- return;
}
- } elseif ($exception instanceof AccessDeniedException) {
- $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
- $token = $this->context->getToken();
- if (!$this->authenticationTrustResolver->isFullFledged($token)) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Access is denied (user is not fully authenticated) by "%s" at line %s; redirecting to authentication entry point', $exception->getFile(), $exception->getLine()));
- }
+ return;
+ }
+
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
+ }
- try {
- $insufficientAuthenticationException = new InsufficientAuthenticationException('Full authentication is required to access this resource.', 0, $exception);
- $insufficientAuthenticationException->setToken($token);
- $response = $this->startAuthentication($request, $insufficientAuthenticationException);
- } catch (\Exception $e) {
- $event->setException($e);
+ try {
+ if (null !== $this->accessDeniedHandler) {
+ $response = $this->accessDeniedHandler->handle($event->getRequest(), $exception);
- return;
- }
- } else {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Access is denied (and user is neither anonymous, nor remember-me) by "%s" at line %s', $exception->getFile(), $exception->getLine()));
+ if ($response instanceof Response) {
+ $event->setResponse($response);
}
+ } elseif (null !== $this->errorPage) {
+ $subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage);
+ $subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
- try {
- if (null !== $this->accessDeniedHandler) {
- $response = $this->accessDeniedHandler->handle($request, $exception);
-
- if (!$response instanceof Response) {
- return;
- }
- } elseif (null !== $this->errorPage) {
- $subRequest = $this->httpUtils->createRequest($request, $this->errorPage);
- $subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
-
- $response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
- } else {
- return;
- }
- } catch (\Exception $e) {
- if (null !== $this->logger) {
- $this->logger->error(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
- }
-
- $event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
-
- return;
- }
+ $event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true));
}
- } elseif ($exception instanceof LogoutException) {
+ } catch (\Exception $e) {
if (null !== $this->logger) {
- $this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
+ $this->logger->error(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
}
- return;
- } else {
- return;
+ $event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
}
+ }
- $event->setResponse($response);
+ private function handleLogoutException(GetResponseForExceptionEvent $event, LogoutException $exception)
+ {
+ if (null !== $this->logger) {
+ $this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
+ }
}
+ /**
+ * @param Request $request
+ * @param AuthenticationException $authException
+ *
+ * @return Response
+ * @throws AuthenticationException
+ */
private function startAuthentication(Request $request, AuthenticationException $authException)
{
if (null === $this->authenticationEntryPoint) {
@@ -181,9 +187,12 @@ class ExceptionListener
return $this->authenticationEntryPoint->start($request, $authException);
}
+ /**
+ * @param Request $request
+ */
protected function setTargetPath(Request $request)
{
- // session isn't required when using http basic authentication mechanism for example
+ // session isn't required when using HTTP basic authentication mechanism for example
if ($request->hasSession() && $request->isMethodSafe()) {
$request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri());
}
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index ca2f439..7dc9503 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -36,7 +36,7 @@ class LogoutListener implements ListenerInterface
private $csrfProvider;
/**
- * Constructor
+ * Constructor.
*
* @param SecurityContextInterface $securityContext
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
@@ -76,9 +76,8 @@ class LogoutListener implements ListenerInterface
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
- * @throws InvalidCsrfTokenException if the CSRF token is invalid
+ * @throws LogoutException if the CSRF token is invalid
* @throws \RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
- * @throws LogoutException
*/
public function handle(GetResponseEvent $event)
{
diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php
index 5a856e2..6ca3842 100644
--- a/Http/Firewall/RememberMeListener.php
+++ b/Http/Firewall/RememberMeListener.php
@@ -35,7 +35,7 @@ class RememberMeListener implements ListenerInterface
private $dispatcher;
/**
- * Constructor
+ * Constructor.
*
* @param SecurityContextInterface $securityContext
* @param RememberMeServicesInterface $rememberMeServices
diff --git a/Http/Firewall/X509AuthenticationListener.php b/Http/Firewall/X509AuthenticationListener.php
index 0b5a6ae..5aabf75 100644
--- a/Http/Firewall/X509AuthenticationListener.php
+++ b/Http/Firewall/X509AuthenticationListener.php
@@ -36,6 +36,9 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener
$this->credentialKey = $credentialKey;
}
+ /**
+ * {@inheritdoc}
+ */
protected function getPreAuthenticatedData(Request $request)
{
if (!$request->server->has($this->userKey)) {
diff --git a/Http/FirewallMap.php b/Http/FirewallMap.php
index dfc0984..0554bed 100644
--- a/Http/FirewallMap.php
+++ b/Http/FirewallMap.php
@@ -25,11 +25,19 @@ class FirewallMap implements FirewallMapInterface
{
private $map = array();
+ /**
+ * @param RequestMatcherInterface $requestMatcher
+ * @param array $listeners
+ * @param ExceptionListener $exceptionListener
+ */
public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null)
{
$this->map[] = array($requestMatcher, $listeners, $exceptionListener);
}
+ /**
+ * {@inheritDoc}
+ */
public function getListeners(Request $request)
{
foreach ($this->map as $elements) {
diff --git a/Http/FirewallMapInterface.php b/Http/FirewallMapInterface.php
index 336125f..1627ab5 100644
--- a/Http/FirewallMapInterface.php
+++ b/Http/FirewallMapInterface.php
@@ -24,7 +24,7 @@ interface FirewallMapInterface
* Returns the authentication listeners, and the exception listener to use
* for the given request.
*
- * If there are no authentication listeners, the first inner are must be
+ * If there are no authentication listeners, the first inner array must be
* empty.
*
* If there is no exception listener, the second element of the outer array
diff --git a/Http/HttpUtils.php b/Http/HttpUtils.php
index 0453520..0c8b21b 100644
--- a/Http/HttpUtils.php
+++ b/Http/HttpUtils.php
@@ -35,7 +35,9 @@ class HttpUtils
* Constructor.
*
* @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
- * @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The Url or Request matcher
+ * @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The URL or Request matcher
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatcher = null)
{
@@ -53,7 +55,7 @@ class HttpUtils
* @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
* @param integer $status The status code
*
- * @return Response A RedirectResponse instance
+ * @return RedirectResponse A RedirectResponse instance
*/
public function createRedirectResponse(Request $request, $path, $status = 302)
{
@@ -122,9 +124,11 @@ class HttpUtils
* Generates a URI, based on the given path or absolute URL.
*
* @param Request $request A Request instance
- * @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
+ * @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
*
* @return string An absolute URL
+ *
+ * @throws \LogicException
*/
public function generateUri($request, $path)
{
@@ -142,7 +146,7 @@ class HttpUtils
$url = $this->urlGenerator->generate($path, $request->attributes->all(), UrlGeneratorInterface::ABSOLUTE_URL);
- // unnecessary query string parameters must be removed from url
+ // unnecessary query string parameters must be removed from URL
// (ie. query parameters that are presents in $attributes)
// fortunately, they all are, so we have to remove entire query string
$position = strpos($url, '?');
diff --git a/Http/Logout/LogoutSuccessHandlerInterface.php b/Http/Logout/LogoutSuccessHandlerInterface.php
index 61642a8..4246fa4 100644
--- a/Http/Logout/LogoutSuccessHandlerInterface.php
+++ b/Http/Logout/LogoutSuccessHandlerInterface.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Http\Logout;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
/**
* LogoutSuccesshandlerInterface.
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index ae61dd7..740d3d6 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -40,7 +40,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
private $userProviders;
/**
- * Constructor
+ * Constructor.
*
* @param array $userProviders
* @param string $key
@@ -80,6 +80,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return $this->options['remember_me_parameter'];
}
+ /**
+ * @return string
+ */
public function getKey()
{
return $this->key;
@@ -94,6 +97,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @return TokenInterface|null
*
* @throws CookieTheftException
+ * @throws \RuntimeException
*/
final public function autoLogin(Request $request)
{
@@ -219,6 +223,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*/
abstract protected function processAutoLoginCookie(array $cookieParts, Request $request);
+ /**
+ * @param Request $request
+ */
protected function onLoginFail(Request $request)
{
}
@@ -284,7 +291,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
/**
- * Checks whether remember-me capabilities where requested
+ * Checks whether remember-me capabilities were requested
*
* @param Request $request
*
diff --git a/Http/RememberMe/ResponseListener.php b/Http/RememberMe/ResponseListener.php
index 03c71c7..6087587 100644
--- a/Http/RememberMe/ResponseListener.php
+++ b/Http/RememberMe/ResponseListener.php
@@ -22,6 +22,9 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*/
class ResponseListener implements EventSubscriberInterface
{
+ /**
+ * @param FilterResponseEvent $event
+ */
public function onKernelResponse(FilterResponseEvent $event)
{
$request = $event->getRequest();
@@ -32,6 +35,9 @@ class ResponseListener implements EventSubscriberInterface
}
}
+ /**
+ * {@inheritDoc}
+ */
public static function getSubscribedEvents()
{
return array(KernelEvents::RESPONSE => 'onKernelResponse');
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index 5a66fe4..df0ea1b 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -116,7 +116,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*
* @param string $class
* @param string $username The username
- * @param integer $expires The unixtime when the cookie expires
+ * @param integer $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
* @throws \RuntimeException if username contains invalid chars
@@ -138,7 +138,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
*
* @param string $class
* @param string $username The username
- * @param integer $expires The unixtime when the cookie expires
+ * @param integer $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
* @throws \RuntimeException when the private key is empty
diff --git a/README.md b/README.md
index 54a8381..53efa5e 100644
--- a/README.md
+++ b/README.md
@@ -19,5 +19,5 @@ Resources
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Security/
- $ composer.phar install --dev
+ $ composer.phar install
$ phpunit
diff --git a/Resources/translations/security.ja.xlf b/Resources/translations/security.ja.xlf
new file mode 100644
index 0000000..6a6b062
--- /dev/null
+++ b/Resources/translations/security.ja.xlf
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+ <file source-language="en" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>認証エラーが発生しました。</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>認証資格がありません。</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>システムの問題により認証要求を処理できませんでした。</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>資格が無効です。</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie が別のユーザーで使用されています。</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>リソースをリクエストする権限がありません。</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF トークンが無効です。</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest の nonce 値が期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>認証トークンをサポートする認証プロバイダーが見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>利用可能なセッションがありません。タイムアウトしたか、Cookie が無効になっています。</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>トークンが見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>ユーザー名が見つかりません。</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>アカウントが有効期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>資格が有効期限切れです。</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>アカウントが無効です。</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>アカウントはロックされています。</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Tests/Acl/Dbal/MutableAclProviderTest.php b/Tests/Acl/Dbal/MutableAclProviderTest.php
index 3e8d65f..00a2228 100644
--- a/Tests/Acl/Dbal/MutableAclProviderTest.php
+++ b/Tests/Acl/Dbal/MutableAclProviderTest.php
@@ -359,6 +359,54 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($newParentParentAcl->getId(), $reloadedAcl->getParentAcl()->getParentAcl()->getId());
}
+ public function testUpdateAclInsertingMultipleObjectFieldAcesThrowsDBConstraintViolations()
+ {
+ $provider = $this->getProvider();
+ $oid = new ObjectIdentity(1, 'Foo');
+ $sid1 = new UserSecurityIdentity('johannes', 'FooClass');
+ $sid2 = new UserSecurityIdentity('guilro', 'FooClass');
+ $sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
+ $fieldName = 'fieldName';
+
+ $acl = $provider->createAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid1, 4);
+ $provider->updateAcl($acl);
+
+ $acl = $provider->findAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid2, 4);
+ $provider->updateAcl($acl);
+
+ $acl = $provider->findAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid3, 4);
+ $provider->updateAcl($acl);
+ }
+
+ public function testUpdateAclDeletingObjectFieldAcesThrowsDBConstraintViolations()
+ {
+ $provider = $this->getProvider();
+ $oid = new ObjectIdentity(1, 'Foo');
+ $sid1 = new UserSecurityIdentity('johannes', 'FooClass');
+ $sid2 = new UserSecurityIdentity('guilro', 'FooClass');
+ $sid3 = new UserSecurityIdentity('bmaz', 'FooClass');
+ $fieldName = 'fieldName';
+
+ $acl = $provider->createAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid1, 4);
+ $provider->updateAcl($acl);
+
+ $acl = $provider->findAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid2, 4);
+ $provider->updateAcl($acl);
+
+ $index = 0;
+ $acl->deleteObjectFieldAce($index, $fieldName);
+ $provider->updateAcl($acl);
+
+ $acl = $provider->findAcl($oid);
+ $acl->insertObjectFieldAce($fieldName, $sid3, 4);
+ $provider->updateAcl($acl);
+ }
+
/**
* Data must have the following format:
* array(
@@ -372,7 +420,7 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
* @param AclProvider $provider
* @param array $data
* @throws \InvalidArgumentException
- * @throws Exception
+ * @throws \Exception
*/
protected function importAcls(AclProvider $provider, array $data)
{
diff --git a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php b/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
index 12eb568..4120995 100644
--- a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
+++ b/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
@@ -20,7 +20,7 @@ use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
{
/**
- * @expectedException InvalidArgumentException
+ * @expectedException \InvalidArgumentException
*/
public function testAuthenticateWithoutProviders()
{
diff --git a/Tests/Core/Authentication/Token/AbstractTokenTest.php b/Tests/Core/Authentication/Token/AbstractTokenTest.php
index 783c27e..5683b78 100644
--- a/Tests/Core/Authentication/Token/AbstractTokenTest.php
+++ b/Tests/Core/Authentication/Token/AbstractTokenTest.php
@@ -11,7 +11,9 @@
namespace Symfony\Component\Security\Tests\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role;
+use Symfony\Component\Security\Core\Role\SwitchUserRole;
class TestUser
{
@@ -28,6 +30,31 @@ class TestUser
}
}
+class ConcreteToken extends AbstractToken
+{
+ private $credentials = 'credentials_value';
+
+ public function __construct($user, array $roles = array())
+ {
+ parent::__construct($roles);
+
+ $this->setUser($user);
+ }
+
+ public function serialize()
+ {
+ return serialize(array($this->credentials, parent::serialize()));
+ }
+
+ public function unserialize($serialized)
+ {
+ list($this->credentials, $parentStr) = unserialize($serialized);
+ parent::unserialize($parentStr);
+ }
+
+ public function getCredentials() {}
+}
+
class AbstractTokenTest extends \PHPUnit_Framework_TestCase
{
public function testGetUsername()
@@ -71,6 +98,20 @@ class AbstractTokenTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($token->getAttributes(), $uToken->getAttributes());
}
+ public function testSerializeParent()
+ {
+ $user = new TestUser('fabien');
+ $token = new ConcreteToken($user, array('ROLE_FOO'));
+
+ $parentToken = new ConcreteToken($user, array(new SwitchUserRole('ROLE_PREVIOUS', $token)));
+ $uToken = unserialize(serialize($parentToken));
+
+ $this->assertEquals(
+ current($parentToken->getRoles())->getSource()->getUser(),
+ current($uToken->getRoles())->getSource()->getUser()
+ );
+ }
+
/**
* @covers Symfony\Component\Security\Core\Authentication\Token\AbstractToken::__construct
*/
diff --git a/Tests/Core/Authentication/Token/RememerMeTokenTest.php b/Tests/Core/Authentication/Token/RememerMeTokenTest.php
index 03275fa..cef3d28 100644
--- a/Tests/Core/Authentication/Token/RememerMeTokenTest.php
+++ b/Tests/Core/Authentication/Token/RememerMeTokenTest.php
@@ -53,7 +53,7 @@ class RememberMeTokenTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException PHPUnit_Framework_Error
+ * @expectedException \PHPUnit_Framework_Error
* @dataProvider getUserArguments
*/
public function testConstructorUserCannotBeNull($user)
diff --git a/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php b/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php
index 3da20eb..67f431f 100644
--- a/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php
+++ b/Tests/Core/Authentication/Token/UsernamePasswordTokenTest.php
@@ -28,7 +28,7 @@ class UsernamePasswordTokenTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException LogicException
+ * @expectedException \LogicException
*/
public function testSetAuthenticatedToTrue()
{
diff --git a/Tests/Core/Authorization/AccessDecisionManagerTest.php b/Tests/Core/Authorization/AccessDecisionManagerTest.php
index 1c706cc..b99423f 100644
--- a/Tests/Core/Authorization/AccessDecisionManagerTest.php
+++ b/Tests/Core/Authorization/AccessDecisionManagerTest.php
@@ -47,7 +47,7 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException InvalidArgumentException
+ * @expectedException \InvalidArgumentException
*/
public function testSetVotersEmpty()
{
diff --git a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
index 49c1051..dd962fd 100644
--- a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
+++ b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
@@ -70,4 +70,21 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Requires PHP >= 5.3.7');
}
}
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testEncodePasswordLength()
+ {
+ $encoder = new BCryptPasswordEncoder(self::VALID_COST);
+
+ $encoder->encodePassword(str_repeat('a', 5000), 'salt');
+ }
+
+ public function testCheckPasswordLength()
+ {
+ $encoder = new BCryptPasswordEncoder(self::VALID_COST);
+
+ $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
+ }
}
diff --git a/Tests/Core/Encoder/BasePasswordEncoderTest.php b/Tests/Core/Encoder/BasePasswordEncoderTest.php
index 2ef1dcc..702efb0 100644
--- a/Tests/Core/Encoder/BasePasswordEncoderTest.php
+++ b/Tests/Core/Encoder/BasePasswordEncoderTest.php
@@ -46,13 +46,19 @@ class BasePasswordEncoderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException InvalidArgumentException
+ * @expectedException \InvalidArgumentException
*/
public function testMergePasswordAndSaltWithException()
{
$this->invokeMergePasswordAndSalt('password', '{foo}');
}
+ public function testIsPasswordTooLong()
+ {
+ $this->assertTrue($this->invokeIsPasswordTooLong(str_repeat('a', 10000)));
+ $this->assertFalse($this->invokeIsPasswordTooLong(str_repeat('a', 10)));
+ }
+
protected function invokeDemergePasswordAndSalt($password)
{
$encoder = new PasswordEncoder();
@@ -82,4 +88,14 @@ class BasePasswordEncoderTest extends \PHPUnit_Framework_TestCase
return $m->invoke($encoder, $p1, $p2);
}
+
+ protected function invokeIsPasswordTooLong($p)
+ {
+ $encoder = new PasswordEncoder();
+ $r = new \ReflectionObject($encoder);
+ $m = $r->getMethod('isPasswordTooLong');
+ $m->setAccessible(true);
+
+ return $m->invoke($encoder, $p);
+ }
}
diff --git a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php b/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php
index 64032c4..f37d3bc 100644
--- a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php
+++ b/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php
@@ -35,11 +35,28 @@ class MessageDigestPasswordEncoderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException LogicException
+ * @expectedException \LogicException
*/
public function testEncodePasswordAlgorithmDoesNotExist()
{
$encoder = new MessageDigestPasswordEncoder('foobar');
$encoder->encodePassword('password', '');
}
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testEncodePasswordLength()
+ {
+ $encoder = new MessageDigestPasswordEncoder();
+
+ $encoder->encodePassword(str_repeat('a', 5000), 'salt');
+ }
+
+ public function testCheckPasswordLength()
+ {
+ $encoder = new MessageDigestPasswordEncoder();
+
+ $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
+ }
}
diff --git a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
index 2c98543..ca16f02 100644
--- a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
+++ b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
@@ -35,11 +35,28 @@ class Pbkdf2PasswordEncoderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException LogicException
+ * @expectedException \LogicException
*/
public function testEncodePasswordAlgorithmDoesNotExist()
{
$encoder = new Pbkdf2PasswordEncoder('foobar');
$encoder->encodePassword('password', '');
}
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testEncodePasswordLength()
+ {
+ $encoder = new Pbkdf2PasswordEncoder('foobar');
+
+ $encoder->encodePassword(str_repeat('a', 5000), 'salt');
+ }
+
+ public function testCheckPasswordLength()
+ {
+ $encoder = new Pbkdf2PasswordEncoder('foobar');
+
+ $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
+ }
}
diff --git a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php b/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php
index af0008f..8b1b888 100644
--- a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php
+++ b/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php
@@ -36,4 +36,21 @@ class PlaintextPasswordEncoderTest extends \PHPUnit_Framework_TestCase
$this->assertSame('foo', $encoder->encodePassword('foo', ''));
}
+
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
+ */
+ public function testEncodePasswordLength()
+ {
+ $encoder = new PlaintextPasswordEncoder();
+
+ $encoder->encodePassword(str_repeat('a', 5000), 'salt');
+ }
+
+ public function testCheckPasswordLength()
+ {
+ $encoder = new PlaintextPasswordEncoder();
+
+ $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
+ }
}
diff --git a/Tests/Core/User/InMemoryProviderTest.php b/Tests/Core/User/InMemoryProviderTest.php
index 5197a29..275426c 100644
--- a/Tests/Core/User/InMemoryProviderTest.php
+++ b/Tests/Core/User/InMemoryProviderTest.php
@@ -42,7 +42,7 @@ class InMemoryUserProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException LogicException
+ * @expectedException \LogicException
*/
public function testCreateUserAlreadyExist()
{
diff --git a/Tests/Core/User/UserTest.php b/Tests/Core/User/UserTest.php
index 26e562f..d05f491 100644
--- a/Tests/Core/User/UserTest.php
+++ b/Tests/Core/User/UserTest.php
@@ -17,7 +17,7 @@ class UserTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers Symfony\Component\Security\Core\User\User::__construct
- * @expectedException InvalidArgumentException
+ * @expectedException \InvalidArgumentException
*/
public function testConstructorException()
{
diff --git a/Tests/Core/Util/SecureRandomTest.php b/Tests/Core/Util/SecureRandomTest.php
index c7ed016..38e9121 100644
--- a/Tests/Core/Util/SecureRandomTest.php
+++ b/Tests/Core/Util/SecureRandomTest.php
@@ -68,7 +68,7 @@ class SecureRandomTest extends \PHPUnit_Framework_TestCase
$runs[$i] = 0;
}
- $addRun = function($run) use (&$runs) {
+ $addRun = function ($run) use (&$runs) {
if ($run > 6) {
$run = 6;
}
diff --git a/Tests/Http/Firewall/ExceptionListenerTest.php b/Tests/Http/Firewall/ExceptionListenerTest.php
new file mode 100644
index 0000000..b1c7622
--- /dev/null
+++ b/Tests/Http/Firewall/ExceptionListenerTest.php
@@ -0,0 +1,189 @@
+<?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\Tests\Http\Firewall;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
+use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
+use Symfony\Component\Security\Http\Firewall\ExceptionListener;
+use Symfony\Component\Security\Http\HttpUtils;
+
+class ExceptionListenerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider getAuthenticationExceptionProvider
+ */
+ public function testAuthenticationExceptionWithoutEntryPoint(\Exception $exception, \Exception $eventException = null)
+ {
+ $event = $this->createEvent($exception);
+
+ $listener = $this->createExceptionListener();
+ $listener->onKernelException($event);
+
+ $this->assertNull($event->getResponse());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException());
+ }
+
+ /**
+ * @dataProvider getAuthenticationExceptionProvider
+ */
+ public function testAuthenticationExceptionWithEntryPoint(\Exception $exception, \Exception $eventException = null)
+ {
+ $event = $this->createEvent($exception = new AuthenticationException());
+
+ $listener = $this->createExceptionListener(null, null, null, $this->createEntryPoint());
+ $listener->onKernelException($event);
+
+ $this->assertEquals('OK', $event->getResponse()->getContent());
+ $this->assertSame($exception, $event->getException());
+ }
+
+ public function getAuthenticationExceptionProvider()
+ {
+ return array(
+ array(new AuthenticationException()),
+ array(new \LogicException('random', 0, $e = new AuthenticationException()), $e),
+ array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AuthenticationException())), $e),
+ array(new \LogicException('random', 0, $e = new AuthenticationException('embed', 0, new AccessDeniedException())), $e),
+ array(new AuthenticationException('random', 0, new \LogicException())),
+ );
+ }
+
+ /**
+ * @dataProvider getAccessDeniedExceptionProvider
+ */
+ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
+ {
+ $event = $this->createEvent($exception);
+
+ $listener = $this->createExceptionListener(null, $this->createTrustResolver(true));
+ $listener->onKernelException($event);
+
+ $this->assertNull($event->getResponse());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ }
+
+ /**
+ * @dataProvider getAccessDeniedExceptionProvider
+ */
+ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null)
+ {
+ $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
+ $kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
+
+ $event = $this->createEvent($exception, $kernel);
+
+ $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils');
+ $httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error')));
+
+ $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), $httpUtils, null, '/error');
+ $listener->onKernelException($event);
+
+ $this->assertEquals('error', $event->getResponse()->getContent());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ }
+
+ /**
+ * @dataProvider getAccessDeniedExceptionProvider
+ */
+ public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null)
+ {
+ $event = $this->createEvent($exception);
+
+ $accessDeniedHandler = $this->getMock('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface');
+ $accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error')));
+
+ $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler);
+ $listener->onKernelException($event);
+
+ $this->assertEquals('error', $event->getResponse()->getContent());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ }
+
+ /**
+ * @dataProvider getAccessDeniedExceptionProvider
+ */
+ public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \Exception $eventException = null)
+ {
+ $event = $this->createEvent($exception);
+
+ $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $context->expects($this->once())->method('getToken')->will($this->returnValue($this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')));
+
+ $listener = $this->createExceptionListener($context, $this->createTrustResolver(false), null, $this->createEntryPoint());
+ $listener->onKernelException($event);
+
+ $this->assertEquals('OK', $event->getResponse()->getContent());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ }
+
+ public function getAccessDeniedExceptionProvider()
+ {
+ return array(
+ array(new AccessDeniedException()),
+ array(new \LogicException('random', 0, $e = new AccessDeniedException()), $e),
+ array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AccessDeniedException())), $e),
+ array(new \LogicException('random', 0, $e = new AccessDeniedException('embed', new AuthenticationException())), $e),
+ array(new AccessDeniedException('random', new \LogicException())),
+ );
+ }
+
+ private function createEntryPoint()
+ {
+ $entryPoint = $this->getMock('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface');
+ $entryPoint->expects($this->once())->method('start')->will($this->returnValue(new Response('OK')));
+
+ return $entryPoint;
+ }
+
+ private function createTrustResolver($fullFledged)
+ {
+ $trustResolver = $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface');
+ $trustResolver->expects($this->once())->method('isFullFledged')->will($this->returnValue($fullFledged));
+
+ return $trustResolver;
+ }
+
+ private function createEvent(\Exception $exception, $kernel = null)
+ {
+ if (null === $kernel) {
+ $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
+ }
+
+ $event = new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
+
+ $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+ $event->setDispatcher($dispatcher);
+
+ return $event;
+ }
+
+ private function createExceptionListener(SecurityContextInterface $context = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
+ {
+ return new ExceptionListener(
+ $context ? $context : $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'),
+ $trustResolver ? $trustResolver : $this->getMock('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface'),
+ $httpUtils ? $httpUtils : $this->getMock('Symfony\Component\Security\Http\HttpUtils'),
+ 'key',
+ $authenticationEntryPoint,
+ $errorPage,
+ $accessDeniedHandler
+ );
+ }
+}
diff --git a/Tests/Http/Firewall/LogoutListenerTest.php b/Tests/Http/Firewall/LogoutListenerTest.php
index ba94b6e..456b281 100644
--- a/Tests/Http/Firewall/LogoutListenerTest.php
+++ b/Tests/Http/Firewall/LogoutListenerTest.php
@@ -142,7 +142,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException RuntimeException
+ * @expectedException \RuntimeException
*/
public function testSuccessHandlerReturnsNonResponse()
{
diff --git a/Tests/Http/Firewall/X509AuthenticationListenerTest.php b/Tests/Http/Firewall/X509AuthenticationListenerTest.php
index 81ac0f7..c48aeac 100644
--- a/Tests/Http/Firewall/X509AuthenticationListenerTest.php
+++ b/Tests/Http/Firewall/X509AuthenticationListenerTest.php
@@ -64,7 +64,7 @@ class X509AuthenticationListenerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testGetPreAuthenticatedDataNoUser()
{
diff --git a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php b/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
index 6de69f1..4699257 100644
--- a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
+++ b/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
@@ -14,7 +14,6 @@ namespace Symfony\Component\Security\Tests\Http\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
-use Symfony\Component\Security\Core\Authentication\Token\Token;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;