diff options
141 files changed, 3631 insertions, 289 deletions
@@ -1,2 +1,4 @@ vendor/ composer.lock +phpunit.xml + diff --git a/Acl/Dbal/AclProvider.php b/Acl/Dbal/AclProvider.php index ada4f22..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 '; + } } } @@ -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 9a20f61..0ac4fa7 100644 --- a/Acl/Dbal/MutableAclProvider.php +++ b/Acl/Dbal/MutableAclProvider.php @@ -147,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/AclCollectionCache.php b/Acl/Domain/AclCollectionCache.php index 88c017c..d3a4b37 100644 --- a/Acl/Domain/AclCollectionCache.php +++ b/Acl/Domain/AclCollectionCache.php @@ -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 da98f5e..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,7 +51,7 @@ final class ObjectIdentity implements ObjectIdentityInterface * Constructs an ObjectIdentity for the given domain object * * @param object $domainObject - * @throws \InvalidArgumentException + * @throws InvalidDomainObjectException * @return ObjectIdentity */ public static function fromDomainObject($domainObject) diff --git a/Acl/Domain/PermissionGrantingStrategy.php b/Acl/Domain/PermissionGrantingStrategy.php index 09e227c..d505843 100644 --- a/Acl/Domain/PermissionGrantingStrategy.php +++ b/Acl/Domain/PermissionGrantingStrategy.php @@ -16,6 +16,7 @@ use Symfony\Component\Security\Acl\Model\AclInterface; use Symfony\Component\Security\Acl\Model\AuditLoggerInterface; use Symfony\Component\Security\Acl\Model\EntryInterface; use Symfony\Component\Security\Acl\Model\PermissionGrantingStrategyInterface; +use Symfony\Component\Security\Acl\Model\SecurityIdentityInterface; /** * The permission granting strategy to apply to the access control list. @@ -123,12 +124,15 @@ class PermissionGrantingStrategy implements PermissionGrantingStrategyInterface * permission/identity combinations are left. Finally, we will either throw * an NoAceFoundException, or deny access. * - * @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 + * @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 + * * @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) { @@ -186,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 ebb0056..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) { diff --git a/Acl/Model/AclProviderInterface.php b/Acl/Model/AclProviderInterface.php index bdb40b7..4be49bf 100644 --- a/Acl/Model/AclProviderInterface.php +++ b/Acl/Model/AclProviderInterface.php @@ -23,6 +23,7 @@ interface AclProviderInterface * * @param ObjectIdentityInterface $parentOid * @param Boolean $directChildrenOnly + * * @return array returns an array of child 'ObjectIdentity's */ public function findChildren(ObjectIdentityInterface $parentOid, $directChildrenOnly = false); @@ -30,20 +31,24 @@ interface AclProviderInterface /** * 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 */ 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 */ public function findAcls(array $oids, array $sids = array()); } diff --git a/Acl/Model/MutableAclInterface.php b/Acl/Model/MutableAclInterface.php index 9028aa9..365a779 100644 --- a/Acl/Model/MutableAclInterface.php +++ b/Acl/Model/MutableAclInterface.php @@ -115,7 +115,6 @@ interface MutableAclInterface extends AclInterface * Sets the parent ACL * * @param AclInterface|null $acl - * @return void */ public function setParentAcl(AclInterface $acl = null); diff --git a/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php b/Acl/Model/SecurityIdentityRetrievalStrategyInterface.php index c20f04b..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 */ public function getSecurityIdentities(TokenInterface $token); } diff --git a/Acl/Permission/MaskBuilder.php b/Acl/Permission/MaskBuilder.php index df1fa7c..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) { diff --git a/Acl/Resources/bin/generateSql.php b/Acl/Resources/bin/generateSql.php index d65874b..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', 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 c570ac3..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 ----- @@ -25,3 +35,8 @@ CHANGELOG `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/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/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 88b0413..f3f6858 100644 --- a/Core/Authentication/RememberMe/PersistentToken.php +++ b/Core/Authentication/RememberMe/PersistentToken.php @@ -32,6 +32,8 @@ final class PersistentToken implements PersistentTokenInterface * @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/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 dec31d5..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. * @@ -31,7 +33,7 @@ interface TokenInterface extends \Serializable /** * Returns the user roles. * - * @return Role[] An array of Role instances. + * @return RoleInterface[] An array of RoleInterface instances. */ public function getRoles(); 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/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/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 9429441..8bad61f 100644 --- a/Core/Encoder/EncoderFactory.php +++ b/Core/Encoder/EncoderFactory.php @@ -51,6 +51,8 @@ class EncoderFactory implements EncoderFactoryInterface * @param array $config * * @return PasswordEncoderInterface + * + * @throws \InvalidArgumentException */ private function createEncoder(array $config) { 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 c495a7f..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 */ public function getReachableRoles(array $roles); } diff --git a/Core/Role/RoleInterface.php b/Core/Role/RoleInterface.php index a3cb266..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> */ 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/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/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/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/Constraint/UserPassword.php index 3279e02..93ca24d 100644 --- a/Core/Validator/Constraint/UserPassword.php +++ b/Core/Validator/Constraint/UserPassword.php @@ -11,17 +11,19 @@ namespace Symfony\Component\Security\Core\Validator\Constraint; -use Symfony\Component\Validator\Constraint; +use Symfony\Component\Security\Core\Validator\Constraints\UserPassword as BaseUserPassword; /** * @Annotation + * + * @deprecated Deprecated since version 2.2, to be removed in 2.3. */ -class UserPassword extends Constraint +class UserPassword extends BaseUserPassword { - public $message = 'This value should be the user current password.'; - - public function validatedBy() + public function __construct($options = null) { - return 'security.validator.user_password'; + trigger_error('UserPassword class in Symfony\Component\Security\Core\Validator\Constraint namespace is deprecated since version 2.2 and will be removed in 2.3. Use the Symfony\Component\Security\Core\Validator\Constraints\UserPassword class instead.', E_USER_DEPRECATED); + + parent::__construct($options); } } diff --git a/Core/Validator/Constraint/UserPasswordValidator.php b/Core/Validator/Constraint/UserPasswordValidator.php index a54906b..0195fe5 100644 --- a/Core/Validator/Constraint/UserPasswordValidator.php +++ b/Core/Validator/Constraint/UserPasswordValidator.php @@ -11,36 +11,19 @@ namespace Symfony\Component\Security\Core\Validator\Constraint; -use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\ConstraintDefinitionException; +use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator as BaseUserPasswordValidator; -class UserPasswordValidator extends ConstraintValidator +/** + * @deprecated Deprecated since version 2.2, to be removed in 2.3. + */ +class UserPasswordValidator extends BaseUserPasswordValidator { - private $securityContext; - private $encoderFactory; - public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory) { - $this->securityContext = $securityContext; - $this->encoderFactory = $encoderFactory; - } - - public function validate($password, Constraint $constraint) - { - $user = $this->securityContext->getToken()->getUser(); - - if (!$user instanceof UserInterface) { - throw new ConstraintDefinitionException('The User must extend UserInterface'); - } - - $encoder = $this->encoderFactory->getEncoder($user); + trigger_error('UserPasswordValidator class in Symfony\Component\Security\Core\Validator\Constraint namespace is deprecated since version 2.2 and will be removed in 2.3. Use the Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator class instead.', E_USER_DEPRECATED); - if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) { - $this->context->addViolation($constraint->message); - } + parent::__construct($securityContext, $encoderFactory); } } diff --git a/Core/Validator/Constraints/UserPassword.php b/Core/Validator/Constraints/UserPassword.php new file mode 100644 index 0000000..ed29b0c --- /dev/null +++ b/Core/Validator/Constraints/UserPassword.php @@ -0,0 +1,28 @@ +<?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\Validator\Constraints; + +use Symfony\Component\Validator\Constraint; + +/** + * @Annotation + */ +class UserPassword extends Constraint +{ + public $message = 'This value should be the user current password.'; + public $service = 'security.validator.user_password'; + + public function validatedBy() + { + return $this->service; + } +} diff --git a/Core/Validator/Constraints/UserPasswordValidator.php b/Core/Validator/Constraints/UserPasswordValidator.php new file mode 100644 index 0000000..a4e0f90 --- /dev/null +++ b/Core/Validator/Constraints/UserPasswordValidator.php @@ -0,0 +1,46 @@ +<?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\Validator\Constraints; + +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\SecurityContextInterface; +use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\ConstraintDefinitionException; + +class UserPasswordValidator extends ConstraintValidator +{ + private $securityContext; + private $encoderFactory; + + public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory) + { + $this->securityContext = $securityContext; + $this->encoderFactory = $encoderFactory; + } + + public function validate($password, Constraint $constraint) + { + $user = $this->securityContext->getToken()->getUser(); + + if (!$user instanceof UserInterface) { + throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.'); + } + + $encoder = $this->encoderFactory->getEncoder($user); + + if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) { + $this->context->addViolation($constraint->message); + } + } +} diff --git a/Http/Authentication/DefaultAuthenticationFailureHandler.php b/Http/Authentication/DefaultAuthenticationFailureHandler.php index 61d77a8..64f84f0 100644 --- a/Http/Authentication/DefaultAuthenticationFailureHandler.php +++ b/Http/Authentication/DefaultAuthenticationFailureHandler.php @@ -13,7 +13,7 @@ namespace Symfony\Component\Security\Http\Authentication; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\HttpKernel\Log\LoggerInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Http\HttpUtils; @@ -50,9 +50,10 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle $this->logger = $logger; $this->options = array_merge(array( - 'failure_path' => null, - 'failure_forward' => false, - 'login_path' => '/login', + 'failure_path' => null, + 'failure_forward' => false, + 'login_path' => '/login', + 'failure_path_parameter' => '_failure_path' ), $options); } @@ -61,6 +62,10 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle */ 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']; } 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/Firewall.php b/Http/Firewall.php index a590fd9..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; @@ -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 410fb73..80f47f7 100644 --- a/Http/Firewall/AbstractAuthenticationListener.php +++ b/Http/Firewall/AbstractAuthenticationListener.php @@ -19,7 +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 Psr\Log\LoggerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -75,6 +75,8 @@ abstract class AbstractAuthenticationListener implements ListenerInterface * successful, or failed authentication attempt * @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, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = array(), LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) { @@ -110,6 +112,9 @@ abstract class AbstractAuthenticationListener implements ListenerInterface * Handles form based authentication. * * @param GetResponseEvent $event A GetResponseEvent instance + * + * @throws \RuntimeException + * @throws SessionUnavailableException */ final public function handle(GetResponseEvent $event) { diff --git a/Http/Firewall/AbstractPreAuthenticatedListener.php b/Http/Firewall/AbstractPreAuthenticatedListener.php index 66041be..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; 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 c24c879..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; @@ -88,7 +88,7 @@ class ContextListener implements ListenerInterface $token = $this->refreshUser($token); } elseif (null !== $token) { if (null !== $this->logger) { - $this->logger->warn(sprintf('Session includes a "%s" where a security token is expected', is_object($token) ? get_class($token) : gettype($token))); + $this->logger->warning(sprintf('Session includes a "%s" where a security token is expected', is_object($token) ? get_class($token) : gettype($token))); } $token = null; @@ -138,6 +138,8 @@ class ContextListener implements ListenerInterface * @param TokenInterface $token * * @return TokenInterface|null + * + * @throws \RuntimeException */ private function refreshUser(TokenInterface $token) { @@ -163,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 2bc4aa5..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) { diff --git a/Http/Firewall/ExceptionListener.php b/Http/Firewall/ExceptionListener.php index f134f9c..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; @@ -106,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); @@ -134,7 +136,7 @@ class ExceptionListener } } 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)); diff --git a/Http/Firewall/LogoutListener.php b/Http/Firewall/LogoutListener.php index 32a0511..ca2f439 100644 --- a/Http/Firewall/LogoutListener.php +++ b/Http/Firewall/LogoutListener.php @@ -75,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) { 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 22330a8..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; @@ -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/HttpUtils.php b/Http/HttpUtils.php index 7e6679e..0453520 100644 --- a/Http/HttpUtils.php +++ b/Http/HttpUtils.php @@ -35,7 +35,7 @@ class HttpUtils * Constructor. * * @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance - * @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher + * @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The Url or Request matcher */ public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatcher = null) { @@ -71,8 +71,8 @@ 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); + if ($request->hasSession()) { + $newRequest->setSession($request->getSession()); } if ($request->attributes->has(SecurityContextInterface::AUTHENTICATION_ERROR)) { @@ -136,16 +136,11 @@ class HttpUtils return $request->getUriForPath($path); } - return $this->generateUrl($path, $request->attributes->all(), true); - } - - private function generateUrl($route, array $attributes = array(), $absolute = false) - { if (null === $this->urlGenerator) { throw new \LogicException('You must provide a UrlGeneratorInterface instance to be able to use routes.'); } - $url = $this->urlGenerator->generate($route, $attributes, $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) diff --git a/Http/RememberMe/AbstractRememberMeServices.php b/Http/RememberMe/AbstractRememberMeServices.php index 4f7c5b9..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,7 +91,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface * * @param Request $request * - * @return TokenInterface + * @return TokenInterface|null + * + * @throws CookieTheftException */ final public function autoLogin(Request $request) { @@ -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) { @@ -172,6 +176,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface */ 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); } diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index 8944672..6500bfd 100644 --- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -19,6 +19,8 @@ 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; +use Psr\Log\LoggerInterface; /** * Concrete implementation of the RememberMeServicesInterface which needs @@ -30,6 +32,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 +64,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 +91,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 +99,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices } $series = $persistentToken->getSeries(); - $tokenValue = $this->generateRandomValue(); + $tokenValue = base64_encode($this->secureRandom->nextBytes(64)); $this->tokenProvider->updateToken($series, $tokenValue, new \DateTime()); $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie( @@ -101,8 +121,8 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices */ protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) { - $series = $this->generateRandomValue(); - $tokenValue = $this->generateRandomValue(); + $series = base64_encode($this->secureRandom->nextBytes(64)); + $tokenValue = base64_encode($this->secureRandom->nextBytes(64)); $this->tokenProvider->createNewToken( new PersistentToken( @@ -126,26 +146,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/ResponseListener.php b/Http/RememberMe/ResponseListener.php index 6cbdcb3..03c71c7 100644 --- a/Http/RememberMe/ResponseListener.php +++ b/Http/RememberMe/ResponseListener.php @@ -12,13 +12,15 @@ 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 +class ResponseListener implements EventSubscriberInterface { public function onKernelResponse(FilterResponseEvent $event) { @@ -29,4 +31,9 @@ class ResponseListener $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; @@ -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 837daad..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() { diff --git a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php b/Tests/Acl/Domain/PermissionGrantingStrategyTest.php index f34bc3e..d200d2b 100644 --- a/Tests/Acl/Domain/PermissionGrantingStrategyTest.php +++ b/Tests/Acl/Domain/PermissionGrantingStrategyTest.php @@ -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/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 4da0337..8b27061 100644 --- a/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php +++ b/Tests/Core/Authentication/Provider/DaoAuthenticationProviderTest.php @@ -18,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() { @@ -30,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() { @@ -48,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() { @@ -105,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() { @@ -161,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() { @@ -185,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 4266f21..8359236 100644 --- a/Tests/Core/Util/ClassUtilsTest.php +++ b/Tests/Core/Util/ClassUtilsTest.php @@ -1,5 +1,14 @@ <?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; 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/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/LogoutListenerTest.php b/Tests/Http/Firewall/LogoutListenerTest.php index aa0f5a7..ba94b6e 100644 --- a/Tests/Http/Firewall/LogoutListenerTest.php +++ b/Tests/Http/Firewall/LogoutListenerTest.php @@ -166,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() { 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/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 ecf98c2..083ce94 100644 --- a/composer.json +++ b/composer.json @@ -17,28 +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.3-dev", + "symfony/http-kernel": ">=2.1,<=2.3-dev" }, "require-dev": { - "symfony/form": "2.1.*", - "symfony/routing": "2.1.*", - "symfony/validator": "2.1.*", + "symfony/form": "~2.0", + "symfony/routing": ">=2.2,<2.3-dev", + "symfony/validator": ">=2.2,<2.3-dev", "doctrine/common": "~2.2", - "doctrine/dbal": "~2.2" + "doctrine/dbal": "~2.2", + "psr/log": "~1.0" }, "suggest": { - "symfony/class-loader": "2.1.*", - "symfony/finder": "2.1.*", - "symfony/form": "2.1.*", - "symfony/validator": "2.1.*", - "symfony/routing": "2.1.*", + "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" + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.2-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"> |