diff options
Diffstat (limited to 'Core')
24 files changed, 188 insertions, 67 deletions
diff --git a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php index 4175907..234bddb 100644 --- a/Core/Authentication/Provider/RememberMeAuthenticationProvider.php +++ b/Core/Authentication/Provider/RememberMeAuthenticationProvider.php @@ -22,6 +22,13 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac private $key; private $providerKey; + /** + * Constructor. + * + * @param UserCheckerInterface $userChecker An UserCheckerInterface interface + * @param string $key A key + * @param string $providerKey A provider key + */ public function __construct(UserCheckerInterface $userChecker, $key, $providerKey) { $this->userChecker = $userChecker; @@ -29,6 +36,9 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac $this->providerKey = $providerKey; } + /** + * {@inheritdoc} + */ public function authenticate(TokenInterface $token) { if (!$this->supports($token)) { @@ -48,6 +58,9 @@ class RememberMeAuthenticationProvider implements AuthenticationProviderInterfac return $authenticatedToken; } + /** + * {@inheritdoc} + */ public function supports(TokenInterface $token) { return $token instanceof RememberMeToken && $token->getProviderKey() === $this->providerKey; diff --git a/Core/Authentication/Provider/UserAuthenticationProvider.php b/Core/Authentication/Provider/UserAuthenticationProvider.php index 626f50b..18c3e70 100644 --- a/Core/Authentication/Provider/UserAuthenticationProvider.php +++ b/Core/Authentication/Provider/UserAuthenticationProvider.php @@ -19,6 +19,7 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Role\SwitchUserRole; /** * UserProviderInterface retrieves users for UsernamePasswordToken tokens. @@ -92,7 +93,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter throw $e; } - $authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); + $authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token)); $authenticatedToken->setAttributes($token->getAttributes()); return $authenticatedToken; @@ -107,6 +108,29 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter } /** + * Retrieves roles from user and appends SwitchUserRole if original token contained one. + * + * @param UserInterface $user The user + * @param TokenInterface $token The token + * + * @return Role[] The user roles + */ + private function getRoles(UserInterface $user, TokenInterface $token) + { + $roles = $user->getRoles(); + + foreach ($token->getRoles() as $role) { + if ($role instanceof SwitchUserRole) { + $roles[] = $role; + + break; + } + } + + return $roles; + } + + /** * Retrieves the user from an implementation-specific location. * * @param string $username The username to retrieve diff --git a/Core/Authentication/RememberMe/InMemoryTokenProvider.php b/Core/Authentication/RememberMe/InMemoryTokenProvider.php index a15c2b4..719d7a1 100644 --- a/Core/Authentication/RememberMe/InMemoryTokenProvider.php +++ b/Core/Authentication/RememberMe/InMemoryTokenProvider.php @@ -22,6 +22,9 @@ class InMemoryTokenProvider implements TokenProviderInterface { private $tokens = array(); + /** + * {@inheritdoc} + */ public function loadTokenBySeries($series) { if (!isset($this->tokens[$series])) { @@ -31,6 +34,9 @@ class InMemoryTokenProvider implements TokenProviderInterface return $this->tokens[$series]; } + /** + * {@inheritdoc} + */ public function updateToken($series, $tokenValue, \DateTime $lastUsed) { if (!isset($this->tokens[$series])) { @@ -47,11 +53,17 @@ class InMemoryTokenProvider implements TokenProviderInterface $this->tokens[$series] = $token; } + /** + * {@inheritdoc} + */ public function deleteTokenBySeries($series) { unset($this->tokens[$series]); } + /** + * {@inheritdoc} + */ public function createNewToken(PersistentTokenInterface $token) { $this->tokens[$token->getSeries()] = $token; diff --git a/Core/Authentication/RememberMe/PersistentToken.php b/Core/Authentication/RememberMe/PersistentToken.php index 8919be9..5df71ec 100644 --- a/Core/Authentication/RememberMe/PersistentToken.php +++ b/Core/Authentication/RememberMe/PersistentToken.php @@ -58,9 +58,7 @@ final class PersistentToken implements PersistentTokenInterface } /** - * Returns the class of the user - * - * @return string + * {@inheritdoc} */ public function getClass() { @@ -68,9 +66,7 @@ final class PersistentToken implements PersistentTokenInterface } /** - * Returns the username - * - * @return string + * {@inheritdoc} */ public function getUsername() { @@ -78,9 +74,7 @@ final class PersistentToken implements PersistentTokenInterface } /** - * Returns the series - * - * @return string + * {@inheritdoc} */ public function getSeries() { @@ -88,9 +82,7 @@ final class PersistentToken implements PersistentTokenInterface } /** - * Returns the token value - * - * @return string + * {@inheritdoc} */ public function getTokenValue() { @@ -98,9 +90,7 @@ final class PersistentToken implements PersistentTokenInterface } /** - * Returns the time the token was last used - * - * @return \DateTime + * {@inheritdoc} */ public function getLastUsed() { diff --git a/Core/Authentication/RememberMe/PersistentTokenInterface.php b/Core/Authentication/RememberMe/PersistentTokenInterface.php index 6e9d891..ad52753 100644 --- a/Core/Authentication/RememberMe/PersistentTokenInterface.php +++ b/Core/Authentication/RememberMe/PersistentTokenInterface.php @@ -20,31 +20,36 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe; interface PersistentTokenInterface { /** - * Returns the class of the user + * Returns the class of the user. + * * @return string */ public function getClass(); /** - * Returns the username + * Returns the username. + * * @return string */ public function getUsername(); /** - * Returns the series + * Returns the series. + * * @return string */ public function getSeries(); /** - * Returns the token value + * Returns the token value. + * * @return string */ public function getTokenValue(); /** - * Returns the last time the cookie was used + * Returns the time the token was last used. + * * @return \DateTime */ public function getLastUsed(); diff --git a/Core/Authentication/Token/AbstractToken.php b/Core/Authentication/Token/AbstractToken.php index 1d65819..e4c46d5 100644 --- a/Core/Authentication/Token/AbstractToken.php +++ b/Core/Authentication/Token/AbstractToken.php @@ -74,6 +74,9 @@ abstract class AbstractToken implements TokenInterface return (string) $this->user; } + /** + * {@inheritdoc} + */ public function getUser() { return $this->user; @@ -146,7 +149,14 @@ abstract class AbstractToken implements TokenInterface */ public function serialize() { - return serialize(array($this->user, $this->authenticated, $this->roles, $this->attributes)); + return serialize( + array( + is_object($this->user) ? clone $this->user : $this->user, + $this->authenticated, + $this->roles, + $this->attributes + ) + ); } /** diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php index cabb6d5..d39fec8 100644 --- a/Core/Authentication/Token/AnonymousToken.php +++ b/Core/Authentication/Token/AnonymousToken.php @@ -18,7 +18,6 @@ use Symfony\Component\Security\Core\Role\RoleInterface; * * @author Fabien Potencier <fabien@symfony.com> */ - class AnonymousToken extends AbstractToken { private $key; diff --git a/Core/Authentication/Token/PreAuthenticatedToken.php b/Core/Authentication/Token/PreAuthenticatedToken.php index ff0572f..abcd2bf 100644 --- a/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/Core/Authentication/Token/PreAuthenticatedToken.php @@ -41,11 +41,19 @@ class PreAuthenticatedToken extends AbstractToken } } + /** + * Returns the provider key. + * + * @return string The provider key + */ public function getProviderKey() { return $this->providerKey; } + /** + * {@inheritdoc} + */ public function getCredentials() { return $this->credentials; @@ -61,11 +69,17 @@ class PreAuthenticatedToken extends AbstractToken $this->credentials = null; } + /** + * {@inheritdoc} + */ public function serialize() { return serialize(array($this->credentials, $this->providerKey, parent::serialize())); } + /** + * {@inheritdoc} + */ public function unserialize($str) { list($this->credentials, $this->providerKey, $parentStr) = unserialize($str); diff --git a/Core/Authentication/Token/RememberMeToken.php b/Core/Authentication/Token/RememberMeToken.php index 6f3d821..609fdad 100644 --- a/Core/Authentication/Token/RememberMeToken.php +++ b/Core/Authentication/Token/RememberMeToken.php @@ -51,6 +51,9 @@ class RememberMeToken extends AbstractToken parent::setAuthenticated(true); } + /** + * {@inheritdoc} + */ public function setAuthenticated($authenticated) { if ($authenticated) { @@ -60,16 +63,29 @@ class RememberMeToken extends AbstractToken parent::setAuthenticated(false); } + /** + * Returns the provider key. + * + * @return string The provider key + */ public function getProviderKey() { return $this->providerKey; } + /** + * Returns the key. + * + * @return string The Key + */ public function getKey() { return $this->key; } + /** + * {@inheritdoc} + */ public function getCredentials() { return ''; diff --git a/Core/Authentication/Token/UsernamePasswordToken.php b/Core/Authentication/Token/UsernamePasswordToken.php index 3854242..b6dfce4 100644 --- a/Core/Authentication/Token/UsernamePasswordToken.php +++ b/Core/Authentication/Token/UsernamePasswordToken.php @@ -60,11 +60,19 @@ class UsernamePasswordToken extends AbstractToken parent::setAuthenticated(false); } + /** + * {@inheritdoc} + */ public function getCredentials() { return $this->credentials; } + /** + * Returns the provider key. + * + * @return string The provider key + */ public function getProviderKey() { return $this->providerKey; diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php index a355421..5a0f122 100644 --- a/Core/Encoder/BCryptPasswordEncoder.php +++ b/Core/Encoder/BCryptPasswordEncoder.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Security\Core\Encoder; -use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; /** * @author Elnur Abdurrakhimov <elnur@elnur.pro> @@ -29,6 +29,7 @@ class BCryptPasswordEncoder extends BasePasswordEncoder * * @param integer $cost The algorithmic cost that should be used * + * @throws \RuntimeException When no BCrypt encoder is available * @throws \InvalidArgumentException if cost is out of range */ public function __construct($cost) @@ -42,7 +43,7 @@ class BCryptPasswordEncoder extends BasePasswordEncoder throw new \InvalidArgumentException('Cost must be in the range of 4-31.'); } - $this->cost = sprintf('%02d', $cost); + $this->cost = $cost; } /** @@ -64,6 +65,10 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + $options = array('cost' => $this->cost); if ($salt) { @@ -78,6 +83,6 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return password_verify($raw, $encoded); + return !$this->isPasswordTooLong($raw) && password_verify($raw, $encoded); } } diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php index c26c9ce..b83eb30 100644 --- a/Core/Encoder/BasePasswordEncoder.php +++ b/Core/Encoder/BasePasswordEncoder.php @@ -20,6 +20,8 @@ use Symfony\Component\Security\Core\Util\StringUtils; */ abstract class BasePasswordEncoder implements PasswordEncoderInterface { + const MAX_PASSWORD_LENGTH = 4096; + /** * Demerges a merge password and salt string. * @@ -83,4 +85,14 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface { return StringUtils::equals($password1, $password2); } + + /** + * Checks if the password is too long. + * + * @return Boolean true if the password is too long, false otherwise + */ + protected function isPasswordTooLong($password) + { + return strlen($password) > self::MAX_PASSWORD_LENGTH; + } } diff --git a/Core/Encoder/MessageDigestPasswordEncoder.php b/Core/Encoder/MessageDigestPasswordEncoder.php index a8bd553..a7e5546 100644 --- a/Core/Encoder/MessageDigestPasswordEncoder.php +++ b/Core/Encoder/MessageDigestPasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * MessageDigestPasswordEncoder uses a message digest algorithm. * @@ -41,6 +43,10 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -61,6 +67,6 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); + return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } } diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php index 4f37ba3..8a5a958 100644 --- a/Core/Encoder/Pbkdf2PasswordEncoder.php +++ b/Core/Encoder/Pbkdf2PasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * Pbkdf2PasswordEncoder uses the PBKDF2 (Password-Based Key Derivation Function 2). * @@ -54,6 +56,10 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -72,7 +78,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); + return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0) diff --git a/Core/Encoder/PlaintextPasswordEncoder.php b/Core/Encoder/PlaintextPasswordEncoder.php index c21f3cd..22f3da4 100644 --- a/Core/Encoder/PlaintextPasswordEncoder.php +++ b/Core/Encoder/PlaintextPasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * PlaintextPasswordEncoder does not do any encoding. * @@ -35,6 +37,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + return $this->mergePasswordAndSalt($raw, $salt); } @@ -43,6 +49,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + return false; + } + $pass2 = $this->mergePasswordAndSalt($raw, $salt); if (!$this->ignorePasswordCase) { diff --git a/Core/Exception/NonceExpiredException.php b/Core/Exception/NonceExpiredException.php index da6fba8..2f6681f 100644 --- a/Core/Exception/NonceExpiredException.php +++ b/Core/Exception/NonceExpiredException.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Security\Core\Exception; -use Symfony\Component\Security\Core\Exception\AuthenticationException; - /** * NonceExpiredException is thrown when an authentication is rejected because * the digest nonce has expired. diff --git a/Core/Role/RoleHierarchy.php b/Core/Role/RoleHierarchy.php index a368a44..2e7df0e 100644 --- a/Core/Role/RoleHierarchy.php +++ b/Core/Role/RoleHierarchy.php @@ -34,11 +34,7 @@ class RoleHierarchy implements RoleHierarchyInterface } /** - * Returns an array of all roles reachable by the given ones. - * - * @param RoleInterface[] $roles An array of RoleInterface instances - * - * @return RoleInterface[] An array of RoleInterface instances + * {@inheritdoc} */ public function getReachableRoles(array $roles) { diff --git a/Core/Role/RoleHierarchyInterface.php b/Core/Role/RoleHierarchyInterface.php index 2ea6ca3..c994009 100644 --- a/Core/Role/RoleHierarchyInterface.php +++ b/Core/Role/RoleHierarchyInterface.php @@ -19,7 +19,7 @@ namespace Symfony\Component\Security\Core\Role; interface RoleHierarchyInterface { /** - * Returns an array of all reachable roles. + * Returns an array of all reachable roles by the given ones. * * Reachable roles are the roles directly assigned but also all roles that * are transitively reachable from them in the role hierarchy. diff --git a/Core/SecurityContext.php b/Core/SecurityContext.php index 1ec43e6..c55cecf 100644 --- a/Core/SecurityContext.php +++ b/Core/SecurityContext.php @@ -46,14 +46,9 @@ class SecurityContext implements SecurityContextInterface } /** - * Checks if the attributes are granted against the current token. + * {@inheritdoc} * * @throws AuthenticationCredentialsNotFoundException when the security context has no authentication token. - * - * @param mixed $attributes - * @param mixed|null $object - * - * @return Boolean */ final public function isGranted($attributes, $object = null) { @@ -73,9 +68,7 @@ class SecurityContext implements SecurityContextInterface } /** - * Gets the currently authenticated token. - * - * @return TokenInterface|null A TokenInterface instance or null if no authentication information is available + * {@inheritdoc} */ public function getToken() { @@ -83,9 +76,7 @@ class SecurityContext implements SecurityContextInterface } /** - * Sets the currently authenticated token. - * - * @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored + * {@inheritdoc} */ public function setToken(TokenInterface $token = null) { diff --git a/Core/SecurityContextInterface.php b/Core/SecurityContextInterface.php index 78d6477..434f9a5 100644 --- a/Core/SecurityContextInterface.php +++ b/Core/SecurityContextInterface.php @@ -34,14 +34,14 @@ interface SecurityContextInterface /** * Sets the authentication token. * - * @param TokenInterface $token + * @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored */ public function setToken(TokenInterface $token = null); /** * Checks if the attributes are granted against the current authentication token and optionally supplied object. * - * @param array $attributes + * @param mixed $attributes * @param mixed $object * * @return Boolean diff --git a/Core/User/InMemoryUserProvider.php b/Core/User/InMemoryUserProvider.php index e87f80c..074c21e 100644 --- a/Core/User/InMemoryUserProvider.php +++ b/Core/User/InMemoryUserProvider.php @@ -56,7 +56,7 @@ class InMemoryUserProvider implements UserProviderInterface public function createUser(UserInterface $user) { if (isset($this->users[strtolower($user->getUsername())])) { - throw new \LogicException('Another user with the same username already exist.'); + throw new \LogicException('Another user with the same username already exists.'); } $this->users[strtolower($user->getUsername())] = $user; diff --git a/Core/User/UserChecker.php b/Core/User/UserChecker.php index 8dde3a6..ac577a3 100644 --- a/Core/User/UserChecker.php +++ b/Core/User/UserChecker.php @@ -32,22 +32,6 @@ class UserChecker implements UserCheckerInterface return; } - if (!$user->isCredentialsNonExpired()) { - $ex = new CredentialsExpiredException('User credentials have expired.'); - $ex->setUser($user); - throw $ex; - } - } - - /** - * {@inheritdoc} - */ - public function checkPostAuth(UserInterface $user) - { - if (!$user instanceof AdvancedUserInterface) { - return; - } - if (!$user->isAccountNonLocked()) { $ex = new LockedException('User account is locked.'); $ex->setUser($user); @@ -66,4 +50,20 @@ class UserChecker implements UserCheckerInterface throw $ex; } } + + /** + * {@inheritdoc} + */ + public function checkPostAuth(UserInterface $user) + { + if (!$user instanceof AdvancedUserInterface) { + return; + } + + if (!$user->isCredentialsNonExpired()) { + $ex = new CredentialsExpiredException('User credentials have expired.'); + $ex->setUser($user); + throw $ex; + } + } } diff --git a/Core/Validator/Constraints/UserPassword.php b/Core/Validator/Constraints/UserPassword.php index ed29b0c..76c4b3b 100644 --- a/Core/Validator/Constraints/UserPassword.php +++ b/Core/Validator/Constraints/UserPassword.php @@ -21,6 +21,9 @@ class UserPassword extends Constraint public $message = 'This value should be the user current password.'; public $service = 'security.validator.user_password'; + /** + * {@inheritdoc} + */ public function validatedBy() { return $this->service; diff --git a/Core/Validator/Constraints/UserPasswordValidator.php b/Core/Validator/Constraints/UserPasswordValidator.php index a4e0f90..ab455f3 100644 --- a/Core/Validator/Constraints/UserPasswordValidator.php +++ b/Core/Validator/Constraints/UserPasswordValidator.php @@ -29,6 +29,9 @@ class UserPasswordValidator extends ConstraintValidator $this->encoderFactory = $encoderFactory; } + /** + * {@inheritdoc} + */ public function validate($password, Constraint $constraint) { $user = $this->securityContext->getToken()->getUser(); |