From fa31260e5eb647c2487def360dbd7dc969dd81f0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 May 2020 23:06:01 +0200 Subject: [PATCH 1/4] [DI] fix typo --- src/Symfony/Component/DependencyInjection/EnvVarProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php index cc9fa3b390..6b7ccf2e18 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php @@ -125,7 +125,7 @@ class EnvVarProcessor implements EnvVarProcessorInterface $env = json_decode($env, true); if (JSON_ERROR_NONE !== json_last_error()) { - throw new RuntimeException(sprintf('Invalid JSON in env var "%s": ', $name)).json_last_error_msg(); + throw new RuntimeException(sprintf('Invalid JSON in env var "%s": ', $name).json_last_error_msg()); } if (!\is_array($env)) { From 308f28678cd1d8fb89dcc97a85f6315e5018a75b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 May 2020 23:17:32 +0200 Subject: [PATCH 2/4] [PropertyAccess] fix merge --- src/Symfony/Component/PropertyAccess/PropertyAccessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 7c1f36f7aa..f5e64651ba 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -408,11 +408,11 @@ class PropertyAccessor implements PropertyAccessorInterface // handle uninitialized properties in PHP >= 7 if (__FILE__ === $trace['file'] - && $access[self::ACCESS_NAME] === $trace['function'] + && $name === $trace['function'] && $object instanceof $trace['class'] && preg_match((sprintf('/Return value (?:of .*::\w+\(\) )?must be of (?:the )?type (\w+), null returned$/')), $e->getMessage(), $matches) ) { - throw new UninitializedPropertyException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', false === strpos(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: 'class').'@anonymous', $access[self::ACCESS_NAME], $matches[1]), 0, $e); + throw new UninitializedPropertyException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', false === strpos(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: key(class_implements($object)) ?: 'class').'@anonymous', $name, $matches[1]), 0, $e); } throw $e; From f297beb42cf34ca96a2c994db0ca18a15a25ed69 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 30 May 2020 11:27:30 +0200 Subject: [PATCH 3/4] [Security] Fixed AbstractToken::hasUserChanged() --- .../Authentication/Token/AbstractToken.php | 7 +- .../Token/AbstractTokenTest.php | 67 ++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index de0ebac264..e59997de34 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -317,10 +317,13 @@ abstract class AbstractToken implements TokenInterface return true; } - $currentUserRoles = array_map('strval', (array) $this->user->getRoles()); $userRoles = array_map('strval', (array) $user->getRoles()); - if (\count($userRoles) !== \count($currentUserRoles) || \count($userRoles) !== \count(array_intersect($userRoles, $currentUserRoles))) { + if ($this instanceof SwitchUserToken) { + $userRoles[] = 'ROLE_PREVIOUS_ADMIN'; + } + + if (\count($userRoles) !== \count($this->getRoleNames()) || \count($userRoles) !== \count(array_intersect($userRoles, $this->getRoleNames()))) { return true; } diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php index 031fe49898..b61af1d6ba 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -238,7 +238,7 @@ class AbstractTokenTest extends TestCase */ public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user) { - $token = new ConcreteToken(['ROLE_FOO']); + $token = new ConcreteToken(); $token->setAuthenticated(true); $this->assertTrue($token->isAuthenticated()); @@ -248,6 +248,21 @@ class AbstractTokenTest extends TestCase $token->setUser($user); $this->assertTrue($token->isAuthenticated()); } + + public function testIsUserChangedWhenSerializing() + { + $token = new ConcreteToken(['ROLE_ADMIN']); + $token->setAuthenticated(true); + $this->assertTrue($token->isAuthenticated()); + + $user = new SerializableUser('wouter', ['ROLE_ADMIN']); + $token->setUser($user); + $this->assertTrue($token->isAuthenticated()); + + $token = unserialize(serialize($token)); + $token->setUser($user); + $this->assertTrue($token->isAuthenticated()); + } } class TestUser @@ -265,6 +280,56 @@ class TestUser } } +class SerializableUser implements UserInterface, \Serializable +{ + private $roles; + private $name; + + public function __construct($name, array $roles = []) + { + $this->name = $name; + $this->roles = $roles; + } + + public function getUsername() + { + return $this->name; + } + + public function getPassword() + { + return '***'; + } + + public function getRoles() + { + if (empty($this->roles)) { + return ['ROLE_USER']; + } + + return $this->roles; + } + + public function eraseCredentials() + { + } + + public function getSalt() + { + return null; + } + + public function serialize() + { + return serialize($this->name); + } + + public function unserialize($serialized) + { + $this->name = unserialize($serialized); + } +} + class ConcreteToken extends AbstractToken { private $credentials = 'credentials_value'; From 4807dab305ca85d2f0a0fa04c4a08e48ae2ab420 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 30 May 2020 10:18:13 +0200 Subject: [PATCH 4/4] [Validator] use "allowedVariables" to configure the ExpressionLanguageSyntax constraint --- .../Validator/Constraints/ExpressionLanguageSyntax.php | 3 +-- .../Constraints/ExpressionLanguageSyntaxValidator.php | 5 +++-- ...taxTest.php => ExpressionLanguageSyntaxValidatorTest.php} | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) rename src/Symfony/Component/Validator/Tests/Constraints/{ExpressionLanguageSyntaxTest.php => ExpressionLanguageSyntaxValidatorTest.php} (94%) diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntax.php b/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntax.php index eab003854d..50790fba05 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntax.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntax.php @@ -29,8 +29,7 @@ class ExpressionLanguageSyntax extends Constraint public $message = 'This value should be a valid expression.'; public $service; - public $validateNames = true; - public $names = []; + public $allowedVariables = null; /** * {@inheritdoc} diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntaxValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntaxValidator.php index e7104452e7..4b67da2c2b 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntaxValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionLanguageSyntaxValidator.php @@ -16,6 +16,7 @@ use Symfony\Component\ExpressionLanguage\SyntaxError; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; +use Symfony\Component\Validator\Exception\UnexpectedValueException; /** * @author Andrey Sevastianov @@ -39,7 +40,7 @@ class ExpressionLanguageSyntaxValidator extends ConstraintValidator } if (!\is_string($expression)) { - throw new UnexpectedTypeException($expression, 'string'); + throw new UnexpectedValueException($expression, 'string'); } if (null === $this->expressionLanguage) { @@ -47,7 +48,7 @@ class ExpressionLanguageSyntaxValidator extends ConstraintValidator } try { - $this->expressionLanguage->lint($expression, ($constraint->validateNames ? ($constraint->names ?? []) : null)); + $this->expressionLanguage->lint($expression, $constraint->allowedVariables); } catch (SyntaxError $exception) { $this->context->buildViolation($constraint->message) ->setParameter('{{ syntax_error }}', $this->formatValue($exception->getMessage())) diff --git a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxTest.php b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxValidatorTest.php similarity index 94% rename from src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxTest.php rename to src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxValidatorTest.php index dc80288c38..7db835b333 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/ExpressionLanguageSyntaxValidatorTest.php @@ -18,7 +18,7 @@ use Symfony\Component\Validator\Constraints\ExpressionLanguageSyntax; use Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator; use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; -class ExpressionLanguageSyntaxTest extends ConstraintValidatorTestCase +class ExpressionLanguageSyntaxValidatorTest extends ConstraintValidatorTestCase { /** * @var \PHPUnit\Framework\MockObject\MockObject|ExpressionLanguage @@ -45,6 +45,7 @@ class ExpressionLanguageSyntaxTest extends ConstraintValidatorTestCase $this->validator->validate($this->value, new ExpressionLanguageSyntax([ 'message' => 'myMessage', + 'allowedVariables' => [], ])); $this->assertNoViolation(); @@ -58,7 +59,6 @@ class ExpressionLanguageSyntaxTest extends ConstraintValidatorTestCase $this->validator->validate($this->value, new ExpressionLanguageSyntax([ 'message' => 'myMessage', - 'validateNames' => false, ])); $this->assertNoViolation(); @@ -73,6 +73,7 @@ class ExpressionLanguageSyntaxTest extends ConstraintValidatorTestCase $this->validator->validate($this->value, new ExpressionLanguageSyntax([ 'message' => 'myMessage', + 'allowedVariables' => [], ])); $this->buildViolation('myMessage')