Use supportsClass where possible

This commit is contained in:
Lynn 2019-12-20 16:07:22 +01:00
parent 135c6f7d9d
commit d3942cbe17
4 changed files with 88 additions and 12 deletions

View File

@ -68,24 +68,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')
@ -93,6 +118,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')
@ -107,6 +138,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')
@ -114,6 +151,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')
@ -171,6 +214,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')
@ -178,6 +227,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')

View File

@ -73,6 +73,10 @@ class ChainUserProvider implements UserProviderInterface
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

View File

@ -168,12 +168,17 @@ class ContextListener 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;
@ -233,7 +238,7 @@ class ContextListener 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($serializedToken) private function safelyUnserialize($serializedToken)

View File

@ -256,7 +256,7 @@ class ContextListenerTest extends TestCase
{ {
$tokenStorage = new TokenStorage(); $tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz'); $refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]); $this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser()); $this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
} }
@ -265,7 +265,7 @@ class ContextListenerTest extends TestCase
{ {
$tokenStorage = new TokenStorage(); $tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz'); $refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], null, true); $this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, true);
$this->assertNull($tokenStorage->getToken()); $this->assertNull($tokenStorage->getToken());
} }
@ -287,7 +287,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');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], null, true, $rememberMeServices); $this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, true, $rememberMeServices);
$this->assertNull($tokenStorage->getToken()); $this->assertNull($tokenStorage->getToken());
} }
@ -296,7 +296,7 @@ class ContextListenerTest extends TestCase
{ {
$tokenStorage = new TokenStorage(); $tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz'); $refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)], $refreshedUser); $this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser()); $this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
} }
@ -313,7 +313,7 @@ class ContextListenerTest extends TestCase
public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders() public function testTokenIsSetToNullIfNoUserWasLoadedByTheRegisteredUserProviders()
{ {
$tokenStorage = new TokenStorage(); $tokenStorage = new TokenStorage();
$this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(), new SupportingUserProvider()]); $this->handleEventWithPreviousSession($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider()]);
$this->assertNull($tokenStorage->getToken()); $this->assertNull($tokenStorage->getToken());
} }
@ -321,14 +321,14 @@ class ContextListenerTest extends TestCase
public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered() public function testRuntimeExceptionIsThrownIfNoSupportingUserProviderWasRegistered()
{ {
$this->expectException('RuntimeException'); $this->expectException('RuntimeException');
$this->handleEventWithPreviousSession(new TokenStorage(), [new NotSupportingUserProvider(), new NotSupportingUserProvider()]); $this->handleEventWithPreviousSession(new TokenStorage(), [new NotSupportingUserProvider(false), new NotSupportingUserProvider(true)]);
} }
public function testAcceptsProvidersAsTraversable() public function testAcceptsProvidersAsTraversable()
{ {
$tokenStorage = new TokenStorage(); $tokenStorage = new TokenStorage();
$refreshedUser = new User('foobar', 'baz'); $refreshedUser = new User('foobar', 'baz');
$this->handleEventWithPreviousSession($tokenStorage, new \ArrayObject([new NotSupportingUserProvider(), new SupportingUserProvider($refreshedUser)]), $refreshedUser); $this->handleEventWithPreviousSession($tokenStorage, new \ArrayObject([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)]), $refreshedUser);
$this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser()); $this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser());
} }
@ -383,6 +383,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) public function loadUserByUsername($username)
{ {
throw new UsernameNotFoundException(); throw new UsernameNotFoundException();
@ -390,7 +398,11 @@ class NotSupportingUserProvider implements UserProviderInterface
public function refreshUser(UserInterface $user) public function refreshUser(UserInterface $user)
{ {
throw new UnsupportedUserException(); if ($this->throwsUnsupportedException) {
throw new UnsupportedUserException();
}
return $user;
} }
public function supportsClass($class) public function supportsClass($class)