Skip to content

Commit 0b96e82

Browse files
authored
Merge pull request #3048 from stof/fix_deprecation
Fix deprecations reported on Symfony 5.4
2 parents e007993 + fc2710a commit 0b96e82

File tree

10 files changed

+125
-52
lines changed

10 files changed

+125
-52
lines changed

DependencyInjection/Compiler/InjectRememberMeServicesPass.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public function process(ContainerBuilder $container)
3434
$firewallName = $container->getParameter('fos_user.firewall_name');
3535
$loginManager = $container->getDefinition('fos_user.security.login_manager');
3636

37-
if ($container->hasDefinition('security.authentication.rememberme.services.persistent.'.$firewallName)) {
37+
if ($container->has('security.authenticator.remember_me_handler.'.$firewallName)) {
38+
$loginManager->replaceArgument(4, new Reference('security.authenticator.remember_me_handler.'.$firewallName));
39+
} elseif ($container->hasDefinition('security.authentication.rememberme.services.persistent.'.$firewallName)) {
3840
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.persistent.'.$firewallName));
3941
} elseif ($container->hasDefinition('security.authentication.rememberme.services.simplehash.'.$firewallName)) {
4042
$loginManager->replaceArgument(4, new Reference('security.authentication.rememberme.services.simplehash.'.$firewallName));

Security/LoginManager.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1818
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
19+
use Symfony\Component\Security\Core\Authorization\Voter\CacheableVoterInterface;
1920
use Symfony\Component\Security\Core\User\UserCheckerInterface;
21+
use Symfony\Component\Security\Http\RememberMe\RememberMeHandlerInterface;
2022
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
2123
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
2224

@@ -48,23 +50,27 @@ class LoginManager implements LoginManagerInterface
4850
private $requestStack;
4951

5052
/**
51-
* @var RememberMeServicesInterface
53+
* @var RememberMeHandlerInterface|RememberMeServicesInterface|null
5254
*/
53-
private $rememberMeService;
55+
private $rememberMeHandler;
5456

5557
/**
56-
* LoginManager constructor.
58+
* @param RememberMeHandlerInterface|RememberMeServicesInterface|null $rememberMeHandler
5759
*/
5860
public function __construct(TokenStorageInterface $tokenStorage, UserCheckerInterface $userChecker,
5961
SessionAuthenticationStrategyInterface $sessionStrategy,
6062
RequestStack $requestStack,
61-
RememberMeServicesInterface $rememberMeService = null
63+
$rememberMeHandler = null
6264
) {
65+
if (null !== $rememberMeHandler && !$rememberMeHandler instanceof RememberMeHandlerInterface && !$rememberMeHandler instanceof RememberMeServicesInterface) {
66+
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be an instance of "%s|%s|null", "%s" given.', __METHOD__, RememberMeHandlerInterface::class, RememberMeServicesInterface::class, \is_object($rememberMeHandler) ? \get_class($rememberMeHandler) : \gettype($rememberMeHandler)));
67+
}
68+
6369
$this->tokenStorage = $tokenStorage;
6470
$this->userChecker = $userChecker;
6571
$this->sessionStrategy = $sessionStrategy;
6672
$this->requestStack = $requestStack;
67-
$this->rememberMeService = $rememberMeService;
73+
$this->rememberMeHandler = $rememberMeHandler;
6874
}
6975

7076
/**
@@ -80,8 +86,10 @@ final public function logInUser($firewallName, UserInterface $user, Response $re
8086
if (null !== $request) {
8187
$this->sessionStrategy->onAuthentication($request, $token);
8288

83-
if (null !== $response && null !== $this->rememberMeService) {
84-
$this->rememberMeService->loginSuccess($request, $response, $token);
89+
if (null !== $response && $this->rememberMeHandler instanceof RememberMeServicesInterface) {
90+
$this->rememberMeHandler->loginSuccess($request, $response, $token);
91+
} elseif ($this->rememberMeHandler instanceof RememberMeHandlerInterface) {
92+
$this->rememberMeHandler->createRememberMeCookie($user);
8593
}
8694
}
8795

@@ -95,6 +103,11 @@ final public function logInUser($firewallName, UserInterface $user, Response $re
95103
*/
96104
protected function createToken($firewall, UserInterface $user)
97105
{
98-
return new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
106+
// Bc layer for Symfony <5.4
107+
if (!interface_exists(CacheableVoterInterface::class)) {
108+
return new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
109+
}
110+
111+
return new UsernamePasswordToken($user, $firewall, $user->getRoles());
99112
}
100113
}

Tests/Security/EmailProviderTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
1717
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
18+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
1819

1920
class EmailProviderTest extends TestCase
2021
{
@@ -47,7 +48,11 @@ public function testLoadUserByUsername()
4748

4849
public function testLoadUserByInvalidUsername()
4950
{
50-
$this->expectException(UsernameNotFoundException::class);
51+
if (class_exists(UserNotFoundException::class)) {
52+
$this->expectException(UserNotFoundException::class);
53+
} else {
54+
$this->expectException(UsernameNotFoundException::class);
55+
}
5156

5257
$this->userManager->expects($this->once())
5358
->method('findUserByEmail')
@@ -82,7 +87,11 @@ public function testRefreshUserBy()
8287

8388
public function testRefreshDeleted()
8489
{
85-
$this->expectException(UsernameNotFoundException::class);
90+
if (class_exists(UserNotFoundException::class)) {
91+
$this->expectException(UserNotFoundException::class);
92+
} else {
93+
$this->expectException(UsernameNotFoundException::class);
94+
}
8695

8796
$user = $this->getMockForAbstractClass('FOS\UserBundle\Model\User');
8897
$this->userManager->expects($this->once())

Tests/Security/EmailUserProviderTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
1717
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
18+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
1819

1920
class EmailUserProviderTest extends TestCase
2021
{
@@ -47,7 +48,11 @@ public function testLoadUserByUsername()
4748

4849
public function testLoadUserByInvalidUsername()
4950
{
50-
$this->expectException(UsernameNotFoundException::class);
51+
if (class_exists(UserNotFoundException::class)) {
52+
$this->expectException(UserNotFoundException::class);
53+
} else {
54+
$this->expectException(UsernameNotFoundException::class);
55+
}
5156

5257
$this->userManager->expects($this->once())
5358
->method('findUserByUsernameOrEmail')

Tests/Security/LoginManagerTest.php

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,17 @@
1111

1212
namespace FOS\UserBundle\Tests\Security;
1313

14+
use FOS\UserBundle\Model\UserInterface;
1415
use FOS\UserBundle\Security\LoginManager;
1516
use PHPUnit\Framework\TestCase;
17+
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpFoundation\RequestStack;
1619
use Symfony\Component\HttpFoundation\Response;
20+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
21+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
22+
use Symfony\Component\Security\Http\RememberMe\RememberMeHandlerInterface;
23+
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
24+
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
1725

1826
class LoginManagerTest extends TestCase
1927
{
@@ -23,66 +31,79 @@ public function testLogInUserWithRequestStack()
2331
$loginManager->logInUser('main', $this->mockUser());
2432
}
2533

26-
public function testLogInUserWithRememberMeAndRequestStack()
34+
public function testLogInUserWithRememberMeHandler()
2735
{
28-
$response = $this->getMockBuilder('Symfony\Component\HttpFoundation\Response')->getMock();
36+
if (!interface_exists(RememberMeHandlerInterface::class)) {
37+
$this->markTestSkipped('This test requires Symfony 5.3+.');
38+
}
2939

30-
$loginManager = $this->createLoginManager('main', $response);
31-
$loginManager->logInUser('main', $this->mockUser(), $response);
40+
$response = new Response();
41+
$user = $this->mockUser();
42+
43+
$rememberMeHandler = $this->createMock(RememberMeHandlerInterface::class);
44+
$rememberMeHandler->expects($this->once())
45+
->method('createRememberMeCookie')
46+
->with($user);
47+
48+
$loginManager = $this->createLoginManager('main', $rememberMeHandler);
49+
$loginManager->logInUser('main', $user, $response);
3250
}
3351

3452
/**
35-
* @param string $firewallName
36-
*
37-
* @return LoginManager
53+
* @group legacy
3854
*/
39-
private function createLoginManager($firewallName, Response $response = null)
55+
public function testLogInUserWithRememberMeService()
4056
{
41-
$tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock();
57+
if (!interface_exists(RememberMeServicesInterface::class)) {
58+
$this->markTestSkipped('This test does not support Symfony 6+.');
59+
}
60+
61+
$response = new Response();
62+
63+
$rememberMeService = $this->createMock(RememberMeServicesInterface::class);
64+
$rememberMeService
65+
->expects($this->once())
66+
->method('loginSuccess')
67+
->with($this->isInstanceOf(Request::class), $response, $this->isInstanceOf(TokenInterface::class));
68+
69+
$loginManager = $this->createLoginManager('main', $rememberMeService);
70+
$loginManager->logInUser('main', $this->mockUser(), $response);
71+
}
4272

73+
/**
74+
* @param RememberMeHandlerInterface|RememberMeServicesInterface|null $rememberMeHandler
75+
*/
76+
private function createLoginManager(string $firewallName, $rememberMeHandler = null): LoginManager
77+
{
78+
$tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
4379
$tokenStorage
4480
->expects($this->once())
4581
->method('setToken')
46-
->with($this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
82+
->with($this->isInstanceOf(TokenInterface::class));
4783

4884
$userChecker = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserCheckerInterface')->getMock();
4985
$userChecker
5086
->expects($this->once())
5187
->method('checkPreAuth')
52-
->with($this->isInstanceOf('FOS\UserBundle\Model\UserInterface'));
88+
->with($this->isInstanceOf(UserInterface::class));
5389

54-
$request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
90+
$request = new Request();
5591

56-
$sessionStrategy = $this->getMockBuilder('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface')->getMock();
92+
$sessionStrategy = $this->getMockBuilder(SessionAuthenticationStrategyInterface::class)->getMock();
5793
$sessionStrategy
5894
->expects($this->once())
5995
->method('onAuthentication')
60-
->with($request, $this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
96+
->with($request, $this->isInstanceOf(TokenInterface::class));
6197

62-
$requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->getMock();
63-
$requestStack
64-
->expects($this->once())
65-
->method('getCurrentRequest')
66-
->will($this->returnValue($request));
67-
68-
$rememberMe = null;
69-
if (null !== $response) {
70-
$rememberMe = $this->getMockBuilder('Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface')->getMock();
71-
$rememberMe
72-
->expects($this->once())
73-
->method('loginSuccess')
74-
->with($request, $response, $this->isInstanceOf('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
75-
}
98+
$requestStack = new RequestStack();
99+
$requestStack->push($request);
76100

77-
return new LoginManager($tokenStorage, $userChecker, $sessionStrategy, $requestStack, $rememberMe);
101+
return new LoginManager($tokenStorage, $userChecker, $sessionStrategy, $requestStack, $rememberMeHandler);
78102
}
79103

80-
/**
81-
* @return mixed
82-
*/
83-
private function mockUser()
104+
private function mockUser(): UserInterface
84105
{
85-
$user = $this->getMockBuilder('FOS\UserBundle\Model\UserInterface')->getMock();
106+
$user = $this->getMockBuilder(UserInterface::class)->getMock();
86107
$user
87108
->expects($this->once())
88109
->method('getRoles')

Tests/Security/UserProviderTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
1717
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
18+
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
1819

1920
class UserProviderTest extends TestCase
2021
{
@@ -47,7 +48,11 @@ public function testLoadUserByUsername()
4748

4849
public function testLoadUserByInvalidUsername()
4950
{
50-
$this->expectException(UsernameNotFoundException::class);
51+
if (class_exists(UserNotFoundException::class)) {
52+
$this->expectException(UserNotFoundException::class);
53+
} else {
54+
$this->expectException(UsernameNotFoundException::class);
55+
}
5156

5257
$this->userManager->expects($this->once())
5358
->method('findUserByUsername')
@@ -82,7 +87,11 @@ public function testRefreshUserBy()
8287

8388
public function testRefreshDeleted()
8489
{
85-
$this->expectException(UsernameNotFoundException::class);
90+
if (class_exists(UserNotFoundException::class)) {
91+
$this->expectException(UserNotFoundException::class);
92+
} else {
93+
$this->expectException(UsernameNotFoundException::class);
94+
}
8695

8796
$user = $this->getMockForAbstractClass('FOS\UserBundle\Model\User');
8897
$this->userManager->expects($this->once())

Tests/Util/PasswordUpdaterTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,28 @@
1313

1414
use FOS\UserBundle\Tests\TestUser;
1515
use FOS\UserBundle\Util\PasswordUpdater;
16+
use PHPUnit\Framework\MockObject\MockObject;
1617
use PHPUnit\Framework\TestCase;
18+
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
1719

20+
/**
21+
* @group legacy
22+
*/
1823
class PasswordUpdaterTest extends TestCase
1924
{
2025
/**
21-
* @var PasswordUpdater
26+
* @var PasswordUpdater&MockObject
2227
*/
2328
private $updater;
2429
private $encoderFactory;
2530

2631
protected function setUp(): void
2732
{
28-
$this->encoderFactory = $this->getMockBuilder('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface')->getMock();
33+
if (!interface_exists(EncoderFactoryInterface::class)) {
34+
$this->markTestSkipped('The PasswordUpdater class does not support Symfony 6+.');
35+
}
36+
37+
$this->encoderFactory = $this->getMockBuilder(EncoderFactoryInterface::class)->getMock();
2938

3039
$this->updater = new PasswordUpdater($this->encoderFactory);
3140
}

Tests/ignored-deprecations.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SwiftMailer does not put phpdoc on overwritten methods and is not maintained anymore to add them.
2+
/Method "Swift_[^"]++" might add "[^"]++" as a native return type declaration in the future\. Do the same in implementation "Swift_[^"]++" now to avoid errors or add an explicit @return annotation to suppress this message\./
3+
# Weird error reported for symfony/validator
4+
/The "Symfony\\Component\\Validator\\Constraint::\$errorNames" property is considered final\. You should not override it in "Symfony\\Component\\Validator\\Constraints\\NotBlank"\./

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"friendsofphp/php-cs-fixer": "^3.0.2, !=3.5.0",
5252
"swiftmailer/swiftmailer": "^4.3 || ^5.0 || ^6.0",
5353
"symfony/console": "^4.4 || ^5.0",
54-
"symfony/phpunit-bridge": "^5.3",
54+
"symfony/phpunit-bridge": "^6.1",
5555
"symfony/yaml": "^4.4 || ^5.0"
5656
},
5757
"config": {

phpunit.xml.dist

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
</exclude>
1919
</whitelist>
2020
</filter>
21+
2122
<php>
22-
<env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" />
23+
<env name="SYMFONY_DEPRECATIONS_HELPER" value="ignoreFile=Tests/ignored-deprecations.txt&amp;max[total]=0" />
2324
</php>
2425
</phpunit>

0 commit comments

Comments
 (0)