Skip to content

Commit 0c0f95f

Browse files
committed
[Security] Move the Security helper to SecurityBundle
1 parent a10071b commit 0c0f95f

29 files changed

+257
-73
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@
186186
use Symfony\Component\RateLimiter\Storage\CacheStorage;
187187
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
188188
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
189+
use Symfony\Component\Security\Core\AuthenticationEvents;
189190
use Symfony\Component\Security\Core\Exception\AuthenticationException;
190-
use Symfony\Component\Security\Core\Security;
191191
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
192192
use Symfony\Component\Semaphore\PersistingStoreInterface as SemaphoreStoreInterface;
193193
use Symfony\Component\Semaphore\Semaphore;
@@ -1020,7 +1020,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
10201020
throw new LogicException('Cannot guard workflows as the ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
10211021
}
10221022

1023-
if (!class_exists(Security::class)) {
1023+
if (!class_exists(AuthenticationEvents::class)) {
10241024
throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security-core".');
10251025
}
10261026

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
use Symfony\Component\HttpKernel\Fragment\FragmentUriGeneratorInterface;
5858
use Symfony\Component\Messenger\Transport\TransportFactory;
5959
use Symfony\Component\PropertyAccess\PropertyAccessor;
60-
use Symfony\Component\Security\Core\Security;
60+
use Symfony\Component\Security\Core\AuthenticationEvents;
6161
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
6262
use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
6363
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
@@ -1036,7 +1036,7 @@ public function testTranslator()
10361036
$files,
10371037
'->registerTranslatorConfiguration() finds Form translation resources'
10381038
);
1039-
$ref = new \ReflectionClass(Security::class);
1039+
$ref = new \ReflectionClass(AuthenticationEvents::class);
10401040
$this->assertContains(
10411041
strtr(\dirname($ref->getFileName()).'/Resources/translations/security.en.xlf', '/', \DIRECTORY_SEPARATOR),
10421042
$files,

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.2
5+
---
6+
7+
8+
* Add the `Security` helper class
9+
410
6.1
511
---
612

src/Symfony/Bundle/SecurityBundle/Resources/config/security.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
1818
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
1919
use Symfony\Bundle\SecurityBundle\Security\LazyFirewallContext;
20+
use Symfony\Bundle\SecurityBundle\Security\Security;
2021
use Symfony\Component\Ldap\Security\LdapUserProvider;
2122
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver;
2223
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
@@ -33,7 +34,6 @@
3334
use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter;
3435
use Symfony\Component\Security\Core\Role\RoleHierarchy;
3536
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
36-
use Symfony\Component\Security\Core\Security;
3737
use Symfony\Component\Security\Core\User\ChainUserProvider;
3838
use Symfony\Component\Security\Core\User\InMemoryUserChecker;
3939
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Security;
13+
14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\Security\Core\Security as LegacySecurity;
16+
17+
/**
18+
* Helper class for commonly-needed security tasks.
19+
*
20+
* @final
21+
*/
22+
class Security extends LegacySecurity
23+
{
24+
public function __construct(ContainerInterface $container)
25+
{
26+
parent::__construct($container, false);
27+
}
28+
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AuthenticatorBundle/LoginFormAuthenticator.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
1818
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19-
use Symfony\Component\Security\Core\Security;
2019
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
2120
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
2221
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
2322
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
23+
use Symfony\Component\Security\Http\SecurityRequestAttributes;
2424
use Symfony\Component\Security\Http\Util\TargetPathTrait;
2525

2626
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
@@ -39,7 +39,7 @@ public function authenticate(Request $request): Passport
3939
{
4040
$username = $request->request->get('_username', '');
4141

42-
$request->getSession()->set(Security::LAST_USERNAME, $username);
42+
$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $username);
4343

4444
return new Passport(
4545
new UserBadge($username),

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginType.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use Symfony\Component\Form\FormEvents;
1919
use Symfony\Component\HttpFoundation\RequestStack;
2020
use Symfony\Component\OptionsResolver\OptionsResolver;
21-
use Symfony\Component\Security\Core\Security;
21+
use Symfony\Component\Security\Http\SecurityRequestAttributes;
2222

2323
/**
2424
* Form type for use with the Security component's form-based authentication
@@ -55,18 +55,18 @@ public function buildForm(FormBuilderInterface $builder, array $options)
5555
* session for an authentication error and last username.
5656
*/
5757
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($request) {
58-
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
59-
$error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
58+
if ($request->attributes->has(SecurityRequestAttributes::AUTHENTICATION_ERROR)) {
59+
$error = $request->attributes->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
6060
} else {
61-
$error = $request->getSession()->get(Security::AUTHENTICATION_ERROR);
61+
$error = $request->getSession()->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
6262
}
6363

6464
if ($error) {
6565
$event->getForm()->addError(new FormError($error->getMessage()));
6666
}
6767

6868
$event->setData(array_replace((array) $event->getData(), [
69-
'username' => $request->getSession()->get(Security::LAST_USERNAME),
69+
'username' => $request->getSession()->get(SecurityRequestAttributes::LAST_USERNAME),
7070
]));
7171
});
7272
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LocalizedController.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Psr\Container\ContainerInterface;
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
17-
use Symfony\Component\Security\Core\Security;
17+
use Symfony\Component\Security\Http\SecurityRequestAttributes;
1818
use Symfony\Contracts\Service\ServiceSubscriberInterface;
1919
use Twig\Environment;
2020

@@ -30,15 +30,15 @@ public function __construct(ContainerInterface $container)
3030
public function loginAction(Request $request)
3131
{
3232
// get the login error if there is one
33-
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
34-
$error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
33+
if ($request->attributes->has(SecurityRequestAttributes::AUTHENTICATION_ERROR)) {
34+
$error = $request->attributes->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
3535
} else {
36-
$error = $request->getSession()->get(Security::AUTHENTICATION_ERROR);
36+
$error = $request->getSession()->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
3737
}
3838

3939
return new Response($this->container->get('twig')->render('@FormLogin/Localized/login.html.twig', [
4040
// last username entered by the user
41-
'last_username' => $request->getSession()->get(Security::LAST_USERNAME),
41+
'last_username' => $request->getSession()->get(SecurityRequestAttributes::LAST_USERNAME),
4242
'error' => $error,
4343
]));
4444
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Controller/LoginController.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
18-
use Symfony\Component\Security\Core\Security;
1918
use Symfony\Component\Security\Core\User\UserInterface;
19+
use Symfony\Component\Security\Http\SecurityRequestAttributes;
2020
use Symfony\Contracts\Service\ServiceSubscriberInterface;
2121
use Twig\Environment;
2222

@@ -32,15 +32,15 @@ public function __construct(ContainerInterface $container)
3232
public function loginAction(Request $request, UserInterface $user = null)
3333
{
3434
// get the login error if there is one
35-
if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
36-
$error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
35+
if ($request->attributes->has(SecurityRequestAttributes::AUTHENTICATION_ERROR)) {
36+
$error = $request->attributes->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
3737
} else {
38-
$error = $request->getSession()->get(Security::AUTHENTICATION_ERROR);
38+
$error = $request->getSession()->get(SecurityRequestAttributes::AUTHENTICATION_ERROR);
3939
}
4040

4141
return new Response($this->container->get('twig')->render('@FormLogin/Login/login.html.twig', [
4242
// last username entered by the user
43-
'last_username' => $request->getSession()->get(Security::LAST_USERNAME),
43+
'last_username' => $request->getSession()->get(SecurityRequestAttributes::LAST_USERNAME),
4444
'error' => $error,
4545
]));
4646
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Tests\Security;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Psr\Container\ContainerInterface;
16+
use Symfony\Bundle\SecurityBundle\Security\Security;
17+
use Symfony\Component\DependencyInjection\ServiceLocator;
18+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
19+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
20+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
21+
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
22+
use Symfony\Component\Security\Core\User\InMemoryUser;
23+
24+
class SecurityTest extends TestCase
25+
{
26+
public function testGetToken()
27+
{
28+
$token = new UsernamePasswordToken(new InMemoryUser('foo', 'bar'), 'provider');
29+
$tokenStorage = $this->createMock(TokenStorageInterface::class);
30+
31+
$tokenStorage->expects($this->once())
32+
->method('getToken')
33+
->willReturn($token);
34+
35+
$container = $this->createContainer('security.token_storage', $tokenStorage);
36+
37+
$security = new Security($container);
38+
$this->assertSame($token, $security->getToken());
39+
}
40+
41+
/**
42+
* @dataProvider getUserTests
43+
*/
44+
public function testGetUser($userInToken, $expectedUser)
45+
{
46+
$token = $this->createMock(TokenInterface::class);
47+
$token->expects($this->any())
48+
->method('getUser')
49+
->willReturn($userInToken);
50+
$tokenStorage = $this->createMock(TokenStorageInterface::class);
51+
52+
$tokenStorage->expects($this->once())
53+
->method('getToken')
54+
->willReturn($token);
55+
56+
$container = $this->createContainer('security.token_storage', $tokenStorage);
57+
58+
$security = new Security($container);
59+
$this->assertSame($expectedUser, $security->getUser());
60+
}
61+
62+
public function getUserTests()
63+
{
64+
yield [null, null];
65+
66+
$user = new InMemoryUser('nice_user', 'foo');
67+
yield [$user, $user];
68+
}
69+
70+
public function testIsGranted()
71+
{
72+
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
73+
74+
$authorizationChecker->expects($this->once())
75+
->method('isGranted')
76+
->with('SOME_ATTRIBUTE', 'SOME_SUBJECT')
77+
->willReturn(true);
78+
79+
$container = $this->createContainer('security.authorization_checker', $authorizationChecker);
80+
81+
$security = new Security($container);
82+
$this->assertTrue($security->isGranted('SOME_ATTRIBUTE', 'SOME_SUBJECT'));
83+
}
84+
85+
private function createContainer(string $serviceId, object $serviceObject): ContainerInterface
86+
{
87+
return new ServiceLocator([$serviceId => fn () => $serviceObject]);
88+
}
89+
}

src/Symfony/Bundle/SecurityBundle/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"symfony/password-hasher": "^5.4|^6.0",
2828
"symfony/security-core": "^5.4|^6.0",
2929
"symfony/security-csrf": "^5.4|^6.0",
30-
"symfony/security-http": "^5.4|^6.0"
30+
"symfony/security-http": "^6.2"
3131
},
3232
"require-dev": {
3333
"doctrine/annotations": "^1.10.4",

src/Symfony/Component/Security/Core/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.2
5+
---
6+
7+
* Deprecate the `Security` class, use `Symfony\Bundle\SecurityBundle\Security\Security` instead
8+
49
6.0
510
---
611

src/Symfony/Component/Security/Core/Security.php

+31-2
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,56 @@
1212
namespace Symfony\Component\Security\Core;
1313

1414
use Psr\Container\ContainerInterface;
15+
use Symfony\Bundle\SecurityBundle\Security\Security as NewSecurityHelper;
1516
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1617
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
1718
use Symfony\Component\Security\Core\User\UserInterface;
1819

1920
/**
2021
* Helper class for commonly-needed security tasks.
2122
*
22-
* @final
23+
* @deprecated since Symfony 6.2, use \Symfony\Bundle\SecurityBundle\Security\Security instead
2324
*/
2425
class Security implements AuthorizationCheckerInterface
2526
{
27+
/**
28+
* @deprecated since Symfony 6.2, use \Symfony\Bundle\SecurityBundle\Security\Security::ACCESS_DENIED_ERROR instead
29+
*
30+
* In 7.0, move this constant to the NewSecurityHelper class and make it reference SecurityRequestAttributes:ACCESS_DENIED_ERROR.
31+
*/
2632
public const ACCESS_DENIED_ERROR = '_security.403_error';
33+
34+
/**
35+
* @deprecated since Symfony 6.2, use \Symfony\Bundle\SecurityBundle\Security\Security::AUTHENTICATION_ERROR instead
36+
*
37+
* In 7.0, move this constant to the NewSecurityHelper class and make it reference SecurityRequestAttributes:AUTHENTICATION_ERROR.
38+
*/
2739
public const AUTHENTICATION_ERROR = '_security.last_error';
40+
41+
/**
42+
* @deprecated since Symfony 6.2, use \Symfony\Bundle\SecurityBundle\Security\Security::LAST_USERNAME instead
43+
*
44+
* In 7.0, move this constant to the NewSecurityHelper class and make it reference SecurityRequestAttributes:LAST_USERNAME.
45+
*/
2846
public const LAST_USERNAME = '_security.last_username';
47+
48+
/**
49+
* @deprecated since Symfony 6.2, use \Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface::MAX_USERNAME_LENGTH instead
50+
*
51+
* In 7.0, move this constant to the NewSecurityHelper class and make it reference AuthenticatorInterface:MAX_USERNAME_LENGTH.
52+
53+
*/
2954
public const MAX_USERNAME_LENGTH = 4096;
3055

3156
private ContainerInterface $container;
3257

33-
public function __construct(ContainerInterface $container)
58+
public function __construct(ContainerInterface $container, bool $triggerDeprecation = true)
3459
{
3560
$this->container = $container;
61+
62+
if ($triggerDeprecation) {
63+
trigger_deprecation('symfony/security-core', '6.2', 'The "%s" class is deprecated, use "%s" instead.', __CLASS__, NewSecurityHelper::class);
64+
}
3665
}
3766

3867
public function getUser(): ?UserInterface

src/Symfony/Component/Security/Core/Tests/SecurityTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use Symfony\Component\Security\Core\Security;
2121
use Symfony\Component\Security\Core\User\InMemoryUser;
2222

23+
/**
24+
* @group legacy
25+
*/
2326
class SecurityTest extends TestCase
2427
{
2528
public function testGetToken()

0 commit comments

Comments
 (0)