diff options
Diffstat (limited to 'Core')
-rw-r--r-- | Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php | 21 | ||||
-rw-r--r-- | Core/Authorization/AccessDecisionManager.php | 6 | ||||
-rw-r--r-- | Core/Authorization/Voter/ExpressionVoter.php | 4 | ||||
-rw-r--r-- | Core/Encoder/BasePasswordEncoder.php | 2 | ||||
-rw-r--r-- | Core/Encoder/EncoderAwareInterface.php | 28 | ||||
-rw-r--r-- | Core/Encoder/EncoderFactory.php | 27 | ||||
-rw-r--r-- | Core/README.md | 2 | ||||
-rw-r--r-- | Core/Role/RoleHierarchy.php | 4 | ||||
-rw-r--r-- | Core/Tests/Authorization/AccessDecisionManagerTest.php | 38 | ||||
-rw-r--r-- | Core/Tests/Encoder/EncoderFactoryTest.php | 64 | ||||
-rw-r--r-- | Core/Validator/Constraints/UserPasswordValidator.php | 5 | ||||
-rw-r--r-- | Core/composer.json | 2 |
12 files changed, 160 insertions, 43 deletions
diff --git a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php index 3affd78..f4d0959 100644 --- a/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php +++ b/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php @@ -47,23 +47,22 @@ class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderIn $this->providerKey = $providerKey; } - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - if (!$this->supports($token)) { - return null; - } - + /** + * {@inheritdoc} + */ + public function authenticate(TokenInterface $token) + { + if (!$this->supports($token)) { + return null; + } if (!$user = $token->getUser()) { throw new BadCredentialsException('No pre-authenticated principal found in request.'); } -/* + /* if (null === $token->getCredentials()) { throw new BadCredentialsException('No pre-authenticated credentials found in request.'); } -*/ + */ $user = $this->userProvider->loadUserByUsername($user); $this->userChecker->checkPostAuth($user); diff --git a/Core/Authorization/AccessDecisionManager.php b/Core/Authorization/AccessDecisionManager.php index 18c3569..9445440 100644 --- a/Core/Authorization/AccessDecisionManager.php +++ b/Core/Authorization/AccessDecisionManager.php @@ -22,6 +22,10 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; */ class AccessDecisionManager implements AccessDecisionManagerInterface { + const STRATEGY_AFFIRMATIVE = 'affirmative'; + const STRATEGY_CONSENSUS = 'consensus'; + const STRATEGY_UNANIMOUS = 'unanimous'; + private $voters; private $strategy; private $allowIfAllAbstainDecisions; @@ -37,7 +41,7 @@ class AccessDecisionManager implements AccessDecisionManagerInterface * * @throws \InvalidArgumentException */ - public function __construct(array $voters, $strategy = 'affirmative', $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) + public function __construct(array $voters, $strategy = self::STRATEGY_AFFIRMATIVE, $allowIfAllAbstainDecisions = false, $allowIfEqualGrantedDeniedDecisions = true) { if (!$voters) { throw new \InvalidArgumentException('You must at least add one voter.'); diff --git a/Core/Authorization/Voter/ExpressionVoter.php b/Core/Authorization/Voter/ExpressionVoter.php index 09953ac..bf6683d 100644 --- a/Core/Authorization/Voter/ExpressionVoter.php +++ b/Core/Authorization/Voter/ExpressionVoter.php @@ -32,7 +32,9 @@ class ExpressionVoter implements VoterInterface /** * Constructor. * - * @param ExpressionLanguage $expressionLanguage + * @param ExpressionLanguage $expressionLanguage + * @param AuthenticationTrustResolverInterface $trustResolver + * @param RoleHierarchyInterface $roleHierarchy */ public function __construct(ExpressionLanguage $expressionLanguage, AuthenticationTrustResolverInterface $trustResolver, RoleHierarchyInterface $roleHierarchy = null) { diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php index b83eb30..aa29876 100644 --- a/Core/Encoder/BasePasswordEncoder.php +++ b/Core/Encoder/BasePasswordEncoder.php @@ -89,6 +89,8 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface /** * Checks if the password is too long. * + * @param string $password The password + * * @return Boolean true if the password is too long, false otherwise */ protected function isPasswordTooLong($password) diff --git a/Core/Encoder/EncoderAwareInterface.php b/Core/Encoder/EncoderAwareInterface.php new file mode 100644 index 0000000..22ae820 --- /dev/null +++ b/Core/Encoder/EncoderAwareInterface.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\Encoder; + +/** + * @author Christophe Coevoet <stof@notk.org> + */ +interface EncoderAwareInterface +{ + /** + * Gets the name of the encoder used to encode the password. + * + * If the method returns null, the standard way to retrieve the encoder + * will be used instead. + * + * @return string + */ + public function getEncoderName(); +} diff --git a/Core/Encoder/EncoderFactory.php b/Core/Encoder/EncoderFactory.php index 8bad61f..bb5ba91 100644 --- a/Core/Encoder/EncoderFactory.php +++ b/Core/Encoder/EncoderFactory.php @@ -30,19 +30,32 @@ class EncoderFactory implements EncoderFactoryInterface */ public function getEncoder($user) { - foreach ($this->encoders as $class => $encoder) { - if ((is_object($user) && !$user instanceof $class) || (!is_object($user) && !is_subclass_of($user, $class) && $user != $class)) { - continue; + $encoderKey = null; + + if ($user instanceof EncoderAwareInterface && (null !== $encoderName = $user->getEncoderName())) { + if (!array_key_exists($encoderName, $this->encoders)) { + throw new \RuntimeException(sprintf('The encoder "%s" was not configured.', $encoderName)); } - if (!$encoder instanceof PasswordEncoderInterface) { - return $this->encoders[$class] = $this->createEncoder($encoder); + $encoderKey = $encoderName; + } else { + foreach ($this->encoders as $class => $encoder) { + if ((is_object($user) && $user instanceof $class) || (!is_object($user) && (is_subclass_of($user, $class) || $user == $class))) { + $encoderKey = $class; + break; + } } + } + + if (null === $encoderKey) { + throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user)); + } - return $this->encoders[$class]; + if (!$this->encoders[$encoderKey] instanceof PasswordEncoderInterface) { + $this->encoders[$encoderKey] = $this->createEncoder($this->encoders[$encoderKey]); } - throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user)); + return $this->encoders[$encoderKey]; } /** diff --git a/Core/README.md b/Core/README.md index 7fc281d..4585a5d 100644 --- a/Core/README.md +++ b/Core/README.md @@ -11,7 +11,7 @@ Resources Documentation: -http://symfony.com/doc/2.4/book/security.html +http://symfony.com/doc/2.5/book/security.html Tests ----- diff --git a/Core/Role/RoleHierarchy.php b/Core/Role/RoleHierarchy.php index 2e7df0e..793007e 100644 --- a/Core/Role/RoleHierarchy.php +++ b/Core/Role/RoleHierarchy.php @@ -19,7 +19,7 @@ namespace Symfony\Component\Security\Core\Role; class RoleHierarchy implements RoleHierarchyInterface { private $hierarchy; - private $map; + protected $map; /** * Constructor. @@ -52,7 +52,7 @@ class RoleHierarchy implements RoleHierarchyInterface return $reachableRoles; } - private function buildRoleMap() + protected function buildRoleMap() { $this->map = array(); foreach ($this->hierarchy as $main => $roles) { diff --git a/Core/Tests/Authorization/AccessDecisionManagerTest.php b/Core/Tests/Authorization/AccessDecisionManagerTest.php index b0557a3..e182838 100644 --- a/Core/Tests/Authorization/AccessDecisionManagerTest.php +++ b/Core/Tests/Authorization/AccessDecisionManagerTest.php @@ -77,34 +77,34 @@ class AccessDecisionManagerTest extends \PHPUnit_Framework_TestCase { return array( // affirmative - array('affirmative', $this->getVoters(1, 0, 0), false, true, true), - array('affirmative', $this->getVoters(1, 2, 0), false, true, true), - array('affirmative', $this->getVoters(0, 1, 0), false, true, false), - array('affirmative', $this->getVoters(0, 0, 1), false, true, false), - array('affirmative', $this->getVoters(0, 0, 1), true, true, true), + array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(1, 0, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(1, 2, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 1, 0), false, true, false), + array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 0, 1), false, true, false), + array(AccessDecisionManager::STRATEGY_AFFIRMATIVE, $this->getVoters(0, 0, 1), true, true, true), // consensus - array('consensus', $this->getVoters(1, 0, 0), false, true, true), - array('consensus', $this->getVoters(1, 2, 0), false, true, false), - array('consensus', $this->getVoters(2, 1, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(1, 0, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(1, 2, 0), false, true, false), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 1, 0), false, true, true), - array('consensus', $this->getVoters(0, 0, 1), false, true, false), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(0, 0, 1), false, true, false), - array('consensus', $this->getVoters(0, 0, 1), true, true, true), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(0, 0, 1), true, true, true), - array('consensus', $this->getVoters(2, 2, 0), false, true, true), - array('consensus', $this->getVoters(2, 2, 1), false, true, true), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 1), false, true, true), - array('consensus', $this->getVoters(2, 2, 0), false, false, false), - array('consensus', $this->getVoters(2, 2, 1), false, false, false), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 0), false, false, false), + array(AccessDecisionManager::STRATEGY_CONSENSUS, $this->getVoters(2, 2, 1), false, false, false), // unanimous - array('unanimous', $this->getVoters(1, 0, 0), false, true, true), - array('unanimous', $this->getVoters(1, 0, 1), false, true, true), - array('unanimous', $this->getVoters(1, 1, 0), false, true, false), + array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 0, 0), false, true, true), + array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 0, 1), false, true, true), + array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(1, 1, 0), false, true, false), - array('unanimous', $this->getVoters(0, 0, 2), false, true, false), - array('unanimous', $this->getVoters(0, 0, 2), true, true, true), + array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(0, 0, 2), false, true, false), + array(AccessDecisionManager::STRATEGY_UNANIMOUS, $this->getVoters(0, 0, 2), true, true, true), ); } diff --git a/Core/Tests/Encoder/EncoderFactoryTest.php b/Core/Tests/Encoder/EncoderFactoryTest.php index 18c8c4a..3d34d04 100644 --- a/Core/Tests/Encoder/EncoderFactoryTest.php +++ b/Core/Tests/Encoder/EncoderFactoryTest.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Core\Tests\Encoder; use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; use Symfony\Component\Security\Core\Encoder\EncoderFactory; +use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; use Symfony\Component\Security\Core\User\User; use Symfony\Component\Security\Core\User\UserInterface; @@ -78,6 +79,59 @@ class EncoderFactoryTest extends \PHPUnit_Framework_TestCase $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); } + + public function testGetNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha256'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha1') + )); + + $encoder = $factory->getEncoder(new EncAwareUser('user', 'pass')); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + public function testGetNullNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $user = new EncAwareUser('user', 'pass'); + $user->encoderName = null; + $encoder = $factory->getEncoder($user); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } + + /** + * @expectedException RuntimeException + */ + public function testGetInvalidNamedEncoderForEncoderAware() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $user = new EncAwareUser('user', 'pass'); + $user->encoderName = 'invalid_encoder_name'; + $encoder = $factory->getEncoder($user); + } + + public function testGetEncoderForEncoderAwareWithClassName() + { + $factory = new EncoderFactory(array( + 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'), + 'encoder_name' => new MessageDigestPasswordEncoder('sha256') + )); + + $encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser'); + $expectedEncoder = new MessageDigestPasswordEncoder('sha1'); + $this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', '')); + } } class SomeUser implements UserInterface @@ -92,3 +146,13 @@ class SomeUser implements UserInterface class SomeChildUser extends SomeUser { } + +class EncAwareUser extends SomeUser implements EncoderAwareInterface +{ + public $encoderName = 'encoder_name'; + + public function getEncoderName() + { + return $this->encoderName; + } +} diff --git a/Core/Validator/Constraints/UserPasswordValidator.php b/Core/Validator/Constraints/UserPasswordValidator.php index ab455f3..5f9ad2a 100644 --- a/Core/Validator/Constraints/UserPasswordValidator.php +++ b/Core/Validator/Constraints/UserPasswordValidator.php @@ -17,6 +17,7 @@ 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\Validator\Exception\UnexpectedTypeException; class UserPasswordValidator extends ConstraintValidator { @@ -34,6 +35,10 @@ class UserPasswordValidator extends ConstraintValidator */ public function validate($password, Constraint $constraint) { + if (!$constraint instanceof UserPassword) { + throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword'); + } + $user = $this->securityContext->getToken()->getUser(); if (!$user instanceof UserInterface) { diff --git a/Core/composer.json b/Core/composer.json index acadcf7..249d4c1 100644 --- a/Core/composer.json +++ b/Core/composer.json @@ -40,7 +40,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "2.5-dev" } } } |