Merge branch '4.3' into 4.4
* 4.3: [Yaml] Throw on unquoted exclamation mark Use supportsClass where possible
This commit is contained in:
commit
9d33550945
@ -70,24 +70,49 @@ class ChainUserProviderTest extends TestCase
|
|||||||
$provider1 = $this->getProvider();
|
$provider1 = $this->getProvider();
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('supportsClass')
|
||||||
->willThrowException(new UnsupportedUserException('unsupported'))
|
->willReturn(false)
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->getProvider();
|
$provider2 = $this->getProvider();
|
||||||
$provider2
|
$provider2
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
|
$provider2
|
||||||
|
->expects($this->once())
|
||||||
|
->method('refreshUser')
|
||||||
|
->willThrowException(new UnsupportedUserException('unsupported'))
|
||||||
|
;
|
||||||
|
|
||||||
|
$provider3 = $this->getProvider();
|
||||||
|
$provider3
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
|
$provider3
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
->willReturn($account = $this->getAccount())
|
->willReturn($account = $this->getAccount())
|
||||||
;
|
;
|
||||||
|
|
||||||
$provider = new ChainUserProvider([$provider1, $provider2]);
|
$provider = new ChainUserProvider([$provider1, $provider2, $provider3]);
|
||||||
$this->assertSame($account, $provider->refreshUser($this->getAccount()));
|
$this->assertSame($account, $provider->refreshUser($this->getAccount()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshUserAgain()
|
public function testRefreshUserAgain()
|
||||||
{
|
{
|
||||||
$provider1 = $this->getProvider();
|
$provider1 = $this->getProvider();
|
||||||
|
$provider1
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
@ -95,6 +120,12 @@ class ChainUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->getProvider();
|
$provider2 = $this->getProvider();
|
||||||
|
$provider2
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
@ -109,6 +140,12 @@ class ChainUserProviderTest extends TestCase
|
|||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\Security\Core\Exception\UnsupportedUserException');
|
$this->expectException('Symfony\Component\Security\Core\Exception\UnsupportedUserException');
|
||||||
$provider1 = $this->getProvider();
|
$provider1 = $this->getProvider();
|
||||||
|
$provider1
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
@ -116,6 +153,12 @@ class ChainUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->getProvider();
|
$provider2 = $this->getProvider();
|
||||||
|
$provider2
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
@ -173,6 +216,12 @@ class ChainUserProviderTest extends TestCase
|
|||||||
public function testAcceptsTraversable()
|
public function testAcceptsTraversable()
|
||||||
{
|
{
|
||||||
$provider1 = $this->getProvider();
|
$provider1 = $this->getProvider();
|
||||||
|
$provider1
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider1
|
$provider1
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
@ -180,6 +229,12 @@ class ChainUserProviderTest extends TestCase
|
|||||||
;
|
;
|
||||||
|
|
||||||
$provider2 = $this->getProvider();
|
$provider2 = $this->getProvider();
|
||||||
|
$provider2
|
||||||
|
->expects($this->once())
|
||||||
|
->method('supportsClass')
|
||||||
|
->willReturn(true)
|
||||||
|
;
|
||||||
|
|
||||||
$provider2
|
$provider2
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('refreshUser')
|
->method('refreshUser')
|
||||||
|
@ -73,6 +73,10 @@ class ChainUserProvider implements UserProviderInterface, PasswordUpgraderInterf
|
|||||||
|
|
||||||
foreach ($this->providers as $provider) {
|
foreach ($this->providers as $provider) {
|
||||||
try {
|
try {
|
||||||
|
if (!$provider->supportsClass(\get_class($user))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return $provider->refreshUser($user);
|
return $provider->refreshUser($user);
|
||||||
} catch (UnsupportedUserException $e) {
|
} catch (UnsupportedUserException $e) {
|
||||||
// try next one
|
// try next one
|
||||||
|
@ -218,12 +218,17 @@ class ContextListener extends AbstractListener implements ListenerInterface
|
|||||||
|
|
||||||
$userNotFoundByProvider = false;
|
$userNotFoundByProvider = false;
|
||||||
$userDeauthenticated = false;
|
$userDeauthenticated = false;
|
||||||
|
$userClass = \get_class($user);
|
||||||
|
|
||||||
foreach ($this->userProviders as $provider) {
|
foreach ($this->userProviders as $provider) {
|
||||||
if (!$provider instanceof UserProviderInterface) {
|
if (!$provider instanceof UserProviderInterface) {
|
||||||
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "%s".', \get_class($provider), UserProviderInterface::class));
|
throw new \InvalidArgumentException(sprintf('User provider "%s" must implement "%s".', \get_class($provider), UserProviderInterface::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$provider->supportsClass($userClass)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$refreshedUser = $provider->refreshUser($user);
|
$refreshedUser = $provider->refreshUser($user);
|
||||||
$newToken = clone $token;
|
$newToken = clone $token;
|
||||||
@ -287,7 +292,7 @@ class ContextListener extends AbstractListener implements ListenerInterface
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', \get_class($user)));
|
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', $userClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function safelyUnserialize(string $serializedToken)
|
private function safelyUnserialize(string $serializedToken)
|
||||||
|
@ -253,7 +253,7 @@ class ContextListenerTest extends TestCase
|
|||||||
public function testIfTokenIsDeauthenticated()
|
public function testIfTokenIsDeauthenticated()
|
||||||
{
|
{
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$refreshedUser = new User('foobar', 'baz');
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]);
|
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]);
|
||||||
|
|
||||||
$this->assertNull($tokenStorage->getToken());
|
$this->assertNull($tokenStorage->getToken());
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ class ContextListenerTest extends TestCase
|
|||||||
$rememberMeServices = $this->createMock(RememberMeServicesInterface::class);
|
$rememberMeServices = $this->createMock(RememberMeServicesInterface::class);
|
||||||
$rememberMeServices->expects($this->once())->method('loginFail');
|
$rememberMeServices->expects($this->once())->method('loginFail');
|
||||||
|
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], null, $rememberMeServices);
|
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, $rememberMeServices);
|
||||||
|
|
||||||
$this->assertNull($tokenStorage->getToken());
|
$this->assertNull($tokenStorage->getToken());
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ class ContextListenerTest extends TestCase
|
|||||||
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
|
public function testTryAllUserProvidersUntilASupportingUserProviderIsFound()
|
||||||
{
|
{
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$refreshedUser = new User('foobar', 'baz');
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser);
|
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
|
||||||
|
|
||||||
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
||||||
}
|
}
|
||||||
@ -291,14 +291,14 @@ class ContextListenerTest extends TestCase
|
|||||||
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
|
public function testNextSupportingUserProviderIsTriedIfPreviousSupportingUserProviderDidNotLoadTheUser()
|
||||||
{
|
{
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$refreshedUser = new User('foobar', 'baz');
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession([new SupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser);
|
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
|
||||||
|
|
||||||
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
|
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
|
||||||
{
|
{
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new SupportingUserProvider()]);
|
$tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider()]);
|
||||||
|
|
||||||
$this->assertNull($tokenStorage->getToken());
|
$this->assertNull($tokenStorage->getToken());
|
||||||
}
|
}
|
||||||
@ -306,13 +306,13 @@ class ContextListenerTest extends TestCase
|
|||||||
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
|
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
|
||||||
{
|
{
|
||||||
$this->expectException('RuntimeException');
|
$this->expectException('RuntimeException');
|
||||||
$this->handleEventWithPreviousSession([new NotSupportingUserProvider(), new NotSupportingUserProvider()]);
|
$this->handleEventWithPreviousSession([new NotSupportingUserProvider(false), new NotSupportingUserProvider(true)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAcceptsProvidersAsTraversable()
|
public function testAcceptsProvidersAsTraversable()
|
||||||
{
|
{
|
||||||
$refreshedUser = new User('foobar', 'baz');
|
$refreshedUser = new User('foobar', 'baz');
|
||||||
$tokenStorage = $this->handleEventWithPreviousSession(new \ArrayObject([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
|
$tokenStorage = $this->handleEventWithPreviousSession(new \ArrayObject([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
|
||||||
|
|
||||||
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
|
||||||
}
|
}
|
||||||
@ -338,7 +338,7 @@ class ContextListenerTest extends TestCase
|
|||||||
$this->assertNotEquals($event->getRefreshedToken()->getUser(), $user);
|
$this->assertNotEquals($event->getRefreshedToken()->getUser(), $user);
|
||||||
});
|
});
|
||||||
|
|
||||||
$listener = new ContextListener($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], 'context_key', null, $eventDispatcher);
|
$listener = new ContextListener($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], 'context_key', null, $eventDispatcher);
|
||||||
$listener(new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
|
$listener(new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST));
|
||||||
|
|
||||||
$this->assertNull($tokenStorage->getToken());
|
$this->assertNull($tokenStorage->getToken());
|
||||||
@ -431,6 +431,14 @@ class ContextListenerTest extends TestCase
|
|||||||
|
|
||||||
class NotSupportingUserProvider implements UserProviderInterface
|
class NotSupportingUserProvider implements UserProviderInterface
|
||||||
{
|
{
|
||||||
|
/** @var bool */
|
||||||
|
private $throwsUnsupportedException;
|
||||||
|
|
||||||
|
public function __construct($throwsUnsupportedException)
|
||||||
|
{
|
||||||
|
$this->throwsUnsupportedException = $throwsUnsupportedException;
|
||||||
|
}
|
||||||
|
|
||||||
public function loadUserByUsername($username): UserInterface
|
public function loadUserByUsername($username): UserInterface
|
||||||
{
|
{
|
||||||
throw new UsernameNotFoundException();
|
throw new UsernameNotFoundException();
|
||||||
@ -438,7 +446,11 @@ class NotSupportingUserProvider implements UserProviderInterface
|
|||||||
|
|
||||||
public function refreshUser(UserInterface $user): UserInterface
|
public function refreshUser(UserInterface $user): UserInterface
|
||||||
{
|
{
|
||||||
throw new UnsupportedUserException();
|
if ($this->throwsUnsupportedException) {
|
||||||
|
throw new UnsupportedUserException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supportsClass($class): bool
|
public function supportsClass($class): bool
|
||||||
|
@ -679,6 +679,10 @@ class Inline
|
|||||||
$nextOffset = $i + $tagLength + 1;
|
$nextOffset = $i + $tagLength + 1;
|
||||||
$nextOffset += strspn($value, ' ', $nextOffset);
|
$nextOffset += strspn($value, ' ', $nextOffset);
|
||||||
|
|
||||||
|
if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) {
|
||||||
|
throw new ParseException(sprintf('Using the unquoted scalar value "!" is not supported. You must quote it.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
|
||||||
|
}
|
||||||
|
|
||||||
// Is followed by a scalar and is a built-in tag
|
// Is followed by a scalar and is a built-in tag
|
||||||
if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
|
if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
|
||||||
// Manage in {@link self::evaluateScalar()}
|
// Manage in {@link self::evaluateScalar()}
|
||||||
|
@ -737,4 +737,69 @@ class InlineTest extends TestCase
|
|||||||
'negative octal number' => [-28, '-034'],
|
'negative octal number' => [-28, '-034'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider unquotedExclamationMarkThrowsProvider
|
||||||
|
*/
|
||||||
|
public function testUnquotedExclamationMarkThrows(string $value)
|
||||||
|
{
|
||||||
|
$this->expectException(ParseException::class);
|
||||||
|
$this->expectExceptionMessageRegExp('/^Using the unquoted scalar value "!" is not supported\. You must quote it at line 1 \(near "/');
|
||||||
|
|
||||||
|
Inline::parse($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unquotedExclamationMarkThrowsProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['!'],
|
||||||
|
['! '],
|
||||||
|
['! '],
|
||||||
|
[' ! '],
|
||||||
|
['[!]'],
|
||||||
|
['[! ]'],
|
||||||
|
['[! ]'],
|
||||||
|
['[!, "foo"]'],
|
||||||
|
['["foo", !, "ccc"]'],
|
||||||
|
['{foo: !}'],
|
||||||
|
['{foo: !}'],
|
||||||
|
['{foo: !, bar: "ccc"}'],
|
||||||
|
['{bar: "ccc", foo: ! }'],
|
||||||
|
['!]]]'],
|
||||||
|
['!}'],
|
||||||
|
['!,}foo,]'],
|
||||||
|
['! [!]'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider quotedExclamationMarkProvider
|
||||||
|
*/
|
||||||
|
public function testQuotedExclamationMark($expected, string $value)
|
||||||
|
{
|
||||||
|
$this->assertSame($expected, Inline::parse($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This provider should stay consistent with unquotedExclamationMarkThrowsProvider
|
||||||
|
public function quotedExclamationMarkProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['!', '"!"'],
|
||||||
|
['! ', '"! "'],
|
||||||
|
[' !', '" !"'],
|
||||||
|
[' ! ', '" ! "'],
|
||||||
|
[['!'], '["!"]'],
|
||||||
|
[['! '], '["! "]'],
|
||||||
|
[['!', 'foo'], '["!", "foo"]'],
|
||||||
|
[['foo', '!', 'ccc'], '["foo", "!", "ccc"]'],
|
||||||
|
[['foo' => '!'], '{foo: "!"}'],
|
||||||
|
[['foo' => ' !'], '{foo: " !"}'],
|
||||||
|
[['foo' => '!', 'bar' => 'ccc'], '{foo: "!", bar: "ccc"}'],
|
||||||
|
[['bar' => 'ccc', 'foo' => '! '], '{bar: "ccc", foo: "! "}'],
|
||||||
|
['!]]]', '"!]]]"'],
|
||||||
|
['!}', '"!}"'],
|
||||||
|
['!,}foo,]', '"!,}foo,]"'],
|
||||||
|
[['!'], '! ["!"]'],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user