summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Acl/Dbal/AclProvider.php44
-rw-r--r--Acl/Dbal/MutableAclProvider.php3
-rw-r--r--Acl/Domain/Acl.php1
-rw-r--r--Acl/Domain/AclCollectionCache.php10
-rw-r--r--Acl/Domain/DoctrineAclCache.php2
-rw-r--r--Acl/Domain/ObjectIdentity.php6
-rw-r--r--Acl/Domain/PermissionGrantingStrategy.php22
-rw-r--r--Acl/Domain/UserSecurityIdentity.php6
-rw-r--r--Acl/Model/AclCacheInterface.php12
-rw-r--r--Acl/Model/AclInterface.php20
-rw-r--r--Acl/Model/AclProviderInterface.php23
-rw-r--r--Acl/Model/AuditLoggerInterface.php2
-rw-r--r--Acl/Model/AuditableAclInterface.php8
-rw-r--r--Acl/Model/AuditableEntryInterface.php4
-rw-r--r--Acl/Model/DomainObjectInterface.php2
-rw-r--r--Acl/Model/EntryInterface.php12
-rw-r--r--Acl/Model/FieldEntryInterface.php2
-rw-r--r--Acl/Model/MutableAclInterface.php31
-rw-r--r--Acl/Model/MutableAclProviderInterface.php6
-rw-r--r--Acl/Model/ObjectIdentityInterface.php6
-rw-r--r--Acl/Model/ObjectIdentityRetrievalStrategyInterface.php2
-rw-r--r--Acl/Model/PermissionGrantingStrategyInterface.php4
-rw-r--r--Acl/Model/SecurityIdentityInterface.php2
-rw-r--r--Acl/Model/SecurityIdentityRetrievalStrategyInterface.php5
-rw-r--r--Acl/Permission/MaskBuilder.php10
-rw-r--r--Acl/Permission/PermissionMapInterface.php4
-rw-r--r--Acl/Resources/bin/generateSql.php9
-rw-r--r--Acl/Voter/AclVoter.php2
-rw-r--r--CHANGELOG.md20
-rw-r--r--Core/Authentication/AuthenticationManagerInterface.php2
-rw-r--r--Core/Authentication/AuthenticationProviderManager.php6
-rw-r--r--Core/Authentication/AuthenticationTrustResolverInterface.php6
-rw-r--r--Core/Authentication/Provider/AuthenticationProviderInterface.php2
-rw-r--r--Core/Authentication/Provider/DaoAuthenticationProvider.php5
-rw-r--r--Core/Authentication/Provider/UserAuthenticationProvider.php3
-rw-r--r--Core/Authentication/RememberMe/PersistentToken.php12
-rw-r--r--Core/Authentication/RememberMe/PersistentTokenInterface.php10
-rw-r--r--Core/Authentication/RememberMe/TokenProviderInterface.php14
-rw-r--r--Core/Authentication/Token/AbstractToken.php4
-rw-r--r--Core/Authentication/Token/AnonymousToken.php10
-rw-r--r--Core/Authentication/Token/RememberMeToken.php2
-rw-r--r--Core/Authentication/Token/TokenInterface.php32
-rw-r--r--Core/Authentication/Token/UsernamePasswordToken.php18
-rw-r--r--Core/AuthenticationEvents.php19
-rw-r--r--Core/Authorization/AccessDecisionManager.php2
-rw-r--r--Core/Authorization/AccessDecisionManagerInterface.php6
-rw-r--r--Core/Authorization/Voter/VoterInterface.php6
-rw-r--r--Core/Encoder/BCryptPasswordEncoder.php148
-rw-r--r--Core/Encoder/BasePasswordEncoder.php15
-rw-r--r--Core/Encoder/EncoderFactory.php4
-rw-r--r--Core/Encoder/EncoderFactoryInterface.php4
-rw-r--r--Core/Encoder/PasswordEncoderInterface.php4
-rw-r--r--Core/Encoder/Pbkdf2PasswordEncoder.php97
-rw-r--r--Core/Exception/AccountExpiredException.php8
-rw-r--r--Core/Exception/AccountStatusException.php45
-rw-r--r--Core/Exception/AuthenticationCredentialsNotFoundException.php8
-rw-r--r--Core/Exception/AuthenticationException.php54
-rw-r--r--Core/Exception/AuthenticationServiceException.php8
-rw-r--r--Core/Exception/BadCredentialsException.php8
-rw-r--r--Core/Exception/CookieTheftException.php8
-rw-r--r--Core/Exception/CredentialsExpiredException.php8
-rw-r--r--Core/Exception/DisabledException.php8
-rw-r--r--Core/Exception/InsufficientAuthenticationException.php8
-rw-r--r--Core/Exception/InvalidCsrfTokenException.php8
-rw-r--r--Core/Exception/LockedException.php8
-rw-r--r--Core/Exception/NonceExpiredException.php8
-rw-r--r--Core/Exception/ProviderNotFoundException.php8
-rw-r--r--Core/Exception/SessionUnavailableException.php8
-rw-r--r--Core/Exception/TokenNotFoundException.php11
-rw-r--r--Core/Exception/UsernameNotFoundException.php51
-rw-r--r--Core/Role/RoleHierarchyInterface.php6
-rw-r--r--Core/Role/RoleInterface.php4
-rw-r--r--Core/SecurityContext.php2
-rw-r--r--Core/SecurityContextInterface.php6
-rw-r--r--Core/User/AdvancedUserInterface.php8
-rw-r--r--Core/User/ChainUserProvider.php8
-rw-r--r--Core/User/EquatableInterface.php2
-rw-r--r--Core/User/InMemoryUserProvider.php7
-rw-r--r--Core/User/User.php1
-rw-r--r--Core/User/UserChecker.php16
-rw-r--r--Core/User/UserCheckerInterface.php4
-rw-r--r--Core/User/UserInterface.php10
-rw-r--r--Core/User/UserProviderInterface.php6
-rw-r--r--Core/Util/ClassUtils.php5
-rw-r--r--Core/Util/SecureRandom.php114
-rw-r--r--Core/Util/SecureRandomInterface.php29
-rw-r--r--Core/Util/StringUtils.php60
-rw-r--r--Core/Validator/Constraints/UserPassword.php (renamed from Core/Validator/Constraint/UserPassword.php)7
-rw-r--r--Core/Validator/Constraints/UserPasswordValidator.php (renamed from Core/Validator/Constraint/UserPasswordValidator.php)4
-rw-r--r--Http/AccessMapInterface.php2
-rw-r--r--Http/Authentication/AuthenticationFailureHandlerInterface.php4
-rw-r--r--Http/Authentication/AuthenticationSuccessHandlerInterface.php4
-rw-r--r--Http/Authentication/DefaultAuthenticationFailureHandler.php92
-rw-r--r--Http/Authentication/DefaultAuthenticationSuccessHandler.php110
-rw-r--r--Http/Authorization/AccessDeniedHandlerInterface.php2
-rw-r--r--Http/EntryPoint/AuthenticationEntryPointInterface.php2
-rw-r--r--Http/EntryPoint/BasicAuthenticationEntryPoint.php2
-rw-r--r--Http/EntryPoint/DigestAuthenticationEntryPoint.php4
-rw-r--r--Http/Event/InteractiveLoginEvent.php16
-rw-r--r--Http/Firewall.php11
-rw-r--r--Http/Firewall/AbstractAuthenticationListener.php92
-rw-r--r--Http/Firewall/AbstractPreAuthenticatedListener.php4
-rw-r--r--Http/Firewall/AccessListener.php5
-rw-r--r--Http/Firewall/AnonymousAuthenticationListener.php2
-rw-r--r--Http/Firewall/BasicAuthenticationListener.php2
-rw-r--r--Http/Firewall/ChannelListener.php2
-rw-r--r--Http/Firewall/ContextListener.php40
-rw-r--r--Http/Firewall/DigestAuthenticationListener.php17
-rw-r--r--Http/Firewall/ExceptionListener.php15
-rw-r--r--Http/Firewall/ListenerInterface.php2
-rw-r--r--Http/Firewall/LogoutListener.php20
-rw-r--r--Http/Firewall/RememberMeListener.php4
-rw-r--r--Http/Firewall/SwitchUserListener.php9
-rw-r--r--Http/Firewall/UsernamePasswordFormAuthenticationListener.php27
-rw-r--r--Http/Firewall/X509AuthenticationListener.php2
-rw-r--r--Http/FirewallMapInterface.php2
-rw-r--r--Http/HttpUtils.php42
-rw-r--r--Http/Logout/DefaultLogoutSuccessHandler.php47
-rw-r--r--Http/Logout/LogoutHandlerInterface.php2
-rw-r--r--Http/Logout/LogoutSuccessHandlerInterface.php2
-rw-r--r--Http/RememberMe/AbstractRememberMeServices.php27
-rw-r--r--Http/RememberMe/PersistentTokenBasedRememberMeServices.php55
-rw-r--r--Http/RememberMe/RememberMeServicesInterface.php6
-rw-r--r--Http/RememberMe/ResponseListener.php39
-rw-r--r--Http/RememberMe/TokenBasedRememberMeServices.php2
-rw-r--r--Http/SecurityEvents.php18
-rw-r--r--Http/Session/SessionAuthenticationStrategyInterface.php2
-rw-r--r--LICENSE2
-rw-r--r--README.md9
-rw-r--r--Resources/translations/security.ar.xlf71
-rw-r--r--Resources/translations/security.ca.xlf71
-rw-r--r--Resources/translations/security.cs.xlf71
-rw-r--r--Resources/translations/security.da.xlf71
-rw-r--r--Resources/translations/security.de.xlf71
-rw-r--r--Resources/translations/security.en.xlf71
-rw-r--r--Resources/translations/security.es.xlf71
-rw-r--r--Resources/translations/security.fa.xlf71
-rw-r--r--Resources/translations/security.fr.xlf71
-rw-r--r--Resources/translations/security.gl.xlf71
-rw-r--r--Resources/translations/security.hu.xlf71
-rw-r--r--Resources/translations/security.it.xlf71
-rw-r--r--Resources/translations/security.lb.xlf71
-rw-r--r--Resources/translations/security.nl.xlf71
-rw-r--r--Resources/translations/security.no.xlf71
-rw-r--r--Resources/translations/security.pl.xlf71
-rw-r--r--Resources/translations/security.pt_BR.xlf71
-rw-r--r--Resources/translations/security.pt_PT.xlf71
-rw-r--r--Resources/translations/security.ro.xlf71
-rw-r--r--Resources/translations/security.ru.xlf71
-rw-r--r--Resources/translations/security.sk.xlf71
-rw-r--r--Resources/translations/security.sl.xlf71
-rw-r--r--Resources/translations/security.sr_Cyrl.xlf71
-rw-r--r--Resources/translations/security.sr_Latn.xlf71
-rw-r--r--Resources/translations/security.sv.xlf71
-rw-r--r--Resources/translations/security.tr.xlf71
-rw-r--r--Resources/translations/security.ua.xlf71
-rw-r--r--Tests/Acl/Dbal/AclProviderTest.php2
-rw-r--r--Tests/Acl/Dbal/MutableAclProviderTest.php4
-rw-r--r--Tests/Acl/Domain/AclTest.php2
-rw-r--r--Tests/Acl/Domain/PermissionGrantingStrategyTest.php4
-rw-r--r--Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php2
-rw-r--r--Tests/Acl/Domain/UserSecurityIdentityTest.php2
-rw-r--r--Tests/Core/Authentication/AuthenticationProviderManagerTest.php6
-rw-r--r--Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php2
-rw-r--r--Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php13
-rw-r--r--Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php4
-rw-r--r--Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php4
-rw-r--r--Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php14
-rw-r--r--Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php4
-rw-r--r--Tests/Core/Encoder/BCryptPasswordEncoderTest.php112
-rw-r--r--Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php45
-rw-r--r--Tests/Core/SecurityContextTest.php2
-rw-r--r--Tests/Core/User/AccountCheckerTest.php8
-rw-r--r--Tests/Core/User/ChainUserProviderTest.php4
-rw-r--r--Tests/Core/User/InMemoryProviderTest.php2
-rw-r--r--Tests/Core/Util/ClassUtilsTest.php11
-rwxr-xr-xTests/Core/Util/SecureRandomTest.php201
-rwxr-xr-xTests/Core/Util/StringUtilsTest.php23
-rw-r--r--Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php161
-rw-r--r--Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php2
-rw-r--r--Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php3
-rw-r--r--Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php2
-rw-r--r--Tests/Http/Firewall/AccessListenerTest.php4
-rw-r--r--Tests/Http/Firewall/ContextListenerTest.php88
-rw-r--r--Tests/Http/Firewall/DigestDataTest.php181
-rw-r--r--Tests/Http/Firewall/LogoutListenerTest.php14
-rw-r--r--Tests/Http/Firewall/RememberMeListenerTest.php2
-rw-r--r--Tests/Http/HttpUtilsTest.php21
-rw-r--r--Tests/Http/RememberMe/AbstractRememberMeServicesTest.php16
-rw-r--r--Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php3
-rw-r--r--Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php2
-rw-r--r--Tests/bootstrap.php22
-rw-r--r--composer.json32
-rw-r--r--phpunit.xml.dist2
195 files changed, 4401 insertions, 566 deletions
diff --git a/.gitignore b/.gitignore
index d1502b0..44de97a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
vendor/
composer.lock
+phpunit.xml
+
diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php
index 8413843..6f47231 100644
--- a/Acl/Dbal/AclProvider.php
+++ b/Acl/Dbal/AclProvider.php
@@ -258,16 +258,40 @@ SELECTCLAUSE;
WHERE (
SELECTCLAUSE;
- $where = '(o.object_identifier = %s AND c.class_type = %s)';
- for ($i=0,$c=count($batch); $i<$c; $i++) {
+ $types = array();
+ $count = count($batch);
+ for ($i = 0; $i < $count; $i++) {
+ if (!isset($types[$batch[$i]->getType()])) {
+ $types[$batch[$i]->getType()] = true;
+ if ($count > 1) {
+ break;
+ }
+ }
+ }
+
+ if (1 === count($types)) {
+ $ids = array();
+ for ($i = 0; $i < $count; $i++) {
+ $ids[] = $this->connection->quote($batch[$i]->getIdentifier());
+ }
+
$sql .= sprintf(
- $where,
- $this->connection->quote($batch[$i]->getIdentifier()),
- $this->connection->quote($batch[$i]->getType())
+ '(o.object_identifier IN (%s) AND c.class_type = %s)',
+ implode(',', $ids),
+ $this->connection->quote($batch[0]->getType())
);
-
- if ($i+1 < $c) {
- $sql .= ' OR ';
+ } else {
+ $where = '(o.object_identifier = %s AND c.class_type = %s)';
+ for ($i = 0; $i < $count; $i++) {
+ $sql .= sprintf(
+ $where,
+ $this->connection->quote($batch[$i]->getIdentifier()),
+ $this->connection->quote($batch[$i]->getType())
+ );
+
+ if ($i+1 < $count) {
+ $sql .= ' OR ';
+ }
}
}
@@ -339,7 +363,7 @@ QUERY;
* @param ObjectIdentityInterface $oid
* @return integer
*/
- protected final function retrieveObjectIdentityPrimaryKey(ObjectIdentityInterface $oid)
+ final protected function retrieveObjectIdentityPrimaryKey(ObjectIdentityInterface $oid)
{
return $this->connection->executeQuery($this->getSelectObjectIdentityIdSql($oid))->fetchColumn();
}
@@ -417,6 +441,8 @@ QUERY;
* @param array $oidLookup
*
* @return \SplObjectStorage mapping object identities to ACL instances
+ *
+ * @throws AclNotFoundException
*/
private function lookupObjectIdentities(array $batch, array $sids, array $oidLookup)
{
diff --git a/Acl/Dbal/MutableAclProvider.php b/Acl/Dbal/MutableAclProvider.php
index 0d46f3a..0ac4fa7 100644
--- a/Acl/Dbal/MutableAclProvider.php
+++ b/Acl/Dbal/MutableAclProvider.php
@@ -17,7 +17,6 @@ use Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException;
use Symfony\Component\Security\Acl\Exception\ConcurrentModificationException;
-use Symfony\Component\Security\Acl\Exception\Exception;
use Symfony\Component\Security\Acl\Model\AclCacheInterface;
use Symfony\Component\Security\Acl\Model\AclInterface;
use Symfony\Component\Security\Acl\Model\EntryInterface;
@@ -148,6 +147,8 @@ class MutableAclProvider extends AclProvider implements MutableAclProviderInterf
* @param string $propertyName
* @param mixed $oldValue
* @param mixed $newValue
+ *
+ * @throws \InvalidArgumentException
*/
public function propertyChanged($sender, $propertyName, $oldValue, $newValue)
{
diff --git a/Acl/Domain/Acl.php b/Acl/Domain/Acl.php
index 6d53131..4665c0e 100644
--- a/Acl/Domain/Acl.php
+++ b/Acl/Domain/Acl.php
@@ -19,7 +19,6 @@ use Symfony\Component\Security\Acl\Model\ObjectIdentityInterface;
use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface;
use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface;
-
/**
* An ACL implementation.
*
diff --git a/Acl/Domain/AclCollectionCache.php b/Acl/Domain/AclCollectionCache.php
index be082c1..d3a4b37 100644
--- a/Acl/Domain/AclCollectionCache.php
+++ b/Acl/Domain/AclCollectionCache.php
@@ -29,9 +29,9 @@ class AclCollectionCache
/**
* Constructor.
*
- * @param AclProviderInterface $aclProvider
- * @param ObjectIdentityRetrievalStrategy $oidRetrievalStrategy
- * @param SecurityIdentityRetrievalStrategy $sidRetrievalStrategy
+ * @param AclProviderInterface $aclProvider
+ * @param ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy
+ * @param SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy
*/
public function __construct(AclProviderInterface $aclProvider, ObjectIdentityRetrievalStrategyInterface $oidRetrievalStrategy, SecurityIdentityRetrievalStrategyInterface $sidRetrievalStrategy)
{
@@ -44,8 +44,8 @@ class AclCollectionCache
* Batch loads ACLs for an entire collection; thus, it reduces the number
* of required queries considerably.
*
- * @param mixed $collection anything that can be passed to foreach()
- * @param array $tokens an array of TokenInterface implementations
+ * @param mixed $collection anything that can be passed to foreach()
+ * @param TokenInterface[] $tokens an array of TokenInterface implementations
*/
public function cache($collection, array $tokens = array())
{
diff --git a/Acl/Domain/DoctrineAclCache.php b/Acl/Domain/DoctrineAclCache.php
index 731f98c..bfc5452 100644
--- a/Acl/Domain/DoctrineAclCache.php
+++ b/Acl/Domain/DoctrineAclCache.php
@@ -36,6 +36,8 @@ class DoctrineAclCache implements AclCacheInterface
* @param Cache $cache
* @param PermissionGrantingStrategyInterface $permissionGrantingStrategy
* @param string $prefix
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(Cache $cache, PermissionGrantingStrategyInterface $permissionGrantingStrategy, $prefix = self::PREFIX)
{
diff --git a/Acl/Domain/ObjectIdentity.php b/Acl/Domain/ObjectIdentity.php
index e37e82b..d7d5f84 100644
--- a/Acl/Domain/ObjectIdentity.php
+++ b/Acl/Domain/ObjectIdentity.php
@@ -31,6 +31,8 @@ final class ObjectIdentity implements ObjectIdentityInterface
*
* @param string $identifier
* @param string $type
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct($identifier, $type)
{
@@ -49,10 +51,10 @@ final class ObjectIdentity implements ObjectIdentityInterface
* Constructs an ObjectIdentity for the given domain object
*
* @param object $domainObject
- * @throws \InvalidArgumentException
+ * @throws InvalidDomainObjectException
* @return ObjectIdentity
*/
- static public function fromDomainObject($domainObject)
+ public static function fromDomainObject($domainObject)
{
if (!is_object($domainObject)) {
throw new InvalidDomainObjectException('$domainObject must be an object.');
diff --git a/Acl/Domain/PermissionGrantingStrategy.php b/Acl/Domain/PermissionGrantingStrategy.php
index c34db2a..d505843 100644
--- a/Acl/Domain/PermissionGrantingStrategy.php
+++ b/Acl/Domain/PermissionGrantingStrategy.php
@@ -121,17 +121,18 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface
* permission/identity combination.
*
* This process is repeated until either a granting ACE is found, or no
- * permission/identity combinations are left. In the latter case, we will
- * call this method on the parent ACL if it exists, and isEntriesInheriting
- * is true. Otherwise, we will either throw an NoAceFoundException, or deny
- * access finally.
+ * permission/identity combinations are left. Finally, we will either throw
+ * an NoAceFoundException, or deny access.
+ *
+ * @param AclInterface $acl
+ * @param EntryInterface[] $aces An array of ACE to check against
+ * @param array $masks An array of permission masks
+ * @param SecurityIdentityInterface[] $sids An array of SecurityIdentityInterface implementations
+ * @param Boolean $administrativeMode True turns off audit logging
*
- * @param AclInterface $acl
- * @param array $aces An array of ACE to check against
- * @param array $masks An array of permission masks
- * @param array $sids An array of SecurityIdentityInterface implementations
- * @param Boolean $administrativeMode True turns off audit logging
* @return Boolean true, or false; either granting, or denying access respectively.
+ *
+ * @throws NoAceFoundException
*/
private function hasSufficientPermissions(AclInterface $acl, array $aces, array $masks, array $sids, $administrativeMode)
{
@@ -189,7 +190,10 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface
*
* @param integer $requiredMask
* @param EntryInterface $ace
+ *
* @return Boolean
+ *
+ * @throws \RuntimeException if the ACE strategy is not supported
*/
private function isAceApplicable($requiredMask, EntryInterface $ace)
{
diff --git a/Acl/Domain/UserSecurityIdentity.php b/Acl/Domain/UserSecurityIdentity.php
index 040e43b..3166a1a 100644
--- a/Acl/Domain/UserSecurityIdentity.php
+++ b/Acl/Domain/UserSecurityIdentity.php
@@ -31,6 +31,8 @@ final class UserSecurityIdentity implements SecurityIdentityInterface
*
* @param string $username the username representation
* @param string $class the user's fully qualified class name
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct($username, $class)
{
@@ -51,7 +53,7 @@ final class UserSecurityIdentity implements SecurityIdentityInterface
* @param UserInterface $user
* @return UserSecurityIdentity
*/
- static public function fromAccount(UserInterface $user)
+ public static function fromAccount(UserInterface $user)
{
return new self($user->getUsername(), ClassUtils::getRealClass($user));
}
@@ -62,7 +64,7 @@ final class UserSecurityIdentity implements SecurityIdentityInterface
* @param TokenInterface $token
* @return UserSecurityIdentity
*/
- static public function fromToken(TokenInterface $token)
+ public static function fromToken(TokenInterface $token)
{
$user = $token->getUser();
diff --git a/Acl/Model/AclCacheInterface.php b/Acl/Model/AclCacheInterface.php
index dd515ce..ea9604e 100644
--- a/Acl/Model/AclCacheInterface.php
+++ b/Acl/Model/AclCacheInterface.php
@@ -23,7 +23,7 @@ interface AclCacheInterface
*
* @param string $primaryKey a serialized primary key
*/
- function evictFromCacheById($primaryKey);
+ public function evictFromCacheById($primaryKey);
/**
* Removes an ACL from the cache
@@ -32,7 +32,7 @@ interface AclCacheInterface
*
* @param ObjectIdentityInterface $oid
*/
- function evictFromCacheByIdentity(ObjectIdentityInterface $oid);
+ public function evictFromCacheByIdentity(ObjectIdentityInterface $oid);
/**
* Retrieves an ACL for the given object identity primary key from the cache
@@ -40,7 +40,7 @@ interface AclCacheInterface
* @param integer $primaryKey
* @return AclInterface
*/
- function getFromCacheById($primaryKey);
+ public function getFromCacheById($primaryKey);
/**
* Retrieves an ACL for the given object identity from the cache
@@ -48,17 +48,17 @@ interface AclCacheInterface
* @param ObjectIdentityInterface $oid
* @return AclInterface
*/
- function getFromCacheByIdentity(ObjectIdentityInterface $oid);
+ public function getFromCacheByIdentity(ObjectIdentityInterface $oid);
/**
* Stores a new ACL in the cache
*
* @param AclInterface $acl
*/
- function putInCache(AclInterface $acl);
+ public function putInCache(AclInterface $acl);
/**
* Removes all ACLs from the cache
*/
- function clearCache();
+ public function clearCache();
}
diff --git a/Acl/Model/AclInterface.php b/Acl/Model/AclInterface.php
index 9094560..fffe591 100644
--- a/Acl/Model/AclInterface.php
+++ b/Acl/Model/AclInterface.php
@@ -28,7 +28,7 @@ interface AclInterface extends \Serializable
*
* @return array
*/
- function getClassAces();
+ public function getClassAces();
/**
* Returns all class-field-based ACEs associated with this ACL
@@ -36,14 +36,14 @@ interface AclInterface extends \Serializable
* @param string $field
* @return array
*/
- function getClassFieldAces($field);
+ public function getClassFieldAces($field);
/**
* Returns all object-based ACEs associated with this ACL
*
* @return array
*/
- function getObjectAces();
+ public function getObjectAces();
/**
* Returns all object-field-based ACEs associated with this ACL
@@ -51,28 +51,28 @@ interface AclInterface extends \Serializable
* @param string $field
* @return array
*/
- function getObjectFieldAces($field);
+ public function getObjectFieldAces($field);
/**
* Returns the object identity associated with this ACL
*
* @return ObjectIdentityInterface
*/
- function getObjectIdentity();
+ public function getObjectIdentity();
/**
* Returns the parent ACL, or null if there is none.
*
* @return AclInterface|null
*/
- function getParentAcl();
+ public function getParentAcl();
/**
* Whether this ACL is inheriting ACEs from a parent ACL.
*
* @return Boolean
*/
- function isEntriesInheriting();
+ public function isEntriesInheriting();
/**
* Determines whether field access is granted
@@ -83,7 +83,7 @@ interface AclInterface extends \Serializable
* @param Boolean $administrativeMode
* @return Boolean
*/
- function isFieldGranted($field, array $masks, array $securityIdentities, $administrativeMode = false);
+ public function isFieldGranted($field, array $masks, array $securityIdentities, $administrativeMode = false);
/**
* Determines whether access is granted
@@ -94,7 +94,7 @@ interface AclInterface extends \Serializable
* @param Boolean $administrativeMode
* @return Boolean
*/
- function isGranted(array $masks, array $securityIdentities, $administrativeMode = false);
+ public function isGranted(array $masks, array $securityIdentities, $administrativeMode = false);
/**
* Whether the ACL has loaded ACEs for all of the passed security identities
@@ -102,5 +102,5 @@ interface AclInterface extends \Serializable
* @param mixed $securityIdentities an implementation of SecurityIdentityInterface, or an array thereof
* @return Boolean
*/
- function isSidLoaded($securityIdentities);
+ public function isSidLoaded($securityIdentities);
}
diff --git a/Acl/Model/AclProviderInterface.php b/Acl/Model/AclProviderInterface.php
index 2f878e1..4be49bf 100644
--- a/Acl/Model/AclProviderInterface.php
+++ b/Acl/Model/AclProviderInterface.php
@@ -23,27 +23,32 @@ interface AclProviderInterface
*
* @param ObjectIdentityInterface $parentOid
* @param Boolean $directChildrenOnly
+ *
* @return array returns an array of child 'ObjectIdentity's
*/
- function findChildren(ObjectIdentityInterface $parentOid, $directChildrenOnly = false);
+ public function findChildren(ObjectIdentityInterface $parentOid, $directChildrenOnly = false);
/**
* Returns the ACL that belongs to the given object identity
*
- * @throws AclNotFoundException when there is no ACL
- * @param ObjectIdentityInterface $oid
- * @param array $sids
+ * @param ObjectIdentityInterface $oid
+ * @param SecurityIdentityInterface[] $sids
+ *
* @return AclInterface
+ *
+ * @throws AclNotFoundException when there is no ACL
*/
- function findAcl(ObjectIdentityInterface $oid, array $sids = array());
+ public function findAcl(ObjectIdentityInterface $oid, array $sids = array());
/**
* Returns the ACLs that belong to the given object identities
*
- * @throws AclNotFoundException when we cannot find an ACL for all identities
- * @param array $oids an array of ObjectIdentityInterface implementations
- * @param array $sids an array of SecurityIdentityInterface implementations
+ * @param ObjectIdentityInterface[] $oids an array of ObjectIdentityInterface implementations
+ * @param SecurityIdentityInterface[] $sids an array of SecurityIdentityInterface implementations
+ *
* @return \SplObjectStorage mapping the passed object identities to ACLs
+ *
+ * @throws AclNotFoundException when we cannot find an ACL for all identities
*/
- function findAcls(array $oids, array $sids = array());
+ public function findAcls(array $oids, array $sids = array());
}
diff --git a/Acl/Model/AuditLoggerInterface.php b/Acl/Model/AuditLoggerInterface.php
index 7cab6f1..09bcbb8 100644
--- a/Acl/Model/AuditLoggerInterface.php
+++ b/Acl/Model/AuditLoggerInterface.php
@@ -25,5 +25,5 @@ interface AuditLoggerInterface
* @param Boolean $granted
* @param EntryInterface $ace
*/
- function logIfNeeded($granted, EntryInterface $ace);
+ public function logIfNeeded($granted, EntryInterface $ace);
}
diff --git a/Acl/Model/AuditableAclInterface.php b/Acl/Model/AuditableAclInterface.php
index 5da593e..14b4c04 100644
--- a/Acl/Model/AuditableAclInterface.php
+++ b/Acl/Model/AuditableAclInterface.php
@@ -25,7 +25,7 @@ interface AuditableAclInterface extends MutableAclInterface
* @param Boolean $auditSuccess
* @param Boolean $auditFailure
*/
- function updateClassAuditing($index, $auditSuccess, $auditFailure);
+ public function updateClassAuditing($index, $auditSuccess, $auditFailure);
/**
* Updates auditing for class-field-based ACE
@@ -35,7 +35,7 @@ interface AuditableAclInterface extends MutableAclInterface
* @param Boolean $auditSuccess
* @param Boolean $auditFailure
*/
- function updateClassFieldAuditing($index, $field, $auditSuccess, $auditFailure);
+ public function updateClassFieldAuditing($index, $field, $auditSuccess, $auditFailure);
/**
* Updates auditing for object-based ACE
@@ -44,7 +44,7 @@ interface AuditableAclInterface extends MutableAclInterface
* @param Boolean $auditSuccess
* @param Boolean $auditFailure
*/
- function updateObjectAuditing($index, $auditSuccess, $auditFailure);
+ public function updateObjectAuditing($index, $auditSuccess, $auditFailure);
/**
* Updates auditing for object-field-based ACE
@@ -54,5 +54,5 @@ interface AuditableAclInterface extends MutableAclInterface
* @param Boolean $auditSuccess
* @param Boolean $auditFailure
*/
- function updateObjectFieldAuditing($index, $field, $auditSuccess, $auditFailure);
+ public function updateObjectFieldAuditing($index, $field, $auditSuccess, $auditFailure);
}
diff --git a/Acl/Model/AuditableEntryInterface.php b/Acl/Model/AuditableEntryInterface.php
index 40c4484..e957965 100644
--- a/Acl/Model/AuditableEntryInterface.php
+++ b/Acl/Model/AuditableEntryInterface.php
@@ -23,12 +23,12 @@ interface AuditableEntryInterface extends EntryInterface
*
* @return Boolean
*/
- function isAuditFailure();
+ public function isAuditFailure();
/**
* Whether auditing for successful denies is turned on
*
* @return Boolean
*/
- function isAuditSuccess();
+ public function isAuditSuccess();
}
diff --git a/Acl/Model/DomainObjectInterface.php b/Acl/Model/DomainObjectInterface.php
index 50bc4c3..195cb4e 100644
--- a/Acl/Model/DomainObjectInterface.php
+++ b/Acl/Model/DomainObjectInterface.php
@@ -25,5 +25,5 @@ interface DomainObjectInterface
*
* @return string
*/
- function getObjectIdentifier();
+ public function getObjectIdentifier();
}
diff --git a/Acl/Model/EntryInterface.php b/Acl/Model/EntryInterface.php
index 6fe0dc8..98b754c 100644
--- a/Acl/Model/EntryInterface.php
+++ b/Acl/Model/EntryInterface.php
@@ -26,40 +26,40 @@ interface EntryInterface extends \Serializable
*
* @return AclInterface
*/
- function getAcl();
+ public function getAcl();
/**
* The primary key of this ACE
*
* @return integer
*/
- function getId();
+ public function getId();
/**
* The permission mask of this ACE
*
* @return integer
*/
- function getMask();
+ public function getMask();
/**
* The security identity associated with this ACE
*
* @return SecurityIdentityInterface
*/
- function getSecurityIdentity();
+ public function getSecurityIdentity();
/**
* The strategy for comparing masks
*
* @return string
*/
- function getStrategy();
+ public function getStrategy();
/**
* Returns whether this ACE is granting, or denying
*
* @return Boolean
*/
- function isGranting();
+ public function isGranting();
}
diff --git a/Acl/Model/FieldEntryInterface.php b/Acl/Model/FieldEntryInterface.php
index a35ddb4..8382ae1 100644
--- a/Acl/Model/FieldEntryInterface.php
+++ b/Acl/Model/FieldEntryInterface.php
@@ -23,5 +23,5 @@ interface FieldEntryInterface extends EntryInterface
*
* @return string
*/
- function getField();
+ public function getField();
}
diff --git a/Acl/Model/MutableAclInterface.php b/Acl/Model/MutableAclInterface.php
index f84e817..365a779 100644
--- a/Acl/Model/MutableAclInterface.php
+++ b/Acl/Model/MutableAclInterface.php
@@ -26,7 +26,7 @@ interface MutableAclInterface extends AclInterface
*
* @param integer $index
*/
- function deleteClassAce($index);
+ public function deleteClassAce($index);
/**
* Deletes a class-field-based ACE
@@ -34,14 +34,14 @@ interface MutableAclInterface extends AclInterface
* @param integer $index
* @param string $field
*/
- function deleteClassFieldAce($index, $field);
+ public function deleteClassFieldAce($index, $field);
/**
* Deletes an object-based ACE
*
* @param integer $index
*/
- function deleteObjectAce($index);
+ public function deleteObjectAce($index);
/**
* Deletes an object-field-based ACE
@@ -49,14 +49,14 @@ interface MutableAclInterface extends AclInterface
* @param integer $index
* @param string $field
*/
- function deleteObjectFieldAce($index, $field);
+ public function deleteObjectFieldAce($index, $field);
/**
* Returns the primary key of this ACL
*
* @return integer
*/
- function getId();
+ public function getId();
/**
* Inserts a class-based ACE
@@ -67,7 +67,7 @@ interface MutableAclInterface extends AclInterface
* @param Boolean $granting
* @param string $strategy
*/
- function insertClassAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
+ public function insertClassAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
/**
* Inserts a class-field-based ACE
@@ -79,7 +79,7 @@ interface MutableAclInterface extends AclInterface
* @param Boolean $granting
* @param string $strategy
*/
- function insertClassFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
+ public function insertClassFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
/**
* Inserts an object-based ACE
@@ -90,7 +90,7 @@ interface MutableAclInterface extends AclInterface
* @param Boolean $granting
* @param string $strategy
*/
- function insertObjectAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
+ public function insertObjectAce(SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
/**
* Inserts an object-field-based ACE
@@ -102,22 +102,21 @@ interface MutableAclInterface extends AclInterface
* @param Boolean $granting
* @param string $strategy
*/
- function insertObjectFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
+ public function insertObjectFieldAce($field, SecurityIdentityInterface $sid, $mask, $index = 0, $granting = true, $strategy = null);
/**
* Sets whether entries are inherited
*
* @param Boolean $boolean
*/
- function setEntriesInheriting($boolean);
+ public function setEntriesInheriting($boolean);
/**
* Sets the parent ACL
*
* @param AclInterface|null $acl
- * @return void
*/
- function setParentAcl(AclInterface $acl = null);
+ public function setParentAcl(AclInterface $acl = null);
/**
* Updates a class-based ACE
@@ -126,7 +125,7 @@ interface MutableAclInterface extends AclInterface
* @param integer $mask
* @param string $strategy if null the strategy should not be changed
*/
- function updateClassAce($index, $mask, $strategy = null);
+ public function updateClassAce($index, $mask, $strategy = null);
/**
* Updates a class-field-based ACE
@@ -136,7 +135,7 @@ interface MutableAclInterface extends AclInterface
* @param integer $mask
* @param string $strategy if null the strategy should not be changed
*/
- function updateClassFieldAce($index, $field, $mask, $strategy = null);
+ public function updateClassFieldAce($index, $field, $mask, $strategy = null);
/**
* Updates an object-based ACE
@@ -145,7 +144,7 @@ interface MutableAclInterface extends AclInterface
* @param integer $mask
* @param string $strategy if null the strategy should not be changed
*/
- function updateObjectAce($index, $mask, $strategy = null);
+ public function updateObjectAce($index, $mask, $strategy = null);
/**
* Updates an object-field-based ACE
@@ -155,5 +154,5 @@ interface MutableAclInterface extends AclInterface
* @param integer $mask
* @param string $strategy if null the strategy should not be changed
*/
- function updateObjectFieldAce($index, $field, $mask, $strategy = null);
+ public function updateObjectFieldAce($index, $field, $mask, $strategy = null);
}
diff --git a/Acl/Model/MutableAclProviderInterface.php b/Acl/Model/MutableAclProviderInterface.php
index 04cf237..cb34b72 100644
--- a/Acl/Model/MutableAclProviderInterface.php
+++ b/Acl/Model/MutableAclProviderInterface.php
@@ -26,7 +26,7 @@ interface MutableAclProviderInterface extends AclProviderInterface
* @param ObjectIdentityInterface $oid
* @return MutableAclInterface
*/
- function createAcl(ObjectIdentityInterface $oid);
+ public function createAcl(ObjectIdentityInterface $oid);
/**
* Deletes the ACL for a given object identity.
@@ -36,7 +36,7 @@ interface MutableAclProviderInterface extends AclProviderInterface
*
* @param ObjectIdentityInterface $oid
*/
- function deleteAcl(ObjectIdentityInterface $oid);
+ public function deleteAcl(ObjectIdentityInterface $oid);
/**
* Persists any changes which were made to the ACL, or any associated
@@ -46,5 +46,5 @@ interface MutableAclProviderInterface extends AclProviderInterface
*
* @param MutableAclInterface $acl
*/
- function updateAcl(MutableAclInterface $acl);
+ public function updateAcl(MutableAclInterface $acl);
}
diff --git a/Acl/Model/ObjectIdentityInterface.php b/Acl/Model/ObjectIdentityInterface.php
index 7e892bf..8ad0eba 100644
--- a/Acl/Model/ObjectIdentityInterface.php
+++ b/Acl/Model/ObjectIdentityInterface.php
@@ -30,7 +30,7 @@ interface ObjectIdentityInterface
* @param ObjectIdentityInterface $identity
* @return Boolean
*/
- function equals(ObjectIdentityInterface $identity);
+ public function equals(ObjectIdentityInterface $identity);
/**
* Obtains a unique identifier for this object. The identifier must not be
@@ -38,12 +38,12 @@ interface ObjectIdentityInterface
*
* @return string cannot return null
*/
- function getIdentifier();
+ public function getIdentifier();
/**
* Returns a type for the domain object. Typically, this is the PHP class name.
*
* @return string cannot return null
*/
- function getType();
+ public function getType();
}
diff --git a/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php b/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php
index e53c3da..b0f7f78 100644
--- a/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php
+++ b/Acl/Model/ObjectIdentityRetrievalStrategyInterface.php
@@ -24,5 +24,5 @@ interface ObjectIdentityRetrievalStrategyInterface
* @param object $domainObject
* @return ObjectIdentityInterface
*/
- function getObjectIdentity($domainObject);
+ public function getObjectIdentity($domainObject);
}
diff --git a/Acl/Model/PermissionGrantingStrategyInterface.php b/Acl/Model/PermissionGrantingStrategyInterface.php
index 7afdfac..7f8f81b 100644
--- a/Acl/Model/PermissionGrantingStrategyInterface.php
+++ b/Acl/Model/PermissionGrantingStrategyInterface.php
@@ -27,7 +27,7 @@ interface PermissionGrantingStrategyInterface
* @param Boolean $administrativeMode
* @return Boolean
*/
- function isGranted(AclInterface $acl, array $masks, array $sids, $administrativeMode = false);
+ public function isGranted(AclInterface $acl, array $masks, array $sids, $administrativeMode = false);
/**
* Determines whether access to a domain object's field is to be granted
@@ -40,5 +40,5 @@ interface PermissionGrantingStrategyInterface
*
* @return Boolean
*/
- function isFieldGranted(AclInterface $acl, $field, array $masks, array $sids, $administrativeMode = false);
+ public function isFieldGranted(AclInterface $acl, $field, array $masks, array $sids, $administrativeMode = false);
}
diff --git a/Acl/Model/SecurityIdentityInterface.php b/Acl/Model/SecurityIdentityInterface.php
index 5bf6189..0a24a54 100644
--- a/Acl/Model/SecurityIdentityInterface.php
+++ b/Acl/Model/SecurityIdentityInterface.php
@@ -26,5 +26,5 @@ interface SecurityIdentityInterface
*
* @param SecurityIdentityInterface $identity
*/
- function equals(SecurityIdentityInterface $identity);
+ public function equals(SecurityIdentityInterface $identity);
}
diff --git a/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php b/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php
index 3bbbaa4..5bb7915 100644
--- a/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php
+++ b/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php
@@ -28,7 +28,8 @@ interface SecurityIdentityRetrievalStrategyInterface
* least specific.
*
* @param TokenInterface $token
- * @return array of SecurityIdentityInterface implementations
+ *
+ * @return SecurityIdentityInterface[] An array of SecurityIdentityInterface implementations
*/
- function getSecurityIdentities(TokenInterface $token);
+ public function getSecurityIdentities(TokenInterface $token);
}
diff --git a/Acl/Permission/MaskBuilder.php b/Acl/Permission/MaskBuilder.php
index 6921558..017e7c0 100644
--- a/Acl/Permission/MaskBuilder.php
+++ b/Acl/Permission/MaskBuilder.php
@@ -73,6 +73,8 @@ class MaskBuilder
* Constructor
*
* @param integer $mask optional; defaults to 0
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct($mask = 0)
{
@@ -87,7 +89,10 @@ class MaskBuilder
* Adds a mask to the permission
*
* @param mixed $mask
+ *
* @return MaskBuilder
+ *
+ * @throws \InvalidArgumentException
*/
public function add($mask)
{
@@ -140,7 +145,10 @@ class MaskBuilder
* Removes a mask from the permission
*
* @param mixed $mask
+ *
* @return MaskBuilder
+ *
+ * @throws \InvalidArgumentException
*/
public function remove($mask)
{
@@ -175,7 +183,7 @@ class MaskBuilder
* @throws \RuntimeException
* @return string
*/
- static public function getCode($mask)
+ public static function getCode($mask)
{
if (!is_int($mask)) {
throw new \InvalidArgumentException('$mask must be an integer.');
diff --git a/Acl/Permission/PermissionMapInterface.php b/Acl/Permission/PermissionMapInterface.php
index c2e49d5..44c15cc 100644
--- a/Acl/Permission/PermissionMapInterface.php
+++ b/Acl/Permission/PermissionMapInterface.php
@@ -28,7 +28,7 @@ interface PermissionMapInterface
* @param object $object
* @return array may return null if permission/object combination is not supported
*/
- function getMasks($permission, $object);
+ public function getMasks($permission, $object);
/**
* Whether this map contains the given permission
@@ -36,5 +36,5 @@ interface PermissionMapInterface
* @param string $permission
* @return Boolean
*/
- function contains($permission);
+ public function contains($permission);
}
diff --git a/Acl/Resources/bin/generateSql.php b/Acl/Resources/bin/generateSql.php
index 25ded7a..4a5ca05 100644
--- a/Acl/Resources/bin/generateSql.php
+++ b/Acl/Resources/bin/generateSql.php
@@ -9,14 +9,14 @@
* file that was distributed with this source code.
*/
-require_once __DIR__.'/../../../../ClassLoader/UniversalClassLoader.php';
+require_once __DIR__.'/../../../../ClassLoader/ClassLoader.php';
-use Symfony\Component\ClassLoader\UniversalClassLoader;
+use Symfony\Component\ClassLoader\ClassLoader;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Security\Acl\Dbal\Schema;
-$loader = new UniversalClassLoader();
-$loader->registerNamespaces(array(
+$loader = new ClassLoader();
+$loader->addPrefixes(array(
'Symfony' => __DIR__.'/../../../../../..',
'Doctrine\\Common' => __DIR__.'/../../../../../../../vendor/doctrine-common/lib',
'Doctrine\\DBAL\\Migrations' => __DIR__.'/../../../../../../../vendor/doctrine-migrations/lib',
@@ -25,7 +25,6 @@ $loader->registerNamespaces(array(
));
$loader->register();
-
$schema = new Schema(array(
'class_table_name' => 'acl_classes',
'entry_table_name' => 'acl_entries',
diff --git a/Acl/Voter/AclVoter.php b/Acl/Voter/AclVoter.php
index 456c434..5e9aee6 100644
--- a/Acl/Voter/AclVoter.php
+++ b/Acl/Voter/AclVoter.php
@@ -11,7 +11,7 @@
namespace Symfony\Component\Security\Acl\Voter;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Acl\Exception\NoAceFoundException;
use Symfony\Component\Security\Acl\Exception\AclNotFoundException;
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2389ac3..82c4312 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,16 @@
CHANGELOG
=========
+2.2.0
+-----
+
+ * `Symfony\Component\Security\Http\Firewall` and
+ `Symfony\Component\Security\Http\RememberMe\ResponseListener` now
+ implements EventSubscriberInterface
+ * added secure random number generator
+ * added PBKDF2 Password encoder
+ * added BCrypt password encoder
+
2.1.0
-----
@@ -20,3 +30,13 @@ CHANGELOG
* `ObjectIdentity::fromDomainObject`, `UserSecurityIdentity::fromAccount` and
`UserSecurityIdentity::fromToken` now return correct identities for proxies
objects (e.g. Doctrine proxies)
+ * [BC BREAK] moved the default authentication success and failure handling to
+ separate classes. The order of arguments in the constructor of the
+ `AbstractAuthenticationListener` has changed.
+ * [BC BREAK] moved the default logout success handling to a separate class. The
+ order of arguments in the constructor of `LogoutListener` has changed.
+ * [BC BREAK] The constructor of `AuthenticationException` and all child
+ classes now matches the constructor of `\Exception`. The extra information
+ getters and setters are removed. There are now dedicated getters/setters for
+ token (`AuthenticationException'), user (`AccountStatusException`) and
+ username (`UsernameNotFoundException`).
diff --git a/Core/Authentication/AuthenticationManagerInterface.php b/Core/Authentication/AuthenticationManagerInterface.php
index 36cdc92..d8f4716 100644
--- a/Core/Authentication/AuthenticationManagerInterface.php
+++ b/Core/Authentication/AuthenticationManagerInterface.php
@@ -31,5 +31,5 @@ interface AuthenticationManagerInterface
*
* @throws AuthenticationException if the authentication fails
*/
- function authenticate(TokenInterface $token);
+ public function authenticate(TokenInterface $token);
}
diff --git a/Core/Authentication/AuthenticationProviderManager.php b/Core/Authentication/AuthenticationProviderManager.php
index 7ca46c0..8b7474b 100644
--- a/Core/Authentication/AuthenticationProviderManager.php
+++ b/Core/Authentication/AuthenticationProviderManager.php
@@ -39,6 +39,8 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
*
* @param AuthenticationProviderInterface[] $providers An array of AuthenticationProviderInterface instances
* @param Boolean $eraseCredentials Whether to erase credentials after authentication or not
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(array $providers, $eraseCredentials = true)
{
@@ -75,7 +77,7 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
break;
}
} catch (AccountStatusException $e) {
- $e->setExtraInformation($token);
+ $e->setToken($token);
throw $e;
} catch (AuthenticationException $e) {
@@ -103,7 +105,7 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface
$this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_FAILURE, new AuthenticationFailureEvent($token, $lastException));
}
- $lastException->setExtraInformation($token);
+ $lastException->setToken($token);
throw $lastException;
}
diff --git a/Core/Authentication/AuthenticationTrustResolverInterface.php b/Core/Authentication/AuthenticationTrustResolverInterface.php
index adcef3c..ac07db0 100644
--- a/Core/Authentication/AuthenticationTrustResolverInterface.php
+++ b/Core/Authentication/AuthenticationTrustResolverInterface.php
@@ -30,7 +30,7 @@ interface AuthenticationTrustResolverInterface
*
* @return Boolean
*/
- function isAnonymous(TokenInterface $token = null);
+ public function isAnonymous(TokenInterface $token = null);
/**
* Resolves whether the passed token implementation is authenticated
@@ -40,7 +40,7 @@ interface AuthenticationTrustResolverInterface
*
* @return Boolean
*/
- function isRememberMe(TokenInterface $token = null);
+ public function isRememberMe(TokenInterface $token = null);
/**
* Resolves whether the passed token implementation is fully authenticated.
@@ -49,5 +49,5 @@ interface AuthenticationTrustResolverInterface
*
* @return Boolean
*/
- function isFullFledged(TokenInterface $token = null);
+ public function isFullFledged(TokenInterface $token = null);
}
diff --git a/Core/Authentication/Provider/AuthenticationProviderInterface.php b/Core/Authentication/Provider/AuthenticationProviderInterface.php
index 956adf1..f63a924 100644
--- a/Core/Authentication/Provider/AuthenticationProviderInterface.php
+++ b/Core/Authentication/Provider/AuthenticationProviderInterface.php
@@ -31,5 +31,5 @@ interface AuthenticationProviderInterface extends AuthenticationManagerInterface
*
* @return Boolean true if the implementation supports the Token, false otherwise
*/
- function supports(TokenInterface $token);
+ public function supports(TokenInterface $token);
}
diff --git a/Core/Authentication/Provider/DaoAuthenticationProvider.php b/Core/Authentication/Provider/DaoAuthenticationProvider.php
index f22045f..a9a2205 100644
--- a/Core/Authentication/Provider/DaoAuthenticationProvider.php
+++ b/Core/Authentication/Provider/DaoAuthenticationProvider.php
@@ -88,9 +88,12 @@ class DaoAuthenticationProvider extends UserAuthenticationProvider
return $user;
} catch (UsernameNotFoundException $notFound) {
+ $notFound->setUsername($username);
throw $notFound;
} catch (\Exception $repositoryProblem) {
- throw new AuthenticationServiceException($repositoryProblem->getMessage(), $token, 0, $repositoryProblem);
+ $ex = new AuthenticationServiceException($repositoryProblem->getMessage(), 0, $repositoryProblem);
+ $ex->setToken($token);
+ throw $ex;
}
}
}
diff --git a/Core/Authentication/Provider/UserAuthenticationProvider.php b/Core/Authentication/Provider/UserAuthenticationProvider.php
index 32d7971..626f50b 100644
--- a/Core/Authentication/Provider/UserAuthenticationProvider.php
+++ b/Core/Authentication/Provider/UserAuthenticationProvider.php
@@ -37,6 +37,8 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
* @param UserCheckerInterface $userChecker An UserCheckerInterface interface
* @param string $providerKey A provider key
* @param Boolean $hideUserNotFoundExceptions Whether to hide user not found exception or not
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(UserCheckerInterface $userChecker, $providerKey, $hideUserNotFoundExceptions = true)
{
@@ -69,6 +71,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
if ($this->hideUserNotFoundExceptions) {
throw new BadCredentialsException('Bad credentials', 0, $notFound);
}
+ $notFound->setUsername($username);
throw $notFound;
}
diff --git a/Core/Authentication/RememberMe/PersistentToken.php b/Core/Authentication/RememberMe/PersistentToken.php
index a31c878..f3f6858 100644
--- a/Core/Authentication/RememberMe/PersistentToken.php
+++ b/Core/Authentication/RememberMe/PersistentToken.php
@@ -27,11 +27,13 @@ final class PersistentToken implements PersistentTokenInterface
/**
* Constructor
*
- * @param string $class
- * @param string $username
- * @param string $series
- * @param string $tokenValue
- * @param DateTime $lastUsed
+ * @param string $class
+ * @param string $username
+ * @param string $series
+ * @param string $tokenValue
+ * @param \DateTime $lastUsed
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct($class, $username, $series, $tokenValue, \DateTime $lastUsed)
{
diff --git a/Core/Authentication/RememberMe/PersistentTokenInterface.php b/Core/Authentication/RememberMe/PersistentTokenInterface.php
index 38acbc3..6e9d891 100644
--- a/Core/Authentication/RememberMe/PersistentTokenInterface.php
+++ b/Core/Authentication/RememberMe/PersistentTokenInterface.php
@@ -23,29 +23,29 @@ interface PersistentTokenInterface
* Returns the class of the user
* @return string
*/
- function getClass();
+ public function getClass();
/**
* Returns the username
* @return string
*/
- function getUsername();
+ public function getUsername();
/**
* Returns the series
* @return string
*/
- function getSeries();
+ public function getSeries();
/**
* Returns the token value
* @return string
*/
- function getTokenValue();
+ public function getTokenValue();
/**
* Returns the last time the cookie was used
* @return \DateTime
*/
- function getLastUsed();
+ public function getLastUsed();
}
diff --git a/Core/Authentication/RememberMe/TokenProviderInterface.php b/Core/Authentication/RememberMe/TokenProviderInterface.php
index db40a1c..0c6f75e 100644
--- a/Core/Authentication/RememberMe/TokenProviderInterface.php
+++ b/Core/Authentication/RememberMe/TokenProviderInterface.php
@@ -27,28 +27,28 @@ interface TokenProviderInterface
*
* @return PersistentTokenInterface
*/
- function loadTokenBySeries($series);
+ public function loadTokenBySeries($series);
/**
* Deletes all tokens belonging to series.
*
* @param string $series
*/
- function deleteTokenBySeries($series);
+ public function deleteTokenBySeries($series);
/**
* Updates the token according to this data.
*
- * @param string $series
- * @param string $tokenValue
- * @param DateTime $lastUsed
+ * @param string $series
+ * @param string $tokenValue
+ * @param \DateTime $lastUsed
*/
- function updateToken($series, $tokenValue, \DateTime $lastUsed);
+ public function updateToken($series, $tokenValue, \DateTime $lastUsed);
/**
* Creates a new token.
*
* @param PersistentTokenInterface $token
*/
- function createNewToken(PersistentTokenInterface $token);
+ public function createNewToken(PersistentTokenInterface $token);
}
diff --git a/Core/Authentication/Token/AbstractToken.php b/Core/Authentication/Token/AbstractToken.php
index ed6e8de..f21aa76 100644
--- a/Core/Authentication/Token/AbstractToken.php
+++ b/Core/Authentication/Token/AbstractToken.php
@@ -33,7 +33,9 @@ abstract class AbstractToken implements TokenInterface
/**
* Constructor.
*
- * @param Role[] $roles An array of roles
+ * @param RoleInterface[] $roles An array of roles
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(array $roles = array())
{
diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php
index ecdd4cc..9b0a084 100644
--- a/Core/Authentication/Token/AnonymousToken.php
+++ b/Core/Authentication/Token/AnonymousToken.php
@@ -24,9 +24,9 @@ class AnonymousToken extends AbstractToken
/**
* Constructor.
*
- * @param string $key The key shared with the authentication provider
- * @param string $user The user
- * @param Role[] $roles An array of roles
+ * @param string $key The key shared with the authentication provider
+ * @param string $user The user
+ * @param RoleInterface[] $roles An array of roles
*/
public function __construct($key, $user, array $roles = array())
{
@@ -66,9 +66,9 @@ class AnonymousToken extends AbstractToken
/**
* {@inheritDoc}
*/
- public function unserialize($str)
+ public function unserialize($serialized)
{
- list($this->key, $parentStr) = unserialize($str);
+ list($this->key, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
}
diff --git a/Core/Authentication/Token/RememberMeToken.php b/Core/Authentication/Token/RememberMeToken.php
index de50e5c..6f3d821 100644
--- a/Core/Authentication/Token/RememberMeToken.php
+++ b/Core/Authentication/Token/RememberMeToken.php
@@ -29,6 +29,8 @@ class RememberMeToken extends AbstractToken
* @param UserInterface $user
* @param string $providerKey
* @param string $key
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(UserInterface $user, $providerKey, $key)
{
diff --git a/Core/Authentication/Token/TokenInterface.php b/Core/Authentication/Token/TokenInterface.php
index 3dafccc..11f69da 100644
--- a/Core/Authentication/Token/TokenInterface.php
+++ b/Core/Authentication/Token/TokenInterface.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
+use Symfony\Component\Security\Core\Role\RoleInterface;
+
/**
* TokenInterface is the interface for the user authentication information.
*
@@ -26,21 +28,21 @@ interface TokenInterface extends \Serializable
*
* @return string
*/
- function __toString();
+ public function __toString();
/**
* Returns the user roles.
*
- * @return Role[] An array of Role instances.
+ * @return RoleInterface[] An array of RoleInterface instances.
*/
- function getRoles();
+ public function getRoles();
/**
* Returns the user credentials.
*
* @return mixed The user credentials
*/
- function getCredentials();
+ public function getCredentials();
/**
* Returns a user representation.
@@ -48,54 +50,54 @@ interface TokenInterface extends \Serializable
* @return mixed either returns an object which implements __toString(), or
* a primitive string is returned.
*/
- function getUser();
+ public function getUser();
/**
* Sets a user.
*
* @param mixed $user
*/
- function setUser($user);
+ public function setUser($user);
/**
* Returns the username.
*
* @return string
*/
- function getUsername();
+ public function getUsername();
/**
* Returns whether the user is authenticated or not.
*
* @return Boolean true if the token has been authenticated, false otherwise
*/
- function isAuthenticated();
+ public function isAuthenticated();
/**
* Sets the authenticated flag.
*
* @param Boolean $isAuthenticated The authenticated flag
*/
- function setAuthenticated($isAuthenticated);
+ public function setAuthenticated($isAuthenticated);
/**
* Removes sensitive information from the token.
*/
- function eraseCredentials();
+ public function eraseCredentials();
/**
* Returns the token attributes.
*
* @return array The token attributes
*/
- function getAttributes();
+ public function getAttributes();
/**
* Sets the token attributes.
*
* @param array $attributes The token attributes
*/
- function setAttributes(array $attributes);
+ public function setAttributes(array $attributes);
/**
* Returns true if the attribute exists.
@@ -104,7 +106,7 @@ interface TokenInterface extends \Serializable
*
* @return Boolean true if the attribute exists, false otherwise
*/
- function hasAttribute($name);
+ public function hasAttribute($name);
/**
* Returns an attribute value.
@@ -115,7 +117,7 @@ interface TokenInterface extends \Serializable
*
* @throws \InvalidArgumentException When attribute doesn't exist for this token
*/
- function getAttribute($name);
+ public function getAttribute($name);
/**
* Sets an attribute.
@@ -123,5 +125,5 @@ interface TokenInterface extends \Serializable
* @param string $name The attribute name
* @param mixed $value The attribute value
*/
- function setAttribute($name, $value);
+ public function setAttribute($name, $value);
}
diff --git a/Core/Authentication/Token/UsernamePasswordToken.php b/Core/Authentication/Token/UsernamePasswordToken.php
index 95eec54..d6e3998 100644
--- a/Core/Authentication/Token/UsernamePasswordToken.php
+++ b/Core/Authentication/Token/UsernamePasswordToken.php
@@ -24,10 +24,10 @@ class UsernamePasswordToken extends AbstractToken
/**
* Constructor.
*
- * @param string $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
- * @param string $credentials This usually is the password of the user
- * @param string $providerKey The provider key
- * @param array $roles An array of roles
+ * @param string $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
+ * @param string $credentials This usually is the password of the user
+ * @param string $providerKey The provider key
+ * @param RoleInterface[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/
@@ -78,14 +78,20 @@ class UsernamePasswordToken extends AbstractToken
$this->credentials = null;
}
+ /**
+ * {@inheritdoc}
+ */
public function serialize()
{
return serialize(array($this->credentials, $this->providerKey, parent::serialize()));
}
- public function unserialize($str)
+ /**
+ * {@inheritdoc}
+ */
+ public function unserialize($serialized)
{
- list($this->credentials, $this->providerKey, $parentStr) = unserialize($str);
+ list($this->credentials, $this->providerKey, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
}
diff --git a/Core/AuthenticationEvents.php b/Core/AuthenticationEvents.php
index 1e0e6ff..90b7142 100644
--- a/Core/AuthenticationEvents.php
+++ b/Core/AuthenticationEvents.php
@@ -13,7 +13,26 @@ namespace Symfony\Component\Security\Core;
final class AuthenticationEvents
{
+ /**
+ * The AUTHENTICATION_SUCCESS event occurs after a user is authenticated
+ * by one provider.
+ *
+ * The event listener method receives a
+ * Symfony\Component\Security\Core\Event\AuthenticationEvent instance.
+ *
+ * @var string
+ */
const AUTHENTICATION_SUCCESS = 'security.authentication.success';
+ /**
+ * The AUTHENTICATION_FAILURE event occurs after a user cannot be
+ * authenticated by any of the providers.
+ *
+ * The event listener method receives a
+ * Symfony\Component\Security\Core\Event\AuthenticationFailureEvent
+ * instance.
+ *
+ * @var string
+ */
const AUTHENTICATION_FAILURE = 'security.authentication.failure';
}
diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php
index a8bb5cf..6028c42 100644
--- a/Core/Authorization/AccessDecisionManager.php
+++ b/Core/Authorization/AccessDecisionManager.php
@@ -34,6 +34,8 @@ class AccessDecisionManager implements AccessDecisionManagerInterface
* @param string $strategy The vote strategy
* @param Boolean $allowIfAllAbstainDecisions Whether to grant access if all voters abstained or not
* @param Boolean $allowIfEqualGrantedDeniedDecisions Whether to grant access if result are equals
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(array $voters, $strategy = 'affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true)
{
diff --git a/Core/Authorization/AccessDecisionManagerInterface.php b/Core/Authorization/AccessDecisionManagerInterface.php
index 648047a..742ea74 100644
--- a/Core/Authorization/AccessDecisionManagerInterface.php
+++ b/Core/Authorization/AccessDecisionManagerInterface.php
@@ -29,7 +29,7 @@ interface AccessDecisionManagerInterface
*
* @return Boolean true if the access is granted, false otherwise
*/
- function decide(TokenInterface $token, array $attributes, $object = null);
+ public function decide(TokenInterface $token, array $attributes, $object = null);
/**
* Checks if the access decision manager supports the given attribute.
@@ -38,7 +38,7 @@ interface AccessDecisionManagerInterface
*
* @return Boolean true if this decision manager supports the attribute, false otherwise
*/
- function supportsAttribute($attribute);
+ public function supportsAttribute($attribute);
/**
* Checks if the access decision manager supports the given class.
@@ -47,5 +47,5 @@ interface AccessDecisionManagerInterface
*
* @return true if this decision manager can process the class
*/
- function supportsClass($class);
+ public function supportsClass($class);
}
diff --git a/Core/Authorization/Voter/VoterInterface.php b/Core/Authorization/Voter/VoterInterface.php
index 41d9e64..1fc93e5 100644
--- a/Core/Authorization/Voter/VoterInterface.php
+++ b/Core/Authorization/Voter/VoterInterface.php
@@ -31,7 +31,7 @@ interface VoterInterface
*
* @return Boolean true if this Voter supports the attribute, false otherwise
*/
- function supportsAttribute($attribute);
+ public function supportsAttribute($attribute);
/**
* Checks if the voter supports the given class.
@@ -40,7 +40,7 @@ interface VoterInterface
*
* @return true if this Voter can process the class
*/
- function supportsClass($class);
+ public function supportsClass($class);
/**
* Returns the vote for the given parameters.
@@ -54,5 +54,5 @@ interface VoterInterface
*
* @return integer either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
*/
- function vote(TokenInterface $token, $object, array $attributes);
+ public function vote(TokenInterface $token, $object, array $attributes);
}
diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php
new file mode 100644
index 0000000..1b7572d
--- /dev/null
+++ b/Core/Encoder/BCryptPasswordEncoder.php
@@ -0,0 +1,148 @@
+<?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\Core\Encoder;
+
+use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
+use Symfony\Component\Security\Core\Util\SecureRandomInterface;
+
+/**
+ * @author Elnur Abdurrakhimov <elnur@elnur.pro>
+ * @author Terje Bråten <terje@braten.be>
+ */
+class BCryptPasswordEncoder extends BasePasswordEncoder
+{
+ /**
+ * @var SecureRandomInterface
+ */
+ private $secureRandom;
+
+ /**
+ * @var string
+ */
+ private $cost;
+
+ private static $prefix = null;
+
+ /**
+ * Constructor.
+ *
+ * @param SecureRandomInterface $secureRandom A SecureRandomInterface instance
+ * @param integer $cost The algorithmic cost that should be used
+ *
+ * @throws \InvalidArgumentException if cost is out of range
+ */
+ public function __construct(SecureRandomInterface $secureRandom, $cost)
+ {
+ $this->secureRandom = $secureRandom;
+
+ $cost = (int) $cost;
+ if ($cost < 4 || $cost > 31) {
+ throw new \InvalidArgumentException('Cost must be in the range of 4-31.');
+ }
+ $this->cost = sprintf('%02d', $cost);
+
+ if (!self::$prefix) {
+ self::$prefix = '$'.(version_compare(phpversion(), '5.3.7', '>=') ? '2y' : '2a').'$';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function encodePassword($raw, $salt)
+ {
+ if (function_exists('password_hash')) {
+ return password_hash($raw, PASSWORD_BCRYPT, array('cost' => $this->cost));
+ }
+
+ $salt = self::$prefix.$this->cost.'$'.$this->encodeSalt($this->getRawSalt());
+ $encoded = crypt($raw, $salt);
+ if (!is_string($encoded) || strlen($encoded) <= 13) {
+ return false;
+ }
+
+ return $encoded;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isPasswordValid($encoded, $raw, $salt)
+ {
+ if (function_exists('password_verify')) {
+ return password_verify($raw, $encoded);
+ }
+
+ $crypted = crypt($raw, $encoded);
+ if (strlen($crypted) <= 13) {
+ return false;
+ }
+
+ return $this->comparePasswords($encoded, $crypted);
+ }
+
+ /**
+ * Encodes the salt to be used by Bcrypt.
+ *
+ * The blowfish/bcrypt algorithm used by PHP crypt expects a different
+ * set and order of characters than the usual base64_encode function.
+ * Regular b64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
+ * Bcrypt b64: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
+ * We care because the last character in our encoded string will
+ * only represent 2 bits. While two known implementations of
+ * bcrypt will happily accept and correct a salt string which
+ * has the 4 unused bits set to non-zero, we do not want to take
+ * chances and we also do not want to waste an additional byte
+ * of entropy.
+ *
+ * @param bytes $random a string of 16 random bytes
+ *
+ * @return string Properly encoded salt to use with php crypt function
+ *
+ * @throws \InvalidArgumentException if string of random bytes is too short
+ */
+ protected function encodeSalt($random)
+ {
+ $len = strlen($random);
+ if ($len < 16) {
+ throw new \InvalidArgumentException('The bcrypt salt needs 16 random bytes.');
+ }
+ if ($len > 16) {
+ $random = substr($random, 0, 16);
+ }
+
+ $base64raw = str_replace('+', '.', base64_encode($random));
+ $salt128bit = substr($base64raw, 0, 21);
+ $lastchar = substr($base64raw, 21, 1);
+ $lastchar = strtr($lastchar, 'AQgw', '.Oeu');
+ $salt128bit .= $lastchar;
+
+ return $salt128bit;
+ }
+
+ /**
+ * @return bytes 16 random bytes to be used in the salt
+ */
+ protected function getRawSalt()
+ {
+ $rawSalt = false;
+ $numBytes = 16;
+ if (function_exists('mcrypt_create_iv')) {
+ $rawSalt = mcrypt_create_iv($numBytes, MCRYPT_DEV_URANDOM);
+ }
+ if (!$rawSalt) {
+ $rawSalt = $this->secureRandom->nextBytes($numBytes);
+ }
+
+ return $rawSalt;
+ }
+}
diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php
index ae1c7d4..c26c9ce 100644
--- a/Core/Encoder/BasePasswordEncoder.php
+++ b/Core/Encoder/BasePasswordEncoder.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Security\Core\Encoder;
+use Symfony\Component\Security\Core\Util\StringUtils;
+
/**
* BasePasswordEncoder is the base class for all password encoders.
*
@@ -50,6 +52,8 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
* @param string $salt the salt to be used
*
* @return string a merged password and salt
+ *
+ * @throws \InvalidArgumentException
*/
protected function mergePasswordAndSalt($password, $salt)
{
@@ -77,15 +81,6 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
*/
protected function comparePasswords($password1, $password2)
{
- if (strlen($password1) !== strlen($password2)) {
- return false;
- }
-
- $result = 0;
- for ($i = 0; $i < strlen($password1); $i++) {
- $result |= ord($password1[$i]) ^ ord($password2[$i]);
- }
-
- return 0 === $result;
+ return StringUtils::equals($password1, $password2);
}
}
diff --git a/Core/Encoder/EncoderFactory.php b/Core/Encoder/EncoderFactory.php
index 7d34cc7..8bad61f 100644
--- a/Core/Encoder/EncoderFactory.php
+++ b/Core/Encoder/EncoderFactory.php
@@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Encoder;
-use Symfony\Component\Security\Core\User\UserInterface;
-
/**
* A generic encoder factory implementation
*
@@ -53,6 +51,8 @@ class EncoderFactory implements EncoderFactoryInterface
* @param array $config
*
* @return PasswordEncoderInterface
+ *
+ * @throws \InvalidArgumentException
*/
private function createEncoder(array $config)
{
diff --git a/Core/Encoder/EncoderFactoryInterface.php b/Core/Encoder/EncoderFactoryInterface.php
index 125e57b..2b9834b 100644
--- a/Core/Encoder/EncoderFactoryInterface.php
+++ b/Core/Encoder/EncoderFactoryInterface.php
@@ -23,11 +23,11 @@ interface EncoderFactoryInterface
/**
* Returns the password encoder to use for the given account.
*
- * @param UserInterface|string $user A UserInterface instance of a class name
+ * @param UserInterface|string $user A UserInterface instance or a class name
*
* @return PasswordEncoderInterface
*
* @throws \RuntimeException when no password encoder could be found for the user
*/
- function getEncoder($user);
+ public function getEncoder($user);
}
diff --git a/Core/Encoder/PasswordEncoderInterface.php b/Core/Encoder/PasswordEncoderInterface.php
index dae6c69..78b4e42 100644
--- a/Core/Encoder/PasswordEncoderInterface.php
+++ b/Core/Encoder/PasswordEncoderInterface.php
@@ -26,7 +26,7 @@ interface PasswordEncoderInterface
*
* @return string The encoded password
*/
- function encodePassword($raw, $salt);
+ public function encodePassword($raw, $salt);
/**
* Checks a raw password against an encoded password.
@@ -37,5 +37,5 @@ interface PasswordEncoderInterface
*
* @return Boolean true if the password is valid, false otherwise
*/
- function isPasswordValid($encoded, $raw, $salt);
+ public function isPasswordValid($encoded, $raw, $salt);
}
diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php
new file mode 100644
index 0000000..656545f
--- /dev/null
+++ b/Core/Encoder/Pbkdf2PasswordEncoder.php
@@ -0,0 +1,97 @@
+<?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\Core\Encoder;
+
+/**
+ * Pbkdf2PasswordEncoder uses the PBKDF2 (Password-Based Key Derivation Function 2).
+ *
+ * Providing a high level of Cryptographic security,
+ * PBKDF2 is recommended by the National Institute of Standards and Technology (NIST).
+ *
+ * But also warrants a warning, using PBKDF2 (with a high number of iterations) slows down the process.
+ * PBKDF2 should be used with caution and care.
+ *
+ * @author Sebastiaan Stok <s.stok@rollerscapes.net>
+ * @author Andrew Johnson
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Pbkdf2PasswordEncoder extends BasePasswordEncoder
+{
+ private $algorithm;
+ private $encodeHashAsBase64;
+ private $iterations;
+ private $length;
+
+ /**
+ * Constructor.
+ *
+ * @param string $algorithm The digest algorithm to use
+ * @param Boolean $encodeHashAsBase64 Whether to base64 encode the password hash
+ * @param integer $iterations The number of iterations to use to stretch the password hash
+ * @param integer $length Length of derived key to create
+ */
+ public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 1000, $length = 40)
+ {
+ $this->algorithm = $algorithm;
+ $this->encodeHashAsBase64 = $encodeHashAsBase64;
+ $this->iterations = $iterations;
+ $this->length = $length;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @throws \LogicException when the algorithm is not supported
+ */
+ public function encodePassword($raw, $salt)
+ {
+ if (!in_array($this->algorithm, hash_algos(), true)) {
+ throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
+ }
+
+ if (function_exists('hash_pbkdf2')) {
+ $digest = hash_pbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length, true);
+ } else {
+ $digest = $this->hashPbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length);
+ }
+
+ return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isPasswordValid($encoded, $raw, $salt)
+ {
+ return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
+ }
+
+ private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0)
+ {
+ // Number of blocks needed to create the derived key
+ $blocks = ceil($length / strlen(hash($algorithm, null, true)));
+ $digest = '';
+
+ for ($i = 1; $i <= $blocks; $i++) {
+ $ib = $block = hash_hmac($algorithm, $salt . pack('N', $i), $password, true);
+
+ // Iterations
+ for ($j = 1; $j < $iterations; $j++) {
+ $ib ^= ($block = hash_hmac($algorithm, $block, $password, true));
+ }
+
+ $digest .= $ib;
+ }
+
+ return substr($digest, 0, $this->length);
+ }
+}
diff --git a/Core/Exception/AccountExpiredException.php b/Core/Exception/AccountExpiredException.php
index f899b1b..a5618ce 100644
--- a/Core/Exception/AccountExpiredException.php
+++ b/Core/Exception/AccountExpiredException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* AccountExpiredException is thrown when the user account has expired.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class AccountExpiredException extends AccountStatusException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Account has expired.';
+ }
}
diff --git a/Core/Exception/AccountStatusException.php b/Core/Exception/AccountStatusException.php
index 958f584..7819e4d 100644
--- a/Core/Exception/AccountStatusException.php
+++ b/Core/Exception/AccountStatusException.php
@@ -11,12 +11,57 @@
namespace Symfony\Component\Security\Core\Exception;
+use Symfony\Component\Security\Core\User\UserInterface;
+
/**
* AccountStatusException is the base class for authentication exceptions
* caused by the user account status.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
abstract class AccountStatusException extends AuthenticationException
{
+ private $user;
+
+ /**
+ * Get the user.
+ *
+ * @return UserInterface
+ */
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ /**
+ * Set the user.
+ *
+ * @param UserInterface $user
+ */
+ public function setUser(UserInterface $user)
+ {
+ $this->user = $user;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ $this->user,
+ parent::serialize(),
+ ));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function unserialize($str)
+ {
+ list($this->user, $parentData) = unserialize($str);
+
+ parent::unserialize($parentData);
+ }
}
diff --git a/Core/Exception/AuthenticationCredentialsNotFoundException.php b/Core/Exception/AuthenticationCredentialsNotFoundException.php
index 16686ad..633b2be 100644
--- a/Core/Exception/AuthenticationCredentialsNotFoundException.php
+++ b/Core/Exception/AuthenticationCredentialsNotFoundException.php
@@ -16,7 +16,15 @@ namespace Symfony\Component\Security\Core\Exception;
* because no Token is available.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class AuthenticationCredentialsNotFoundException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Authentication credentials could not be found.';
+ }
}
diff --git a/Core/Exception/AuthenticationException.php b/Core/Exception/AuthenticationException.php
index 074dad0..2b897c2 100644
--- a/Core/Exception/AuthenticationException.php
+++ b/Core/Exception/AuthenticationException.php
@@ -11,36 +11,42 @@
namespace Symfony\Component\Security\Core\Exception;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+
/**
* AuthenticationException is the base class for all authentication exceptions.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class AuthenticationException extends \RuntimeException implements \Serializable
{
- private $extraInformation;
-
- public function __construct($message, $extraInformation = null, $code = 0, \Exception $previous = null)
- {
- parent::__construct($message, $code, $previous);
+ private $token;
- $this->extraInformation = $extraInformation;
- }
-
- public function getExtraInformation()
+ /**
+ * Get the token.
+ *
+ * @return TokenInterface
+ */
+ public function getToken()
{
- return $this->extraInformation;
+ return $this->token;
}
- public function setExtraInformation($extraInformation)
+ /**
+ * Set the token.
+ *
+ * @param TokenInterface $token
+ */
+ public function setToken(TokenInterface $token)
{
- $this->extraInformation = $extraInformation;
+ $this->token = $token;
}
public function serialize()
{
return serialize(array(
- $this->extraInformation,
+ $this->token,
$this->code,
$this->message,
$this->file,
@@ -51,11 +57,31 @@ class AuthenticationException extends \RuntimeException implements \Serializable
public function unserialize($str)
{
list(
- $this->extraInformation,
+ $this->token,
$this->code,
$this->message,
$this->file,
$this->line
) = unserialize($str);
}
+
+ /**
+ * Message key to be used by the translation component.
+ *
+ * @return string
+ */
+ public function getMessageKey()
+ {
+ return 'An authentication exception occurred.';
+ }
+
+ /**
+ * Message data to be used by the translation component.
+ *
+ * @return array
+ */
+ public function getMessageData()
+ {
+ return array();
+ }
}
diff --git a/Core/Exception/AuthenticationServiceException.php b/Core/Exception/AuthenticationServiceException.php
index 5b32d81..758a4f0 100644
--- a/Core/Exception/AuthenticationServiceException.php
+++ b/Core/Exception/AuthenticationServiceException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* AuthenticationServiceException is thrown when an authentication request could not be processed due to a system problem.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class AuthenticationServiceException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Authentication request could not be processed due to a system problem.';
+ }
}
diff --git a/Core/Exception/BadCredentialsException.php b/Core/Exception/BadCredentialsException.php
index 2eae5b8..5deecca 100644
--- a/Core/Exception/BadCredentialsException.php
+++ b/Core/Exception/BadCredentialsException.php
@@ -15,11 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* BadCredentialsException is thrown when the user credentials are invalid.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class BadCredentialsException extends AuthenticationException
{
- public function __construct($message, $code = 0, \Exception $previous = null)
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
{
- parent::__construct($message, null, $code, $previous);
+ return 'Invalid credentials.';
}
}
diff --git a/Core/Exception/CookieTheftException.php b/Core/Exception/CookieTheftException.php
index 2ada78d..8d9e154 100644
--- a/Core/Exception/CookieTheftException.php
+++ b/Core/Exception/CookieTheftException.php
@@ -16,7 +16,15 @@ namespace Symfony\Component\Security\Core\Exception;
* detects that a presented cookie has already been used by someone else.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class CookieTheftException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Cookie has already been used by someone else.';
+ }
}
diff --git a/Core/Exception/CredentialsExpiredException.php b/Core/Exception/CredentialsExpiredException.php
index a4d42c8..b9bf2d1 100644
--- a/Core/Exception/CredentialsExpiredException.php
+++ b/Core/Exception/CredentialsExpiredException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* CredentialsExpiredException is thrown when the user account credentials have expired.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class CredentialsExpiredException extends AccountStatusException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Credentials have expired.';
+ }
}
diff --git a/Core/Exception/DisabledException.php b/Core/Exception/DisabledException.php
index fd26221..5571ab1 100644
--- a/Core/Exception/DisabledException.php
+++ b/Core/Exception/DisabledException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* DisabledException is thrown when the user account is disabled.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class DisabledException extends AccountStatusException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Account is disabled.';
+ }
}
diff --git a/Core/Exception/InsufficientAuthenticationException.php b/Core/Exception/InsufficientAuthenticationException.php
index bbf5517..74fc2b9 100644
--- a/Core/Exception/InsufficientAuthenticationException.php
+++ b/Core/Exception/InsufficientAuthenticationException.php
@@ -17,7 +17,15 @@ namespace Symfony\Component\Security\Core\Exception;
* This is the case when a user is anonymous and the resource to be displayed has an access role.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class InsufficientAuthenticationException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Not privileged to request the resource.';
+ }
}
diff --git a/Core/Exception/InvalidCsrfTokenException.php b/Core/Exception/InvalidCsrfTokenException.php
index 4181bac..ce0e1f4 100644
--- a/Core/Exception/InvalidCsrfTokenException.php
+++ b/Core/Exception/InvalidCsrfTokenException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* This exception is thrown when the csrf token is invalid.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class InvalidCsrfTokenException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Invalid CSRF token.';
+ }
}
diff --git a/Core/Exception/LockedException.php b/Core/Exception/LockedException.php
index 6fa0b77..6532f70 100644
--- a/Core/Exception/LockedException.php
+++ b/Core/Exception/LockedException.php
@@ -15,7 +15,15 @@ namespace Symfony\Component\Security\Core\Exception;
* LockedException is thrown if the user account is locked.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class LockedException extends AccountStatusException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Account is locked.';
+ }
}
diff --git a/Core/Exception/NonceExpiredException.php b/Core/Exception/NonceExpiredException.php
index 6a6a781..da6fba8 100644
--- a/Core/Exception/NonceExpiredException.php
+++ b/Core/Exception/NonceExpiredException.php
@@ -18,7 +18,15 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
* the digest nonce has expired.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class NonceExpiredException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Digest nonce has expired.';
+ }
}
diff --git a/Core/Exception/ProviderNotFoundException.php b/Core/Exception/ProviderNotFoundException.php
index e11c8aa..ea2b1fd 100644
--- a/Core/Exception/ProviderNotFoundException.php
+++ b/Core/Exception/ProviderNotFoundException.php
@@ -16,7 +16,15 @@ namespace Symfony\Component\Security\Core\Exception;
* supports an authentication Token.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class ProviderNotFoundException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'No authentication provider found to support the authentication token.';
+ }
}
diff --git a/Core/Exception/SessionUnavailableException.php b/Core/Exception/SessionUnavailableException.php
index 519164a..4b47b18 100644
--- a/Core/Exception/SessionUnavailableException.php
+++ b/Core/Exception/SessionUnavailableException.php
@@ -21,7 +21,15 @@ namespace Symfony\Component\Security\Core\Exception;
* request.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class SessionUnavailableException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'No session available, it either timed out or cookies are not enabled.';
+ }
}
diff --git a/Core/Exception/TokenNotFoundException.php b/Core/Exception/TokenNotFoundException.php
index 593f3ad..fb85abf 100644
--- a/Core/Exception/TokenNotFoundException.php
+++ b/Core/Exception/TokenNotFoundException.php
@@ -1,5 +1,4 @@
<?php
-namespace Symfony\Component\Security\Core\Exception;
/*
* This file is part of the Symfony package.
@@ -10,11 +9,21 @@ namespace Symfony\Component\Security\Core\Exception;
* file that was distributed with this source code.
*/
+namespace Symfony\Component\Security\Core\Exception;
+
/**
* TokenNotFoundException is thrown if a Token cannot be found.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class TokenNotFoundException extends AuthenticationException
{
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'No token could be found.';
+ }
}
diff --git a/Core/Exception/UsernameNotFoundException.php b/Core/Exception/UsernameNotFoundException.php
index 38533e7..f656bac 100644
--- a/Core/Exception/UsernameNotFoundException.php
+++ b/Core/Exception/UsernameNotFoundException.php
@@ -15,7 +15,58 @@ namespace Symfony\Component\Security\Core\Exception;
* UsernameNotFoundException is thrown if a User cannot be found by its username.
*
* @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
*/
class UsernameNotFoundException extends AuthenticationException
{
+ private $username;
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getMessageKey()
+ {
+ return 'Username could not be found.';
+ }
+
+ /**
+ * Get the username.
+ *
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ /**
+ * Set the username.
+ *
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function serialize()
+ {
+ return serialize(array(
+ $this->username,
+ parent::serialize(),
+ ));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function unserialize($str)
+ {
+ list($this->username, $parentData) = unserialize($str);
+
+ parent::unserialize($parentData);
+ }
}
diff --git a/Core/Role/RoleHierarchyInterface.php b/Core/Role/RoleHierarchyInterface.php
index d873b80..2ea6ca3 100644
--- a/Core/Role/RoleHierarchyInterface.php
+++ b/Core/Role/RoleHierarchyInterface.php
@@ -24,9 +24,9 @@ interface RoleHierarchyInterface
* Reachable roles are the roles directly assigned but also all roles that
* are transitively reachable from them in the role hierarchy.
*
- * @param array $roles An array of directly assigned roles
+ * @param RoleInterface[] $roles An array of directly assigned roles
*
- * @return array An array of all reachable roles
+ * @return RoleInterface[] An array of all reachable roles
*/
- function getReachableRoles(array $roles);
+ public function getReachableRoles(array $roles);
}
diff --git a/Core/Role/RoleInterface.php b/Core/Role/RoleInterface.php
index debda3a..3d4cbea 100644
--- a/Core/Role/RoleInterface.php
+++ b/Core/Role/RoleInterface.php
@@ -15,7 +15,7 @@ namespace Symfony\Component\Security\Core\Role;
* RoleInterface represents a role granted to a user.
*
* A role must either have a string representation or it needs to be explicitly
- * supported by an at least one AccessDecisionManager.
+ * supported by at least one AccessDecisionManager.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
@@ -31,5 +31,5 @@ interface RoleInterface
*
* @return string|null A string representation of the role, or null
*/
- function getRole();
+ public function getRole();
}
diff --git a/Core/SecurityContext.php b/Core/SecurityContext.php
index bc6493b..1ec43e6 100644
--- a/Core/SecurityContext.php
+++ b/Core/SecurityContext.php
@@ -55,7 +55,7 @@ class SecurityContext implements SecurityContextInterface
*
* @return Boolean
*/
- public final function isGranted($attributes, $object = null)
+ final public function isGranted($attributes, $object = null)
{
if (null === $this->token) {
throw new AuthenticationCredentialsNotFoundException('The security context contains no authentication token. One possible reason may be that there is no firewall configured for this URL.');
diff --git a/Core/SecurityContextInterface.php b/Core/SecurityContextInterface.php
index 77c5bf8..78d6477 100644
--- a/Core/SecurityContextInterface.php
+++ b/Core/SecurityContextInterface.php
@@ -29,14 +29,14 @@ interface SecurityContextInterface
*
* @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
*/
- function getToken();
+ public function getToken();
/**
* Sets the authentication token.
*
* @param TokenInterface $token
*/
- function setToken(TokenInterface $token = null);
+ public function setToken(TokenInterface $token = null);
/**
* Checks if the attributes are granted against the current authentication token and optionally supplied object.
@@ -46,5 +46,5 @@ interface SecurityContextInterface
*
* @return Boolean
*/
- function isGranted($attributes, $object = null);
+ public function isGranted($attributes, $object = null);
}
diff --git a/Core/User/AdvancedUserInterface.php b/Core/User/AdvancedUserInterface.php
index e951c65..5b3a51a 100644
--- a/Core/User/AdvancedUserInterface.php
+++ b/Core/User/AdvancedUserInterface.php
@@ -47,7 +47,7 @@ interface AdvancedUserInterface extends UserInterface
*
* @see AccountExpiredException
*/
- function isAccountNonExpired();
+ public function isAccountNonExpired();
/**
* Checks whether the user is locked.
@@ -59,7 +59,7 @@ interface AdvancedUserInterface extends UserInterface
*
* @see LockedException
*/
- function isAccountNonLocked();
+ public function isAccountNonLocked();
/**
* Checks whether the user's credentials (password) has expired.
@@ -71,7 +71,7 @@ interface AdvancedUserInterface extends UserInterface
*
* @see CredentialsExpiredException
*/
- function isCredentialsNonExpired();
+ public function isCredentialsNonExpired();
/**
* Checks whether the user is enabled.
@@ -83,5 +83,5 @@ interface AdvancedUserInterface extends UserInterface
*
* @see DisabledException
*/
- function isEnabled();
+ public function isEnabled();
}
diff --git a/Core/User/ChainUserProvider.php b/Core/User/ChainUserProvider.php
index 376ba1c..3ff1ea9 100644
--- a/Core/User/ChainUserProvider.php
+++ b/Core/User/ChainUserProvider.php
@@ -44,7 +44,9 @@ class ChainUserProvider implements UserProviderInterface
}
}
- throw new UsernameNotFoundException(sprintf('There is no user with name "%s".', $username));
+ $ex = new UsernameNotFoundException(sprintf('There is no user with name "%s".', $username));
+ $ex->setUsername($username);
+ throw $ex;
}
/**
@@ -66,7 +68,9 @@ class ChainUserProvider implements UserProviderInterface
}
if ($supportedUserFound) {
- throw new UsernameNotFoundException(sprintf('There is no user with name "%s".', $user->getUsername()));
+ $ex = new UsernameNotFoundException(sprintf('There is no user with name "%s".', $user->getUsername()));
+ $ex->setUsername($user->getUsername());
+ throw $ex;
} else {
throw new UnsupportedUserException(sprintf('The account "%s" is not supported.', get_class($user)));
}
diff --git a/Core/User/EquatableInterface.php b/Core/User/EquatableInterface.php
index e2bde9e..645b77c 100644
--- a/Core/User/EquatableInterface.php
+++ b/Core/User/EquatableInterface.php
@@ -33,5 +33,5 @@ interface EquatableInterface
*
* @return Boolean
*/
- function isEqualTo(UserInterface $user);
+ public function isEqualTo(UserInterface $user);
}
diff --git a/Core/User/InMemoryUserProvider.php b/Core/User/InMemoryUserProvider.php
index eae2083..e87f80c 100644
--- a/Core/User/InMemoryUserProvider.php
+++ b/Core/User/InMemoryUserProvider.php
@@ -50,6 +50,8 @@ class InMemoryUserProvider implements UserProviderInterface
* Adds a new User to the provider.
*
* @param UserInterface $user A UserInterface instance
+ *
+ * @throws \LogicException
*/
public function createUser(UserInterface $user)
{
@@ -66,7 +68,10 @@ class InMemoryUserProvider implements UserProviderInterface
public function loadUserByUsername($username)
{
if (!isset($this->users[strtolower($username)])) {
- throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
+ $ex = new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
+ $ex->setUsername($username);
+
+ throw $ex;
}
$user = $this->users[strtolower($username)];
diff --git a/Core/User/User.php b/Core/User/User.php
index 6076603..b378e1b 100644
--- a/Core/User/User.php
+++ b/Core/User/User.php
@@ -22,6 +22,7 @@ final class User implements AdvancedUserInterface
{
private $username;
private $password;
+ private $enabled;
private $accountNonExpired;
private $credentialsNonExpired;
private $accountNonLocked;
diff --git a/Core/User/UserChecker.php b/Core/User/UserChecker.php
index 93897a1..8dde3a6 100644
--- a/Core/User/UserChecker.php
+++ b/Core/User/UserChecker.php
@@ -33,7 +33,9 @@ class UserChecker implements UserCheckerInterface
}
if (!$user->isCredentialsNonExpired()) {
- throw new CredentialsExpiredException('User credentials have expired.', $user);
+ $ex = new CredentialsExpiredException('User credentials have expired.');
+ $ex->setUser($user);
+ throw $ex;
}
}
@@ -47,15 +49,21 @@ class UserChecker implements UserCheckerInterface
}
if (!$user->isAccountNonLocked()) {
- throw new LockedException('User account is locked.', $user);
+ $ex = new LockedException('User account is locked.');
+ $ex->setUser($user);
+ throw $ex;
}
if (!$user->isEnabled()) {
- throw new DisabledException('User account is disabled.', $user);
+ $ex = new DisabledException('User account is disabled.');
+ $ex->setUser($user);
+ throw $ex;
}
if (!$user->isAccountNonExpired()) {
- throw new AccountExpiredException('User account has expired.', $user);
+ $ex = new AccountExpiredException('User account has expired.');
+ $ex->setUser($user);
+ throw $ex;
}
}
}
diff --git a/Core/User/UserCheckerInterface.php b/Core/User/UserCheckerInterface.php
index 61f0f6e..3dd8d51 100644
--- a/Core/User/UserCheckerInterface.php
+++ b/Core/User/UserCheckerInterface.php
@@ -25,12 +25,12 @@ interface UserCheckerInterface
*
* @param UserInterface $user a UserInterface instance
*/
- function checkPreAuth(UserInterface $user);
+ public function checkPreAuth(UserInterface $user);
/**
* Checks the user account after authentication.
*
* @param UserInterface $user a UserInterface instance
*/
- function checkPostAuth(UserInterface $user);
+ public function checkPostAuth(UserInterface $user);
}
diff --git a/Core/User/UserInterface.php b/Core/User/UserInterface.php
index ce3b3a8..ed96ca9 100644
--- a/Core/User/UserInterface.php
+++ b/Core/User/UserInterface.php
@@ -47,7 +47,7 @@ interface UserInterface
*
* @return Role[] The user roles
*/
- function getRoles();
+ public function getRoles();
/**
* Returns the password used to authenticate the user.
@@ -57,7 +57,7 @@ interface UserInterface
*
* @return string The password
*/
- function getPassword();
+ public function getPassword();
/**
* Returns the salt that was originally used to encode the password.
@@ -66,14 +66,14 @@ interface UserInterface
*
* @return string The salt
*/
- function getSalt();
+ public function getSalt();
/**
* Returns the username used to authenticate the user.
*
* @return string The username
*/
- function getUsername();
+ public function getUsername();
/**
* Removes sensitive data from the user.
@@ -83,5 +83,5 @@ interface UserInterface
*
* @return void
*/
- function eraseCredentials();
+ public function eraseCredentials();
}
diff --git a/Core/User/UserProviderInterface.php b/Core/User/UserProviderInterface.php
index dbd7924..6669c43 100644
--- a/Core/User/UserProviderInterface.php
+++ b/Core/User/UserProviderInterface.php
@@ -48,7 +48,7 @@ interface UserProviderInterface
* @throws UsernameNotFoundException if the user is not found
*
*/
- function loadUserByUsername($username);
+ public function loadUserByUsername($username);
/**
* Refreshes the user for the account interface.
@@ -63,7 +63,7 @@ interface UserProviderInterface
*
* @throws UnsupportedUserException if the account is not supported
*/
- function refreshUser(UserInterface $user);
+ public function refreshUser(UserInterface $user);
/**
* Whether this provider supports the given user class
@@ -72,5 +72,5 @@ interface UserProviderInterface
*
* @return Boolean
*/
- function supportsClass($class);
+ public function supportsClass($class);
}
diff --git a/Core/Util/ClassUtils.php b/Core/Util/ClassUtils.php
index 7b583a3..26bf1a1 100644
--- a/Core/Util/ClassUtils.php
+++ b/Core/Util/ClassUtils.php
@@ -37,6 +37,11 @@ class ClassUtils
const MARKER_LENGTH = 6;
/**
+ * This class should not be instantiated
+ */
+ private function __construct() {}
+
+ /**
* Gets the real class name of a class name that could be a proxy.
*
* @param string|object
diff --git a/Core/Util/SecureRandom.php b/Core/Util/SecureRandom.php
new file mode 100644
index 0000000..841b9af
--- /dev/null
+++ b/Core/Util/SecureRandom.php
@@ -0,0 +1,114 @@
+<?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\Core\Util;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * A secure random number generator implementation.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class SecureRandom implements SecureRandomInterface
+{
+ private $logger;
+ private $useOpenSsl;
+ private $seed;
+ private $seedUpdated;
+ private $seedLastUpdatedAt;
+ private $seedFile;
+
+ /**
+ * Constructor.
+ *
+ * Be aware that a guessable seed will severely compromise the PRNG
+ * algorithm that is employed.
+ *
+ * @param string $seedFile
+ * @param LoggerInterface $logger
+ */
+ public function __construct($seedFile = null, LoggerInterface $logger = null)
+ {
+ $this->seedFile = $seedFile;
+ $this->logger = $logger;
+
+ // determine whether to use OpenSSL
+ if (defined('PHP_WINDOWS_VERSION_BUILD') && version_compare(PHP_VERSION, '5.3.4', '<')) {
+ $this->useOpenSsl = false;
+ } elseif (!function_exists('openssl_random_pseudo_bytes')) {
+ if (null !== $this->logger) {
+ $this->logger->notice('It is recommended that you enable the "openssl" extension for random number generation.');
+ }
+ $this->useOpenSsl = false;
+ } else {
+ $this->useOpenSsl = true;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function nextBytes($nbBytes)
+ {
+ // try OpenSSL
+ if ($this->useOpenSsl) {
+ $bytes = openssl_random_pseudo_bytes($nbBytes, $strong);
+
+ if (false !== $bytes && true === $strong) {
+ return $bytes;
+ }
+
+ if (null !== $this->logger) {
+ $this->logger->info('OpenSSL did not produce a secure random number.');
+ }
+ }
+
+ // initialize seed
+ if (null === $this->seed) {
+ if (null === $this->seedFile) {
+ throw new \RuntimeException('You need to specify a file path to store the seed.');
+ }
+
+ if (is_file($this->seedFile)) {
+ list($this->seed, $this->seedLastUpdatedAt) = $this->readSeed();
+ } else {
+ $this->seed = uniqid(mt_rand(), true);
+ $this->updateSeed();
+ }
+ }
+
+ $bytes = '';
+ while (strlen($bytes) < $nbBytes) {
+ static $incr = 1;
+ $bytes .= hash('sha512', $incr++.$this->seed.uniqid(mt_rand(), true).$nbBytes, true);
+ $this->seed = base64_encode(hash('sha512', $this->seed.$bytes.$nbBytes, true));
+ $this->updateSeed();
+ }
+
+ return substr($bytes, 0, $nbBytes);
+ }
+
+ private function readSeed()
+ {
+ return json_decode(file_get_contents($this->seedFile));
+ }
+
+ private function updateSeed()
+ {
+ if (!$this->seedUpdated && $this->seedLastUpdatedAt < time() - mt_rand(1, 10)) {
+ file_put_contents($this->seedFile, json_encode(array($this->seed, microtime(true))));
+ }
+
+ $this->seedUpdated = true;
+ }
+}
diff --git a/Core/Util/SecureRandomInterface.php b/Core/Util/SecureRandomInterface.php
new file mode 100644
index 0000000..2c35a72
--- /dev/null
+++ b/Core/Util/SecureRandomInterface.php
@@ -0,0 +1,29 @@
+<?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\Core\Util;
+
+/**
+ * Interface that needs to be implemented by all secure random number generators.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface SecureRandomInterface
+{
+ /**
+ * Generates the specified number of secure random bytes.
+ *
+ * @param integer $nbBytes
+ *
+ * @return string
+ */
+ public function nextBytes($nbBytes);
+}
diff --git a/Core/Util/StringUtils.php b/Core/Util/StringUtils.php
new file mode 100644
index 0000000..2e8925d
--- /dev/null
+++ b/Core/Util/StringUtils.php
@@ -0,0 +1,60 @@
+<?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\Core\Util;
+
+/**
+ * String utility functions.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class StringUtils
+{
+ /**
+ * This class should not be instantiated
+ */
+ private function __construct() {}
+
+ /**
+ * Compares two strings.
+ *
+ * This method implements a constant-time algorithm to compare strings.
+ *
+ * @param string $knownString The string of known length to compare against
+ * @param string $userInput The string that the user can control
+ *
+ * @return Boolean true if the two strings are the same, false otherwise
+ */
+ public static function equals($knownString, $userInput)
+ {
+ // Prevent issues if string length is 0
+ $knownString .= chr(0);
+ $userInput .= chr(0);
+
+ $knownLen = strlen($knownString);
+ $userLen = strlen($userInput);
+
+ // Set the result to the difference between the lengths
+ $result = $knownLen - $userLen;
+
+ // Note that we ALWAYS iterate over the user-supplied length
+ // This is to prevent leaking length information
+ for ($i = 0; $i < $userLen; $i++) {
+ // Using % here is a trick to prevent notices
+ // It's safe, since if the lengths are different
+ // $result is already non-0
+ $result |= (ord($knownString[$i % $knownLen]) ^ ord($userInput[$i]));
+ }
+
+ // They are only identical strings if $result is exactly 0...
+ return 0 === $result;
+ }
+}
diff --git a/Core/Validator/Constraint/UserPassword.php b/Core/Validator/Constraints/UserPassword.php
index ef6e1ec..ed29b0c 100644
--- a/Core/Validator/Constraint/UserPassword.php
+++ b/Core/Validator/Constraints/UserPassword.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Core\Validator\Constraint;
+namespace Symfony\Component\Security\Core\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
@@ -18,10 +18,11 @@ use Symfony\Component\Validator\Constraint;
*/
class UserPassword extends Constraint
{
- public $message = 'This value should be the user current password';
+ public $message = 'This value should be the user current password.';
+ public $service = 'security.validator.user_password';
public function validatedBy()
{
- return 'security.validator.user_password';
+ return $this->service;
}
}
diff --git a/Core/Validator/Constraint/UserPasswordValidator.php b/Core/Validator/Constraints/UserPasswordValidator.php
index a54906b..a4e0f90 100644
--- a/Core/Validator/Constraint/UserPasswordValidator.php
+++ b/Core/Validator/Constraints/UserPasswordValidator.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Security\Core\Validator\Constraint;
+namespace Symfony\Component\Security\Core\Validator\Constraints;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
@@ -34,7 +34,7 @@ class UserPasswordValidator extends ConstraintValidator
$user = $this->securityContext->getToken()->getUser();
if (!$user instanceof UserInterface) {
- throw new ConstraintDefinitionException('The User must extend UserInterface');
+ throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.');
}
$encoder = $this->encoderFactory->getEncoder($user);
diff --git a/Http/AccessMapInterface.php b/Http/AccessMapInterface.php
index dbd7282..7d15fee 100644
--- a/Http/AccessMapInterface.php
+++ b/Http/AccessMapInterface.php
@@ -29,5 +29,5 @@ interface AccessMapInterface
*
* @return array A tuple of security attributes and the required channel
*/
- function getPatterns(Request $request);
+ public function getPatterns(Request $request);
}
diff --git a/Http/Authentication/AuthenticationFailureHandlerInterface.php b/Http/Authentication/AuthenticationFailureHandlerInterface.php
index 9cd7496..8dbd29a 100644
--- a/Http/Authentication/AuthenticationFailureHandlerInterface.php
+++ b/Http/Authentication/AuthenticationFailureHandlerInterface.php
@@ -33,7 +33,7 @@ interface AuthenticationFailureHandlerInterface
* @param Request $request
* @param AuthenticationException $exception
*
- * @return Response|null the response to return
+ * @return Response The response to return, never null
*/
- function onAuthenticationFailure(Request $request, AuthenticationException $exception);
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception);
}
diff --git a/Http/Authentication/AuthenticationSuccessHandlerInterface.php b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
index 8917f3e..5c08e73 100644
--- a/Http/Authentication/AuthenticationSuccessHandlerInterface.php
+++ b/Http/Authentication/AuthenticationSuccessHandlerInterface.php
@@ -33,7 +33,7 @@ interface AuthenticationSuccessHandlerInterface
* @param Request $request
* @param TokenInterface $token
*
- * @return Response|null the response to return
+ * @return Response never null
*/
- function onAuthenticationSuccess(Request $request, TokenInterface $token);
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token);
}
diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php
new file mode 100644
index 0000000..64f84f0
--- /dev/null
+++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php
@@ -0,0 +1,92 @@
+<?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\Http\Authentication;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+use Symfony\Component\Security\Http\HttpUtils;
+
+/**
+ * Class with the default authentication failure handling logic.
+ *
+ * Can be optionally be extended from by the developer to alter the behaviour
+ * while keeping the default behaviour.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandlerInterface
+{
+ protected $httpKernel;
+ protected $httpUtils;
+ protected $logger;
+ protected $options;
+
+ /**
+ * Constructor.
+ *
+ * @param HttpKernelInterface $httpKernel
+ * @param HttpUtils $httpUtils
+ * @param array $options Options for processing a failed authentication attempt.
+ * @param LoggerInterface $logger Optional logger
+ */
+ public function __construct(HttpKernelInterface $httpKernel, HttpUtils $httpUtils, array $options, LoggerInterface $logger = null)
+ {
+ $this->httpKernel = $httpKernel;
+ $this->httpUtils = $httpUtils;
+ $this->logger = $logger;
+
+ $this->options = array_merge(array(
+ 'failure_path' => null,
+ 'failure_forward' => false,
+ 'login_path' => '/login',
+ 'failure_path_parameter' => '_failure_path'
+ ), $options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
+ {
+ 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'];
+ }
+
+ if ($this->options['failure_forward']) {
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('Forwarding to %s', $this->options['failure_path']));
+ }
+
+ $subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
+ $subRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+
+ return $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+ }
+
+ if (null !== $this->logger) {
+ $this->logger->debug(sprintf('Redirecting to %s', $this->options['failure_path']));
+ }
+
+ $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $exception);
+
+ return $this->httpUtils->createRedirectResponse($request, $this->options['failure_path']);
+ }
+}
diff --git a/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
new file mode 100644
index 0000000..dd7a7d5
--- /dev/null
+++ b/Http/Authentication/DefaultAuthenticationSuccessHandler.php
@@ -0,0 +1,110 @@
+<?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\Http\Authentication;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\HttpUtils;
+
+/**
+ * Class with the default authentication success handling logic.
+ *
+ * Can be optionally be extended from by the developer to alter the behaviour
+ * while keeping the default behaviour.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface
+{
+ protected $httpUtils;
+ protected $options;
+ protected $providerKey;
+
+ /**
+ * Constructor.
+ *
+ * @param HttpUtils $httpUtils
+ * @param array $options Options for processing a successful authentication attempt.
+ */
+ public function __construct(HttpUtils $httpUtils, array $options)
+ {
+ $this->httpUtils = $httpUtils;
+
+ $this->options = array_merge(array(
+ 'always_use_default_target_path' => false,
+ 'default_target_path' => '/',
+ 'login_path' => '/login',
+ 'target_path_parameter' => '_target_path',
+ 'use_referer' => false,
+ ), $options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onAuthenticationSuccess(Request $request, TokenInterface $token)
+ {
+ return $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
+ }
+
+ /**
+ * Get the provider key.
+ *
+ * @return string
+ */
+ public function getProviderKey()
+ {
+ return $this->providerKey;
+ }
+
+ /**
+ * Set the provider key.
+ *
+ * @param string $providerKey
+ */
+ public function setProviderKey($providerKey)
+ {
+ $this->providerKey = $providerKey;
+ }
+
+ /**
+ * Builds the target URL according to the defined options.
+ *
+ * @param Request $request
+ *
+ * @return string
+ */
+ protected function determineTargetUrl(Request $request)
+ {
+ if ($this->options['always_use_default_target_path']) {
+ return $this->options['default_target_path'];
+ }
+
+ if ($targetUrl = $request->get($this->options['target_path_parameter'], null, true)) {
+ return $targetUrl;
+ }
+
+ if (null !== $this->providerKey && $targetUrl = $request->getSession()->get('_security.'.$this->providerKey.'.target_path')) {
+ $request->getSession()->remove('_security.'.$this->providerKey.'.target_path');
+
+ return $targetUrl;
+ }
+
+ if ($this->options['use_referer'] && ($targetUrl = $request->headers->get('Referer')) && $targetUrl !== $this->httpUtils->generateUri($request, $this->options['login_path'])) {
+ return $targetUrl;
+ }
+
+ return $this->options['default_target_path'];
+ }
+}
diff --git a/Http/Authorization/AccessDeniedHandlerInterface.php b/Http/Authorization/AccessDeniedHandlerInterface.php
index 8670cbb..a10a5d0 100644
--- a/Http/Authorization/AccessDeniedHandlerInterface.php
+++ b/Http/Authorization/AccessDeniedHandlerInterface.php
@@ -30,5 +30,5 @@ interface AccessDeniedHandlerInterface
*
* @return Response may return null
*/
- function handle(Request $request, AccessDeniedException $accessDeniedException);
+ public function handle(Request $request, AccessDeniedException $accessDeniedException);
}
diff --git a/Http/EntryPoint/AuthenticationEntryPointInterface.php b/Http/EntryPoint/AuthenticationEntryPointInterface.php
index 9fc3501..d190fc7 100644
--- a/Http/EntryPoint/AuthenticationEntryPointInterface.php
+++ b/Http/EntryPoint/AuthenticationEntryPointInterface.php
@@ -30,5 +30,5 @@ interface AuthenticationEntryPointInterface
*
* @return Response
*/
- function start(Request $request, AuthenticationException $authException = null);
+ public function start(Request $request, AuthenticationException $authException = null);
}
diff --git a/Http/EntryPoint/BasicAuthenticationEntryPoint.php b/Http/EntryPoint/BasicAuthenticationEntryPoint.php
index 6ba3872..44ece5e 100644
--- a/Http/EntryPoint/BasicAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/BasicAuthenticationEntryPoint.php
@@ -34,7 +34,7 @@ class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
{
$response = new Response();
$response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName));
- $response->setStatusCode(401, $authException ? $authException->getMessage() : null);
+ $response->setStatusCode(401);
return $response;
}
diff --git a/Http/EntryPoint/DigestAuthenticationEntryPoint.php b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
index ec92419..1131b58 100644
--- a/Http/EntryPoint/DigestAuthenticationEntryPoint.php
+++ b/Http/EntryPoint/DigestAuthenticationEntryPoint.php
@@ -16,7 +16,7 @@ use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface
use Symfony\Component\Security\Core\Exception\NonceExpiredException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
/**
* DigestAuthenticationEntryPoint starts an HTTP Digest authentication.
@@ -57,7 +57,7 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
$response = new Response();
$response->headers->set('WWW-Authenticate', $authenticateHeader);
- $response->setStatusCode(401, $authException ? $authException->getMessage() : null);
+ $response->setStatusCode(401);
return $response;
}
diff --git a/Http/Event/InteractiveLoginEvent.php b/Http/Event/InteractiveLoginEvent.php
index f242501..2225d92 100644
--- a/Http/Event/InteractiveLoginEvent.php
+++ b/Http/Event/InteractiveLoginEvent.php
@@ -21,17 +21,33 @@ class InteractiveLoginEvent extends Event
private $authenticationToken;
+ /**
+ * Constructor.
+ *
+ * @param Request $request A Request instance
+ * @param TokenInterface $authenticationToken A TokenInterface instance
+ */
public function __construct(Request $request, TokenInterface $authenticationToken)
{
$this->request = $request;
$this->authenticationToken = $authenticationToken;
}
+ /**
+ * Gets the request.
+ *
+ * @return Request A Request instance
+ */
public function getRequest()
{
return $this->request;
}
+ /**
+ * Gets the authentication token.
+ *
+ * @return TokenInterface A TokenInterface instance
+ */
public function getAuthenticationToken()
{
return $this->authenticationToken;
diff --git a/Http/Firewall.php b/Http/Firewall.php
index 91eb6a9..e083fdb 100644
--- a/Http/Firewall.php
+++ b/Http/Firewall.php
@@ -12,8 +12,10 @@
namespace Symfony\Component\Security\Http;
use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Firewall uses a FirewallMap to register security listeners for the given
@@ -25,7 +27,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
-class Firewall
+class Firewall implements EventSubscriberInterface
{
private $map;
private $dispatcher;
@@ -33,7 +35,7 @@ class Firewall
/**
* Constructor.
*
- * @param FirewallMap $map A FirewallMap instance
+ * @param FirewallMapInterface $map A FirewallMapInterface instance
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
*/
public function __construct(FirewallMapInterface $map, EventDispatcherInterface $dispatcher)
@@ -68,4 +70,9 @@ class Firewall
}
}
}
+
+ public static function getSubscribedEvents()
+ {
+ return array(KernelEvents::REQUEST => array('onKernelRequest', 8));
+ }
}
diff --git a/Http/Firewall/AbstractAuthenticationListener.php b/Http/Firewall/AbstractAuthenticationListener.php
index a5924ff..562ba10 100644
--- a/Http/Firewall/AbstractAuthenticationListener.php
+++ b/Http/Firewall/AbstractAuthenticationListener.php
@@ -19,8 +19,7 @@ use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -70,14 +69,16 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
* @param SessionAuthenticationStrategyInterface $sessionStrategy
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
* @param string $providerKey
+ * @param AuthenticationSuccessHandlerInterface $successHandler
+ * @param AuthenticationFailureHandlerInterface $failureHandler
* @param array $options An array of options for the processing of a
* successful, or failed authentication attempt
- * @param AuthenticationSuccessHandlerInterface $successHandler
- * @param AuthenticationFailureHandlerInterface $failureHandler
- * @param LoggerInterface $logger A LoggerInterface instance
- * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ * @param LoggerInterface $logger A LoggerInterface instance
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ *
+ * @throws \InvalidArgumentException
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
+ public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
@@ -119,8 +120,11 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
* Handles form based authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
+ *
+ * @throws \RuntimeException
+ * @throws SessionUnavailableException
*/
- public final function handle(GetResponseEvent $event)
+ final public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
@@ -178,7 +182,7 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
*
* @param Request $request A Request instance
*
- * @return TokenInterface The authenticated token, or null if full authentication is not possible
+ * @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response
*
* @throws AuthenticationException if the authentication fails
*/
@@ -192,34 +196,13 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->securityContext->setToken(null);
- if (null !== $this->failureHandler) {
- if (null !== $response = $this->failureHandler->onAuthenticationFailure($request, $failed)) {
- return $response;
- }
- }
-
- if (null === $this->options['failure_path']) {
- $this->options['failure_path'] = $this->options['login_path'];
- }
-
- if ($this->options['failure_forward']) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Forwarding to %s', $this->options['failure_path']));
- }
-
- $subRequest = $this->httpUtils->createRequest($request, $this->options['failure_path']);
- $subRequest->attributes->set(SecurityContextInterface::AUTHENTICATION_ERROR, $failed);
+ $response = $this->failureHandler->onAuthenticationFailure($request, $failed);
- return $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Authentication Failure Handler did not return a Response.');
}
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Redirecting to %s', $this->options['failure_path']));
- }
-
- $request->getSession()->set(SecurityContextInterface::AUTHENTICATION_ERROR, $failed);
-
- return $this->httpUtils->createRedirectResponse($request, $this->options['failure_path']);
+ return $response;
}
private function onSuccess(GetResponseEvent $event, Request $request, TokenInterface $token)
@@ -239,12 +222,10 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
$this->dispatcher->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $loginEvent);
}
- $response = null;
- if (null !== $this->successHandler) {
- $response = $this->successHandler->onAuthenticationSuccess($request, $token);
- }
- if (null === $response) {
- $response = $this->httpUtils->createRedirectResponse($request, $this->determineTargetUrl($request));
+ $response = $this->successHandler->onAuthenticationSuccess($request, $token);
+
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Authentication Success Handler did not return a Response.');
}
if (null !== $this->rememberMeServices) {
@@ -253,35 +234,4 @@ abstract class AbstractAuthenticationListener implements ListenerInterface
return $response;
}
-
- /**
- * Builds the target URL according to the defined options.
- *
- * @param Request $request
- *
- * @return string
- */
- private function determineTargetUrl(Request $request)
- {
- if ($this->options['always_use_default_target_path']) {
- return $this->options['default_target_path'];
- }
-
- if ($targetUrl = $request->get($this->options['target_path_parameter'], null, true)) {
- return $targetUrl;
- }
-
- $session = $request->getSession();
- if ($targetUrl = $session->get('_security.' . $this->providerKey . '.target_path')) {
- $session->remove('_security.' . $this->providerKey . '.target_path');
-
- return $targetUrl;
- }
-
- if ($this->options['use_referer'] && ($targetUrl = $request->headers->get('Referer')) && $targetUrl !== $request->getUriForPath($this->options['login_path'])) {
- return $targetUrl;
- }
-
- return $this->options['default_target_path'];
- }
}
diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php
index 66d0ea1..d7e46cf 100644
--- a/Http/Firewall/AbstractPreAuthenticatedListener.php
+++ b/Http/Firewall/AbstractPreAuthenticatedListener.php
@@ -18,7 +18,7 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -51,7 +51,7 @@ abstract class AbstractPreAuthenticatedListener implements ListenerInterface
*
* @param GetResponseEvent $event A GetResponseEvent instance
*/
- public final function handle(GetResponseEvent $event)
+ final public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
diff --git a/Http/Firewall/AccessListener.php b/Http/Firewall/AccessListener.php
index 3e2d3a5..c3894ef 100644
--- a/Http/Firewall/AccessListener.php
+++ b/Http/Firewall/AccessListener.php
@@ -15,7 +15,7 @@ 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 Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
@@ -46,6 +46,9 @@ class AccessListener implements ListenerInterface
* Handles access authorization.
*
* @param GetResponseEvent $event A GetResponseEvent instance
+ *
+ * @throws AccessDeniedException
+ * @throws AuthenticationCredentialsNotFoundException
*/
public function handle(GetResponseEvent $event)
{
diff --git a/Http/Firewall/AnonymousAuthenticationListener.php b/Http/Firewall/AnonymousAuthenticationListener.php
index d00865d..af2213b 100644
--- a/Http/Firewall/AnonymousAuthenticationListener.php
+++ b/Http/Firewall/AnonymousAuthenticationListener.php
@@ -12,7 +12,7 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\SecurityContextInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
diff --git a/Http/Firewall/BasicAuthenticationListener.php b/Http/Firewall/BasicAuthenticationListener.php
index e331179..5b1c8b3 100644
--- a/Http/Firewall/BasicAuthenticationListener.php
+++ b/Http/Firewall/BasicAuthenticationListener.php
@@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
diff --git a/Http/Firewall/ChannelListener.php b/Http/Firewall/ChannelListener.php
index 9b0f8c6..9e4a6ee 100644
--- a/Http/Firewall/ChannelListener.php
+++ b/Http/Firewall/ChannelListener.php
@@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Http\AccessMapInterface;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/**
diff --git a/Http/Firewall/ContextListener.php b/Http/Firewall/ContextListener.php
index bb1e308..8c71876 100644
--- a/Http/Firewall/ContextListener.php
+++ b/Http/Firewall/ContextListener.php
@@ -12,7 +12,7 @@
namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\HttpKernel\HttpKernelInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -70,24 +70,31 @@ class ContextListener implements ListenerInterface
}
$request = $event->getRequest();
-
$session = $request->hasPreviousSession() ? $request->getSession() : null;
if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) {
$this->context->setToken(null);
- } else {
- if (null !== $this->logger) {
- $this->logger->debug('Read SecurityContext from the session');
- }
- $token = unserialize($token);
+ return;
+ }
+
+ $token = unserialize($token);
+
+ if (null !== $this->logger) {
+ $this->logger->debug('Read SecurityContext from the session');
+ }
- if (null !== $token) {
- $token = $this->refreshUser($token);
+ if ($token instanceof TokenInterface) {
+ $token = $this->refreshUser($token);
+ } elseif (null !== $token) {
+ if (null !== $this->logger) {
+ $this->logger->warning(sprintf('Session includes a "%s" where a security token is expected', is_object($token) ? get_class($token) : gettype($token)));
}
- $this->context->setToken($token);
+ $token = null;
}
+
+ $this->context->setToken($token);
}
/**
@@ -109,12 +116,17 @@ class ContextListener implements ListenerInterface
$this->logger->debug('Write SecurityContext in the session');
}
- if (null === $session = $event->getRequest()->getSession()) {
+ $request = $event->getRequest();
+ $session = $request->getSession();
+
+ if (null === $session) {
return;
}
if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
- $session->remove('_security_'.$this->contextKey);
+ if ($request->hasPreviousSession()) {
+ $session->remove('_security_'.$this->contextKey);
+ }
} else {
$session->set('_security_'.$this->contextKey, serialize($token));
}
@@ -126,6 +138,8 @@ class ContextListener implements ListenerInterface
* @param TokenInterface $token
*
* @return TokenInterface|null
+ *
+ * @throws \RuntimeException
*/
private function refreshUser(TokenInterface $token)
{
@@ -151,7 +165,7 @@ class ContextListener implements ListenerInterface
// let's try the next user provider
} catch (UsernameNotFoundException $notFound) {
if (null !== $this->logger) {
- $this->logger->warn(sprintf('Username "%s" could not be found.', $user->getUsername()));
+ $this->logger->warning(sprintf('Username "%s" could not be found.', $user->getUsername()));
}
return null;
diff --git a/Http/Firewall/DigestAuthenticationListener.php b/Http/Firewall/DigestAuthenticationListener.php
index 5c529da..7ab3dcf 100644
--- a/Http/Firewall/DigestAuthenticationListener.php
+++ b/Http/Firewall/DigestAuthenticationListener.php
@@ -14,7 +14,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
@@ -54,6 +54,8 @@ class DigestAuthenticationListener implements ListenerInterface
* Handles digest authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
+ *
+ * @throws AuthenticationServiceException
*/
public function handle(GetResponseEvent $event)
{
@@ -141,11 +143,12 @@ class DigestData
public function __construct($header)
{
$this->header = $header;
- $parts = preg_split('/, /', $header);
+ preg_match_all('/(\w+)=("((?:[^"\\\\]|\\\\.)+)"|([^\s,$]+))/', $header, $matches, PREG_SET_ORDER);
$this->elements = array();
- foreach ($parts as $part) {
- list($key, $value) = explode('=', $part);
- $this->elements[$key] = '"' === $value[0] ? substr($value, 1, -1) : $value;
+ foreach ($matches as $match) {
+ if (isset($match[1]) && isset($match[3])) {
+ $this->elements[$match[1]] = isset($match[4]) ? $match[4] : $match[3];
+ }
}
}
@@ -156,7 +159,7 @@ class DigestData
public function getUsername()
{
- return $this->elements['username'];
+ return strtr($this->elements['username'], array("\\\"" => "\"", "\\\\" => "\\"));
}
public function validateAndDecode($entryPointKey, $expectedRealm)
@@ -188,7 +191,7 @@ class DigestData
$this->nonceExpiryTime = $nonceTokens[0];
if (md5($this->nonceExpiryTime.':'.$entryPointKey) !== $nonceTokens[1]) {
- new BadCredentialsException(sprintf('Nonce token compromised "%s".', $nonceAsPlainText));
+ throw new BadCredentialsException(sprintf('Nonce token compromised "%s".', $nonceAsPlainText));
}
}
diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php
index 9a53827..0f81d1b 100644
--- a/Http/Firewall/ExceptionListener.php
+++ b/Http/Firewall/ExceptionListener.php
@@ -23,7 +23,7 @@ use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationExceptio
use Symfony\Component\Security\Core\Exception\LogoutException;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
@@ -97,6 +97,8 @@ class ExceptionListener
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) {
@@ -104,7 +106,9 @@ class ExceptionListener
}
try {
- $response = $this->startAuthentication($request, new InsufficientAuthenticationException('Full authentication is required to access this resource.', $token, 0, $exception));
+ $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);
@@ -127,15 +131,12 @@ class ExceptionListener
$subRequest->attributes->set(SecurityContextInterface::ACCESS_DENIED_ERROR, $exception);
$response = $event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
- $response->setStatusCode(403);
} else {
- $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
-
return;
}
} catch (\Exception $e) {
if (null !== $this->logger) {
- $this->logger->err(sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()));
+ $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));
@@ -148,8 +149,6 @@ class ExceptionListener
$this->logger->info(sprintf('Logout exception occurred; wrapping with AccessDeniedHttpException (%s)', $exception->getMessage()));
}
- $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
-
return;
} else {
return;
diff --git a/Http/Firewall/ListenerInterface.php b/Http/Firewall/ListenerInterface.php
index ccde86e..b670474 100644
--- a/Http/Firewall/ListenerInterface.php
+++ b/Http/Firewall/ListenerInterface.php
@@ -25,5 +25,5 @@ interface ListenerInterface
*
* @param GetResponseEvent $event
*/
- function handle(GetResponseEvent $event);
+ public function handle(GetResponseEvent $event);
}
diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php
index d145fa1..ca2f439 100644
--- a/Http/Firewall/LogoutListener.php
+++ b/Http/Firewall/LogoutListener.php
@@ -40,11 +40,11 @@ class LogoutListener implements ListenerInterface
*
* @param SecurityContextInterface $securityContext
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
- * @param array $options An array of options to process a logout attempt
* @param LogoutSuccessHandlerInterface $successHandler A LogoutSuccessHandlerInterface instance
+ * @param array $options An array of options to process a logout attempt
* @param CsrfProviderInterface $csrfProvider A CsrfProviderInterface instance
*/
- public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, array $options = array(), LogoutSuccessHandlerInterface $successHandler = null, CsrfProviderInterface $csrfProvider = null)
+ public function __construct(SecurityContextInterface $securityContext, HttpUtils $httpUtils, LogoutSuccessHandlerInterface $successHandler, array $options = array(), CsrfProviderInterface $csrfProvider = null)
{
$this->securityContext = $securityContext;
$this->httpUtils = $httpUtils;
@@ -52,7 +52,6 @@ class LogoutListener implements ListenerInterface
'csrf_parameter' => '_csrf_token',
'intention' => 'logout',
'logout_path' => '/logout',
- 'target_url' => '/',
), $options);
$this->successHandler = $successHandler;
$this->csrfProvider = $csrfProvider;
@@ -76,8 +75,10 @@ class LogoutListener implements ListenerInterface
* validate the request.
*
* @param GetResponseEvent $event A GetResponseEvent instance
+ *
* @throws InvalidCsrfTokenException if the CSRF token is invalid
- * @throws RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
+ * @throws \RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
+ * @throws LogoutException
*/
public function handle(GetResponseEvent $event)
{
@@ -95,14 +96,9 @@ class LogoutListener implements ListenerInterface
}
}
- if (null !== $this->successHandler) {
- $response = $this->successHandler->onLogoutSuccess($request);
-
- if (!$response instanceof Response) {
- throw new \RuntimeException('Logout Success Handler did not return a Response.');
- }
- } else {
- $response = $this->httpUtils->createRedirectResponse($request, $this->options['target_url']);
+ $response = $this->successHandler->onLogoutSuccess($request);
+ if (!$response instanceof Response) {
+ throw new \RuntimeException('Logout Success Handler did not return a Response.');
}
// handle multiple logout attempts gracefully
diff --git a/Http/Firewall/RememberMeListener.php b/Http/Firewall/RememberMeListener.php
index 3614f79..5a856e2 100644
--- a/Http/Firewall/RememberMeListener.php
+++ b/Http/Firewall/RememberMeListener.php
@@ -11,7 +11,7 @@
namespace Symfony\Component\Security\Http\Firewall;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
@@ -82,7 +82,7 @@ class RememberMeListener implements ListenerInterface
}
} catch (AuthenticationException $failed) {
if (null !== $this->logger) {
- $this->logger->warn(
+ $this->logger->warning(
'SecurityContext not populated with remember-me token as the'
.' AuthenticationManager rejected the AuthenticationToken returned'
.' by the RememberMeServices: '.$failed->getMessage()
diff --git a/Http/Firewall/SwitchUserListener.php b/Http/Firewall/SwitchUserListener.php
index 7f0aa78..bad6b2b 100644
--- a/Http/Firewall/SwitchUserListener.php
+++ b/Http/Firewall/SwitchUserListener.php
@@ -16,7 +16,7 @@ use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -71,6 +71,8 @@ class SwitchUserListener implements ListenerInterface
* Handles digest authentication.
*
* @param GetResponseEvent $event A GetResponseEvent instance
+ *
+ * @throws \LogicException
*/
public function handle(GetResponseEvent $event)
{
@@ -102,6 +104,9 @@ class SwitchUserListener implements ListenerInterface
* @param Request $request A Request instance
*
* @return TokenInterface|null The new TokenInterface if successfully switched, null otherwise
+ *
+ * @throws \LogicException
+ * @throws AccessDeniedException
*/
private function attemptSwitchUser(Request $request)
{
@@ -148,6 +153,8 @@ class SwitchUserListener implements ListenerInterface
* @param Request $request A Request instance
*
* @return TokenInterface The original TokenInterface instance
+ *
+ * @throws AuthenticationCredentialsNotFoundException
*/
private function attemptExitUser(Request $request)
{
diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
index 35b0b11..81c2b37 100644
--- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
+++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php
@@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
@@ -37,15 +37,15 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
/**
* {@inheritdoc}
*/
- public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, array $options = array(), AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
+ public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfProviderInterface $csrfProvider = null)
{
- parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, array_merge(array(
+ parent::__construct($securityContext, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge(array(
'username_parameter' => '_username',
'password_parameter' => '_password',
'csrf_parameter' => '_csrf_token',
'intention' => 'authenticate',
'post_only' => true,
- ), $options), $successHandler, $failureHandler, $logger, $dispatcher);
+ ), $options), $logger, $dispatcher);
$this->csrfProvider = $csrfProvider;
}
@@ -55,7 +55,7 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
*/
protected function requiresAuthentication(Request $request)
{
- if ($this->options['post_only'] && !$request->isMethod('post')) {
+ if ($this->options['post_only'] && !$request->isMethod('POST')) {
return false;
}
@@ -67,14 +67,6 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
*/
protected function attemptAuthentication(Request $request)
{
- if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) {
- if (null !== $this->logger) {
- $this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod()));
- }
-
- return null;
- }
-
if (null !== $this->csrfProvider) {
$csrfToken = $request->get($this->options['csrf_parameter'], null, true);
@@ -83,8 +75,13 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
}
}
- $username = trim($request->get($this->options['username_parameter'], null, true));
- $password = $request->get($this->options['password_parameter'], null, true);
+ if ($this->options['post_only']) {
+ $username = trim($request->request->get($this->options['username_parameter'], null, true));
+ $password = $request->request->get($this->options['password_parameter'], null, true);
+ } else {
+ $username = trim($request->get($this->options['username_parameter'], null, true));
+ $password = $request->get($this->options['password_parameter'], null, true);
+ }
$request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username);
diff --git a/Http/Firewall/X509AuthenticationListener.php b/Http/Firewall/X509AuthenticationListener.php
index 2f4b78a..0b5a6ae 100644
--- a/Http/Firewall/X509AuthenticationListener.php
+++ b/Http/Firewall/X509AuthenticationListener.php
@@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
diff --git a/Http/FirewallMapInterface.php b/Http/FirewallMapInterface.php
index 5a42ff1..336125f 100644
--- a/Http/FirewallMapInterface.php
+++ b/Http/FirewallMapInterface.php
@@ -34,5 +34,5 @@ interface FirewallMapInterface
*
* @return array of the format array(array(AuthenticationListener), ExceptionListener)
*/
- function getListeners(Request $request);
+ public function getListeners(Request $request);
}
diff --git a/Http/HttpUtils.php b/Http/HttpUtils.php
index 1c87e77..0453520 100644
--- a/Http/HttpUtils.php
+++ b/Http/HttpUtils.php
@@ -16,6 +16,7 @@ use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
@@ -33,12 +34,15 @@ class HttpUtils
/**
* Constructor.
*
- * @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
- * @param UrlMatcherInterface $urlMatcher A UrlMatcherInterface instance
+ * @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
+ * @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The Url or Request matcher
*/
- public function __construct(UrlGeneratorInterface $urlGenerator = null, UrlMatcherInterface $urlMatcher = null)
+ public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatcher = null)
{
$this->urlGenerator = $urlGenerator;
+ if ($urlMatcher !== null && !$urlMatcher instanceof UrlMatcherInterface && !$urlMatcher instanceof RequestMatcherInterface) {
+ throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
+ }
$this->urlMatcher = $urlMatcher;
}
@@ -66,9 +70,9 @@ class HttpUtils
*/
public function createRequest(Request $request, $path)
{
- $newRequest = Request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
- if ($session = $request->getSession()) {
- $newRequest->setSession($session);
+ $newRequest = $request::create($this->generateUri($request, $path), 'get', array(), $request->cookies->all(), array(), $request->server->all());
+ if ($request->hasSession()) {
+ $newRequest->setSession($request->getSession());
}
if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) {
@@ -96,7 +100,12 @@ class HttpUtils
{
if ('/' !== $path[0]) {
try {
- $parameters = $this->urlMatcher->match($request->getPathInfo());
+ // matching a request is more powerful than matching a URL path + context, so try that first
+ if ($this->urlMatcher instanceof RequestMatcherInterface) {
+ $parameters = $this->urlMatcher->matchRequest($request);
+ } else {
+ $parameters = $this->urlMatcher->match($request->getPathInfo());
+ }
return $path === $parameters['_route'];
} catch (MethodNotAllowedException $e) {
@@ -106,7 +115,7 @@ class HttpUtils
}
}
- return $path === $request->getPathInfo();
+ return $path === rawurldecode($request->getPathInfo());
}
/**
@@ -127,15 +136,20 @@ class HttpUtils
return $request->getUriForPath($path);
}
- return $this->generateUrl($path, true);
- }
-
- private function generateUrl($route, $absolute = false)
- {
if (null === $this->urlGenerator) {
throw new \LogicException('You must provide a UrlGeneratorInterface instance to be able to use routes.');
}
- return $this->urlGenerator->generate($route, array(), $absolute);
+ $url = $this->urlGenerator->generate($path, $request->attributes->all(), UrlGeneratorInterface::ABSOLUTE_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, '?');
+ if (false !== $position) {
+ $url = substr($url, 0, $position);
+ }
+
+ return $url;
}
}
diff --git a/Http/Logout/DefaultLogoutSuccessHandler.php b/Http/Logout/DefaultLogoutSuccessHandler.php
new file mode 100644
index 0000000..e06cb6d
--- /dev/null
+++ b/Http/Logout/DefaultLogoutSuccessHandler.php
@@ -0,0 +1,47 @@
+<?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\Http\Logout;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Security\Http\HttpUtils;
+use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+
+/**
+ * Default logout success handler will redirect users to a configured path.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Alexander <iam.asm89@gmail.com>
+ */
+class DefaultLogoutSuccessHandler implements LogoutSuccessHandlerInterface
+{
+ protected $httpUtils;
+ protected $targetUrl;
+
+ /**
+ * @param HttpUtils $httpUtils
+ * @param string $targetUrl
+ */
+ public function __construct(HttpUtils $httpUtils, $targetUrl = '/')
+ {
+ $this->httpUtils = $httpUtils;
+
+ $this->targetUrl = $targetUrl;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function onLogoutSuccess(Request $request)
+ {
+ return $this->httpUtils->createRedirectResponse($request, $this->targetUrl);
+ }
+}
diff --git a/Http/Logout/LogoutHandlerInterface.php b/Http/Logout/LogoutHandlerInterface.php
index 71be388..5e1cea8 100644
--- a/Http/Logout/LogoutHandlerInterface.php
+++ b/Http/Logout/LogoutHandlerInterface.php
@@ -31,5 +31,5 @@ interface LogoutHandlerInterface
* @param Response $response
* @param TokenInterface $token
*/
- function logout(Request $request, Response $response, TokenInterface $token);
+ public function logout(Request $request, Response $response, TokenInterface $token);
}
diff --git a/Http/Logout/LogoutSuccessHandlerInterface.php b/Http/Logout/LogoutSuccessHandlerInterface.php
index fb1dd64..61642a8 100644
--- a/Http/Logout/LogoutSuccessHandlerInterface.php
+++ b/Http/Logout/LogoutSuccessHandlerInterface.php
@@ -33,5 +33,5 @@ interface LogoutSuccessHandlerInterface
*
* @return Response never null
*/
- function onLogoutSuccess(Request $request);
+ public function onLogoutSuccess(Request $request);
}
diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php
index d61a6ce..ae61dd7 100644
--- a/Http/RememberMe/AbstractRememberMeServices.php
+++ b/Http/RememberMe/AbstractRememberMeServices.php
@@ -22,7 +22,7 @@ use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Cookie;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
+use Psr\Log\LoggerInterface;
/**
* Base class implementing the RememberMeServicesInterface
@@ -47,6 +47,8 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param string $providerKey
* @param array $options
* @param LoggerInterface $logger
+ *
+ * @throws \InvalidArgumentException
*/
public function __construct(array $userProviders, $key, $providerKey, array $options = array(), LoggerInterface $logger = null)
{
@@ -89,9 +91,11 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*
* @param Request $request
*
- * @return TokenInterface
+ * @return TokenInterface|null
+ *
+ * @throws CookieTheftException
*/
- public final function autoLogin(Request $request)
+ final public function autoLogin(Request $request)
{
if (null === $cookie = $request->cookies->get($this->options['name'])) {
return;
@@ -125,7 +129,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
}
} catch (UnsupportedUserException $unSupported) {
if (null !== $this->logger) {
- $this->logger->warn('User class for remember-me cookie not supported.');
+ $this->logger->warning('User class for remember-me cookie not supported.');
}
} catch (AuthenticationException $invalid) {
if (null !== $this->logger) {
@@ -156,7 +160,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*
* @param Request $request
*/
- public final function loginFail(Request $request)
+ final public function loginFail(Request $request)
{
$this->cancelCookie($request);
$this->onLoginFail($request);
@@ -170,8 +174,11 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param Response $response
* @param TokenInterface $token The token that resulted in a successful authentication
*/
- public final function loginSuccess(Request $request, Response $response, TokenInterface $token)
+ final public function loginSuccess(Request $request, Response $response, TokenInterface $token)
{
+ // Make sure any old remember-me cookies are cancelled
+ $this->cancelCookie($request);
+
if (!$token->getUser() instanceof UserInterface) {
if (null !== $this->logger) {
$this->logger->debug('Remember-me ignores token since it does not contain a UserInterface implementation.');
@@ -192,6 +199,12 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
$this->logger->debug('Remember-me was requested; setting cookie.');
}
+ // Remove attribute from request that sets a NULL cookie.
+ // It was set by $this->cancelCookie()
+ // (cancelCookie does other things too for some RememberMeServices
+ // so we should still call it at the start of this method)
+ $request->attributes->remove(self::COOKIE_ATTR_NAME);
+
$this->onLoginSuccess($request, $response, $token);
}
@@ -221,7 +234,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*/
abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token);
- protected final function getUserProvider($class)
+ final protected function getUserProvider($class)
{
foreach ($this->userProviders as $provider) {
if ($provider->supportsClass($class)) {
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
index 8944672..9f4013d 100644
--- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
+++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php
@@ -19,6 +19,7 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Util\SecureRandomInterface;
/**
* Concrete implementation of the RememberMeServicesInterface which needs
@@ -30,6 +31,24 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
{
private $tokenProvider;
+ private $secureRandom;
+
+ /**
+ * Constructor.
+ *
+ * @param array $userProviders
+ * @param string $key
+ * @param string $providerKey
+ * @param array $options
+ * @param LoggerInterface $logger
+ * @param SecureRandomInterface $secureRandom
+ */
+ public function __construct(array $userProviders, $key, $providerKey, array $options = array(), LoggerInterface $logger = null, SecureRandomInterface $secureRandom)
+ {
+ parent::__construct($userProviders, $key, $providerKey, $options, $logger);
+
+ $this->secureRandom = $secureRandom;
+ }
/**
* Sets the token provider
@@ -44,10 +63,12 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
/**
* {@inheritDoc}
*/
- public function logout(Request $request, Response $response, TokenInterface $token)
+ protected function cancelCookie(Request $request)
{
- parent::logout($request, $response, $token);
+ // Delete cookie on the client
+ parent::cancelCookie($request);
+ // Delete cookie from the tokenProvider
if (null !== ($cookie = $request->cookies->get($this->options['name']))
&& count($parts = $this->decodeCookie($cookie)) === 2
) {
@@ -69,8 +90,6 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
$persistentToken = $this->tokenProvider->loadTokenBySeries($series);
if ($persistentToken->getTokenValue() !== $tokenValue) {
- $this->tokenProvider->deleteTokenBySeries($series);
-
throw new CookieTheftException('This token was already used. The account is possibly compromised.');
}
@@ -79,7 +98,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
}
$series = $persistentToken->getSeries();
- $tokenValue = $this->generateRandomValue();
+ $tokenValue = $this->secureRandom->nextBytes(64);
$this->tokenProvider->updateToken($series, $tokenValue, new \DateTime());
$request->attributes->set(self::COOKIE_ATTR_NAME,
new Cookie(
@@ -101,8 +120,8 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
*/
protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token)
{
- $series = $this->generateRandomValue();
- $tokenValue = $this->generateRandomValue();
+ $series = $this->secureRandom->nextBytes(64);
+ $tokenValue = $this->secureRandom->nextBytes(64);
$this->tokenProvider->createNewToken(
new PersistentToken(
@@ -126,26 +145,4 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
)
);
}
-
- /**
- * Generates a cryptographically strong random value
- *
- * @return string
- */
- protected function generateRandomValue()
- {
- if (function_exists('openssl_random_pseudo_bytes')) {
- $bytes = openssl_random_pseudo_bytes(64, $strong);
-
- if (true === $strong && false !== $bytes) {
- return base64_encode($bytes);
- }
- }
-
- if (null !== $this->logger) {
- $this->logger->warn('Could not produce a cryptographically strong random value. Please install/update the OpenSSL extension.');
- }
-
- return base64_encode(hash('sha512', uniqid(mt_rand(), true), true));
- }
}
diff --git a/Http/RememberMe/RememberMeServicesInterface.php b/Http/RememberMe/RememberMeServicesInterface.php
index 0497c69..a00dcef 100644
--- a/Http/RememberMe/RememberMeServicesInterface.php
+++ b/Http/RememberMe/RememberMeServicesInterface.php
@@ -51,7 +51,7 @@ interface RememberMeServicesInterface
*
* @return TokenInterface
*/
- function autoLogin(Request $request);
+ public function autoLogin(Request $request);
/**
* Called whenever an interactive authentication attempt was made, but the
@@ -61,7 +61,7 @@ interface RememberMeServicesInterface
*
* @param Request $request
*/
- function loginFail(Request $request);
+ public function loginFail(Request $request);
/**
* Called whenever an interactive authentication attempt is successful
@@ -78,5 +78,5 @@ interface RememberMeServicesInterface
* @param Response $response
* @param TokenInterface $token
*/
- function loginSuccess(Request $request, Response $response, TokenInterface $token);
+ public function loginSuccess(Request $request, Response $response, TokenInterface $token);
}
diff --git a/Http/RememberMe/ResponseListener.php b/Http/RememberMe/ResponseListener.php
new file mode 100644
index 0000000..03c71c7
--- /dev/null
+++ b/Http/RememberMe/ResponseListener.php
@@ -0,0 +1,39 @@
+<?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\Http\RememberMe;
+
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Adds remember-me cookies to the Response.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ResponseListener implements EventSubscriberInterface
+{
+ public function onKernelResponse(FilterResponseEvent $event)
+ {
+ $request = $event->getRequest();
+ $response = $event->getResponse();
+
+ if ($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)) {
+ $response->headers->setCookie($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME));
+ }
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return array(KernelEvents::RESPONSE => 'onKernelResponse');
+ }
+}
diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php
index bd828f2..5a66fe4 100644
--- a/Http/RememberMe/TokenBasedRememberMeServices.php
+++ b/Http/RememberMe/TokenBasedRememberMeServices.php
@@ -43,7 +43,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
$user = $this->getUserProvider($class)->loadUserByUsername($username);
} catch (\Exception $ex) {
if (!$ex instanceof AuthenticationException) {
- $ex = new AuthenticationException($ex->getMessage(), null, $ex->getCode(), $ex);
+ $ex = new AuthenticationException($ex->getMessage(), $ex->getCode(), $ex);
}
throw $ex;
diff --git a/Http/SecurityEvents.php b/Http/SecurityEvents.php
index a6c4e42..45fae29 100644
--- a/Http/SecurityEvents.php
+++ b/Http/SecurityEvents.php
@@ -13,7 +13,25 @@ namespace Symfony\Component\Security\Http;
final class SecurityEvents
{
+ /**
+ * The INTERACTIVE_LOGIN event occurs after a user is logged in
+ * interactively for authentication based on http, cookies or X509.
+ *
+ * The event listener method receives a
+ * Symfony\Component\Security\Http\Event\InteractiveLoginEvent instance.
+ *
+ * @var string
+ */
const INTERACTIVE_LOGIN = 'security.interactive_login';
+ /**
+ * The SWITCH_USER event occurs before switch to another user and
+ * before exit from an already switched user.
+ *
+ * The event listener method receives a
+ * Symfony\Component\Security\Http\Event\SwitchUserEvent instance.
+ *
+ * @var string
+ */
const SWITCH_USER = 'security.switch_user';
}
diff --git a/Http/Session/SessionAuthenticationStrategyInterface.php b/Http/Session/SessionAuthenticationStrategyInterface.php
index 34f5089..2bc292b 100644
--- a/Http/Session/SessionAuthenticationStrategyInterface.php
+++ b/Http/Session/SessionAuthenticationStrategyInterface.php
@@ -33,5 +33,5 @@ interface SessionAuthenticationStrategyInterface
* @param Request $request
* @param TokenInterface $token
*/
- function onAuthentication(Request $request, TokenInterface $token);
+ public function onAuthentication(Request $request, TokenInterface $token);
}
diff --git a/LICENSE b/LICENSE
index cdffe7a..88a57f8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2012 Fabien Potencier
+Copyright (c) 2004-2013 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 7ae97b1..057f844 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,6 @@ Resources
You can run the unit tests with the following command:
- phpunit
-
-If you also want to run the unit tests that depend on other Symfony
-Components, install dev dependencies before running PHPUnit:
-
- php composer.phar install --dev
+ $ cd path/to/Symfony/Component/Security/
+ $ composer.phar install --dev
+ $ phpunit
diff --git a/Resources/translations/security.ar.xlf b/Resources/translations/security.ar.xlf
new file mode 100644
index 0000000..fd18ee6
--- /dev/null
+++ b/Resources/translations/security.ar.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>ملفات تعريف الارتباط(cookies) تم استخدامها من قبل شخص اخر.</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>رمز الموقع غير صحيح.</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>لا يوجد صلة بينك و بين الموقع اما انها انتهت او ان متصفحك لا يدعم خاصية ملفات تعريف الارتباط (cookies).</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/Resources/translations/security.ca.xlf b/Resources/translations/security.ca.xlf
new file mode 100644
index 0000000..7ece260
--- /dev/null
+++ b/Resources/translations/security.ca.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>Ha succeït un error d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>No s'han trobat les credencials d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La solicitud d'autenticació no s'ha pogut processar per un problema del sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credencials no vàlides.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>La cookie ja ha estat utilitzada per una altra persona.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>No té privilegis per solicitar el recurs.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF no vàlid.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>El vector d'inicialització (digest nonce) ha expirat.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No s'ha trobat un proveïdor d'autenticació que suporti el token d'autenticació.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No hi ha sessió disponible, ha expirat o les cookies no estan habilitades.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No s'ha trobat cap token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>No s'ha trobat el nom d'usuari.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>El compte ha expirat.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Les credencials han expirat.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>El compte està deshabilitat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>El compte està bloquejat.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.cs.xlf b/Resources/translations/security.cs.xlf
new file mode 100644
index 0000000..bd146c6
--- /dev/null
+++ b/Resources/translations/security.cs.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>Při ověřování došlo k chybě.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Ověřovací údaje nebyly nalezeny.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Požadavek na ověření nemohl být zpracován kvůli systémové chybě.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neplatné přihlašovací údaje.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie již bylo použité někým jiným.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemáte oprávnění přistupovat k prostředku.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neplatný CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Platnost inicializačního vektoru (digest nonce) vypršela.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Poskytovatel pro ověřovací token nebyl nalezen.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Session není k dispozici, vypršela její platnost, nebo jsou zakázané cookies.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token nebyl nalezen.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Přihlašovací jméno nebylo nalezeno.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Platnost účtu vypršela.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Platnost přihlašovacích údajů vypršela.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Účet je zakázaný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Účet je zablokovaný.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.da.xlf b/Resources/translations/security.da.xlf
new file mode 100644
index 0000000..9c7b886
--- /dev/null
+++ b/Resources/translations/security.da.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="no" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>En fejl indtraf ved godkendelse.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Loginoplysninger kan findes.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Godkendelsesanmodning kan ikke behandles på grund af et systemfejl.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ugyldige loginoplysninger.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie er allerede brugt af en anden.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Ingen tilladselese at anvende kilden.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ugyldigt CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen godkendelsesudbyder er fundet til understøttelsen af godkendelsestoken.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen session tilgængelig, sessionen er enten udløbet eller cookies er ikke aktiveret.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kan findes.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Brugernavn kan ikke findes.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Brugerkonto er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Loginoplysninger er udløbet.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Brugerkonto er deaktiveret.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Brugerkonto er låst.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.de.xlf b/Resources/translations/security.de.xlf
new file mode 100644
index 0000000..e5946ed
--- /dev/null
+++ b/Resources/translations/security.de.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>Es ist ein Fehler bei der Authentifikation aufgetreten.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Es konnten keine Zugangsdaten gefunden werden.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Die Authentifikation konnte wegen eines Systemproblems nicht bearbeitet werden.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Fehlerhafte Zugangsdaten.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie wurde bereits von jemand anderem verwendet.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Keine Rechte, um die Ressource anzufragen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ungültiges CSRF-Token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce ist abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Es wurde kein Authentifizierungs-Provider gefunden, der das Authentifizierungs-Token unterstützt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Keine Session verfügbar, entweder ist diese abgelaufen oder Cookies sind nicht aktiviert.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Es wurde kein Token gefunden.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Der Benutzername wurde nicht gefunden.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Der Account ist abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Die Zugangsdaten sind abgelaufen.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Der Account ist deaktiviert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Der Account ist gesperrt.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.en.xlf b/Resources/translations/security.en.xlf
new file mode 100644
index 0000000..3640698
--- /dev/null
+++ b/Resources/translations/security.en.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>An authentication exception occurred.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Authentication credentials could not be found.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Authentication request could not be processed due to a system problem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Invalid credentials.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie has already been used by someone else.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Not privileged to request the resource.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Invalid CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce has expired.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No authentication provider found to support the authentication token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No session available, it either timed out or cookies are not enabled.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No token could be found.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username could not be found.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account has expired.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Credentials have expired.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Account is disabled.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Account is locked.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.es.xlf b/Resources/translations/security.es.xlf
new file mode 100644
index 0000000..00cefbb
--- /dev/null
+++ b/Resources/translations/security.es.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>Ocurrió un error de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>No se encontraron las credenciales de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La solicitud de autenticación no se pudo procesar debido a un problema del sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciales no válidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>La cookie ya ha sido usada por otra persona.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>No tiene privilegios para solicitar el recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF no válido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>El vector de inicialización (digest nonce) ha expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>No se encontró un proveedor de autenticación que soporte el token de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>No hay ninguna sesión disponible, ha expirado o las cookies no están habilitados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>No se encontró ningún token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>No se encontró el nombre de usuario.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>La cuenta ha expirado.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Las credenciales han expirado.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>La cuenta está deshabilitada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>La cuenta está bloqueada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.fa.xlf b/Resources/translations/security.fa.xlf
new file mode 100644
index 0000000..0b76290
--- /dev/null
+++ b/Resources/translations/security.fa.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>کوکی قبلا برای شخص دیگری استفاده شده است.</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>جلسه‌ای در دسترس نیست. این میتواند یا به دلیل پایان یافتن زمان باشد یا اینکه کوکی ها فعال نیستند.</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/Resources/translations/security.fr.xlf b/Resources/translations/security.fr.xlf
new file mode 100644
index 0000000..f3965d3
--- /dev/null
+++ b/Resources/translations/security.fr.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>Une exception d'authentification s'est produite.</target>
+ </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>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La requête d'authentification n'a pas pu être executée à cause d'un problème système.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Droits invalides.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Le cookie a déjà été utilisé par quelqu'un d'autre.</target>
+ </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>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Jeton CSRF invalide.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Le digest nonce a expiré.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Aucun fournisseur d'authentification n'a été trouvé pour supporter le jeton d'authentification.</target>
+ </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>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Aucun jeton n'a pu être trouvé.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Le nom d'utilisateur ne peut pas être trouvé.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Le compte a expiré.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Les droits ont expirés.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Le compte est désactivé.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Le compte est bloqué.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.gl.xlf b/Resources/translations/security.gl.xlf
new file mode 100644
index 0000000..ed6491f
--- /dev/null
+++ b/Resources/translations/security.gl.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>Ocorreu un erro de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Non se atoparon as credenciais de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A solicitude de autenticación no puido ser procesada debido a un problema do sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais non válidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>A cookie xa foi empregado por outro usuario.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Non ten privilexios para solicitar o recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF non válido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>O vector de inicialización (digest nonce) expirou.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Non se atopou un provedor de autenticación que soporte o token de autenticación.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Non hai ningunha sesión dispoñible, expirou ou as cookies non están habilitadas.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Non se atopou ningún token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Non se atopou o nome de usuario.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta expirou.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais expiraron.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>A conta está deshabilitada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta está bloqueada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.hu.xlf b/Resources/translations/security.hu.xlf
new file mode 100644
index 0000000..7243970
--- /dev/null
+++ b/Resources/translations/security.hu.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>Hitelesítési hiba lépett fel.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Nem találhatók hitelesítési információk.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A hitelesítési kérést rendszerhiba miatt nem lehet feldolgozni.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Érvénytelen hitelesítési információk.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Ezt a sütit valaki más már felhasználta.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nem rendelkezik az erőforrás eléréséhez szükséges jogosultsággal.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Érvénytelen CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>A kivonat bélyege (nonce) lejárt.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nem található a hitelesítési tokent támogató hitelesítési szolgáltatás.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Munkamenet nem áll rendelkezésre, túllépte az időkeretet vagy a sütik le vannak tiltva.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nem található token.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>A felhasználónév nem található.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A fiók lejárt.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>A hitelesítési információk lejártak.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Felfüggesztett fiók.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Zárolt fiók.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.it.xlf b/Resources/translations/security.it.xlf
new file mode 100644
index 0000000..75d81cc
--- /dev/null
+++ b/Resources/translations/security.it.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>Si è verificato un errore di autenticazione.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Impossibile trovare le credenziali di autenticazione.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>La richiesta di autenticazione non può essere processata a causa di un errore di sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenziali non valide.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Il cookie è già stato usato da qualcun altro.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Non hai i privilegi per richiedere questa risorsa.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF token non valido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Il numero di autenticazione è scaduto.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Non è stato trovato un valido fornitore di autenticazione per supportare il token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Nessuna sessione disponibile, può essere scaduta o i cookie non sono abilitati.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nessun token trovato.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Username non trovato.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account scaduto.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Credenziali scadute.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>L'account è disabilitato.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>L'account è bloccato.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.lb.xlf b/Resources/translations/security.lb.xlf
new file mode 100644
index 0000000..3dc76d5
--- /dev/null
+++ b/Resources/translations/security.lb.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" target-language="lb" datatype="plaintext" original="security.en.xlf">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>Bei der Authentifikatioun ass e Feeler opgetrueden.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Et konnte keng Zouganksdate fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>D'Ufro fir eng Authentifikatioun konnt wéinst engem Problem vum System net beaarbecht ginn.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ongëlteg Zouganksdaten.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>De Cookie gouf scho vun engem anere benotzt.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Keng Rechter fir d'Ressource unzefroen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ongëltegen CSRF-Token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Den eemolege Schlëssel ass ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Et gouf keen Authentifizéierungs-Provider fonnt deen den Authentifizéierungs-Token ënnerstëtzt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Keng Sëtzung disponibel. Entweder ass se ofgelaf oder Cookies sinn net aktivéiert.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Et konnt keen Token fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>De Benotzernumm konnt net fonnt ginn.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Den Account ass ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>D'Zouganksdate sinn ofgelaf.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>De Konto ass deaktivéiert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>De Konto ass gespaart.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.nl.xlf b/Resources/translations/security.nl.xlf
new file mode 100644
index 0000000..8969e9e
--- /dev/null
+++ b/Resources/translations/security.nl.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>Er heeft zich een authenticatieprobleem voorgedaan.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Authenticatiegegevens konden niet worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Authenticatieaanvraag kon niet worden verwerkt door een technisch probleem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ongeldige inloggegevens.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie is al door een ander persoon gebruikt.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Onvoldoende rechten om de aanvraag te verwerken.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>CSRF-code is ongeldig.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Serverauthenticatiesleutel (digest nonce) is verlopen.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Geen authenticatieprovider gevonden die de authenticatietoken ondersteunt.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Geen sessie beschikbaar, mogelijk is deze verlopen of cookies zijn uitgeschakeld.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Er kon geen authenticatietoken worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Gebruikersnaam kon niet worden gevonden.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Account is verlopen.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Authenticatiegegevens zijn verlopen.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Account is gedeactiveerd.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Account is geblokkeerd.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.no.xlf b/Resources/translations/security.no.xlf
new file mode 100644
index 0000000..3857ab4
--- /dev/null
+++ b/Resources/translations/security.no.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="no" datatype="plaintext" original="file.ext">
+ <body>
+ <trans-unit id="1">
+ <source>An authentication exception occurred.</source>
+ <target>En autentiserings feil har skjedd.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Påloggingsinformasjonen kunne ikke bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentiserings forespørselen kunne ikke bli prosessert grunnet en system feil.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Ugyldig påloggingsinformasjonen.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie har allerede blitt brukt av noen andre.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Ingen tilgang til å be om gitt kilde.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ugyldig CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce er utløpt.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen autentiserings tilbyder funnet som støtter gitt autentiserings token.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen sesjon tilgjengelig, sesjonen er enten utløpt eller cookies ikke skrudd på.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kunne bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Brukernavn kunne ikke bli funnet.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Brukerkonto har utgått.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Påloggingsinformasjon har utløpt.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Brukerkonto er deaktivert.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Brukerkonto er sperret.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.pl.xlf b/Resources/translations/security.pl.xlf
new file mode 100644
index 0000000..8d563d2
--- /dev/null
+++ b/Resources/translations/security.pl.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>Wystąpił błąd uwierzytelniania.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Dane uwierzytelniania nie zostały znalezione.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Żądanie uwierzytelniania nie mogło zostać pomyślnie zakończone z powodu problemu z systemem.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Nieprawidłowe dane.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>To ciasteczko jest używane przez kogoś innego.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Brak uprawnień dla żądania wskazanego zasobu.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Nieprawidłowy token CSRF.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Kod dostępu wygasł.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nie znaleziono mechanizmu uwierzytelniania zdolnego do obsługi przesłanego tokenu.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Brak danych sesji, sesja wygasła lub ciasteczka nie są włączone.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nie znaleziono tokenu.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Użytkownik o podanej nazwie nie istnieje.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Konto wygasło.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Dane uwierzytelniania wygasły.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Konto jest wyłączone.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Konto jest zablokowane.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.pt_BR.xlf b/Resources/translations/security.pt_BR.xlf
new file mode 100644
index 0000000..846fd49
--- /dev/null
+++ b/Resources/translations/security.pt_BR.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>Uma exceção ocorreu durante a autenticação.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>As credenciais de autenticação não foram encontradas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>A autenticação não pôde ser concluída devido a um problema no sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais inválidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Este cookie já esta em uso.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Não possui privilégios o bastante para requisitar este recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF inválido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nenhum provedor de autenticação encontrado para suportar o token de autenticação.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Nenhuma sessão disponível, ela expirou ou cookies estão desativados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Nenhum token foi encontrado.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Nome de usuário não encontrado.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta esta expirada.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais estão expiradas.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Conta desativada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta esta travada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.pt_PT.xlf b/Resources/translations/security.pt_PT.xlf
new file mode 100644
index 0000000..e661000
--- /dev/null
+++ b/Resources/translations/security.pt_PT.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>Ocorreu um excepção durante a autenticação.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>As credenciais de autenticação não foram encontradas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>O pedido de autenticação não foi concluído devido a um problema no sistema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Credenciais inválidas.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Este cookie já esta em uso.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Não possui privilégios para aceder a este recurso.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Token CSRF inválido.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Digest nonce expirado.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nenhum fornecedor de autenticação encontrado para suportar o token de autenticação.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Não existe sessão disponível, esta expirou ou os cookies estão desativados.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>O token não foi encontrado.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Nome de utilizador não encontrado.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>A conta expirou.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>As credenciais expiraram.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Conta desativada.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>A conta esta trancada.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.ro.xlf b/Resources/translations/security.ro.xlf
new file mode 100644
index 0000000..440f110
--- /dev/null
+++ b/Resources/translations/security.ro.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>A apărut o eroare de autentificare.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Informațiile de autentificare nu au fost găsite.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Sistemul nu a putut procesa cererea de autentificare din cauza unei erori.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Date de autentificare invalide.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookieul este folosit deja de altcineva.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Permisiuni insuficiente pentru resursa cerută.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Tokenul CSRF este invalid.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Tokenul temporar a expirat.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Nu a fost găsit nici un agent de autentificare pentru tokenul specificat.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesiunea nu mai este disponibilă, a expirat sau suportul pentru cookieuri nu este activat.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Tokenul nu a putut fi găsit.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Numele de utilizator nu a fost găsit.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Contul a expirat.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Datele de autentificare au expirat.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Contul este dezactivat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Contul este blocat.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.ru.xlf b/Resources/translations/security.ru.xlf
new file mode 100644
index 0000000..1964f95
--- /dev/null
+++ b/Resources/translations/security.ru.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>Время действия одноразового ключа дайджеста истекло.</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>Сессия не найдена, ее время истекло, либо cookies не включены.</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/Resources/translations/security.sk.xlf b/Resources/translations/security.sk.xlf
new file mode 100644
index 0000000..e6552a6
--- /dev/null
+++ b/Resources/translations/security.sk.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>Pri overovaní došlo k chybe.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Overovacie údaje neboli nájdené.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Požiadavok na overenie nemohol byť spracovaný kvôli systémovej chybe.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neplatné prihlasovacie údaje.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookie už bolo použité niekým iným.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemáte oprávnenie pristupovať k prostriedku.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neplatný CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Platnosť inicializačného vektoru (digest nonce) skončila.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Poskytovateľ pre overovací token nebol nájdený.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Session nie je k dispozíci, vypršala jej platnosť, alebo sú zakázané cookies.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token nebol nájdený.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Prihlasovacie meno nebolo nájdené.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Platnosť účtu skončila.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Platnosť prihlasovacích údajov skončila.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Účet je zakázaný.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Účet je zablokovaný.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.sl.xlf b/Resources/translations/security.sl.xlf
new file mode 100644
index 0000000..ee70c9a
--- /dev/null
+++ b/Resources/translations/security.sl.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>Prišlo je do izjeme pri preverjanju avtentikacije.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Poverilnic za avtentikacijo ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Zahteve za avtentikacijo ni bilo mogoče izvesti zaradi sistemske težave.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Neveljavne pravice.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Piškotek je uporabil že nekdo drug.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nimate privilegijev za zahtevani vir.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Neveljaven CSRF žeton.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Začasni žeton je potekel.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ponudnika avtentikacije za podporo prijavnega žetona ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Seja ni na voljo, ali je potekla ali pa piškotki niso omogočeni.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Žetona ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Uporabniškega imena ni bilo mogoče najti.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Račun je potekel.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Poverilnice so potekle.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Račun je onemogočen.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Račun je zaklenjen.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.sr_Cyrl.xlf b/Resources/translations/security.sr_Cyrl.xlf
new file mode 100644
index 0000000..35e4ddf
--- /dev/null
+++ b/Resources/translations/security.sr_Cyrl.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>Колачић је већ искоришћен од стране неког другог.</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>Време криптографског кључа је истекло.</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>Сесија није доступна, истекла је или су колачићи искључени.</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/Resources/translations/security.sr_Latn.xlf b/Resources/translations/security.sr_Latn.xlf
new file mode 100644
index 0000000..ddc4807
--- /dev/null
+++ b/Resources/translations/security.sr_Latn.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>Izuzetak pri autentifikaciji.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Autentifikacioni podaci nisu pronađeni.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Zahtev za autentifikaciju ne može biti obrađen zbog sistemskih problema.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Nevalidni podaci za autentifikaciju.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Kolačić je već iskorišćen od strane nekog drugog.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Nemate prava pristupa ovom resursu.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Nevalidan CSRF token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Vreme kriptografskog ključa je isteklo.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Autentifikacioni provajder za podršku tokena nije pronađen.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Sesija nije dostupna, istekla je ili su kolačići isključeni.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Token ne može biti pronađen.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Korisničko ime ne može biti pronađeno.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Nalog je istekao.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Podaci za autentifikaciju su istekli.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Nalog je onemogućen.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Nalog je zaključan.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.sv.xlf b/Resources/translations/security.sv.xlf
new file mode 100644
index 0000000..b5f6209
--- /dev/null
+++ b/Resources/translations/security.sv.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>Ett autentiseringsfel har inträffat.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Uppgifterna för autentisering kunde inte hittas.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Autentiseringen kunde inte genomföras på grund av systemfel.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Felaktiga uppgifter.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Cookien har redan använts av någon annan.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Saknar rättigheter för resursen.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Ogiltig CSRF-token.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Förfallen digest nonce.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Ingen leverantör för autentisering hittades för angiven autentiseringstoken.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Ingen session finns tillgänglig, antingen har den förfallit eller är cookies inte aktiverat.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Ingen token kunde hittas.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Användarnamnet kunde inte hittas.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Kontot har förfallit.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Uppgifterna har förfallit.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Kontot är inaktiverat.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Kontot är låst.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.tr.xlf b/Resources/translations/security.tr.xlf
new file mode 100644
index 0000000..fbf9b26
--- /dev/null
+++ b/Resources/translations/security.tr.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>Bir yetkilendirme istisnası oluştu.</target>
+ </trans-unit>
+ <trans-unit id="2">
+ <source>Authentication credentials could not be found.</source>
+ <target>Yetkilendirme girdileri bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="3">
+ <source>Authentication request could not be processed due to a system problem.</source>
+ <target>Bir sistem hatası nedeniyle yetkilendirme isteği işleme alınamıyor.</target>
+ </trans-unit>
+ <trans-unit id="4">
+ <source>Invalid credentials.</source>
+ <target>Geçersiz girdiler.</target>
+ </trans-unit>
+ <trans-unit id="5">
+ <source>Cookie has already been used by someone else.</source>
+ <target>Çerez bir başkası tarafından zaten kullanılmıştı.</target>
+ </trans-unit>
+ <trans-unit id="6">
+ <source>Not privileged to request the resource.</source>
+ <target>Kaynak talebi için imtiyaz bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="7">
+ <source>Invalid CSRF token.</source>
+ <target>Geçersiz CSRF fişi.</target>
+ </trans-unit>
+ <trans-unit id="8">
+ <source>Digest nonce has expired.</source>
+ <target>Derleme zaman aşımı gerçekleşti.</target>
+ </trans-unit>
+ <trans-unit id="9">
+ <source>No authentication provider found to support the authentication token.</source>
+ <target>Yetkilendirme fişini destekleyecek yetkilendirme sağlayıcısı bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="10">
+ <source>No session available, it either timed out or cookies are not enabled.</source>
+ <target>Oturum bulunamadı, zaman aşımına uğradı veya çerezler etkin değil.</target>
+ </trans-unit>
+ <trans-unit id="11">
+ <source>No token could be found.</source>
+ <target>Bilet bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="12">
+ <source>Username could not be found.</source>
+ <target>Kullanıcı adı bulunamadı.</target>
+ </trans-unit>
+ <trans-unit id="13">
+ <source>Account has expired.</source>
+ <target>Hesap zaman aşımına uğradı.</target>
+ </trans-unit>
+ <trans-unit id="14">
+ <source>Credentials have expired.</source>
+ <target>Girdiler zaman aşımına uğradı.</target>
+ </trans-unit>
+ <trans-unit id="15">
+ <source>Account is disabled.</source>
+ <target>Hesap devre dışı bırakılmış.</target>
+ </trans-unit>
+ <trans-unit id="16">
+ <source>Account is locked.</source>
+ <target>Hesap kilitlenmiş.</target>
+ </trans-unit>
+ </body>
+ </file>
+</xliff>
diff --git a/Resources/translations/security.ua.xlf b/Resources/translations/security.ua.xlf
new file mode 100644
index 0000000..7972121
--- /dev/null
+++ b/Resources/translations/security.ua.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>Хтось інший вже використав цей сookie.</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>Закінчився термін дії одноразового ключа дайджесту.</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>Сесія недоступна, її час вийшов, або cookies вимкнено.</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/AclProviderTest.php b/Tests/Acl/Dbal/AclProviderTest.php
index e03edc0..83771ee 100644
--- a/Tests/Acl/Dbal/AclProviderTest.php
+++ b/Tests/Acl/Dbal/AclProviderTest.php
@@ -27,7 +27,7 @@ class AclProviderTest extends \PHPUnit_Framework_TestCase
protected $insertSidStmt;
/**
- * @expectedException Symfony\Component\Security\Acl\Exception\AclNotFoundException
+ * @expectedException \Symfony\Component\Security\Acl\Exception\AclNotFoundException
* @expectedMessage There is no ACL for the given object identity.
*/
public function testFindAclThrowsExceptionWhenNoAclExists()
diff --git a/Tests/Acl/Dbal/MutableAclProviderTest.php b/Tests/Acl/Dbal/MutableAclProviderTest.php
index e264b6d..3e8d65f 100644
--- a/Tests/Acl/Dbal/MutableAclProviderTest.php
+++ b/Tests/Acl/Dbal/MutableAclProviderTest.php
@@ -53,7 +53,7 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException
+ * @expectedException \Symfony\Component\Security\Acl\Exception\AclAlreadyExistsException
*/
public function testCreateAclThrowsExceptionWhenAclAlreadyExists()
{
@@ -267,7 +267,7 @@ class MutableAclProviderTest extends \PHPUnit_Framework_TestCase
$provider->updateAcl($acl);
}
- public function testUpdateAclThrowsExceptionOnConcurrentModifcationOfSharedProperties()
+ public function testUpdateAclThrowsExceptionOnConcurrentModificationOfSharedProperties()
{
$provider = $this->getProvider();
$acl1 = $provider->createAcl(new ObjectIdentity(1, 'Foo'));
diff --git a/Tests/Acl/Domain/AclTest.php b/Tests/Acl/Domain/AclTest.php
index b6f3d79..4b67e62 100644
--- a/Tests/Acl/Domain/AclTest.php
+++ b/Tests/Acl/Domain/AclTest.php
@@ -433,7 +433,7 @@ class AclTest extends \PHPUnit_Framework_TestCase
* @expectedException \InvalidArgumentException
* @dataProvider getUpdateFieldAuditingTests
*/
- public function testUpdateFieldAuditingthrowsExceptionOnInvalidField($type)
+ public function testUpdateFieldAuditingThrowsExceptionOnInvalidField($type)
{
$acl = $this->getAcl();
$acl->{'update'.$type.'Auditing'}(0, 'foo', true, true);
diff --git a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php b/Tests/Acl/Domain/PermissionGrantingStrategyTest.php
index 67c9f3f..d200d2b 100644
--- a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php
+++ b/Tests/Acl/Domain/PermissionGrantingStrategyTest.php
@@ -31,7 +31,7 @@ class PermissionGrantingStrategyTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($strategy->isGranted($acl, array(1), array($sid)));
}
- public function testIsGrantedFallsbackToClassAcesIfNoApplicableObjectAceWasFound()
+ public function testIsGrantedFallsBackToClassAcesIfNoApplicableObjectAceWasFound()
{
$strategy = new PermissionGrantingStrategy();
$acl = $this->getAcl($strategy);
@@ -73,7 +73,7 @@ class PermissionGrantingStrategyTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Acl\Exception\NoAceFoundException
+ * @expectedException \Symfony\Component\Security\Acl\Exception\NoAceFoundException
*/
public function testIsGrantedReturnsExceptionIfNoAceIsFound()
{
diff --git a/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php b/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php
index 2083728..f649653 100644
--- a/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php
+++ b/Tests/Acl/Domain/SecurityIdentityRetrievalStrategyTest.php
@@ -116,7 +116,6 @@ class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
->will($this->returnValue($username))
;
-
return $account;
}
@@ -177,7 +176,6 @@ class SecurityIdentityRetrievalStrategyTest extends \PHPUnit_Framework_TestCase
;
}
-
return new SecurityIdentityRetrievalStrategy($roleHierarchy, $trustResolver);
}
}
diff --git a/Tests/Acl/Domain/UserSecurityIdentityTest.php b/Tests/Acl/Domain/UserSecurityIdentityTest.php
index 9650803..1d6a3c5 100644
--- a/Tests/Acl/Domain/UserSecurityIdentityTest.php
+++ b/Tests/Acl/Domain/UserSecurityIdentityTest.php
@@ -25,7 +25,7 @@ class UserSecurityIdentityTest extends \PHPUnit_Framework_TestCase
}
// Test that constructor never changes the type, even for proxies
- public function testContructorWithProxy()
+ public function testConstructorWithProxy()
{
$id = new UserSecurityIdentity('foo', 'Acme\DemoBundle\Proxy\__CG__\Symfony\Component\Security\Tests\Acl\Domain\Foo');
diff --git a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php b/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
index c57967b..12eb568 100644
--- a/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
+++ b/Tests/Core/Authentication/AuthenticationProviderManagerTest.php
@@ -37,7 +37,7 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
$manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
$this->fail();
} catch (ProviderNotFoundException $e) {
- $this->assertSame($token, $e->getExtraInformation());
+ $this->assertSame($token, $e->getToken());
}
}
@@ -51,7 +51,7 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
$manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
$this->fail();
} catch (AccountStatusException $e) {
- $this->assertSame($token, $e->getExtraInformation());
+ $this->assertSame($token, $e->getToken());
}
}
@@ -65,7 +65,7 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase
$manager->authenticate($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
$this->fail();
} catch (AuthenticationException $e) {
- $this->assertSame($token, $e->getExtraInformation());
+ $this->assertSame($token, $e->getToken());
}
}
diff --git a/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php b/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php
index 0a76724..d0da147 100644
--- a/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php
+++ b/Tests/Core/Authentication/Provider/AnonymousAuthenticationProviderTest.php
@@ -31,7 +31,7 @@ class AnonymousAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testAuthenticateWhenKeyIsNotValid()
{
diff --git a/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php b/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php
index 8bff354..8b27061 100644
--- a/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php
+++ b/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php
@@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Tests\Core\Authentication\Provider;
-
use Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder;
use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider;
@@ -19,7 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationPro
class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
{
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationServiceException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException
*/
public function testRetrieveUserWhenProviderDoesNotReturnAnUserInterface()
{
@@ -31,7 +30,7 @@ class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testRetrieveUserWhenUsernameIsNotFound()
{
@@ -49,7 +48,7 @@ class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationServiceException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException
*/
public function testRetrieveUserWhenAnExceptionOccurs()
{
@@ -106,7 +105,7 @@ class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testCheckAuthenticationWhenCredentialsAreEmpty()
{
@@ -162,7 +161,7 @@ class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testCheckAuthenticationWhenCredentialsAreNotValid()
{
@@ -186,7 +185,7 @@ class DaoAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testCheckAuthenticationDoesNotReauthenticateWhenPasswordHasChanged()
{
diff --git a/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php b/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
index 9476c0d..f7ffb1e 100644
--- a/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
+++ b/Tests/Core/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php
@@ -42,7 +42,7 @@ class PreAuthenticatedAuthenticationProviderTest extends \PHPUnit_Framework_Test
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testAuthenticateWhenNoUserIsSet()
{
@@ -70,7 +70,7 @@ class PreAuthenticatedAuthenticationProviderTest extends \PHPUnit_Framework_Test
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\LockedException
+ * @expectedException \Symfony\Component\Security\Core\Exception\LockedException
*/
public function testAuthenticateWhenUserCheckerThrowsException()
{
diff --git a/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php b/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php
index fcc2514..5e250e0 100644
--- a/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php
+++ b/Tests/Core/Authentication/Provider/RememberMeAuthenticationProviderTest.php
@@ -34,7 +34,7 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testAuthenticateWhenKeysDoNotMatch()
{
@@ -45,7 +45,7 @@ class RememberMeAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AccountExpiredException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException
*/
public function testAuthenticateWhenPostChecksFails()
{
diff --git a/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php b/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php
index 1b68531..1516a5f 100644
--- a/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php
+++ b/Tests/Core/Authentication/Provider/UserAuthenticationProviderTest.php
@@ -33,7 +33,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testAuthenticateWhenUsernameIsNotFound()
{
@@ -47,7 +47,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
*/
public function testAuthenticateWhenUsernameIsNotFoundAndHideIsTrue()
{
@@ -61,7 +61,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationServiceException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationServiceException
*/
public function testAuthenticateWhenProviderDoesNotReturnAnUserInterface()
{
@@ -75,7 +75,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\CredentialsExpiredException
+ * @expectedException \Symfony\Component\Security\Core\Exception\CredentialsExpiredException
*/
public function testAuthenticateWhenPreChecksFails()
{
@@ -95,7 +95,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AccountExpiredException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException
*/
public function testAuthenticateWhenPostChecksFails()
{
@@ -115,7 +115,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
* @expectedExceptionMessage Bad credentials
*/
public function testAuthenticateWhenPostCheckAuthenticationFails()
@@ -134,7 +134,7 @@ class UserAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\BadCredentialsException
+ * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
* @expectedExceptionMessage Foo
*/
public function testAuthenticateWhenPostCheckAuthenticationFailsWithHideFalse()
diff --git a/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php b/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php
index 3944fb1..1739714 100644
--- a/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php
+++ b/Tests/Core/Authentication/RememberMe/InMemoryTokenProviderTest.php
@@ -27,7 +27,7 @@ class InMemoryTokenProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\TokenNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\TokenNotFoundException
*/
public function testLoadTokenBySeriesThrowsNotFoundException()
{
@@ -49,7 +49,7 @@ class InMemoryTokenProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\TokenNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\TokenNotFoundException
*/
public function testDeleteToken()
{
diff --git a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
new file mode 100644
index 0000000..bfaf5fc
--- /dev/null
+++ b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php
@@ -0,0 +1,112 @@
+<?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\Core\Encoder;
+
+use Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder;
+
+/**
+ * @author Elnur Abdurrakhimov <elnur@elnur.pro>
+ */
+class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase
+{
+ const PASSWORD = 'password';
+ const BYTES = '0123456789abcdef';
+ const VALID_COST = '04';
+
+ const SECURE_RANDOM_INTERFACE = 'Symfony\Component\Security\Core\Util\SecureRandomInterface';
+
+ /**
+ * @var \PHPUnit_Framework_MockObject_MockObject
+ */
+ private $secureRandom;
+
+ protected function setUp()
+ {
+ $this->secureRandom = $this->getMock(self::SECURE_RANDOM_INTERFACE);
+
+ $this->secureRandom
+ ->expects($this->any())
+ ->method('nextBytes')
+ ->will($this->returnValue(self::BYTES))
+ ;
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testCostBelowRange()
+ {
+ new BCryptPasswordEncoder($this->secureRandom, 3);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testCostAboveRange()
+ {
+ new BCryptPasswordEncoder($this->secureRandom, 32);
+ }
+
+ public function testCostInRange()
+ {
+ for ($cost = 4; $cost <= 31; $cost++) {
+ new BCryptPasswordEncoder($this->secureRandom, $cost);
+ }
+ }
+
+ public function testResultLength()
+ {
+ $encoder = new BCryptPasswordEncoder($this->secureRandom, self::VALID_COST);
+ $result = $encoder->encodePassword(self::PASSWORD, null);
+ $this->assertEquals(60, strlen($result));
+ }
+
+ public function testValidation()
+ {
+ $encoder = new BCryptPasswordEncoder($this->secureRandom, self::VALID_COST);
+ $result = $encoder->encodePassword(self::PASSWORD, null);
+ $this->assertTrue($encoder->isPasswordValid($result, self::PASSWORD, null));
+ $this->assertFalse($encoder->isPasswordValid($result, 'anotherPassword', null));
+ }
+
+ public function testValidationKnownPassword()
+ {
+ $encoder = new BCryptPasswordEncoder($this->secureRandom, self::VALID_COST);
+ $prefix = '$'.(version_compare(phpversion(), '5.3.7', '>=')
+ ? '2y' : '2a').'$';
+
+ $encrypted = $prefix.'04$ABCDEFGHIJKLMNOPQRSTU.uTmwd4KMSHxbUsG7bng8x7YdA0PM1iq';
+ $this->assertTrue($encoder->isPasswordValid($encrypted, self::PASSWORD, null));
+ }
+
+ public function testSecureRandomIsUsed()
+ {
+ if (function_exists('mcrypt_create_iv')) {
+ return;
+ }
+
+ $this->secureRandom
+ ->expects($this->atLeastOnce())
+ ->method('nextBytes')
+ ;
+
+ $encoder = new BCryptPasswordEncoder($this->secureRandom, self::VALID_COST);
+ $result = $encoder->encodePassword(self::PASSWORD, null);
+
+ $prefix = '$'.(version_compare(phpversion(), '5.3.7', '>=')
+ ? '2y' : '2a').'$';
+ $salt = 'MDEyMzQ1Njc4OWFiY2RlZe';
+ $expected = crypt(self::PASSWORD, $prefix . self::VALID_COST . '$' . $salt);
+
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
new file mode 100644
index 0000000..2c98543
--- /dev/null
+++ b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php
@@ -0,0 +1,45 @@
+<?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\Core\Encoder;
+
+use Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder;
+
+class Pbkdf2PasswordEncoderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testIsPasswordValid()
+ {
+ $encoder = new Pbkdf2PasswordEncoder('sha256', false, 1, 40);
+
+ $this->assertTrue($encoder->isPasswordValid('c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab106974c75607c8a3', 'password', ''));
+ }
+
+ public function testEncodePassword()
+ {
+ $encoder = new Pbkdf2PasswordEncoder('sha256', false, 1, 40);
+ $this->assertSame('c1232f10f62715fda06ae7c0a2037ca19b33cf103b727ba56d870c11f290a2ab106974c75607c8a3', $encoder->encodePassword('password', ''));
+
+ $encoder = new Pbkdf2PasswordEncoder('sha256', true, 1, 40);
+ $this->assertSame('wSMvEPYnFf2gaufAogN8oZszzxA7cnulbYcMEfKQoqsQaXTHVgfIow==', $encoder->encodePassword('password', ''));
+
+ $encoder = new Pbkdf2PasswordEncoder('sha256', false, 2, 40);
+ $this->assertSame('8bc2f9167a81cdcfad1235cd9047f1136271c1f978fcfcb35e22dbeafa4634f6fd2214218ed63ebb', $encoder->encodePassword('password', ''));
+ }
+
+ /**
+ * @expectedException LogicException
+ */
+ public function testEncodePasswordAlgorithmDoesNotExist()
+ {
+ $encoder = new Pbkdf2PasswordEncoder('foobar');
+ $encoder->encodePassword('password', '');
+ }
+}
diff --git a/Tests/Core/SecurityContextTest.php b/Tests/Core/SecurityContextTest.php
index 66a4b13..124ebf9 100644
--- a/Tests/Core/SecurityContextTest.php
+++ b/Tests/Core/SecurityContextTest.php
@@ -41,7 +41,7 @@ class SecurityContextTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testVoteWithoutAuthenticationToken()
{
diff --git a/Tests/Core/User/AccountCheckerTest.php b/Tests/Core/User/AccountCheckerTest.php
index 315e0d4..f28067f 100644
--- a/Tests/Core/User/AccountCheckerTest.php
+++ b/Tests/Core/User/AccountCheckerTest.php
@@ -33,7 +33,7 @@ class UserCheckerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\CredentialsExpiredException
+ * @expectedException \Symfony\Component\Security\Core\Exception\CredentialsExpiredException
*/
public function testCheckPreAuthCredentialsExpired()
{
@@ -65,7 +65,7 @@ class UserCheckerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\LockedException
+ * @expectedException \Symfony\Component\Security\Core\Exception\LockedException
*/
public function testCheckPostAuthAccountLocked()
{
@@ -78,7 +78,7 @@ class UserCheckerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\DisabledException
+ * @expectedException \Symfony\Component\Security\Core\Exception\DisabledException
*/
public function testCheckPostAuthDisabled()
{
@@ -92,7 +92,7 @@ class UserCheckerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AccountExpiredException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AccountExpiredException
*/
public function testCheckPostAuthAccountExpired()
{
diff --git a/Tests/Core/User/ChainUserProviderTest.php b/Tests/Core/User/ChainUserProviderTest.php
index 5edbbed..0fddcd6 100644
--- a/Tests/Core/User/ChainUserProviderTest.php
+++ b/Tests/Core/User/ChainUserProviderTest.php
@@ -42,7 +42,7 @@ class ChainUserProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testLoadUserByUsernameThrowsUsernameNotFoundException()
{
@@ -107,7 +107,7 @@ class ChainUserProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\UnsupportedUserException
+ * @expectedException \Symfony\Component\Security\Core\Exception\UnsupportedUserException
*/
public function testRefreshUserThrowsUnsupportedUserException()
{
diff --git a/Tests/Core/User/InMemoryProviderTest.php b/Tests/Core/User/InMemoryProviderTest.php
index 9230be4..5197a29 100644
--- a/Tests/Core/User/InMemoryProviderTest.php
+++ b/Tests/Core/User/InMemoryProviderTest.php
@@ -52,7 +52,7 @@ class InMemoryUserProviderTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\UsernameNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
*/
public function testLoadUserByUsernameDoesNotExist()
{
diff --git a/Tests/Core/Util/ClassUtilsTest.php b/Tests/Core/Util/ClassUtilsTest.php
index 16378a6..8359236 100644
--- a/Tests/Core/Util/ClassUtilsTest.php
+++ b/Tests/Core/Util/ClassUtilsTest.php
@@ -1,12 +1,21 @@
<?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\Core\Util
{
use Symfony\Component\Security\Core\Util\ClassUtils;
class ClassUtilsTest extends \PHPUnit_Framework_TestCase
{
- static public function dataGetClass()
+ public static function dataGetClass()
{
return array(
array('stdClass', 'stdClass'),
diff --git a/Tests/Core/Util/SecureRandomTest.php b/Tests/Core/Util/SecureRandomTest.php
new file mode 100755
index 0000000..c7ed016
--- /dev/null
+++ b/Tests/Core/Util/SecureRandomTest.php
@@ -0,0 +1,201 @@
+<?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\Core\Util;
+
+use Symfony\Component\Security\Core\Util\SecureRandom;
+
+class SecureRandomTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * T1: Monobit test
+ *
+ * @dataProvider getSecureRandoms
+ */
+ public function testMonobit($secureRandom)
+ {
+ $nbOnBits = substr_count($this->getBitSequence($secureRandom, 20000), '1');
+ $this->assertTrue($nbOnBits > 9654 && $nbOnBits < 10346, 'Monobit test failed, number of turned on bits: '.$nbOnBits);
+ }
+
+ /**
+ * T2: Chi-square test with 15 degrees of freedom (chi-Quadrat-Anpassungstest)
+ *
+ * @dataProvider getSecureRandoms
+ */
+ public function testPoker($secureRandom)
+ {
+ $b = $this->getBitSequence($secureRandom, 20000);
+ $c = array();
+ for ($i = 0; $i <= 15; $i++) {
+ $c[$i] = 0;
+ }
+
+ for ($j = 1; $j <= 5000; $j++) {
+ $k = 4 * $j - 1;
+ $c[8 * $b[$k - 3] + 4 * $b[$k - 2] + 2 * $b[$k - 1] + $b[$k]] += 1;
+ }
+
+ $f = 0;
+ for ($i = 0; $i <= 15; $i++) {
+ $f += $c[$i] * $c[$i];
+ }
+
+ $Y = 16/5000 * $f - 5000;
+
+ $this->assertTrue($Y > 1.03 && $Y < 57.4, 'Poker test failed, Y = '.$Y);
+ }
+
+ /**
+ * Run test
+ *
+ * @dataProvider getSecureRandoms
+ */
+ public function testRun($secureRandom)
+ {
+ $b = $this->getBitSequence($secureRandom, 20000);
+
+ $runs = array();
+ for ($i = 1; $i <= 6; $i++) {
+ $runs[$i] = 0;
+ }
+
+ $addRun = function($run) use (&$runs) {
+ if ($run > 6) {
+ $run = 6;
+ }
+
+ $runs[$run] += 1;
+ };
+
+ $currentRun = 0;
+ $lastBit = null;
+ for ($i = 0; $i < 20000; $i++) {
+ if ($lastBit === $b[$i]) {
+ $currentRun += 1;
+ } else {
+ if ($currentRun > 0) {
+ $addRun($currentRun);
+ }
+
+ $lastBit = $b[$i];
+ $currentRun = 0;
+ }
+ }
+ if ($currentRun > 0) {
+ $addRun($currentRun);
+ }
+
+ $this->assertTrue($runs[1] > 2267 && $runs[1] < 2733, 'Runs of length 1 outside of defined interval: '.$runs[1]);
+ $this->assertTrue($runs[2] > 1079 && $runs[2] < 1421, 'Runs of length 2 outside of defined interval: '.$runs[2]);
+ $this->assertTrue($runs[3] > 502 && $runs[3] < 748, 'Runs of length 3 outside of defined interval: '.$runs[3]);
+ $this->assertTrue($runs[4] > 233 && $runs[4] < 402, 'Runs of length 4 outside of defined interval: '.$runs[4]);
+ $this->assertTrue($runs[5] > 90 && $runs[5] < 223, 'Runs of length 5 outside of defined interval: '.$runs[5]);
+ $this->assertTrue($runs[6] > 90 && $runs[6] < 233, 'Runs of length 6 outside of defined interval: '.$runs[6]);
+ }
+
+ /**
+ * Long-run test
+ *
+ * @dataProvider getSecureRandoms
+ */
+ public function testLongRun($secureRandom)
+ {
+ $b = $this->getBitSequence($secureRandom, 20000);
+
+ $longestRun = 0;
+ $currentRun = $lastBit = null;
+ for ($i = 0; $i < 20000; $i++) {
+ if ($lastBit === $b[$i]) {
+ $currentRun += 1;
+ } else {
+ if ($currentRun > $longestRun) {
+ $longestRun = $currentRun;
+ }
+ $lastBit = $b[$i];
+ $currentRun = 0;
+ }
+ }
+ if ($currentRun > $longestRun) {
+ $longestRun = $currentRun;
+ }
+
+ $this->assertTrue($longestRun < 34, 'Failed longest run test: '.$longestRun);
+ }
+
+ /**
+ * Serial Correlation (Autokorrelationstest)
+ *
+ * @dataProvider getSecureRandoms
+ */
+ public function testSerialCorrelation($secureRandom)
+ {
+ $shift = rand(1, 5000);
+ $b = $this->getBitSequence($secureRandom, 20000);
+
+ $Z = 0;
+ for ($i = 0; $i < 5000; $i++) {
+ $Z += $b[$i] === $b[$i + $shift] ? 1 : 0;
+ }
+
+ $this->assertTrue($Z > 2326 && $Z < 2674, 'Failed serial correlation test: '.$Z);
+ }
+
+ public function getSecureRandoms()
+ {
+ $secureRandoms = array();
+
+ // only add if openssl is indeed present
+ $secureRandom = new SecureRandom();
+ if ($this->hasOpenSsl($secureRandom)) {
+ $secureRandoms[] = array($secureRandom);
+ }
+
+ // no-openssl with custom seed provider
+ $secureRandom = new SecureRandom(sys_get_temp_dir().'/_sf2.seed');
+ $this->disableOpenSsl($secureRandom);
+ $secureRandoms[] = array($secureRandom);
+
+ return $secureRandoms;
+ }
+
+ protected function disableOpenSsl($secureRandom)
+ {
+ $ref = new \ReflectionProperty($secureRandom, 'useOpenSsl');
+ $ref->setAccessible(true);
+ $ref->setValue($secureRandom, false);
+ $ref->setAccessible(false);
+ }
+
+ protected function hasOpenSsl($secureRandom)
+ {
+ $ref = new \ReflectionProperty($secureRandom, 'useOpenSsl');
+ $ref->setAccessible(true);
+
+ $ret = $ref->getValue($secureRandom);
+
+ $ref->setAccessible(false);
+
+ return $ret;
+ }
+
+ private function getBitSequence($secureRandom, $length)
+ {
+ $bitSequence = '';
+ for ($i = 0; $i < $length; $i += 40) {
+ $value = unpack('H*', $secureRandom->nextBytes(5));
+ $value = str_pad(base_convert($value[1], 16, 2), 40, '0', STR_PAD_LEFT);
+ $bitSequence .= $value;
+ }
+
+ return substr($bitSequence, 0, $length);
+ }
+}
diff --git a/Tests/Core/Util/StringUtilsTest.php b/Tests/Core/Util/StringUtilsTest.php
new file mode 100755
index 0000000..aac4139
--- /dev/null
+++ b/Tests/Core/Util/StringUtilsTest.php
@@ -0,0 +1,23 @@
+<?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\Core\Util;
+
+use Symfony\Component\Security\Core\Util\StringUtils;
+
+class StringUtilsTest extends \PHPUnit_Framework_TestCase
+{
+ public function testEquals()
+ {
+ $this->assertTrue(StringUtils::equals('password', 'password'));
+ $this->assertFalse(StringUtils::equals('password', 'foo'));
+ }
+}
diff --git a/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php b/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php
new file mode 100644
index 0000000..c3a8370
--- /dev/null
+++ b/Tests/Core/Validator/Constraints/UserPasswordValidatorTest.php
@@ -0,0 +1,161 @@
+<?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\Core\Validator\Constraints;
+
+use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
+use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator;
+
+class UserPasswordValidatorTest extends \PHPUnit_Framework_TestCase
+{
+ const PASSWORD_VALID = true;
+ const PASSWORD_INVALID = false;
+
+ protected $context;
+
+ protected function setUp()
+ {
+ if (false === class_exists('Symfony\Component\Validator\Validator')) {
+ $this->markTestSkipped('The Validator component is required for this test.');
+ }
+
+ $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+ }
+
+ protected function tearDown()
+ {
+ $this->context = null;
+ }
+
+ public function testPasswordIsValid()
+ {
+ $user = $this->createUser();
+ $securityContext = $this->createSecurityContext($user);
+
+ $encoder = $this->createPasswordEncoder(static::PASSWORD_VALID);
+ $encoderFactory = $this->createEncoderFactory($encoder);
+
+ $validator = new UserPasswordValidator($securityContext, $encoderFactory);
+ $validator->initialize($this->context);
+
+ $this
+ ->context
+ ->expects($this->never())
+ ->method('addViolation')
+ ;
+
+ $validator->validate('secret', new UserPassword());
+ }
+
+ public function testPasswordIsNotValid()
+ {
+ $user = $this->createUser();
+ $securityContext = $this->createSecurityContext($user);
+
+ $encoder = $this->createPasswordEncoder(static::PASSWORD_INVALID);
+ $encoderFactory = $this->createEncoderFactory($encoder);
+
+ $validator = new UserPasswordValidator($securityContext, $encoderFactory);
+ $validator->initialize($this->context);
+
+ $this
+ ->context
+ ->expects($this->once())
+ ->method('addViolation')
+ ;
+
+ $validator->validate('secret', new UserPassword());
+ }
+
+ public function testUserIsNotValid()
+ {
+ $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+ $user = $this->getMock('Foo\Bar\User');
+ $encoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
+ $securityContext = $this->createSecurityContext($user);
+
+ $validator = new UserPasswordValidator($securityContext, $encoderFactory);
+ $validator->initialize($this->context);
+ $validator->validate('secret', new UserPassword());
+ }
+
+ protected function createUser()
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
+
+ $mock
+ ->expects($this->once())
+ ->method('getPassword')
+ ->will($this->returnValue('s3Cr3t'))
+ ;
+
+ $mock
+ ->expects($this->once())
+ ->method('getSalt')
+ ->will($this->returnValue('^S4lt$'))
+ ;
+
+ return $mock;
+ }
+
+ protected function createPasswordEncoder($isPasswordValid = true)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
+
+ $mock
+ ->expects($this->once())
+ ->method('isPasswordValid')
+ ->will($this->returnValue($isPasswordValid))
+ ;
+
+ return $mock;
+ }
+
+ protected function createEncoderFactory($encoder = null)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
+
+ $mock
+ ->expects($this->once())
+ ->method('getEncoder')
+ ->will($this->returnValue($encoder))
+ ;
+
+ return $mock;
+ }
+
+ protected function createSecurityContext($user = null)
+ {
+ $token = $this->createAuthenticationToken($user);
+
+ $mock = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $mock
+ ->expects($this->once())
+ ->method('getToken')
+ ->will($this->returnValue($token))
+ ;
+
+ return $mock;
+ }
+
+ protected function createAuthenticationToken($user = null)
+ {
+ $mock = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $mock
+ ->expects($this->once())
+ ->method('getUser')
+ ->will($this->returnValue($user))
+ ;
+
+ return $mock;
+ }
+}
diff --git a/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php b/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php
index b442309..b9e289d 100644
--- a/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php
+++ b/Tests/Http/EntryPoint/BasicAuthenticationEntryPointTest.php
@@ -34,7 +34,6 @@ class BasicAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
$this->assertEquals(401, $response->getStatusCode());
- $this->assertAttributeEquals('The exception message', 'statusText', $response);
}
public function testStartWithoutAuthException()
@@ -47,6 +46,5 @@ class BasicAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate'));
$this->assertEquals(401, $response->getStatusCode());
- $this->assertAttributeEquals('Unauthorized', 'statusText', $response);
}
}
diff --git a/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php b/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php
index ae0e3cc..8dfd618 100644
--- a/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php
+++ b/Tests/Http/EntryPoint/DigestAuthenticationEntryPointTest.php
@@ -34,7 +34,6 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$response = $entryPoint->start($request, $authenticationException);
$this->assertEquals(401, $response->getStatusCode());
- $this->assertAttributeEquals('TheAuthenticationExceptionMessage', 'statusText', $response);
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
@@ -46,7 +45,6 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$response = $entryPoint->start($request);
$this->assertEquals(401, $response->getStatusCode());
- $this->assertAttributeEquals('Unauthorized', 'statusText', $response);
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}"$/', $response->headers->get('WWW-Authenticate'));
}
@@ -60,7 +58,6 @@ class DigestAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$response = $entryPoint->start($request, $nonceExpiredException);
$this->assertEquals(401, $response->getStatusCode());
- $this->assertAttributeEquals('TheNonceExpiredExceptionMessage', 'statusText', $response);
$this->assertRegExp('/^Digest realm="TheRealmName", qop="auth", nonce="[a-zA-Z0-9\/+]+={0,2}", stale="true"$/', $response->headers->get('WWW-Authenticate'));
}
}
diff --git a/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php b/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php
index 2e72340..1cf2c2d 100644
--- a/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php
+++ b/Tests/Http/EntryPoint/FormAuthenticationEntryPointTest.php
@@ -64,7 +64,7 @@ class FormAuthenticationEntryPointTest extends \PHPUnit_Framework_TestCase
$httpKernel
->expects($this->once())
->method('handle')
- ->with($this->equalTo($request), $this->equalTo(HttpKernelInterface::SUB_REQUEST))
+ ->with($this->equalTo($subRequest), $this->equalTo(HttpKernelInterface::SUB_REQUEST))
->will($this->returnValue($response))
;
diff --git a/Tests/Http/Firewall/AccessListenerTest.php b/Tests/Http/Firewall/AccessListenerTest.php
index e3ffbfc..53ab350 100644
--- a/Tests/Http/Firewall/AccessListenerTest.php
+++ b/Tests/Http/Firewall/AccessListenerTest.php
@@ -31,7 +31,7 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AccessDeniedException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess()
{
@@ -198,7 +198,7 @@ class AccessListenerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
*/
public function testHandleWhenTheSecurityContextHasNoToken()
{
diff --git a/Tests/Http/Firewall/ContextListenerTest.php b/Tests/Http/Firewall/ContextListenerTest.php
index 646ed23..ffe6195 100644
--- a/Tests/Http/Firewall/ContextListenerTest.php
+++ b/Tests/Http/Firewall/ContextListenerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Test\Component\Security\Http\Firewall;
+namespace Symfony\Component\Security\Tests\Http\Firewall;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -82,17 +82,30 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($session->has('_security_session'));
}
- protected function runSessionOnKernelResponse($newToken, $original = null)
+ public function testOnKernelResponseWithoutSession()
{
+ $this->securityContext->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
+ $request = new Request();
$session = new Session(new MockArraySessionStorage());
+ $request->setSession($session);
- if ($original !== null) {
- $session->set('_security_session', $original);
- }
+ $event = new FilterResponseEvent(
+ $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'),
+ $request,
+ HttpKernelInterface::MASTER_REQUEST,
+ new Response()
+ );
- $this->securityContext->setToken($newToken);
+ $listener = new ContextListener($this->securityContext, array(), 'session');
+ $listener->onKernelResponse($event);
+ $this->assertTrue($session->isStarted());
+ }
+
+ public function testOnKernelResponseWithoutSessionNorToken()
+ {
$request = new Request();
+ $session = new Session(new MockArraySessionStorage());
$request->setSession($session);
$event = new FilterResponseEvent(
@@ -105,13 +118,65 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
$listener = new ContextListener($this->securityContext, array(), 'session');
$listener->onKernelResponse($event);
- return $session;
+ $this->assertFalse($session->isStarted());
}
- public function testOnKernelResponseWithoutSession()
+ /**
+ * @dataProvider provideInvalidToken
+ */
+ public function testInvalidTokenInSession($token)
{
- $this->securityContext->setToken(new UsernamePasswordToken('test1', 'pass1', 'phpunit'));
+ $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface');
+ $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $event->expects($this->any())
+ ->method('getRequest')
+ ->will($this->returnValue($request));
+ $request->expects($this->any())
+ ->method('hasPreviousSession')
+ ->will($this->returnValue(true));
+ $request->expects($this->any())
+ ->method('getSession')
+ ->will($this->returnValue($session));
+ $session->expects($this->any())
+ ->method('get')
+ ->with('_security_key123')
+ ->will($this->returnValue(serialize($token)));
+ $context->expects($this->once())
+ ->method('setToken')
+ ->with(null);
+
+ $listener = new ContextListener($context, array(), 'key123');
+ $listener->handle($event);
+ }
+
+ public function provideInvalidToken()
+ {
+ return array(
+ array(new \__PHP_Incomplete_Class()),
+ array(null),
+ );
+ }
+
+ protected function runSessionOnKernelResponse($newToken, $original = null)
+ {
+ $session = new Session(new MockArraySessionStorage());
+
+ if ($original !== null) {
+ $session->set('_security_session', $original);
+ }
+
+ $this->securityContext->setToken($newToken);
+
$request = new Request();
+ $request->setSession($session);
+ $request->cookies->set('MOCKSESSID', true);
$event = new FilterResponseEvent(
$this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'),
@@ -123,6 +188,5 @@ class ContextListenerTest extends \PHPUnit_Framework_TestCase
$listener = new ContextListener($this->securityContext, array(), 'session');
$listener->onKernelResponse($event);
- $this->assertFalse($request->hasSession());
- }
-}
+ return $session;
+ }}
diff --git a/Tests/Http/Firewall/DigestDataTest.php b/Tests/Http/Firewall/DigestDataTest.php
new file mode 100644
index 0000000..cfb929c
--- /dev/null
+++ b/Tests/Http/Firewall/DigestDataTest.php
@@ -0,0 +1,181 @@
+<?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\Security\Http\Firewall\DigestData;
+
+class DigestDataTest extends \PHPUnit_Framework_TestCase
+{
+ public function testGetResponse()
+ {
+ $digestAuth = new DigestData(
+ 'username="user", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('b52938fc9e6d7c01be7702ece9031b42', $digestAuth->getResponse());
+ }
+
+ public function testGetUsername()
+ {
+ $digestAuth = new DigestData(
+ 'username="user", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('user', $digestAuth->getUsername());
+ }
+
+ public function testGetUsernameWithQuote()
+ {
+ $digestAuth = new DigestData(
+ 'username="\"user\"", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('"user"', $digestAuth->getUsername());
+ }
+
+ public function testGetUsernameWithQuoteAndEscape()
+ {
+ $digestAuth = new DigestData(
+ 'username="\"u\\\\\"ser\"", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('"u\\"ser"', $digestAuth->getUsername());
+ }
+
+ public function testGetUsernameWithSingleQuote()
+ {
+ $digestAuth = new DigestData(
+ 'username="\"u\'ser\"", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('"u\'ser"', $digestAuth->getUsername());
+ }
+
+ public function testGetUsernameWithSingleQuoteAndEscape()
+ {
+ $digestAuth = new DigestData(
+ 'username="\"u\\\'ser\"", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('"u\\\'ser"', $digestAuth->getUsername());
+ }
+
+ public function testGetUsernameWithEscape()
+ {
+ $digestAuth = new DigestData(
+ 'username="\"u\\ser\"", realm="Welcome, robot!", ' .
+ 'nonce="MTM0NzMyMTgyMy42NzkzOmRlZjM4NmIzOGNjMjE0OWJiNDU0MDAxNzJmYmM1MmZl", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $this->assertEquals('"u\\ser"', $digestAuth->getUsername());
+ }
+
+ public function testValidateAndDecode()
+ {
+ $time = microtime(true);
+ $key = 'ThisIsAKey';
+ $nonce = base64_encode($time . ':' . md5($time . ':' . $key));
+
+ $digestAuth = new DigestData(
+ 'username="user", realm="Welcome, robot!", nonce="' . $nonce . '", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ try {
+ $digestAuth->validateAndDecode($key, 'Welcome, robot!');
+ } catch (\Exception $e) {
+ $this->fail(sprintf('testValidateAndDecode fail with message: %s', $e->getMessage()));
+ }
+ }
+
+ public function testCalculateServerDigest()
+ {
+ $this->calculateServerDigest('user', 'Welcome, robot!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
+ }
+
+ public function testCalculateServerDigestWithQuote()
+ {
+ $this->calculateServerDigest('\"user\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
+ }
+
+ public function testCalculateServerDigestWithQuoteAndEscape()
+ {
+ $this->calculateServerDigest('\"u\\\\\"ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
+ }
+
+ public function testCalculateServerDigestEscape()
+ {
+ $this->calculateServerDigest('\"u\\ser\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
+ $this->calculateServerDigest('\"u\\ser\\\\\"', 'Welcome, \"robot\"!', 'pass,word=password', 'ThisIsAKey', '00000001', 'MDIwODkz', 'auth', 'GET', '/path/info?p1=5&p2=5');
+ }
+
+ public function testIsNonceExpired()
+ {
+ $time = microtime(true) + 10;
+ $key = 'ThisIsAKey';
+ $nonce = base64_encode($time . ':' . md5($time . ':' . $key));
+
+ $digestAuth = new DigestData(
+ 'username="user", realm="Welcome, robot!", nonce="' . $nonce . '", ' .
+ 'uri="/path/info?p1=5&p2=5", cnonce="MDIwODkz", nc=00000001, qop="auth", ' .
+ 'response="b52938fc9e6d7c01be7702ece9031b42"'
+ );
+
+ $digestAuth->validateAndDecode($key, 'Welcome, robot!');
+
+ $this->assertFalse($digestAuth->isNonceExpired());
+ }
+
+ protected function setUp()
+ {
+ class_exists('Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener', true);
+ }
+
+ private function calculateServerDigest($username, $realm, $password, $key, $nc, $cnonce, $qop, $method, $uri)
+ {
+ $time = microtime(true);
+ $nonce = base64_encode($time . ':' . md5($time . ':' . $key));
+
+ $response = md5(
+ md5($username . ':' . $realm . ':' . $password) . ':' . $nonce . ':' . $nc . ':' . $cnonce . ':' . $qop . ':' . md5($method . ':' . $uri)
+ );
+
+ $digest = sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"',
+ $username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response
+ );
+
+ $digestAuth = new DigestData($digest);
+
+ $this->assertEquals($digestAuth->getResponse(), $digestAuth->calculateServerDigest($password, $method));
+ }
+}
diff --git a/Tests/Http/Firewall/LogoutListenerTest.php b/Tests/Http/Firewall/LogoutListenerTest.php
index 6ffeed9..ba94b6e 100644
--- a/Tests/Http/Firewall/LogoutListenerTest.php
+++ b/Tests/Http/Firewall/LogoutListenerTest.php
@@ -103,7 +103,9 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
public function testHandleMatchedPathWithoutSuccessHandlerAndCsrfValidation()
{
- list($listener, $context, $httpUtils, $options) = $this->getListener();
+ $successHandler = $this->getSuccessHandler();
+
+ list($listener, $context, $httpUtils, $options) = $this->getListener($successHandler);
list($event, $request) = $this->getGetResponseEvent();
@@ -112,9 +114,9 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
->with($request, $options['logout_path'])
->will($this->returnValue(true));
- $httpUtils->expects($this->once())
- ->method('createRedirectResponse')
- ->with($request, $options['target_url'])
+ $successHandler->expects($this->once())
+ ->method('onLogoutSuccess')
+ ->with($request)
->will($this->returnValue($response = new Response()));
$context->expects($this->once())
@@ -164,7 +166,7 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
}
/**
- * @expectedException Symfony\Component\Security\Core\Exception\LogoutException
+ * @expectedException \Symfony\Component\Security\Core\Exception\LogoutException
*/
public function testCsrfValidationFails()
{
@@ -231,13 +233,13 @@ class LogoutListenerTest extends \PHPUnit_Framework_TestCase
$listener = new LogoutListener(
$context = $this->getContext(),
$httpUtils = $this->getHttpUtils(),
+ $successHandler ?: $this->getSuccessHandler(),
$options = array(
'csrf_parameter' => '_csrf_token',
'intention' => 'logout',
'logout_path' => '/logout',
'target_url' => '/',
),
- $successHandler,
$csrfProvider
);
diff --git a/Tests/Http/Firewall/RememberMeListenerTest.php b/Tests/Http/Firewall/RememberMeListenerTest.php
index 5f31273..8ad4c55 100644
--- a/Tests/Http/Firewall/RememberMeListenerTest.php
+++ b/Tests/Http/Firewall/RememberMeListenerTest.php
@@ -177,7 +177,7 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
protected function getLogger()
{
- return $this->getMock('Symfony\Component\HttpKernel\Log\LoggerInterface');
+ return $this->getMock('Psr\Log\LoggerInterface');
}
protected function getManager()
diff --git a/Tests/Http/HttpUtilsTest.php b/Tests/Http/HttpUtilsTest.php
index a30051f..bf078da 100644
--- a/Tests/Http/HttpUtilsTest.php
+++ b/Tests/Http/HttpUtilsTest.php
@@ -97,6 +97,11 @@ class HttpUtilsTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($utils->checkRequestPath($this->getRequest(), '/'));
$this->assertFalse($utils->checkRequestPath($this->getRequest(), '/foo'));
+ $this->assertTrue($utils->checkRequestPath($this->getRequest('/foo%20bar'), '/foo bar'));
+ // Plus must not decoded to space
+ $this->assertTrue($utils->checkRequestPath($this->getRequest('/foo+bar'), '/foo+bar'));
+ // Checking unicode
+ $this->assertTrue($utils->checkRequestPath($this->getRequest(urlencode('/вход')), '/вход'));
$urlMatcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface');
$urlMatcher
@@ -132,13 +137,25 @@ class HttpUtilsTest extends \PHPUnit_Framework_TestCase
$utils->checkRequestPath($this->getRequest(), 'foobar');
}
- private function getUrlGenerator()
+ public function testGenerateUriRemovesQueryString()
+ {
+ $method = new \ReflectionMethod('Symfony\Component\Security\Http\HttpUtils', 'generateUri');
+ $method->setAccessible(true);
+
+ $utils = new HttpUtils($this->getUrlGenerator());
+ $this->assertEquals('/foo/bar', $method->invoke($utils, new Request(), 'route_name'));
+
+ $utils = new HttpUtils($this->getUrlGenerator('/foo/bar?param=value'));
+ $this->assertEquals('/foo/bar', $method->invoke($utils, new Request(), 'route_name'));
+ }
+
+ private function getUrlGenerator($generatedUrl = '/foo/bar')
{
$urlGenerator = $this->getMock('Symfony\Component\Routing\Generator\UrlGeneratorInterface');
$urlGenerator
->expects($this->any())
->method('generate')
- ->will($this->returnValue('/foo/bar'))
+ ->will($this->returnValue($generatedUrl))
;
return $urlGenerator;
diff --git a/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php b/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php
index fc8dffb..8571686 100644
--- a/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php
+++ b/Tests/Http/RememberMe/AbstractRememberMeServicesTest.php
@@ -39,7 +39,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testAutoLoginReturnsNullWhenNoCookie()
{
- $service = $this->getService(null, array('name' => 'foo'));
+ $service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$this->assertNull($service->autoLogin(new Request()));
}
@@ -49,7 +49,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
*/
public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface()
{
- $service = $this->getService(null, array('name' => 'foo'));
+ $service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request;
$request->cookies->set('foo', 'foo');
@@ -64,7 +64,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testAutoLogin()
{
- $service = $this->getService(null, array('name' => 'foo'));
+ $service = $this->getService(null, array('name' => 'foo', 'path' => null, 'domain' => null));
$request = new Request();
$request->cookies->set('foo', 'foo');
@@ -112,7 +112,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testLoginSuccessIsNotProcessedWhenTokenDoesNotContainUserInterfaceImplementation()
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request;
$response = new Response;
$account = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
@@ -135,7 +135,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testLoginSuccessIsNotProcessedWhenRememberMeIsNotRequested()
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$request = new Request;
$response = new Response;
$account = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
@@ -159,7 +159,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testLoginSuccessWhenRememberMeAlwaysIsTrue()
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request;
$response = new Response;
$account = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
@@ -184,7 +184,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
*/
public function testLoginSuccessWhenRememberMeParameterWithPathIsPositive($value)
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]'));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]', 'path' => null, 'domain' => null));
$request = new Request;
$request->request->set('foo', array('bar' => $value));
@@ -211,7 +211,7 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
*/
public function testLoginSuccessWhenRememberMeParameterIsPositive($value)
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo'));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null));
$request = new Request;
$request->request->set('foo', $value);
diff --git a/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
index 3b3691d..7fc3021 100644
--- a/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
+++ b/Tests/Http/RememberMe/PersistentTokenBasedRememberMeServicesTest.php
@@ -22,6 +22,7 @@ use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices;
use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
use Symfony\Component\Security\Core\Exception\CookieTheftException;
+use Symfony\Component\Security\Core\Util\SecureRandom;
class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
{
@@ -318,7 +319,7 @@ class PersistentTokenBasedRememberMeServicesTest extends \PHPUnit_Framework_Test
$userProvider = $this->getProvider();
}
- return new PersistentTokenBasedRememberMeServices(array($userProvider), 'fookey', 'fookey', $options, $logger);
+ return new PersistentTokenBasedRememberMeServices(array($userProvider), 'fookey', 'fookey', $options, $logger, new SecureRandom(sys_get_temp_dir().'/_sf2.seed'));
}
protected function getProvider()
diff --git a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php b/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
index 407db02..6de69f1 100644
--- a/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
+++ b/Tests/Http/RememberMe/TokenBasedRememberMeServicesTest.php
@@ -179,7 +179,7 @@ class TokenBasedRememberMeServicesTest extends \PHPUnit_Framework_TestCase
public function testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImplementation()
{
- $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true));
+ $service = $this->getService(null, array('name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null));
$request = new Request;
$response = new Response;
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php
deleted file mode 100644
index 84ae3a6..0000000
--- a/Tests/bootstrap.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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.
- */
-
-spl_autoload_register(function ($class) {
- if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Security')) {
- if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Security')).'.php')) {
- require_once $file;
- }
- }
-});
-
-if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) {
- require_once $loader;
-}
diff --git a/composer.json b/composer.json
index 17b3e15..dd4eecf 100644
--- a/composer.json
+++ b/composer.json
@@ -17,32 +17,34 @@
],
"require": {
"php": ">=5.3.3",
- "symfony/event-dispatcher": "2.1.*",
- "symfony/http-foundation": "2.1.*",
- "symfony/http-kernel": "2.1.*"
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/http-foundation": ">=2.1,<2.4-dev",
+ "symfony/http-kernel": ">=2.1,<=2.3-dev"
},
"require-dev": {
- "symfony/form": "2.1.*",
- "symfony/routing": "2.1.*",
- "symfony/validator": "2.1.*",
- "doctrine/common": ">=2.2,<2.4-dev",
- "doctrine/dbal": ">=2.2,<2.4-dev"
+ "symfony/form": "~2.0",
+ "symfony/routing": ">=2.2,<2.4-dev",
+ "symfony/validator": ">=2.2,<2.4-dev",
+ "doctrine/common": "~2.2",
+ "doctrine/dbal": "~2.2",
+ "psr/log": "~1.0"
},
"suggest": {
- "symfony/class-loader": "self.version",
- "symfony/finder": "self.version",
- "symfony/form": "self.version",
- "symfony/validator": "self.version",
- "symfony/routing": "self.version",
+ "symfony/class-loader": "2.2.*",
+ "symfony/finder": "2.2.*",
+ "symfony/form": "2.2.*",
+ "symfony/validator": "2.2.*",
+ "symfony/routing": "2.2.*",
"doctrine/dbal": "to use the built-in ACL implementation"
},
"autoload": {
- "psr-0": { "Symfony\\Component\\Security": "" }
+ "psr-0": { "Symfony\\Component\\Security\\": "" }
},
"target-dir": "Symfony/Component/Security",
+ "minimum-stability": "dev",
"extra": {
"branch-alias": {
- "dev-master": "2.1-dev"
+ "dev-master": "2.3-dev"
}
}
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 0560cf5..f45a44e 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -9,7 +9,7 @@
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
- bootstrap="Tests/bootstrap.php"
+ bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Symfony Security Component Test Suite">