diff --git a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php index 4a23cb42a0580..ad48ed7323c40 100644 --- a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php @@ -117,8 +117,7 @@ public function createNewToken(PersistentTokenInterface $token) $sql = 'INSERT INTO rememberme_token (class, username, series, value, lastUsed) VALUES (:class, :username, :series, :value, :lastUsed)'; $paramValues = [ 'class' => $token->getClass(), - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - 'username' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(), + 'username' => $token->getUserIdentifier(), 'series' => $token->getSeries(), 'value' => $token->getTokenValue(), 'lastUsed' => $token->getLastUsed(), diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 7b9cc03222dfd..dc7bfdd7bfd95 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -46,16 +46,6 @@ public function __construct(ManagerRegistry $registry, string $classOrAlias, str $this->property = $property; } - /** - * {@inheritdoc} - */ - public function loadUserByUsername(string $username): UserInterface - { - trigger_deprecation('symfony/doctrine-bridge', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__); - - return $this->loadUserByIdentifier($username); - } - public function loadUserByIdentifier(string $identifier): UserInterface { $repository = $this->getRepository(); @@ -66,14 +56,7 @@ public function loadUserByIdentifier(string $identifier): UserInterface throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, get_debug_type($repository))); } - // @deprecated since Symfony 5.3, change to $repository->loadUserByIdentifier() in 6.0 - if (method_exists($repository, 'loadUserByIdentifier')) { - $user = $repository->loadUserByIdentifier($identifier); - } else { - trigger_deprecation('symfony/doctrine-bridge', '5.3', 'Not implementing method "loadUserByIdentifier()" in user loader "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($repository)); - - $user = $repository->loadUserByUsername($identifier); - } + $user = $repository->loadUserByIdentifier($identifier); } if (null === $user) { diff --git a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php index 8af4a612966a6..e22e0bff05ead 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -22,15 +22,14 @@ * * @see UserInterface * - * @method UserInterface|null loadUserByIdentifier(string $identifier) loads the user for the given user identifier (e.g. username or email). - * This method must return null if the user is not found. - * * @author Michal Trojanowski */ interface UserLoaderInterface { /** - * @deprecated since Symfony 5.3, use loadUserByIdentifier() instead + * Loads the user for the given user identifier (e.g. username or email). + * + * This method must return null if the user is not found. */ - public function loadUserByUsername(string $username): ?UserInterface; + public function loadUserByIdentifier(string $identifier): ?UserInterface; } diff --git a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php index 7e48c1544c7bc..8f8086a846200 100644 --- a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php @@ -46,12 +46,7 @@ public function __invoke(array $record): array 'roles' => $token->getRoleNames(), ]; - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - if (method_exists($token, 'getUserIdentifier')) { - $record['extra'][$this->getKey()]['username'] = $record['extra'][$this->getKey()]['user_identifier'] = $token->getUserIdentifier(); - } else { - $record['extra'][$this->getKey()]['username'] = $token->getUsername(); - } + $record['extra'][$this->getKey()]['user_identifier'] = $token->getUserIdentifier(); } return $record; diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php index c6430ee2c66ac..602e9db61a82d 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php @@ -17,7 +17,6 @@ use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\User; /** * Tests the SwitchUserTokenProcessor. @@ -28,13 +27,8 @@ class SwitchUserTokenProcessorTest extends TestCase { public function testProcessor() { - if (class_exists(InMemoryUser::class)) { - $originalToken = new UsernamePasswordToken(new InMemoryUser('original_user', 'password', ['ROLE_SUPER_ADMIN']), 'provider', ['ROLE_SUPER_ADMIN']); - $switchUserToken = new SwitchUserToken(new InMemoryUser('user', 'passsword', ['ROLE_USER']), 'provider', ['ROLE_USER'], $originalToken); - } else { - $originalToken = new UsernamePasswordToken(new User('original_user', 'password', ['ROLE_SUPER_ADMIN']), null, 'provider', ['ROLE_SUPER_ADMIN']); - $switchUserToken = new SwitchUserToken(new User('user', 'passsword', ['ROLE_USER']), null, 'provider', ['ROLE_USER'], $originalToken); - } + $originalToken = new UsernamePasswordToken(new InMemoryUser('original_user', 'password', ['ROLE_SUPER_ADMIN']), 'provider', ['ROLE_SUPER_ADMIN']); + $switchUserToken = new SwitchUserToken(new InMemoryUser('user', 'passsword', ['ROLE_USER']), 'provider', ['ROLE_USER'], $originalToken); $tokenStorage = $this->createMock(TokenStorageInterface::class); $tokenStorage->method('getToken')->willReturn($switchUserToken); @@ -46,12 +40,9 @@ public function testProcessor() 'impersonator_token' => [ 'authenticated' => true, 'roles' => ['ROLE_SUPER_ADMIN'], - 'username' => 'original_user', + 'user_identifier' => 'original_user', ], ]; - if (method_exists($originalToken, 'getUserIdentifier')) { - $expected['impersonator_token']['user_identifier'] = 'original_user'; - } $this->assertEquals($expected, $record['extra']); } diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index b0afdf6ba2ac6..e73f8ca757d9d 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -24,7 +24,7 @@ "require-dev": { "symfony/console": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", - "symfony/security-core": "^5.4|^6.0", + "symfony/security-core": "^6.0", "symfony/var-dumper": "^5.4|^6.0", "symfony/mailer": "^5.4|^6.0", "symfony/mime": "^5.4|^6.0", @@ -32,7 +32,8 @@ }, "conflict": { "symfony/console": "<5.4", - "symfony/http-foundation": "<5.4" + "symfony/http-foundation": "<5.4", + "symfony/security-core": "<6.0" }, "suggest": { "symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.", diff --git a/src/Symfony/Bridge/Twig/AppVariable.php b/src/Symfony/Bridge/Twig/AppVariable.php index 78791f95cc150..f816ba2990b3d 100644 --- a/src/Symfony/Bridge/Twig/AppVariable.php +++ b/src/Symfony/Bridge/Twig/AppVariable.php @@ -78,10 +78,7 @@ public function getUser(): ?object return null; } - $user = $token->getUser(); - - // @deprecated since 5.4, $user will always be a UserInterface instance - return \is_object($user) ? $user : null; + return $token->getUser(); } /** diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index f5fcbeada6562..462f9f7874879 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -95,13 +95,6 @@ public function testGetUser() $this->assertEquals($user, $this->appVariable->getUser()); } - public function testGetUserWithUsernameAsTokenUser() - { - $this->setTokenStorage($user = 'username'); - - $this->assertNull($this->appVariable->getUser()); - } - public function testGetTokenWithNoToken() { $tokenStorage = $this->createMock(TokenStorageInterface::class); diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php index 106d457aa5077..0e1ede0f3b840 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php @@ -409,13 +409,7 @@ protected function getUser(): ?object return null; } - // @deprecated since 5.4, $user will always be a UserInterface instance - if (!\is_object($user = $token->getUser())) { - // e.g. anonymous authentication - return null; - } - - return $user; + return $token->getUser(); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php index 2c15bd3eb1887..bd7804af088e7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php +++ b/src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php @@ -119,7 +119,7 @@ public function loginUser(object $user, string $firewallContext = 'main'): self } $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); - // @deprecated since Symfony 5.4 + // required for compatibilty with Symfony 5.4 if (method_exists($token, 'isAuthenticated')) { $token->setAuthenticated(true, false); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php index 9a5c5510ce14e..128e85c9be7e1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php @@ -39,7 +39,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Routing\RouterInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; @@ -146,19 +145,6 @@ public function testGetUser() $this->assertSame($controller->getUser(), $user); } - /** - * @group legacy - */ - public function testGetUserAnonymousUserConvertedToNull() - { - $token = new AnonymousToken('default', 'anon.'); - - $controller = $this->createController(); - $controller->setContainer($this->getContainerWithTokenStorage($token)); - - $this->assertNull($controller->getUser()); - } - public function testGetUserWithEmptyTokenStorage() { $controller = $this->createController(); diff --git a/src/Symfony/Bundle/SecurityBundle/Command/DebugFirewallCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/DebugFirewallCommand.php index ca9f232a106af..a956feaeea58e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/DebugFirewallCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/DebugFirewallCommand.php @@ -35,23 +35,17 @@ final class DebugFirewallCommand extends Command private $contexts; private $eventDispatchers; private $authenticators; - private $authenticatorManagerEnabled; /** * @param string[] $firewallNames * @param AuthenticatorInterface[][] $authenticators */ - public function __construct(array $firewallNames, ContainerInterface $contexts, ContainerInterface $eventDispatchers, array $authenticators, bool $authenticatorManagerEnabled) + public function __construct(array $firewallNames, ContainerInterface $contexts, ContainerInterface $eventDispatchers, array $authenticators) { - if (!$authenticatorManagerEnabled) { - trigger_deprecation('symfony/security-bundle', '5.4', 'Setting the $authenticatorManagerEnabled argument of "%s" to "false" is deprecated, use the new authenticator system instead.', __METHOD__); - } - $this->firewallNames = $firewallNames; $this->contexts = $contexts; $this->eventDispatchers = $eventDispatchers; $this->authenticators = $authenticators; - $this->authenticatorManagerEnabled = $authenticatorManagerEnabled; parent::__construct(); } @@ -119,9 +113,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->displayEventListeners($name, $context, $io); } - if ($this->authenticatorManagerEnabled) { - $this->displayAuthenticators($name, $io); - } + $this->displayAuthenticators($name, $io); return 0; } diff --git a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php index 24a10d1e53db6..a1ee29f9e00ba 100644 --- a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php +++ b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php @@ -17,7 +17,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; @@ -44,14 +43,9 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn private $firewallMap; private $firewall; private $hasVarDumper; - private $authenticatorManagerEnabled; - public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null, FirewallMapInterface $firewallMap = null, TraceableFirewallListener $firewall = null, bool $authenticatorManagerEnabled = false) + public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null, FirewallMapInterface $firewallMap = null, TraceableFirewallListener $firewall = null) { - if (!$authenticatorManagerEnabled) { - trigger_deprecation('symfony/security-bundle', '5.4', 'Setting the $authenticatorManagerEnabled argument of "%s" to "false" is deprecated, use the new authenticator system instead.', __METHOD__); - } - $this->tokenStorage = $tokenStorage; $this->roleHierarchy = $roleHierarchy; $this->logoutUrlGenerator = $logoutUrlGenerator; @@ -59,7 +53,6 @@ public function __construct(TokenStorageInterface $tokenStorage = null, RoleHier $this->firewallMap = $firewallMap; $this->firewall = $firewall; $this->hasVarDumper = class_exists(ClassStub::class); - $this->authenticatorManagerEnabled = $authenticatorManagerEnabled; } /** @@ -104,8 +97,7 @@ public function collect(Request $request, Response $response, \Throwable $except $impersonatorUser = null; if ($token instanceof SwitchUserToken) { $originalToken = $token->getOriginalToken(); - // @deprecated since Symfony 5.3, change to $originalToken->getUserIdentifier() in 6.0 - $impersonatorUser = method_exists($originalToken, 'getUserIdentifier') ? $originalToken->getUserIdentifier() : $originalToken->getUsername(); + $impersonatorUser = $originalToken->getUserIdentifier(); } if (null !== $this->roleHierarchy) { @@ -118,7 +110,7 @@ public function collect(Request $request, Response $response, \Throwable $except $logoutUrl = null; try { - if (null !== $this->logoutUrlGenerator && !$token instanceof AnonymousToken) { + if (null !== $this->logoutUrlGenerator) { $logoutUrl = $this->logoutUrlGenerator->getLogoutPath(); } } catch (\Exception $e) { @@ -134,8 +126,7 @@ public function collect(Request $request, Response $response, \Throwable $except 'token' => $token, 'token_class' => $this->hasVarDumper ? new ClassStub(\get_class($token)) : \get_class($token), 'logout_url' => $logoutUrl, - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - 'user' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(), + 'user' => $token->getUserIdentifier(), 'roles' => $assignedRoles, 'inherited_roles' => array_unique($inheritedRoles), 'supports_role_hierarchy' => null !== $this->roleHierarchy, @@ -184,7 +175,6 @@ public function collect(Request $request, Response $response, \Throwable $except if (null !== $firewallConfig) { $this->data['firewall'] = [ 'name' => $firewallConfig->getName(), - 'allows_anonymous' => $this->authenticatorManagerEnabled ? false : $firewallConfig->allowsAnonymous(), 'request_matcher' => $firewallConfig->getRequestMatcher(), 'security_enabled' => $firewallConfig->isSecurityEnabled(), 'stateless' => $firewallConfig->isStateless(), @@ -213,8 +203,6 @@ public function collect(Request $request, Response $response, \Throwable $except if ($this->firewall) { $this->data['listeners'] = $this->firewall->getWrappedListeners(); } - - $this->data['authenticator_manager_enabled'] = $this->authenticatorManagerEnabled; } /** @@ -362,9 +350,4 @@ public function getName(): string { return 'security'; } - - public function isAuthenticatorManagerEnabled(): bool - { - return $this->data['authenticator_manager_enabled']; - } } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfTokenClearingLogoutHandlerPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfTokenClearingLogoutHandlerPass.php deleted file mode 100644 index 8cabb9d73d363..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/RegisterCsrfTokenClearingLogoutHandlerPass.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\ContainerBuilder; - -trigger_deprecation('symfony/security-bundle', '5.1', 'The "%s" class is deprecated.', RegisterCsrfTokenClearingLogoutHandlerPass::class); - -/** - * @deprecated since symfony/security-bundle 5.1 - */ -class RegisterCsrfTokenClearingLogoutHandlerPass extends RegisterCsrfFeaturesPass -{ - public function process(ContainerBuilder $container) - { - if (!$container->has('security.csrf.token_storage')) { - return; - } - - $this->registerLogoutHandler($container); - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php index 62aaaef03ae70..150aa26042973 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php @@ -13,7 +13,6 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -33,16 +32,10 @@ class MainConfiguration implements ConfigurationInterface private $userProviderFactories; /** - * @param (SecurityFactoryInterface|AuthenticatorFactoryInterface)[] $factories + * @param AuthenticatorFactoryInterface[] $factories */ public function __construct(array $factories, array $userProviderFactories) { - if (\is_array(current($factories))) { - trigger_deprecation('symfony/security-bundle', '5.4', 'Passing an array of arrays as 1st argument to "%s" is deprecated, pass a sorted array of factories instead.', __METHOD__); - - $factories = array_merge(...array_values($factories)); - } - $this->factories = $factories; $this->userProviderFactories = $userProviderFactories; } @@ -83,10 +76,6 @@ public function getConfigTreeBuilder() ->defaultValue(SessionAuthenticationStrategy::MIGRATE) ->end() ->booleanNode('hide_user_not_found')->defaultTrue()->end() - ->booleanNode('always_authenticate_before_granting') - ->defaultFalse() - ->setDeprecated('symfony/security-bundle', '5.4') - ->end() ->booleanNode('erase_credentials')->defaultTrue()->end() ->booleanNode('enable_authenticator_manager')->defaultFalse()->info('Enables the new Symfony Security system based on Authenticators, all used authenticators must support this before enabling this.')->end() ->arrayNode('access_decision_manager') diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php index d0c8eefeb32d6..cd1894d36679f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AbstractFactory.php @@ -24,7 +24,7 @@ * @author Lukas Kahwe Smith * @author Johannes M. Schmitt */ -abstract class AbstractFactory implements SecurityFactoryInterface +abstract class AbstractFactory implements AuthenticatorFactoryInterface { protected $options = [ 'check_path' => '/login_check', @@ -48,26 +48,9 @@ abstract class AbstractFactory implements SecurityFactoryInterface 'failure_path_parameter' => '_failure_path', ]; - public function create(ContainerBuilder $container, string $id, array $config, string $userProviderId, ?string $defaultEntryPointId) + final public function addOption(string $name, mixed $default = null) { - // authentication provider - $authProviderId = $this->createAuthProvider($container, $id, $config, $userProviderId); - - // authentication listener - $listenerId = $this->createListener($container, $id, $config, $userProviderId); - - // add remember-me aware tag if requested - if ($this->isRememberMeAware($config)) { - $container - ->getDefinition($listenerId) - ->addTag('security.remember_me_aware', ['id' => $id, 'provider' => $userProviderId]) - ; - } - - // create entry point if applicable (optional) - $entryPointId = $this->createEntryPoint($container, $id, $config, $defaultEntryPointId); - - return [$authProviderId, $listenerId, $entryPointId]; + $this->options[$name] = $default; } public function addConfiguration(NodeDefinition $node) @@ -90,73 +73,6 @@ public function addConfiguration(NodeDefinition $node) } } - final public function addOption(string $name, mixed $default = null) - { - $this->options[$name] = $default; - } - - /** - * Subclasses must return the id of a service which implements the - * AuthenticationProviderInterface. - * - * @return string - */ - abstract protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId); - - /** - * Subclasses must return the id of the abstract listener template. - * - * Listener definitions should inherit from the AbstractAuthenticationListener - * like this: - * - * - * - * In the above case, this method would return "my.listener.id". - * - * @return string - */ - abstract protected function getListenerId(); - - /** - * Subclasses may create an entry point of their as they see fit. The - * default implementation does not change the default entry point. - * - * @return string|null the entry point id - */ - protected function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPointId) - { - return $defaultEntryPointId; - } - - /** - * Subclasses may disable remember-me features for the listener, by - * always returning false from this method. - * - * @return bool Whether a possibly configured RememberMeServices should be set for this listener - */ - protected function isRememberMeAware(array $config) - { - return $config['remember_me']; - } - - protected function createListener(ContainerBuilder $container, string $id, array $config, string $userProvider) - { - $listenerId = $this->getListenerId(); - $listener = new ChildDefinition($listenerId); - $listener->replaceArgument(4, $id); - $listener->replaceArgument(5, new Reference($this->createAuthenticationSuccessHandler($container, $id, $config))); - $listener->replaceArgument(6, new Reference($this->createAuthenticationFailureHandler($container, $id, $config))); - $listener->replaceArgument(7, array_intersect_key($config, $this->options)); - - $listenerId .= '.'.$id; - $container->setDefinition($listenerId, $listener); - - return $listenerId; - } - protected function createAuthenticationSuccessHandler(ContainerBuilder $container, string $id, array $config) { $successHandlerId = $this->getSuccessHandlerId($id); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php deleted file mode 100644 index b216dd137a704..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AnonymousFactory.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; - -use Symfony\Component\Config\Definition\Builder\NodeDefinition; -use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Parameter; - -/** - * @author Wouter de Jong - * - * @internal - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class AnonymousFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface -{ - public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint): array - { - if (null === $config['secret']) { - $config['secret'] = new Parameter('container.build_hash'); - } - - $listenerId = 'security.authentication.listener.anonymous.'.$id; - $container - ->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.anonymous')) - ->replaceArgument(1, $config['secret']) - ; - - $providerId = 'security.authentication.provider.anonymous.'.$id; - $container - ->setDefinition($providerId, new ChildDefinition('security.authentication.provider.anonymous')) - ->replaceArgument(0, $config['secret']) - ; - - return [$providerId, $listenerId, $defaultEntryPoint]; - } - - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string - { - throw new InvalidConfigurationException(sprintf('The authenticator manager no longer has "anonymous" security. Please remove this option under the "%s" firewall'.($config['lazy'] ? ' and add "lazy: true"' : '').'.', $firewallName)); - } - - public function getPriority(): int - { - return -60; - } - - public function getPosition(): string - { - return 'anonymous'; - } - - public function getKey(): string - { - return 'anonymous'; - } - - public function addConfiguration(NodeDefinition $builder) - { - $builder - ->beforeNormalization() - ->ifTrue(function ($v) { return 'lazy' === $v; }) - ->then(function ($v) { return ['lazy' => true]; }) - ->end() - ->children() - ->booleanNode('lazy')->defaultFalse()->setDeprecated('symfony/security-bundle', '5.1', 'Using "anonymous: lazy" to make the firewall lazy is deprecated, use "anonymous: true" and "lazy: true" instead.')->end() - ->scalarNode('secret')->defaultNull()->end() - ->end() - ; - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.php index 6ecec3e281ae2..3bf7f893e1830 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.php @@ -15,21 +15,17 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; /** - * @method int getPriority() defines the position at which the authenticator is called - * * @author Wouter de Jong */ interface AuthenticatorFactoryInterface { /** - * Creates the authenticator service(s) for the provided configuration. - * - * @return string|string[] The authenticator service ID(s) to be used by the firewall + * Defines the priority at which the authenticator is called. */ - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId); + public function getPriority(): int; /** - * Defines the configuration key used to reference the authenticator + * Defines the configuration key used to reference the provider * in the firewall configuration. * * @return string @@ -37,4 +33,11 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal public function getKey(); public function addConfiguration(NodeDefinition $builder); + + /** + * Creates the authenticator service(s) for the provided configuration. + * + * @return string|string[] The authenticator service ID(s) to be used by the firewall + */ + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string|array; } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/CustomAuthenticatorFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/CustomAuthenticatorFactory.php index 94761785d7802..269b6e85a925d 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/CustomAuthenticatorFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/CustomAuthenticatorFactory.php @@ -20,23 +20,13 @@ * * @internal */ -class CustomAuthenticatorFactory implements AuthenticatorFactoryInterface, SecurityFactoryInterface +class CustomAuthenticatorFactory implements AuthenticatorFactoryInterface { - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - throw new \LogicException('Custom authenticators are not supported when "security.enable_authenticator_manager" is not set to true.'); - } - public function getPriority(): int { return 0; } - public function getPosition(): string - { - return 'pre_auth'; - } - public function getKey(): string { return 'custom_authenticators'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php index 7a5267c3bd388..a4f781ef98cd1 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginFactory.php @@ -25,7 +25,7 @@ * * @internal */ -class FormLoginFactory extends AbstractFactory implements AuthenticatorFactoryInterface +class FormLoginFactory extends AbstractFactory { public const PRIORITY = -30; @@ -44,11 +44,6 @@ public function getPriority(): int return self::PRIORITY; } - public function getPosition(): string - { - return 'form'; - } - public function getKey(): string { return 'form-login'; @@ -65,53 +60,6 @@ public function addConfiguration(NodeDefinition $node) ; } - protected function getListenerId(): string - { - return 'security.authentication.listener.form'; - } - - protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId): string - { - if ($config['enable_csrf'] ?? false) { - throw new InvalidConfigurationException('The "enable_csrf" option of "form_login" is only available when "security.enable_authenticator_manager" is set to "true", use "csrf_token_generator" instead.'); - } - - $provider = 'security.authentication.provider.dao.'.$id; - $container - ->setDefinition($provider, new ChildDefinition('security.authentication.provider.dao')) - ->replaceArgument(0, new Reference($userProviderId)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->replaceArgument(2, $id) - ; - - return $provider; - } - - protected function createListener(ContainerBuilder $container, string $id, array $config, string $userProvider) - { - $listenerId = parent::createListener($container, $id, $config, $userProvider); - - $container - ->getDefinition($listenerId) - ->addArgument(isset($config['csrf_token_generator']) ? new Reference($config['csrf_token_generator']) : null) - ; - - return $listenerId; - } - - protected function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPointId): ?string - { - $entryPointId = 'security.authentication.form_entry_point.'.$id; - $container - ->setDefinition($entryPointId, new ChildDefinition('security.authentication.form_entry_point')) - ->addArgument(new Reference('security.http_utils')) - ->addArgument($config['login_path']) - ->addArgument($config['use_forward']) - ; - - return $entryPointId; - } - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { if (isset($config['csrf_token_generator'])) { diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginLdapFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginLdapFactory.php index 04c2bc9b27869..a439ca0adf316 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginLdapFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FormLoginLdapFactory.php @@ -12,10 +12,6 @@ namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; use Symfony\Component\Config\Definition\Builder\NodeDefinition; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Security\Core\Exception\LogicException; /** * FormLoginLdapFactory creates services for form login ldap authentication. @@ -29,30 +25,6 @@ class FormLoginLdapFactory extends FormLoginFactory { use LdapFactoryTrait; - protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId): string - { - $provider = 'security.authentication.provider.ldap_bind.'.$id; - $definition = $container - ->setDefinition($provider, new ChildDefinition('security.authentication.provider.ldap_bind')) - ->replaceArgument(0, new Reference($userProviderId)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->replaceArgument(2, $id) - ->replaceArgument(3, new Reference($config['service'])) - ->replaceArgument(4, $config['dn_string']) - ->replaceArgument(6, $config['search_dn']) - ->replaceArgument(7, $config['search_password']) - ; - - if (!empty($config['query_string'])) { - if ('' === $config['search_dn'] || '' === $config['search_password']) { - throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.'); - } - $definition->addMethodCall('setQueryString', [$config['query_string']]); - } - - return $provider; - } - public function addConfiguration(NodeDefinition $node) { parent::addConfiguration($node); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardAuthenticationFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardAuthenticationFactory.php deleted file mode 100644 index a83a6d987dd52..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/GuardAuthenticationFactory.php +++ /dev/null @@ -1,151 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; - -use Symfony\Component\Config\Definition\Builder\NodeDefinition; -use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\DependencyInjection\Argument\IteratorArgument; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator; - -/** - * Configures the "guard" authentication provider key under a firewall. - * - * @author Ryan Weaver - * - * @internal - */ -class GuardAuthenticationFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface -{ - public function getPosition(): string - { - return 'pre_auth'; - } - - public function getPriority(): int - { - return 0; - } - - public function getKey(): string - { - return 'guard'; - } - - public function addConfiguration(NodeDefinition $node) - { - $node - ->fixXmlConfig('authenticator') - ->children() - ->scalarNode('provider') - ->info('A key from the "providers" section of your security config, in case your user provider is different than the firewall') - ->end() - ->scalarNode('entry_point') - ->info('A service id (of one of your authenticators) whose start() method should be called when an anonymous user hits a page that requires authentication') - ->defaultValue(null) - ->end() - ->arrayNode('authenticators') - ->info('An array of service ids for all of your "authenticators"') - ->requiresAtLeastOneElement() - ->prototype('scalar')->end() - ->end() - ->end() - ; - } - - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - $authenticatorIds = $config['authenticators']; - $authenticatorReferences = []; - foreach ($authenticatorIds as $authenticatorId) { - $authenticatorReferences[] = new Reference($authenticatorId); - } - - $authenticators = new IteratorArgument($authenticatorReferences); - - // configure the GuardAuthenticationFactory to have the dynamic constructor arguments - $providerId = 'security.authentication.provider.guard.'.$id; - $container - ->setDefinition($providerId, new ChildDefinition('security.authentication.provider.guard')) - ->replaceArgument(0, $authenticators) - ->replaceArgument(1, new Reference($userProvider)) - ->replaceArgument(2, $id) - ->replaceArgument(3, new Reference('security.user_checker.'.$id)) - ; - - // listener - $listenerId = 'security.authentication.listener.guard.'.$id; - $listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.guard')); - $listener->replaceArgument(2, $id); - $listener->replaceArgument(3, $authenticators); - - // determine the entryPointId to use - $entryPointId = $this->determineEntryPoint($defaultEntryPoint, $config); - - // this is always injected - then the listener decides if it should be used - $container - ->getDefinition($listenerId) - ->addTag('security.remember_me_aware', ['id' => $id, 'provider' => $userProvider]); - - return [$providerId, $listenerId, $entryPointId]; - } - - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId) - { - $userProvider = new Reference($userProviderId); - $authenticatorIds = []; - - if (isset($config['entry_point'])) { - throw new InvalidConfigurationException('The "security.firewall.'.$firewallName.'.guard.entry_point" option has no effect in the new authenticator system, configure "security.firewall.'.$firewallName.'.entry_point" instead.'); - } - - $guardAuthenticatorIds = $config['authenticators']; - foreach ($guardAuthenticatorIds as $i => $guardAuthenticatorId) { - $container->setDefinition($authenticatorIds[] = 'security.authenticator.guard.'.$firewallName.'.'.$i, new Definition(GuardBridgeAuthenticator::class)) - ->setArguments([ - new Reference($guardAuthenticatorId), - $userProvider, - ]); - } - - return $authenticatorIds; - } - - private function determineEntryPoint(?string $defaultEntryPointId, array $config): string - { - if ($defaultEntryPointId) { - // explode if they've configured the entry_point, but there is already one - if ($config['entry_point']) { - throw new \LogicException(sprintf('The guard authentication provider cannot use the "%s" entry_point because another entry point is already configured by another provider! Either remove the other provider or move the entry_point configuration as a root key under your firewall (i.e. at the same level as "guard").', $config['entry_point'])); - } - - return $defaultEntryPointId; - } - - if ($config['entry_point']) { - // if it's configured explicitly, use it! - return $config['entry_point']; - } - - $authenticatorIds = $config['authenticators']; - if (1 == \count($authenticatorIds)) { - // if there is only one authenticator, use that as the entry point - return array_shift($authenticatorIds); - } - - // we have multiple entry points - we must ask them to configure one - throw new \LogicException(sprintf('Because you have multiple guard authenticators, you need to set the "guard.entry_point" key to one of your authenticators (%s).', implode(', ', $authenticatorIds))); - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php index e35b8a0a49618..02f2009ac1eca 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php @@ -23,40 +23,10 @@ * * @internal */ -class HttpBasicFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface +class HttpBasicFactory implements AuthenticatorFactoryInterface { public const PRIORITY = -50; - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - $provider = 'security.authentication.provider.dao.'.$id; - $container - ->setDefinition($provider, new ChildDefinition('security.authentication.provider.dao')) - ->replaceArgument(0, new Reference($userProvider)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->replaceArgument(2, $id) - ; - - // entry point - $entryPointId = $defaultEntryPoint; - if (null === $entryPointId) { - $entryPointId = 'security.authentication.basic_entry_point.'.$id; - $container - ->setDefinition($entryPointId, new ChildDefinition('security.authentication.basic_entry_point')) - ->addArgument($config['realm']) - ; - } - - // listener - $listenerId = 'security.authentication.listener.basic.'.$id; - $listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.basic')); - $listener->replaceArgument(2, $id); - $listener->replaceArgument(3, new Reference($entryPointId)); - $listener->addMethodCall('setSessionAuthenticationStrategy', [new Reference('security.authentication.session_strategy.'.$id)]); - - return [$provider, $listenerId, $entryPointId]; - } - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { $authenticatorId = 'security.authenticator.http_basic.'.$firewallName; @@ -73,11 +43,6 @@ public function getPriority(): int return self::PRIORITY; } - public function getPosition(): string - { - return 'http'; - } - public function getKey(): string { return 'http-basic'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php index b19a696faa4c2..9307cba86e3f3 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php @@ -22,7 +22,7 @@ * * @internal */ -class JsonLoginFactory extends AbstractFactory implements AuthenticatorFactoryInterface +class JsonLoginFactory extends AbstractFactory { public const PRIORITY = -40; @@ -39,14 +39,6 @@ public function getPriority(): int return self::PRIORITY; } - /** - * {@inheritdoc} - */ - public function getPosition(): string - { - return 'form'; - } - /** * {@inheritdoc} */ @@ -55,58 +47,7 @@ public function getKey(): string return 'json-login'; } - /** - * {@inheritdoc} - */ - protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId): string - { - $provider = 'security.authentication.provider.dao.'.$id; - $container - ->setDefinition($provider, new ChildDefinition('security.authentication.provider.dao')) - ->replaceArgument(0, new Reference($userProviderId)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->replaceArgument(2, $id) - ; - - return $provider; - } - - /** - * {@inheritdoc} - */ - protected function getListenerId(): string - { - return 'security.authentication.listener.json'; - } - - /** - * {@inheritdoc} - */ - protected function isRememberMeAware(array $config): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - protected function createListener(ContainerBuilder $container, string $id, array $config, string $userProvider) - { - $listenerId = $this->getListenerId(); - $listener = new ChildDefinition($listenerId); - $listener->replaceArgument(3, $id); - $listener->replaceArgument(4, isset($config['success_handler']) ? new Reference($this->createAuthenticationSuccessHandler($container, $id, $config)) : null); - $listener->replaceArgument(5, isset($config['failure_handler']) ? new Reference($this->createAuthenticationFailureHandler($container, $id, $config)) : null); - $listener->replaceArgument(6, array_intersect_key($config, $this->options)); - $listener->addMethodCall('setSessionAuthenticationStrategy', [new Reference('security.authentication.session_strategy.'.$id)]); - - $listenerId .= '.'.$id; - $container->setDefinition($listenerId, $listener); - - return $listenerId; - } - - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId) + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { $authenticatorId = 'security.authenticator.json_login.'.$firewallName; $options = array_intersect_key($config, $this->options); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginLdapFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginLdapFactory.php index c8b77faff3c01..3b4ff7a048df2 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginLdapFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginLdapFactory.php @@ -12,10 +12,6 @@ namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; use Symfony\Component\Config\Definition\Builder\NodeDefinition; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Security\Core\Exception\LogicException; /** * JsonLoginLdapFactory creates services for json login ldap authentication. @@ -26,30 +22,6 @@ class JsonLoginLdapFactory extends JsonLoginFactory { use LdapFactoryTrait; - protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId): string - { - $provider = 'security.authentication.provider.ldap_bind.'.$id; - $definition = $container - ->setDefinition($provider, new ChildDefinition('security.authentication.provider.ldap_bind')) - ->replaceArgument(0, new Reference($userProviderId)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->replaceArgument(2, $id) - ->replaceArgument(3, new Reference($config['service'])) - ->replaceArgument(4, $config['dn_string']) - ->replaceArgument(6, $config['search_dn']) - ->replaceArgument(7, $config['search_password']) - ; - - if (!empty($config['query_string'])) { - if ('' === $config['search_dn'] || '' === $config['search_password']) { - throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.'); - } - $definition->addMethodCall('setQueryString', [$config['query_string']]); - } - - return $provider; - } - public function addConfiguration(NodeDefinition $node) { parent::addConfiguration($node); diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php index 5badfb237c5da..88e34192abf14 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php @@ -25,7 +25,7 @@ /** * @internal */ -class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryInterface +class LoginLinkFactory extends AbstractFactory { public const PRIORITY = -20; @@ -153,29 +153,4 @@ public function getPriority(): int { return self::PRIORITY; } - - public function getPosition(): string - { - return 'form'; - } - - protected function createAuthProvider(ContainerBuilder $container, string $id, array $config, string $userProviderId): string - { - throw new \Exception('The old authentication system is not supported with login_link.'); - } - - protected function getListenerId(): string - { - throw new \Exception('The old authentication system is not supported with login_link.'); - } - - protected function createListener(ContainerBuilder $container, string $id, array $config, string $userProvider) - { - throw new \Exception('The old authentication system is not supported with login_link.'); - } - - protected function createEntryPoint(ContainerBuilder $container, string $id, array $config, ?string $defaultEntryPointId): ?string - { - throw new \Exception('The old authentication system is not supported with login_link.'); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php index dc829be2edd9e..5b5c1a55bce0a 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginThrottlingFactory.php @@ -27,25 +27,14 @@ * * @internal */ -class LoginThrottlingFactory implements AuthenticatorFactoryInterface, SecurityFactoryInterface +class LoginThrottlingFactory implements AuthenticatorFactoryInterface { - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - throw new \LogicException('Login throttling is not supported when "security.enable_authenticator_manager" is not set to true.'); - } - public function getPriority(): int { // this factory doesn't register any authenticators, this priority doesn't matter return 0; } - public function getPosition(): string - { - // this factory doesn't register any authenticators, this position doesn't matter - return 'pre_auth'; - } - public function getKey(): string { return 'login_throttling'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php index de1b9a73115c6..b33136891809f 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RememberMeFactory.php @@ -20,18 +20,16 @@ use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\Security\Core\Authentication\RememberMe\CacheTokenVerifier; -use Symfony\Component\Security\Http\EventListener\RememberMeLogoutListener; /** * @internal */ -class RememberMeFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface, PrependExtensionInterface +class RememberMeFactory implements AuthenticatorFactoryInterface, PrependExtensionInterface { public const PRIORITY = -50; @@ -47,61 +45,6 @@ class RememberMeFactory implements SecurityFactoryInterface, AuthenticatorFactor 'remember_me_parameter' => '_remember_me', ]; - public function create(ContainerBuilder $container, string $id, array $config, ?string $userProvider, ?string $defaultEntryPoint): array - { - // authentication provider - $authProviderId = 'security.authentication.provider.rememberme.'.$id; - $container - ->setDefinition($authProviderId, new ChildDefinition('security.authentication.provider.rememberme')) - ->replaceArgument(0, new Reference('security.user_checker.'.$id)) - ->addArgument($config['secret']) - ->addArgument($id) - ; - - // remember me services - $templateId = $this->generateRememberMeServicesTemplateId($config, $id); - $rememberMeServicesId = $templateId.'.'.$id; - - // attach to remember-me aware listeners - $userProviders = []; - foreach ($container->findTaggedServiceIds('security.remember_me_aware') as $serviceId => $attributes) { - foreach ($attributes as $attribute) { - if (!isset($attribute['id']) || $attribute['id'] !== $id) { - continue; - } - - if (!isset($attribute['provider'])) { - throw new \RuntimeException('Each "security.remember_me_aware" tag must have a provider attribute.'); - } - - // context listeners don't need a provider - if ('none' !== $attribute['provider']) { - $userProviders[] = new Reference($attribute['provider']); - } - - $container - ->getDefinition($serviceId) - ->addMethodCall('setRememberMeServices', [new Reference($rememberMeServicesId)]) - ; - } - } - - $this->createRememberMeServices($container, $id, $templateId, $userProviders, $config); - - // remember-me listener - $listenerId = 'security.authentication.listener.rememberme.'.$id; - $listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.rememberme')); - $listener->replaceArgument(1, new Reference($rememberMeServicesId)); - $listener->replaceArgument(5, $config['catch_exceptions']); - - // remember-me logout listener - $container->setDefinition('security.logout.listener.remember_me.'.$id, new Definition(RememberMeLogoutListener::class)) - ->addArgument(new Reference($rememberMeServicesId)) - ->addTag('kernel.event_subscriber', ['dispatcher' => 'security.event_dispatcher.'.$id]); - - return [$authProviderId, $listenerId, $defaultEntryPoint]; - } - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { if (!$container->hasDefinition('security.authenticator.remember_me')) { @@ -179,11 +122,6 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal return $authenticatorId; } - public function getPosition(): string - { - return 'remember_me'; - } - public function getPriority(): int { return self::PRIORITY; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php index d32cffa0e4c48..de79af1494f42 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php @@ -24,30 +24,11 @@ * * @internal */ -class RemoteUserFactory implements SecurityFactoryInterface, AuthenticatorFactoryInterface +class RemoteUserFactory implements AuthenticatorFactoryInterface { public const PRIORITY = -10; - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - $providerId = 'security.authentication.provider.pre_authenticated.'.$id; - $container - ->setDefinition($providerId, new ChildDefinition('security.authentication.provider.pre_authenticated')) - ->replaceArgument(0, new Reference($userProvider)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->addArgument($id) - ; - - $listenerId = 'security.authentication.listener.remote_user.'.$id; - $listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.remote_user')); - $listener->replaceArgument(2, $id); - $listener->replaceArgument(3, $config['user']); - $listener->addMethodCall('setSessionAuthenticationStrategy', [new Reference('security.authentication.session_strategy.'.$id)]); - - return [$providerId, $listenerId, $defaultEntryPoint]; - } - - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId) + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { $authenticatorId = 'security.authenticator.remote_user.'.$firewallName; $container @@ -65,11 +46,6 @@ public function getPriority(): int return self::PRIORITY; } - public function getPosition(): string - { - return 'pre_auth'; - } - public function getKey(): string { return 'remote-user'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php deleted file mode 100644 index 4551a6cbcc11b..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SecurityFactoryInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory; - -use Symfony\Component\Config\Definition\Builder\NodeDefinition; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * SecurityFactoryInterface is the interface for all security authentication listener. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use AuthenticatorFactoryInterface instead. - */ -interface SecurityFactoryInterface -{ - /** - * Configures the container services required to use the authentication listener. - * - * @return array containing three values: - * - the provider id - * - the listener id - * - the entry point id - */ - public function create(ContainerBuilder $container, string $id, array $config, string $userProviderId, ?string $defaultEntryPointId); - - /** - * Defines the position at which the provider is called. - * Possible values: pre_auth, form, http, and remember_me. - * - * @return string - */ - public function getPosition(); - - /** - * Defines the configuration key used to reference the provider - * in the firewall configuration. - * - * @return string - */ - public function getKey(); - - public function addConfiguration(NodeDefinition $builder); -} diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php index 269d36916404a..f59783defd11c 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php @@ -23,32 +23,11 @@ * * @internal */ -class X509Factory implements SecurityFactoryInterface, AuthenticatorFactoryInterface +class X509Factory implements AuthenticatorFactoryInterface { public const PRIORITY = -10; - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array - { - $providerId = 'security.authentication.provider.pre_authenticated.'.$id; - $container - ->setDefinition($providerId, new ChildDefinition('security.authentication.provider.pre_authenticated')) - ->replaceArgument(0, new Reference($userProvider)) - ->replaceArgument(1, new Reference('security.user_checker.'.$id)) - ->addArgument($id) - ; - - // listener - $listenerId = 'security.authentication.listener.x509.'.$id; - $listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.x509')); - $listener->replaceArgument(2, $id); - $listener->replaceArgument(3, $config['user']); - $listener->replaceArgument(4, $config['credentials']); - $listener->addMethodCall('setSessionAuthenticationStrategy', [new Reference('security.authentication.session_strategy.'.$id)]); - - return [$providerId, $listenerId, $defaultEntryPoint]; - } - - public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId) + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { $authenticatorId = 'security.authenticator.x509.'.$firewallName; $container @@ -67,11 +46,6 @@ public function getPriority(): int return self::PRIORITY; } - public function getPosition(): string - { - return 'pre_auth'; - } - public function getKey(): string { return 'x509'; diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php index ceb04e340c8ea..0abb1ce247f5e 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php @@ -50,28 +50,6 @@ public function addConfiguration(NodeDefinition $node) ->arrayNode('users') ->useAttributeAsKey('identifier') ->normalizeKeys(false) - ->beforeNormalization() - ->always() - ->then(function ($v) { - $deprecation = false; - foreach ($v as $i => $child) { - if (!isset($child['name'])) { - continue; - } - - $deprecation = true; - - $v[$i]['identifier'] = $child['name']; - unset($v[$i]['name']); - } - - if ($deprecation) { - trigger_deprecation('symfony/security-bundle', '5.3', 'The "in_memory.user.name" option is deprecated, use "identifier" instead.'); - } - - return $v; - }) - ->end() ->prototype('array') ->children() ->scalarNode('password')->defaultNull()->end() diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 1726ff9394366..bec9af1a19ce3 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -14,7 +14,6 @@ use Symfony\Bridge\Twig\Extension\LogoutUrlExtension; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FirewallListenerFactoryInterface; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\FileLocator; @@ -39,7 +38,6 @@ use Symfony\Component\PasswordHasher\Hasher\SodiumPasswordHasher; use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\User\ChainUserProvider; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Http\Event\CheckPassportEvent; @@ -54,14 +52,11 @@ class SecurityExtension extends Extension implements PrependExtensionInterface private $requestMatchers = []; private $expressions = []; private $contextListeners = []; - /** @var array */ + /** @var list */ private $factories = []; - /** @var (AuthenticatorFactoryInterface|SecurityFactoryInterface)[] */ + /** @var AuthenticatorFactoryInterface[] */ private $sortedFactories = []; private $userProviderFactories = []; - private $statelessFirewallKeys = []; - - private $authenticatorManagerEnabled = false; public function prepend(ContainerBuilder $container) { @@ -88,42 +83,18 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('security.php'); $loader->load('password_hasher.php'); $loader->load('security_listeners.php'); - $loader->load('security_rememberme.php'); - - if ($this->authenticatorManagerEnabled = $config['enable_authenticator_manager']) { - if ($config['always_authenticate_before_granting']) { - throw new InvalidConfigurationException('The security option "always_authenticate_before_granting" cannot be used when "enable_authenticator_manager" is set to true. If you rely on this behavior, set it to false.'); - } - - $loader->load('security_authenticator.php'); - - // The authenticator system no longer has anonymous tokens. This makes sure AccessListener - // and AuthorizationChecker do not throw AuthenticationCredentialsNotFoundException when no - // token is available in the token storage. - $container->getDefinition('security.access_listener')->setArgument(3, false); - $container->getDefinition('security.authorization_checker')->setArgument(3, false); - $container->getDefinition('security.authorization_checker')->setArgument(4, false); - } else { - trigger_deprecation('symfony/security-bundle', '5.3', 'Not setting the "security.enable_authenticator_manager" config option to true is deprecated.'); - if ($config['always_authenticate_before_granting']) { - $authorizationChecker = $container->getDefinition('security.authorization_checker'); - $authorizationCheckerArgs = $authorizationChecker->getArguments(); - array_splice($authorizationCheckerArgs, 1, 0, [new Reference('security.authentication_manager')]); - $authorizationChecker->setArguments($authorizationCheckerArgs); - } - - $loader->load('security_legacy.php'); + if (!$config['enable_authenticator_manager']) { + throw new InvalidConfigurationException('"security.enable_authenticator_manager" must be set to "true".'); } + $loader->load('security_authenticator.php'); + if ($container::willBeAvailable('symfony/twig-bridge', LogoutUrlExtension::class, ['symfony/security-bundle'])) { $loader->load('templating_twig.php'); } $loader->load('collectors.php'); - $loader->load('guard.php'); - - $container->getDefinition('data_collector.security')->addArgument($this->authenticatorManagerEnabled); if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) { $loader->load('security_debug.php'); @@ -149,22 +120,16 @@ public function load(array $configs, ContainerBuilder $container) ->addArgument($config['access_decision_manager']['allow_if_equal_granted_denied']); } - $container->setParameter('security.access.always_authenticate_before_granting', $config['always_authenticate_before_granting']); $container->setParameter('security.authentication.hide_user_not_found', $config['hide_user_not_found']); if (class_exists(Application::class)) { $loader->load('debug_console.php'); - $debugCommand = $container->getDefinition('security.command.debug_firewall'); - $debugCommand->replaceArgument(4, $this->authenticatorManagerEnabled); } $this->createFirewalls($config, $container); $this->createAuthorization($config, $container); $this->createRoleHierarchy($config, $container); - $container->getDefinition('security.authentication.guard_handler') - ->replaceArgument(2, $this->statelessFirewallKeys); - if ($config['password_hashers']) { $this->createHashers($config['password_hashers'], $container); } @@ -177,6 +142,11 @@ public function load(array $configs, ContainerBuilder $container) $container->registerForAutoconfiguration(VoterInterface::class) ->addTag('security.voter'); + + // required for compatibility with Symfony 5.4 + $container->getDefinition('security.access_listener')->setArgument(3, false); + $container->getDefinition('security.authorization_checker')->setArgument(2, false); + $container->getDefinition('security.authorization_checker')->setArgument(3, false); } private function createRoleHierarchy(array $config, ContainerBuilder $container) @@ -296,17 +266,6 @@ private function createFirewalls(array $config, ContainerBuilder $container) $mapDef->replaceArgument(0, new Reference('security.firewall.context_locator')); $mapDef->replaceArgument(1, new IteratorArgument($map)); - if (!$this->authenticatorManagerEnabled) { - // add authentication providers to authentication manager - $authenticationProviders = array_map(function ($id) { - return new Reference($id); - }, array_values(array_unique($authenticationProviders))); - - $container - ->getDefinition('security.authentication.manager') - ->replaceArgument(0, new IteratorArgument($authenticationProviders)); - } - // register an autowire alias for the UserCheckerInterface if no custom user checker service is configured if (!$customUserChecker) { $container->setAlias('Symfony\Component\Security\Core\User\UserCheckerInterface', new Alias('security.user_checker', false)); @@ -350,11 +309,9 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ } $defaultProvider = $providerIds[$normalizedName]; - if ($this->authenticatorManagerEnabled) { - $container->setDefinition('security.listener.'.$id.'.user_provider', new ChildDefinition('security.listener.user_provider.abstract')) - ->addTag('kernel.event_listener', ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport']) - ->replaceArgument(0, new Reference($defaultProvider)); - } + $container->setDefinition('security.listener.'.$id.'.user_provider', new ChildDefinition('security.listener.user_provider.abstract')) + ->addTag('kernel.event_listener', ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport']) + ->replaceArgument(0, new Reference($defaultProvider)); } elseif (1 === \count($providerIds)) { $defaultProvider = reset($providerIds); } @@ -377,16 +334,13 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ // Context serializer listener if (false === $firewall['stateless']) { $contextKey = $firewall['context'] ?? $id; - $listeners[] = new Reference($contextListenerId = $this->createContextListener($container, $contextKey, $this->authenticatorManagerEnabled ? $firewallEventDispatcherId : null)); + $listeners[] = new Reference($contextListenerId = $this->createContextListener($container, $contextKey, $firewallEventDispatcherId)); $sessionStrategyId = 'security.authentication.session_strategy'; - if ($this->authenticatorManagerEnabled) { - $container - ->setDefinition('security.listener.session.'.$id, new ChildDefinition('security.listener.session')) - ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); - } + $container + ->setDefinition('security.listener.session.'.$id, new ChildDefinition('security.listener.session')) + ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); } else { - $this->statelessFirewallKeys[] = $id; $sessionStrategyId = 'security.authentication.session_strategy_noop'; } $container->setAlias(new Alias('security.authentication.session_strategy.'.$id, false), $sessionStrategyId); @@ -449,47 +403,43 @@ private function createFirewall(ContainerBuilder $container, string $id, array $ $firewallAuthenticationProviders = []; [$authListeners, $defaultEntryPoint] = $this->createAuthenticationListeners($container, $id, $firewall, $firewallAuthenticationProviders, $defaultProvider, $providerIds, $configuredEntryPoint, $contextListenerId); - if (!$this->authenticatorManagerEnabled) { - $authenticationProviders = array_merge($authenticationProviders, $firewallAuthenticationProviders); - } else { - // $configuredEntryPoint is resolved into a service ID and stored in $defaultEntryPoint - $configuredEntryPoint = $defaultEntryPoint; + // $configuredEntryPoint is resolved into a service ID and stored in $defaultEntryPoint + $configuredEntryPoint = $defaultEntryPoint; - // authenticator manager - $authenticators = array_map(function ($id) { - return new Reference($id); - }, $firewallAuthenticationProviders); - $container - ->setDefinition($managerId = 'security.authenticator.manager.'.$id, new ChildDefinition('security.authenticator.manager')) - ->replaceArgument(0, $authenticators) - ->replaceArgument(2, new Reference($firewallEventDispatcherId)) - ->replaceArgument(3, $id) - ->replaceArgument(7, $firewall['required_badges'] ?? []) - ->addTag('monolog.logger', ['channel' => 'security']) - ; + // authenticator manager + $authenticators = array_map(function ($id) { + return new Reference($id); + }, $firewallAuthenticationProviders); + $container + ->setDefinition($managerId = 'security.authenticator.manager.'.$id, new ChildDefinition('security.authenticator.manager')) + ->replaceArgument(0, $authenticators) + ->replaceArgument(2, new Reference($firewallEventDispatcherId)) + ->replaceArgument(3, $id) + ->replaceArgument(7, $firewall['required_badges'] ?? []) + ->addTag('monolog.logger', ['channel' => 'security']) + ; - $managerLocator = $container->getDefinition('security.authenticator.managers_locator'); - $managerLocator->replaceArgument(0, array_merge($managerLocator->getArgument(0), [$id => new ServiceClosureArgument(new Reference($managerId))])); + $managerLocator = $container->getDefinition('security.authenticator.managers_locator'); + $managerLocator->replaceArgument(0, array_merge($managerLocator->getArgument(0), [$id => new ServiceClosureArgument(new Reference($managerId))])); - // authenticator manager listener - $container - ->setDefinition('security.firewall.authenticator.'.$id, new ChildDefinition('security.firewall.authenticator')) - ->replaceArgument(0, new Reference($managerId)) - ; + // authenticator manager listener + $container + ->setDefinition('security.firewall.authenticator.'.$id, new ChildDefinition('security.firewall.authenticator')) + ->replaceArgument(0, new Reference($managerId)) + ; - // user checker listener - $container - ->setDefinition('security.listener.user_checker.'.$id, new ChildDefinition('security.listener.user_checker')) - ->replaceArgument(0, new Reference('security.user_checker.'.$id)) - ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); + // user checker listener + $container + ->setDefinition('security.listener.user_checker.'.$id, new ChildDefinition('security.listener.user_checker')) + ->replaceArgument(0, new Reference('security.user_checker.'.$id)) + ->addTag('kernel.event_subscriber', ['dispatcher' => $firewallEventDispatcherId]); - $listeners[] = new Reference('security.firewall.authenticator.'.$id); + $listeners[] = new Reference('security.firewall.authenticator.'.$id); - // Add authenticators to the debug:firewall command - if ($container->hasDefinition('security.command.debug_firewall')) { - $debugCommand = $container->getDefinition('security.command.debug_firewall'); - $debugCommand->replaceArgument(3, array_merge($debugCommand->getArgument(3), [$id => $authenticators])); - } + // Add authenticators to the debug:firewall command + if ($container->hasDefinition('security.command.debug_firewall')) { + $debugCommand = $container->getDefinition('security.command.debug_firewall'); + $debugCommand->replaceArgument(3, array_merge($debugCommand->getArgument(3), [$id => $authenticators])); } $config->replaceArgument(7, $configuredEntryPoint ?: $defaultEntryPoint); @@ -546,7 +496,6 @@ private function createContextListener(ContainerBuilder $container, string $cont private function createAuthenticationListeners(ContainerBuilder $container, string $id, array $firewall, array &$authenticationProviders, ?string $defaultProvider, array $providerIds, ?string $defaultEntryPoint, string $contextListenerId = null) { $listeners = []; - $hasListeners = false; $entryPoints = []; foreach ($this->getSortedFactories() as $factory) { @@ -555,26 +504,19 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri if (isset($firewall[$key])) { $userProvider = $this->getUserProvider($container, $id, $firewall, $key, $defaultProvider, $providerIds, $contextListenerId); - if ($this->authenticatorManagerEnabled) { - if (!$factory instanceof AuthenticatorFactoryInterface) { - throw new InvalidConfigurationException(sprintf('Cannot configure AuthenticatorManager as "%s" authentication does not support it, set "security.enable_authenticator_manager" to `false`.', $key)); - } + if (!$factory instanceof AuthenticatorFactoryInterface) { + throw new InvalidConfigurationException(sprintf('Cannot configure AuthenticatorManager as "%s" authentication does not support it, set "security.enable_authenticator_manager" to `false`.', $key)); + } - $authenticators = $factory->createAuthenticator($container, $id, $firewall[$key], $userProvider); - if (\is_array($authenticators)) { - foreach ($authenticators as $authenticator) { - $authenticationProviders[] = $authenticator; - $entryPoints[] = $authenticator; - } - } else { - $authenticationProviders[] = $authenticators; - $entryPoints[$key] = $authenticators; + $authenticators = $factory->createAuthenticator($container, $id, $firewall[$key], $userProvider); + if (\is_array($authenticators)) { + foreach ($authenticators as $authenticator) { + $authenticationProviders[] = $authenticator; + $entryPoints[] = $authenticator; } } else { - [$provider, $listenerId, $defaultEntryPoint] = $factory->create($container, $id, $firewall[$key], $userProvider, $defaultEntryPoint); - - $listeners[] = new Reference($listenerId); - $authenticationProviders[] = $provider; + $authenticationProviders[] = $authenticators; + $entryPoints[$key] = $authenticators; } if ($factory instanceof FirewallListenerFactoryInterface) { @@ -591,10 +533,6 @@ private function createAuthenticationListeners(ContainerBuilder $container, stri // the actual entry point is configured by the RegisterEntryPointPass $container->setParameter('security.'.$id.'._indexed_authenticators', $entryPoints); - if (false === $hasListeners && !$this->authenticatorManagerEnabled) { - throw new InvalidConfigurationException(sprintf('No authentication listener registered for firewall "%s".', $id)); - } - return [$listeners, $defaultEntryPoint]; } @@ -637,10 +575,6 @@ private function createHashers(array $hashers, ContainerBuilder $container) { $hasherMap = []; foreach ($hashers as $class => $hasher) { - // @deprecated since Symfony 5.3, remove the check in 6.0 - if (class_exists($class) && !is_a($class, PasswordAuthenticatedUserInterface::class, true)) { - trigger_deprecation('symfony/security-bundle', '5.3', 'Configuring a password hasher for a user class that does not implement "%s" is deprecated, class "%s" should implement it.', PasswordAuthenticatedUserInterface::class, $class); - } $hasherMap[$class] = $this->createHasher($hasher); } @@ -901,26 +835,9 @@ private function createRequestMatcher(ContainerBuilder $container, string $path return $this->requestMatchers[$id] = new Reference($id); } - /** - * @deprecated since Symfony 5.4, use "addAuthenticatorFactory()" instead - */ - public function addSecurityListenerFactory(SecurityFactoryInterface $factory) - { - trigger_deprecation('symfony/security-bundle', '5.4', 'Method "%s()" is deprecated, use "addAuthenticatorFactory()" instead.', __METHOD__); - - $this->factories[] = [[ - 'pre_auth' => -10, - 'form' => -30, - 'http' => -40, - 'remember_me' => -50, - 'anonymous' => -60, - ][$factory->getPosition()], $factory]; - $this->sortedFactories = []; - } - public function addAuthenticatorFactory(AuthenticatorFactoryInterface $factory) { - $this->factories[] = [method_exists($factory, 'getPriority') ? $factory->getPriority() : 0, $factory]; + $this->factories[] = [$factory->getPriority(), $factory]; $this->sortedFactories = []; } @@ -994,7 +911,7 @@ private function isValidIp(string $cidr): bool } /** - * @return (AuthenticatorFactoryInterface|SecurityFactoryInterface)[] + * @return AuthenticatorFactoryInterface[] */ private function getSortedFactories(): array { diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.php deleted file mode 100644 index a57add5e51c3d..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Loader\Configurator; - -use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener; -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider; - -return static function (ContainerConfigurator $container) { - $container->services() - ->set('security.authentication.guard_handler', GuardAuthenticatorHandler::class) - ->args([ - service('security.token_storage'), - service('event_dispatcher')->nullOnInvalid(), - abstract_arg('stateless firewall keys'), - ]) - ->call('setSessionAuthenticationStrategy', [service('security.authentication.session_strategy')]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->alias(GuardAuthenticatorHandler::class, 'security.authentication.guard_handler') - ->deprecate('symfony/security-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.guard', GuardAuthenticationProvider::class) - ->abstract() - ->args([ - abstract_arg('Authenticators'), - abstract_arg('User Provider'), - abstract_arg('Provider-shared Key'), - abstract_arg('User Checker'), - service('security.password_hasher'), - ]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.guard', GuardAuthenticationListener::class) - ->abstract() - ->args([ - service('security.authentication.guard_handler'), - service('security.authentication.manager'), - abstract_arg('Provider-shared Key'), - abstract_arg('Authenticators'), - service('logger')->nullOnInvalid(), - param('security.authentication.hide_user_not_found'), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - ; -}; diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php index 5a817bb2af494..23a748905e01a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.php @@ -58,7 +58,6 @@ ->args([ service('security.token_storage'), service('security.access.decision_manager'), - param('security.access.always_authenticate_before_granting'), ]) ->alias(AuthorizationCheckerInterface::class, 'security.authorization_checker') diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.php index fd83cd3b96108..58be697595d42 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator.php @@ -13,9 +13,7 @@ use Symfony\Bundle\SecurityBundle\Security\UserAuthenticator; use Symfony\Component\DependencyInjection\ServiceLocator; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticatorManager; -use Symfony\Component\Security\Http\Authentication\NoopAuthenticationManager; use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator; use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator; @@ -60,10 +58,6 @@ ]) ->alias(UserAuthenticatorInterface::class, 'security.user_authenticator') - ->set('security.authentication.manager', NoopAuthenticationManager::class) - ->alias(AuthenticationManagerInterface::class, 'security.authentication.manager') - ->deprecate('symfony/security-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use the new authenticator system instead.') - ->set('security.firewall.authenticator', AuthenticatorManagerListener::class) ->abstract() ->args([ diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_remember_me.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_remember_me.php index 13c8f5e341c01..8304ed9b832da 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_remember_me.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_remember_me.php @@ -18,10 +18,14 @@ use Symfony\Component\Security\Http\EventListener\RememberMeListener; use Symfony\Component\Security\Http\RememberMe\PersistentRememberMeHandler; use Symfony\Component\Security\Http\RememberMe\RememberMeHandlerInterface; +use Symfony\Component\Security\Http\RememberMe\ResponseListener; use Symfony\Component\Security\Http\RememberMe\SignatureRememberMeHandler; return static function (ContainerConfigurator $container) { $container->services() + ->set('security.rememberme.response_listener', ResponseListener::class) + ->tag('kernel.event_subscriber') + ->set('security.authenticator.remember_me_signature_hasher', SignatureHasher::class) ->args([ service('property_accessor'), diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_legacy.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_legacy.php deleted file mode 100644 index ec829ea1cbf85..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_legacy.php +++ /dev/null @@ -1,150 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Loader\Configurator; - -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; -use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Provider\PreAuthenticatedAuthenticationProvider; -use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener; -use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener; -use Symfony\Component\Security\Http\Firewall\RemoteUserAuthenticationListener; -use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener; -use Symfony\Component\Security\Http\Firewall\UsernamePasswordJsonAuthenticationListener; -use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener; - -return static function (ContainerConfigurator $container) { - $container->services() - - // Authentication related services - ->set('security.authentication.manager', AuthenticationProviderManager::class) - ->args([ - abstract_arg('providers'), - param('security.authentication.manager.erase_credentials'), - ]) - ->call('setEventDispatcher', [service('event_dispatcher')]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - ->alias(AuthenticationManagerInterface::class, 'security.authentication.manager') - ->deprecate('symfony/security-bundle', '5.3', 'The "%alias_id%" alias is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.anonymous', AnonymousAuthenticationListener::class) - ->args([ - service('security.untracked_token_storage'), - abstract_arg('Key'), - service('logger')->nullOnInvalid(), - service('security.authentication.manager'), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.anonymous', AnonymousAuthenticationProvider::class) - ->args([abstract_arg('Key')]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.form', UsernamePasswordFormAuthenticationListener::class) - ->parent('security.authentication.listener.abstract') - ->abstract() - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.x509', X509AuthenticationListener::class) - ->abstract() - ->args([ - service('security.token_storage'), - service('security.authentication.manager'), - abstract_arg('Provider-shared Key'), - abstract_arg('x509 user'), - abstract_arg('x509 credentials'), - service('logger')->nullOnInvalid(), - service('event_dispatcher')->nullOnInvalid(), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.json', UsernamePasswordJsonAuthenticationListener::class) - ->abstract() - ->args([ - service('security.token_storage'), - service('security.authentication.manager'), - service('security.http_utils'), - abstract_arg('Provider-shared Key'), - abstract_arg('Failure handler'), - abstract_arg('Success Handler'), - [], // Options - service('logger')->nullOnInvalid(), - service('event_dispatcher')->nullOnInvalid(), - service('property_accessor')->nullOnInvalid(), - ]) - ->call('setTranslator', [service('translator')->ignoreOnInvalid()]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.remote_user', RemoteUserAuthenticationListener::class) - ->abstract() - ->args([ - service('security.token_storage'), - service('security.authentication.manager'), - abstract_arg('Provider-shared Key'), - abstract_arg('REMOTE_USER server env var'), - service('logger')->nullOnInvalid(), - service('event_dispatcher')->nullOnInvalid(), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.listener.basic', BasicAuthenticationListener::class) - ->abstract() - ->args([ - service('security.token_storage'), - service('security.authentication.manager'), - abstract_arg('Provider-shared Key'), - abstract_arg('Entry Point'), - service('logger')->nullOnInvalid(), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.dao', DaoAuthenticationProvider::class) - ->abstract() - ->args([ - abstract_arg('User Provider'), - abstract_arg('User Checker'), - abstract_arg('Provider-shared Key'), - service('security.password_hasher_factory'), - param('security.authentication.hide_user_not_found'), - ]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.ldap_bind', LdapBindAuthenticationProvider::class) - ->abstract() - ->args([ - abstract_arg('User Provider'), - abstract_arg('UserChecker'), - abstract_arg('Provider-shared Key'), - abstract_arg('LDAP'), - abstract_arg('Base DN'), - param('security.authentication.hide_user_not_found'), - abstract_arg('search dn'), - abstract_arg('search password'), - ]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.pre_authenticated', PreAuthenticatedAuthenticationProvider::class) - ->abstract() - ->args([ - abstract_arg('User Provider'), - abstract_arg('UserChecker'), - ]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - ; -}; diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php index 72129d1bbf865..2bbe4caa39c5a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.php @@ -16,9 +16,6 @@ use Symfony\Component\Security\Http\Authentication\CustomAuthenticationSuccessHandler; use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler; use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler; -use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint; -use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint; -use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint; use Symfony\Component\Security\Http\EventListener\CookieClearingLogoutListener; use Symfony\Component\Security\Http\EventListener\DefaultLogoutListener; use Symfony\Component\Security\Http\EventListener\SessionLogoutListener; @@ -32,16 +29,6 @@ return static function (ContainerConfigurator $container) { $container->services() - ->set('security.authentication.basic_entry_point', BasicAuthenticationEntryPoint::class) - ->deprecate('symfony/security-bundle', '5.4', 'The "%service_id%" service is deprecated, the logic is contained in the authenticators.') - - ->set('security.authentication.retry_entry_point', RetryAuthenticationEntryPoint::class) - ->deprecate('symfony/security-bundle', '5.4', 'The "%service_id%" service is deprecated, the logic is integrated directly in "security.channel_listener".') - ->args([ - inline_service('int')->factory([service('router.request_context'), 'getHttpPort']), - inline_service('int')->factory([service('router.request_context'), 'getHttpsPort']), - ]) - ->set('security.channel_listener', ChannelListener::class) ->args([ service('security.access_map'), @@ -86,12 +73,6 @@ abstract_arg('target url'), ]) - ->set('security.authentication.form_entry_point', FormAuthenticationEntryPoint::class) - ->abstract() - ->args([ - service('http_kernel'), - ]) - ->set('security.authentication.listener.abstract') ->abstract() ->args([ @@ -176,7 +157,6 @@ service('security.token_storage'), service('security.access.decision_manager'), service('security.access_map'), - service('security.authentication.manager'), ]) ->tag('monolog.logger', ['channel' => 'security']) ; diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.php deleted file mode 100644 index 1c0e3557ef2c5..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\DependencyInjection\Loader\Configurator; - -use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\RememberMe\InMemoryTokenProvider; -use Symfony\Component\Security\Http\Firewall\RememberMeListener; -use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices; -use Symfony\Component\Security\Http\RememberMe\ResponseListener; -use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; - -return static function (ContainerConfigurator $container) { - $container->services() - ->set('security.authentication.listener.rememberme', RememberMeListener::class) - ->abstract() - ->args([ - service('security.untracked_token_storage'), - service('security.authentication.rememberme'), - service('security.authentication.manager'), - service('logger')->nullOnInvalid(), - service('event_dispatcher')->nullOnInvalid(), - abstract_arg('Catch exception flag set in RememberMeFactory'), - service('security.authentication.session_strategy'), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.authentication.provider.rememberme', RememberMeAuthenticationProvider::class) - ->abstract() - ->args([abstract_arg('User Checker')]) - ->deprecate('symfony/security-bundle', '5.3', 'The "%service_id%" service is deprecated, use the new authenticator system instead.') - - ->set('security.rememberme.token.provider.in_memory', InMemoryTokenProvider::class) - - ->set('security.authentication.rememberme.services.abstract') - ->abstract() - ->args([ - [], // User Providers - abstract_arg('Shared Token Key'), - abstract_arg('Shared Provider Key'), - [], // Options - service('logger')->nullOnInvalid(), - ]) - ->tag('monolog.logger', ['channel' => 'security']) - - ->set('security.authentication.rememberme.services.persistent', PersistentTokenBasedRememberMeServices::class) - ->parent('security.authentication.rememberme.services.abstract') - ->abstract() - - ->set('security.authentication.rememberme.services.simplehash', TokenBasedRememberMeServices::class) - ->parent('security.authentication.rememberme.services.abstract') - ->abstract() - - ->set('security.rememberme.response_listener', ResponseListener::class) - ->tag('kernel.event_subscriber') - ; -}; diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig index 6b50856d335cc..120a22e95c64e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig +++ b/src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig @@ -96,7 +96,7 @@ {% if collector.token %}
- {{ collector.user == 'anon.' ? 'Anonymous' : collector.user }} + {{ collector.user }} Username
@@ -163,12 +163,6 @@ {{ include('@WebProfiler/Icon/' ~ (collector.firewall.stateless ? 'yes' : 'no') ~ '.svg') }} Stateless
- {% if collector.authenticatorManagerEnabled == false %} -
- {{ include('@WebProfiler/Icon/' ~ (collector.firewall.allows_anonymous ? 'yes' : 'no') ~ '.svg') }} - Allows anonymous -
- {% endif %} {% if collector.firewall.security_enabled %} diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php index 779920b5a4320..82aa466f8686b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php @@ -64,16 +64,6 @@ public function isSecurityEnabled(): bool return $this->securityEnabled; } - /** - * @deprecated since Symfony 5.4 - */ - public function allowsAnonymous(): bool - { - trigger_deprecation('symfony/security-bundle', '5.4', 'The "%s()" method is deprecated.', __METHOD__); - - return \in_array('anonymous', $this->listeners, true); - } - public function isStateless(): bool { return $this->stateless; diff --git a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php index 4c2c3046f004f..01eeb74c3a094 100644 --- a/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php +++ b/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php @@ -22,11 +22,9 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterTokenUsageTrackingPass; use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\ReplaceDecoratedRememberMeHandlerPass; use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\SortFirewallListenersPass; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AnonymousFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\CustomAuthenticatorFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginLdapFactory; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardAuthenticationFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpBasicFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\HttpBasicLdapFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\JsonLoginFactory; @@ -68,8 +66,6 @@ public function build(ContainerBuilder $container) $extension->addAuthenticatorFactory(new RememberMeFactory()); $extension->addAuthenticatorFactory(new X509Factory()); $extension->addAuthenticatorFactory(new RemoteUserFactory()); - $extension->addAuthenticatorFactory(new GuardAuthenticationFactory()); - $extension->addAuthenticatorFactory(new AnonymousFactory()); $extension->addAuthenticatorFactory(new CustomAuthenticatorFactory()); $extension->addAuthenticatorFactory(new LoginThrottlingFactory()); $extension->addAuthenticatorFactory(new LoginLinkFactory()); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php index a25a43b53c53d..503e8b9b9c3c6 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php @@ -72,7 +72,6 @@ public function testCollectWhenAuthenticationTokenIsNull() $this->assertCount(0, $collector->getInheritedRoles()); $this->assertEmpty($collector->getUser()); $this->assertNull($collector->getFirewall()); - $this->assertTrue($collector->isAuthenticatorManagerEnabled()); } /** @dataProvider provideRoles */ @@ -95,7 +94,6 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm $this->assertSame($normalizedRoles, $collector->getRoles()->getValue(true)); $this->assertSame($inheritedRoles, $collector->getInheritedRoles()->getValue(true)); $this->assertSame('hhamon', $collector->getUser()); - $this->assertTrue($collector->isAuthenticatorManagerEnabled()); } public function testCollectSwitchUserToken() @@ -151,7 +149,6 @@ public function testGetFirewall() $this->assertSame($firewallConfig->getAccessDeniedUrl(), $collected['access_denied_url']); $this->assertSame($firewallConfig->getUserChecker(), $collected['user_checker']); $this->assertSame($firewallConfig->getListeners(), $collected['listeners']->getValue()); - $this->assertTrue($collector->isAuthenticatorManagerEnabled()); } public function testGetFirewallReturnsNull() diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index c9d0759afc960..bbc538030e820 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -223,137 +223,6 @@ public function testFirewalls() $this->assertFalse($container->hasAlias('Symfony\Component\Security\Core\User\UserCheckerInterface', 'No user checker alias is registered when custom user checker services are registered')); } - /** - * @group legacy - */ - public function testLegacyFirewalls() - { - $container = $this->getContainer('legacy_container1'); - $arguments = $container->getDefinition('security.firewall.map')->getArguments(); - $listeners = []; - $configs = []; - foreach (array_keys($arguments[1]->getValues()) as $contextId) { - $contextDef = $container->getDefinition($contextId); - $arguments = $contextDef->getArguments(); - $listeners[] = array_map('strval', $arguments[0]->getValues()); - - $configDef = $container->getDefinition((string) $arguments[3]); - $configs[] = array_values($configDef->getArguments()); - } - - // the IDs of the services are case sensitive or insensitive depending on - // the Symfony version. Transform them to lowercase to simplify tests. - $configs[0][2] = strtolower($configs[0][2]); - $configs[2][2] = strtolower($configs[2][2]); - - $this->assertEquals([ - [ - 'simple', - 'security.user_checker', - '.security.request_matcher.xmi9dcw', - false, - false, - '', - '', - '', - '', - '', - [], - null, - ], - [ - 'secure', - 'security.user_checker', - null, - true, - true, - 'security.user.provider.concrete.default', - null, - 'security.authentication.form_entry_point.secure', - null, - null, - [ - 'switch_user', - 'x509', - 'remote_user', - 'form_login', - 'http_basic', - 'remember_me', - 'anonymous', - ], - [ - 'parameter' => '_switch_user', - 'role' => 'ROLE_ALLOWED_TO_SWITCH', - ], - ], - [ - 'host', - 'security.user_checker', - '.security.request_matcher.iw4hyjb', - true, - false, - 'security.user.provider.concrete.default', - 'host', - 'security.authentication.basic_entry_point.host', - null, - null, - [ - 'http_basic', - 'anonymous', - ], - null, - ], - [ - 'with_user_checker', - 'app.user_checker', - null, - true, - false, - 'security.user.provider.concrete.default', - 'with_user_checker', - 'security.authentication.basic_entry_point.with_user_checker', - null, - null, - [ - 'http_basic', - 'anonymous', - ], - null, - ], - ], $configs); - - $this->assertEquals([ - [], - [ - 'security.channel_listener', - 'security.authentication.listener.x509.secure', - 'security.authentication.listener.remote_user.secure', - 'security.authentication.listener.form.secure', - 'security.authentication.listener.basic.secure', - 'security.authentication.listener.rememberme.secure', - 'security.authentication.listener.anonymous.secure', - 'security.authentication.switchuser_listener.secure', - 'security.access_listener', - ], - [ - 'security.channel_listener', - 'security.context_listener.0', - 'security.authentication.listener.basic.host', - 'security.authentication.listener.anonymous.host', - 'security.access_listener', - ], - [ - 'security.channel_listener', - 'security.context_listener.1', - 'security.authentication.listener.basic.with_user_checker', - 'security.authentication.listener.anonymous.with_user_checker', - 'security.access_listener', - ], - ], $listeners); - - $this->assertFalse($container->hasAlias('Symfony\Component\Security\Core\User\UserCheckerInterface', 'No user checker alias is registered when custom user checker services are registered')); - } - public function testFirewallRequestMatchers() { $container = $this->getContainer('container1'); @@ -712,26 +581,6 @@ public function testHashersWithBCrypt() ]], $container->getDefinition('security.password_hasher_factory')->getArguments()); } - /** - * @group legacy - */ - public function testLegacyRememberMeThrowExceptionsDefault() - { - $container = $this->getContainer('legacy_container1'); - $this->assertTrue($container->getDefinition('security.authentication.listener.rememberme.secure')->getArgument(5)); - } - - /** - * @group legacy - */ - public function testLegacyRememberMeThrowExceptions() - { - $container = $this->getContainer('legacy_remember_me_options'); - $service = $container->getDefinition('security.authentication.listener.rememberme.main'); - $this->assertEquals('security.authentication.rememberme.services.persistent.main', $service->getArgument(1)); - $this->assertFalse($service->getArgument(5)); - } - public function testUserCheckerConfig() { $this->assertEquals('app.user_checker', $this->getContainer('container1')->getAlias('security.user_checker.with_user_checker')); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php index 76d17b482005a..f155c135a26ad 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php @@ -77,7 +77,7 @@ 'logout' => true, 'remember_me' => ['secret' => 'TheSecret'], 'user_checker' => null, - 'entry_point' => 'form_login' + 'entry_point' => 'form_login', ], 'host' => [ 'provider' => 'default', diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/legacy_container1.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/legacy_container1.php deleted file mode 100644 index 6118929a36f69..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/legacy_container1.php +++ /dev/null @@ -1,108 +0,0 @@ -loadFromExtension('security', [ - 'password_hashers' => [ - 'JMS\FooBundle\Entity\User1' => 'plaintext', - 'JMS\FooBundle\Entity\User2' => [ - 'algorithm' => 'sha1', - 'encode_as_base64' => false, - 'iterations' => 5, - ], - 'JMS\FooBundle\Entity\User3' => [ - 'algorithm' => 'md5', - ], - 'JMS\FooBundle\Entity\User4' => [ - 'id' => 'security.hasher.foo', - ], - 'JMS\FooBundle\Entity\User5' => [ - 'algorithm' => 'pbkdf2', - 'hash_algorithm' => 'sha1', - 'encode_as_base64' => false, - 'iterations' => 5, - 'key_length' => 30, - ], - 'JMS\FooBundle\Entity\User6' => [ - 'algorithm' => 'native', - 'time_cost' => 8, - 'memory_cost' => 100, - 'cost' => 15, - ], - 'JMS\FooBundle\Entity\User7' => [ - 'algorithm' => 'auto', - ], - ], - 'providers' => [ - 'default' => [ - 'memory' => [ - 'users' => [ - 'foo' => ['password' => 'foo', 'roles' => 'ROLE_USER'], - ], - ], - ], - 'digest' => [ - 'memory' => [ - 'users' => [ - 'foo' => ['password' => 'foo', 'roles' => 'ROLE_USER, ROLE_ADMIN'], - ], - ], - ], - 'basic' => [ - 'memory' => [ - 'users' => [ - 'foo' => ['password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => 'ROLE_SUPER_ADMIN'], - 'bar' => ['password' => '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'roles' => ['ROLE_USER', 'ROLE_ADMIN']], - ], - ], - ], - 'service' => [ - 'id' => 'user.manager', - ], - 'chain' => [ - 'chain' => [ - 'providers' => ['service', 'basic'], - ], - ], - ], - - 'firewalls' => [ - 'simple' => ['provider' => 'default', 'pattern' => '/login', 'security' => false], - 'secure' => ['stateless' => true, - 'provider' => 'default', - 'http_basic' => true, - 'form_login' => true, - 'anonymous' => true, - 'switch_user' => true, - 'x509' => true, - 'remote_user' => true, - 'logout' => true, - 'remember_me' => ['secret' => 'TheSecret'], - 'user_checker' => null, - ], - 'host' => [ - 'provider' => 'default', - 'pattern' => '/test', - 'host' => 'foo\\.example\\.org', - 'methods' => ['GET', 'POST'], - 'anonymous' => true, - 'http_basic' => true, - ], - 'with_user_checker' => [ - 'provider' => 'default', - 'user_checker' => 'app.user_checker', - 'anonymous' => true, - 'http_basic' => true, - ], - ], - - 'access_control' => [ - ['path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => ['get', 'POST'], 'port' => 8000], - ['path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'], - ['path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUserIdentifier() matches '/^admin/'"], - ], - - 'role_hierarchy' => [ - 'ROLE_ADMIN' => 'ROLE_USER', - 'ROLE_SUPER_ADMIN' => ['ROLE_USER', 'ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], - 'ROLE_REMOTE' => 'ROLE_USER,ROLE_ADMIN', - ], -]); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/no_custom_user_checker.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/no_custom_user_checker.php index 1ac4f46dfe495..29d93a1f2ec3e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/no_custom_user_checker.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/no_custom_user_checker.php @@ -23,7 +23,7 @@ 'logout' => true, 'remember_me' => ['secret' => 'TheSecret'], 'user_checker' => null, - 'entry_point' => 'form_login' + 'entry_point' => 'form_login', ], ], ]); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/legacy_container1.xml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/legacy_container1.xml deleted file mode 100644 index ed7afe5e833ee..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/legacy_container1.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - app.user_checker - - - ROLE_USER - ROLE_USER,ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH - ROLE_USER,ROLE_ADMIN - - - - - - diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/legacy_container1.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/legacy_container1.yml deleted file mode 100644 index 3eb50b91b7370..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/legacy_container1.yml +++ /dev/null @@ -1,87 +0,0 @@ -security: - password_hashers: - JMS\FooBundle\Entity\User1: plaintext - JMS\FooBundle\Entity\User2: - algorithm: sha1 - encode_as_base64: false - iterations: 5 - JMS\FooBundle\Entity\User3: - algorithm: md5 - JMS\FooBundle\Entity\User4: - id: security.hasher.foo - JMS\FooBundle\Entity\User5: - algorithm: pbkdf2 - hash_algorithm: sha1 - encode_as_base64: false - iterations: 5 - key_length: 30 - JMS\FooBundle\Entity\User6: - algorithm: native - time_cost: 8 - memory_cost: 100 - cost: 15 - JMS\FooBundle\Entity\User7: - algorithm: auto - - providers: - default: - memory: - users: - foo: { password: foo, roles: ROLE_USER } - digest: - memory: - users: - foo: { password: foo, roles: 'ROLE_USER, ROLE_ADMIN' } - basic: - memory: - users: - foo: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: ROLE_SUPER_ADMIN } - bar: { password: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33, roles: [ROLE_USER, ROLE_ADMIN] } - service: - id: user.manager - chain: - chain: - providers: [service, basic] - - - firewalls: - simple: { pattern: /login, security: false } - secure: - provider: default - stateless: true - http_basic: true - form_login: true - anonymous: true - switch_user: - x509: true - remote_user: true - logout: true - remember_me: - secret: TheSecret - user_checker: ~ - - host: - provider: default - pattern: /test - host: foo\.example\.org - methods: [GET,POST] - anonymous: true - http_basic: true - - with_user_checker: - provider: default - anonymous: ~ - http_basic: ~ - user_checker: app.user_checker - - role_hierarchy: - ROLE_ADMIN: ROLE_USER - ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] - ROLE_REMOTE: ROLE_USER,ROLE_ADMIN - - access_control: - - { path: /blog/524, role: ROLE_USER, requires_channel: https, methods: [get, POST], port: 8000} - - - path: /blog/.* - role: IS_AUTHENTICATED_ANONYMOUSLY - - { path: /blog/524, role: IS_AUTHENTICATED_ANONYMOUSLY, allow_if: "token.getUserIdentifier() matches '/^admin/'" } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php index 8ebb389beff79..12247ac64ad42 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/MainConfigurationTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; @@ -20,8 +19,6 @@ class MainConfigurationTest extends TestCase { - use ExpectDeprecationTrait; - /** * The minimal, required config needed to not have any required validation * issues. @@ -126,18 +123,4 @@ public function testFirewalls() $configuration = new MainConfiguration(['stub' => $factory], []); $configuration->getConfigTreeBuilder(); } - - /** - * @group legacy - */ - public function testLegacyFirewalls() - { - $factory = $this->createMock(AuthenticatorFactoryInterface::class); - $factory->expects($this->once())->method('addConfiguration'); - - $this->expectDeprecation('Since symfony/security-bundle 5.4: Passing an array of arrays as 1st argument to "Symfony\Bundle\SecurityBundle\DependencyInjection\MainConfiguration::__construct" is deprecated, pass a sorted array of factories instead.'); - - $configuration = new MainConfiguration(['http_basic' => ['stub' => $factory]], []); - $configuration->getConfigTreeBuilder(); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php index 12f7f4a03f221..ff4108d25cdc9 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/AbstractFactoryTest.php @@ -14,38 +14,14 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; class AbstractFactoryTest extends TestCase { - public function testCreate() + private ContainerBuilder $container; + + protected function setUp(): void { - [$container, $authProviderId, $listenerId, $entryPointId] = $this->callFactory('foo', [ - 'use_forward' => true, - 'failure_path' => '/foo', - 'success_handler' => 'custom_success_handler', - 'failure_handler' => 'custom_failure_handler', - 'remember_me' => true, - ], 'user_provider', 'entry_point'); - - // auth provider - $this->assertEquals('auth_provider', $authProviderId); - - // listener - $this->assertEquals('abstract_listener.foo', $listenerId); - $this->assertTrue($container->hasDefinition('abstract_listener.foo')); - $definition = $container->getDefinition('abstract_listener.foo'); - $this->assertEquals([ - 'index_4' => 'foo', - 'index_5' => new Reference('security.authentication.success_handler.foo.abstract_factory'), - 'index_6' => new Reference('security.authentication.failure_handler.foo.abstract_factory'), - 'index_7' => [ - 'use_forward' => true, - ], - ], $definition->getArguments()); - - // entry point - $this->assertEquals('entry_point', $entryPointId, '->create() does not change the default entry point.'); + $this->container = new ContainerBuilder(); } /** @@ -60,14 +36,12 @@ public function testDefaultFailureHandler($serviceId, $defaultHandlerInjection) if ($serviceId) { $options['failure_handler'] = $serviceId; + $this->container->register($serviceId, \stdClass::class); } - [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + $this->callFactory('foo', $options, 'user_provider', 'entry_point'); - $definition = $container->getDefinition('abstract_listener.foo'); - $arguments = $definition->getArguments(); - $this->assertEquals(new Reference('security.authentication.failure_handler.foo.abstract_factory'), $arguments['index_6']); - $failureHandler = $container->findDefinition((string) $arguments['index_6']); + $failureHandler = $this->container->getDefinition('security.authentication.failure_handler.foo.stub'); $methodCalls = $failureHandler->getMethodCalls(); if ($defaultHandlerInjection) { @@ -98,14 +72,12 @@ public function testDefaultSuccessHandler($serviceId, $defaultHandlerInjection) if ($serviceId) { $options['success_handler'] = $serviceId; + $this->container->register($serviceId, \stdClass::class); } - [$container] = $this->callFactory('foo', $options, 'user_provider', 'entry_point'); + $this->callFactory('foo', $options, 'user_provider', 'entry_point'); - $definition = $container->getDefinition('abstract_listener.foo'); - $arguments = $definition->getArguments(); - $this->assertEquals(new Reference('security.authentication.success_handler.foo.abstract_factory'), $arguments['index_5']); - $successHandler = $container->findDefinition((string) $arguments['index_5']); + $successHandler = $this->container->getDefinition('security.authentication.success_handler.foo.stub'); $methodCalls = $successHandler->getMethodCalls(); if ($defaultHandlerInjection) { @@ -126,33 +98,29 @@ public function getSuccessHandlers() ]; } - protected function callFactory($id, $config, $userProviderId, $defaultEntryPointId) + protected function callFactory(string $firewallName, array $config, string $userProviderId, string $defaultEntryPointId) + { + (new StubFactory())->createAuthenticator($this->container, $firewallName, $config, $userProviderId); + } +} + +class StubFactory extends AbstractFactory +{ + public function getPriority(): int + { + return 0; + } + + public function getKey(): string { - $factory = $this->getMockForAbstractClass(AbstractFactory::class); - - $factory - ->expects($this->once()) - ->method('createAuthProvider') - ->willReturn('auth_provider') - ; - $factory - ->expects($this->atLeastOnce()) - ->method('getListenerId') - ->willReturn('abstract_listener') - ; - $factory - ->expects($this->any()) - ->method('getKey') - ->willReturn('abstract_factory') - ; - - $container = new ContainerBuilder(); - $container->register('auth_provider'); - $container->register('custom_success_handler'); - $container->register('custom_failure_handler'); - - [$authProviderId, $listenerId, $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); - - return [$container, $authProviderId, $listenerId, $entryPointId]; + return 'stub'; + } + + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string + { + $this->createAuthenticationSuccessHandler($container, $firewallName, $config); + $this->createAuthenticationFailureHandler($container, $firewallName, $config); + + return 'stub_authenticator_id'; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php deleted file mode 100644 index f13f5c35a90df..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Security/Factory/GuardAuthenticationFactoryTest.php +++ /dev/null @@ -1,201 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Security\Factory; - -use PHPUnit\Framework\TestCase; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\GuardAuthenticationFactory; -use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; -use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\DependencyInjection\Argument\IteratorArgument; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator; - -class GuardAuthenticationFactoryTest extends TestCase -{ - /** - * @dataProvider getValidConfigurationTests - */ - public function testAddValidConfiguration(array $inputConfig, array $expectedConfig) - { - $factory = new GuardAuthenticationFactory(); - $nodeDefinition = new ArrayNodeDefinition('guard'); - $factory->addConfiguration($nodeDefinition); - - $node = $nodeDefinition->getNode(); - $normalizedConfig = $node->normalize($inputConfig); - $finalizedConfig = $node->finalize($normalizedConfig); - - $this->assertEquals($expectedConfig, $finalizedConfig); - } - - /** - * @dataProvider getInvalidConfigurationTests - */ - public function testAddInvalidConfiguration(array $inputConfig) - { - $this->expectException(InvalidConfigurationException::class); - $factory = new GuardAuthenticationFactory(); - $nodeDefinition = new ArrayNodeDefinition('guard'); - $factory->addConfiguration($nodeDefinition); - - $node = $nodeDefinition->getNode(); - $normalizedConfig = $node->normalize($inputConfig); - // will validate and throw an exception on invalid - $node->finalize($normalizedConfig); - } - - public function getValidConfigurationTests() - { - $tests = []; - - // completely basic - $tests[] = [ - [ - 'authenticators' => ['authenticator1', 'authenticator2'], - 'provider' => 'some_provider', - 'entry_point' => 'the_entry_point', - ], - [ - 'authenticators' => ['authenticator1', 'authenticator2'], - 'provider' => 'some_provider', - 'entry_point' => 'the_entry_point', - ], - ]; - - // testing xml config fix: authenticator -> authenticators - $tests[] = [ - [ - 'authenticator' => ['authenticator1', 'authenticator2'], - ], - [ - 'authenticators' => ['authenticator1', 'authenticator2'], - 'entry_point' => null, - ], - ]; - - return $tests; - } - - public function getInvalidConfigurationTests() - { - $tests = []; - - // testing not empty - $tests[] = [ - ['authenticators' => []], - ]; - - return $tests; - } - - public function testBasicCreate() - { - // simple configuration - $config = [ - 'authenticators' => ['authenticator123'], - 'entry_point' => null, - ]; - [$container, $entryPointId] = $this->executeCreate($config, null); - $this->assertEquals('authenticator123', $entryPointId); - - $providerDefinition = $container->getDefinition('security.authentication.provider.guard.my_firewall'); - $this->assertEquals([ - 'index_0' => new IteratorArgument([new Reference('authenticator123')]), - 'index_1' => new Reference('my_user_provider'), - 'index_2' => 'my_firewall', - 'index_3' => new Reference('security.user_checker.my_firewall'), - ], $providerDefinition->getArguments()); - - $listenerDefinition = $container->getDefinition('security.authentication.listener.guard.my_firewall'); - $this->assertEquals('my_firewall', $listenerDefinition->getArgument(2)); - $this->assertEquals([new Reference('authenticator123')], $listenerDefinition->getArgument(3)->getValues()); - } - - public function testExistingDefaultEntryPointUsed() - { - // any existing default entry point is used - $config = [ - 'authenticators' => ['authenticator123'], - 'entry_point' => null, - ]; - [, $entryPointId] = $this->executeCreate($config, 'some_default_entry_point'); - $this->assertEquals('some_default_entry_point', $entryPointId); - } - - public function testCannotOverrideDefaultEntryPoint() - { - $this->expectException(\LogicException::class); - // any existing default entry point is used - $config = [ - 'authenticators' => ['authenticator123'], - 'entry_point' => 'authenticator123', - ]; - $this->executeCreate($config, 'some_default_entry_point'); - } - - public function testMultipleAuthenticatorsRequiresEntryPoint() - { - $this->expectException(\LogicException::class); - // any existing default entry point is used - $config = [ - 'authenticators' => ['authenticator123', 'authenticatorABC'], - 'entry_point' => null, - ]; - $this->executeCreate($config, null); - } - - public function testCreateWithEntryPoint() - { - // any existing default entry point is used - $config = [ - 'authenticators' => ['authenticator123', 'authenticatorABC'], - 'entry_point' => 'authenticatorABC', - ]; - [, $entryPointId] = $this->executeCreate($config, null); - $this->assertEquals('authenticatorABC', $entryPointId); - } - - public function testAuthenticatorSystemCreate() - { - $container = new ContainerBuilder(); - $firewallName = 'my_firewall'; - $userProviderId = 'my_user_provider'; - $config = [ - 'authenticators' => ['authenticator123'], - 'entry_point' => null, - ]; - $factory = new GuardAuthenticationFactory(); - - $authenticators = $factory->createAuthenticator($container, $firewallName, $config, $userProviderId); - $this->assertEquals('security.authenticator.guard.my_firewall.0', $authenticators[0]); - - $authenticatorDefinition = $container->getDefinition('security.authenticator.guard.my_firewall.0'); - $this->assertEquals(GuardBridgeAuthenticator::class, $authenticatorDefinition->getClass()); - $this->assertEquals('authenticator123', (string) $authenticatorDefinition->getArgument(0)); - $this->assertEquals($userProviderId, (string) $authenticatorDefinition->getArgument(1)); - } - - private function executeCreate(array $config, $defaultEntryPointId) - { - $container = new ContainerBuilder(); - $container->register('security.authentication.provider.guard'); - $container->register('security.authentication.listener.guard'); - $id = 'my_firewall'; - $userProviderId = 'my_user_provider'; - - $factory = new GuardAuthenticationFactory(); - [, , $entryPointId] = $factory->create($container, $id, $config, $userProviderId, $defaultEntryPointId); - - return [$container, $entryPointId]; - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 7add558e7e8ef..1c9d4b6743fc3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -12,14 +12,11 @@ namespace Symfony\Bundle\SecurityBundle\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension; +use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AuthenticatorFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FirewallListenerFactoryInterface; -use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\DependencyInjection\Fixtures\UserProvider\DummyProvider; -use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\Security\EntryPointStub; -use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AppCustomAuthenticator; use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; @@ -35,8 +32,6 @@ use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AuthenticatorInterface as GuardAuthenticatorInterface; -use Symfony\Component\Security\Guard\Token\GuardTokenInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; @@ -69,30 +64,6 @@ public function testInvalidCheckPath() $container->compile(); } - /** - * @group legacy - */ - public function testFirewallWithoutAuthenticationListener() - { - $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('No authentication listener registered for firewall "some_firewall"'); - $container = $this->getRawContainer(); - - $container->loadFromExtension('security', [ - 'providers' => [ - 'default' => ['id' => 'foo'], - ], - - 'firewalls' => [ - 'some_firewall' => [ - 'pattern' => '/.*', - ], - ], - ]); - - $container->compile(); - } - public function testFirewallWithInvalidUserProvider() { $this->expectException(InvalidConfigurationException::class); @@ -144,36 +115,6 @@ public function testDisableRoleHierarchyVoter() $this->assertFalse($container->hasDefinition('security.access.role_hierarchy_voter')); } - /** - * @group legacy - */ - public function testGuardHandlerIsPassedStatelessFirewalls() - { - $container = $this->getRawContainer(); - - $container->loadFromExtension('security', [ - 'providers' => [ - 'default' => ['id' => 'foo'], - ], - - 'firewalls' => [ - 'some_firewall' => [ - 'pattern' => '^/admin', - 'http_basic' => null, - ], - 'stateless_firewall' => [ - 'pattern' => '/.*', - 'stateless' => true, - 'http_basic' => null, - ], - ], - ]); - - $container->compile(); - $definition = $container->getDefinition('security.authentication.guard_handler'); - $this->assertSame(['stateless_firewall'], $definition->getArgument(2)); - } - public function testSwitchUserNotStatelessOnStatelessFirewall() { $container = $this->getRawContainer(); @@ -373,40 +314,6 @@ public function testDoNotRegisterTheUserProviderAliasWithMultipleProviders() $this->assertFalse($container->has(UserProviderInterface::class)); } - /** - * @dataProvider sessionConfigurationProvider - * @group legacy - */ - public function testRememberMeCookieInheritFrameworkSessionCookie($config, $samesite, $secure) - { - $container = $this->getRawContainer(); - - $container->registerExtension(new FrameworkExtension()); - $container->setParameter('kernel.bundles_metadata', []); - $container->setParameter('kernel.project_dir', __DIR__); - $container->setParameter('kernel.cache_dir', __DIR__); - $container->setParameter('kernel.container_class', 'FooContainer'); - - $container->loadFromExtension('security', [ - 'firewalls' => [ - 'default' => [ - 'form_login' => null, - 'remember_me' => ['secret' => 'baz'], - ], - ], - ]); - $container->loadFromExtension('framework', [ - 'session' => $config, - ]); - - $container->compile(); - - $definition = $container->getDefinition('security.authentication.rememberme.services.simplehash.default'); - - $this->assertEquals($samesite, $definition->getArgument(3)['samesite']); - $this->assertEquals($secure, $definition->getArgument(3)['secure']); - } - /** * @dataProvider acceptableIpsProvider */ @@ -563,48 +470,6 @@ public function testValidAccessControlWithEmptyRow() $this->assertTrue(true, 'extension throws an InvalidConfigurationException if there is one more more empty access control items'); } - /** - * @group legacy - * @dataProvider provideEntryPointFirewalls - */ - public function testAuthenticatorManagerEnabledEntryPoint(array $firewall, $entryPointId) - { - $container = $this->getRawContainer(); - $container->register(AppCustomAuthenticator::class); - $container->loadFromExtension('security', [ - 'enable_authenticator_manager' => true, - 'providers' => [ - 'first' => ['id' => 'users'], - ], - - 'firewalls' => [ - 'main' => $firewall, - ], - ]); - - $container->compile(); - - $this->assertEquals($entryPointId, (string) $container->getDefinition('security.firewall.map.config.main')->getArgument(7)); - $this->assertEquals($entryPointId, (string) $container->getDefinition('security.exception_listener.main')->getArgument(4)); - } - - public function provideEntryPointFirewalls() - { - // only one entry point available - yield [['http_basic' => true], 'security.authenticator.http_basic.main']; - // explicitly configured by authenticator key - yield [['form_login' => true, 'http_basic' => true, 'entry_point' => 'form_login'], 'security.authenticator.form_login.main']; - // explicitly configured another service - yield [['form_login' => true, 'entry_point' => EntryPointStub::class], EntryPointStub::class]; - // no entry point required - yield [['json_login' => true], null]; - - // only one guard authenticator entry point available - yield [[ - 'guard' => ['authenticators' => [AppCustomAuthenticator::class]], - ], 'security.authenticator.guard.main.0']; - } - /** * @dataProvider provideEntryPointRequiredData */ @@ -637,24 +502,6 @@ public function provideEntryPointRequiredData() ]; } - /** - * @group legacy - */ - public function testAlwaysAuthenticateBeforeGrantingCannotBeTrueWithAuthenticatorManager() - { - $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The security option "always_authenticate_before_granting" cannot be used when "enable_authenticator_manager" is set to true. If you rely on this behavior, set it to false.'); - - $container = $this->getRawContainer(); - $container->loadFromExtension('security', [ - 'enable_authenticator_manager' => true, - 'always_authenticate_before_granting' => true, - 'firewalls' => ['main' => []], - ]); - - $container->compile(); - } - /** * @dataProvider provideConfigureCustomAuthenticatorData */ @@ -764,17 +611,15 @@ public function provideUserCheckerConfig() yield [['user_checker' => TestUserChecker::class], TestUserChecker::class]; } - /** - * @group legacy - */ public function testConfigureCustomFirewallListener() { $container = $this->getRawContainer(); /** @var SecurityExtension $extension */ $extension = $container->getExtension('security'); - $extension->addSecurityListenerFactory(new TestFirewallListenerFactory()); + $extension->addAuthenticatorFactory(new TestFirewallListenerFactory()); $container->loadFromExtension('security', [ + 'enable_authenticator_manager' => true, 'firewalls' => [ 'main' => [ 'custom_listener' => true, @@ -790,26 +635,6 @@ public function testConfigureCustomFirewallListener() $this->assertContains('custom_firewall_listener_id', $firewallListeners); } - /** - * @group legacy - */ - public function testLegacyAuthorizationManagerSignature() - { - $container = $this->getRawContainer(); - $container->loadFromExtension('security', [ - 'always_authenticate_before_granting' => true, - 'firewalls' => ['main' => ['http_basic' => true]], - ]); - - $container->compile(); - - $args = $container->getDefinition('security.authorization_checker')->getArguments(); - $this->assertEquals('security.token_storage', (string) $args[0]); - $this->assertEquals('security.authentication_manager', (string) $args[1]); - $this->assertEquals('security.access.decision_manager', (string) $args[2]); - $this->assertEquals('%security.access.always_authenticate_before_granting%', (string) $args[3]); - } - protected function getRawContainer() { $container = new ContainerBuilder(); @@ -847,60 +672,24 @@ public function authenticate(Request $request): Passport { } + /** + * @internal for compatibility with Symfony 5.4 + */ public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface { } - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response - { - } - - public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response - { - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { } -} -class NullAuthenticator implements GuardAuthenticatorInterface -{ - public function start(Request $request, AuthenticationException $authException = null): Response - { - } - - public function supports(Request $request): bool - { - } - - public function getCredentials(Request $request): mixed - { - } - - public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface - { - } - - public function checkCredentials($credentials, UserInterface $user): bool - { - } - - public function createAuthenticatedToken(UserInterface $user, string $providerKey): GuardTokenInterface + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response { } public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response { } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response - { - } - - public function supportsRememberMe(): bool - { - } } class TestUserChecker implements UserCheckerInterface @@ -914,7 +703,7 @@ public function checkPostAuth(UserInterface $user) } } -class TestFirewallListenerFactory implements SecurityFactoryInterface, FirewallListenerFactoryInterface +class TestFirewallListenerFactory implements AuthenticatorFactoryInterface, FirewallListenerFactoryInterface { public function createListeners(ContainerBuilder $container, string $firewallName, array $config): array { @@ -923,17 +712,14 @@ public function createListeners(ContainerBuilder $container, string $firewallNam return ['custom_firewall_listener_id']; } - public function create(ContainerBuilder $container, string $id, array $config, string $userProvider, ?string $defaultEntryPoint): array + public function createAuthenticator(ContainerBuilder $container, string $firewallName, array $config, string $userProviderId): string { - $container->register('provider_id', \stdClass::class); - $container->register('listener_id', \stdClass::class); - - return ['provider_id', 'listener_id', $defaultEntryPoint]; + return 'test_authenticator_id'; } - public function getPosition(): string + public function getPriority(): int { - return 'form'; + return 0; } public function getKey(): string diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AbstractWebTestCase.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AbstractWebTestCase.php index f9363e8290dc0..737aa8fbd3048 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AbstractWebTestCase.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AbstractWebTestCase.php @@ -19,7 +19,7 @@ abstract class AbstractWebTestCase extends BaseWebTestCase { public static function assertRedirect($response, $location) { - self::assertTrue($response->isRedirect(), 'Response is not a redirect, got status code: '.substr($response, 0, 2000)); + self::assertTrue($response->isRedirect(), "Response is not a redirect, got:\n".(($p = strpos($response, '-->')) ? substr($response, 0, $p + 3) : $response)); self::assertEquals('http://localhost'.$location, $response->headers->get('Location')); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AnonymousTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AnonymousTest.php deleted file mode 100644 index f0155701cbbd0..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AnonymousTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\Functional; - -/** - * @group legacy - */ -class AnonymousTest extends AbstractWebTestCase -{ - public function testAnonymous() - { - $client = $this->createClient(['test_case' => 'Anonymous', 'root_config' => 'config.yml']); - - $client->request('GET', '/'); - - $this->assertSame(401, $client->getResponse()->getStatusCode()); - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php index 6e6267b7f8c14..03b4663ef9250 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticationCommencingTest.php @@ -20,15 +20,4 @@ public function testAuthenticationIsCommencingIfAccessDeniedExceptionIsWrapped() $client->request('GET', '/secure-but-not-covered-by-access-control'); $this->assertRedirect($client->getResponse(), '/login'); } - - /** - * @group legacy - */ - public function testLegacyAuthenticationIsCommencingIfAccessDeniedExceptionIsWrapped() - { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_config.yml']); - - $client->request('GET', '/secure-but-not-covered-by-access-control'); - $this->assertRedirect($client->getResponse(), '/login'); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AutowiringTypesTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AutowiringTypesTest.php index 9aa2b6f80a57a..9e3b4a5523783 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AutowiringTypesTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/AutowiringTypesTest.php @@ -30,22 +30,6 @@ public function testAccessDecisionManagerAutowiring() $this->assertInstanceOf(TraceableAccessDecisionManager::class, $autowiredServices->getAccessDecisionManager(), 'The debug.security.access.decision_manager service should be injected in non-debug mode'); } - /** - * @group legacy - */ - public function testLegacyAccessDecisionManagerAutowiring() - { - static::bootKernel(['debug' => false, 'root_config' => 'legacy_config.yml']); - - $autowiredServices = static::getContainer()->get('test.autowiring_types.autowired_services'); - $this->assertInstanceOf(AccessDecisionManager::class, $autowiredServices->getAccessDecisionManager(), 'The security.access.decision_manager service should be injected in debug mode'); - - static::bootKernel(['debug' => true, 'root_config' => 'legacy_config.yml']); - - $autowiredServices = static::getContainer()->get('test.autowiring_types.autowired_services'); - $this->assertInstanceOf(TraceableAccessDecisionManager::class, $autowiredServices->getAccessDecisionManager(), 'The debug.security.access.decision_manager service should be injected in non-debug mode'); - } - protected static function createKernel(array $options = []): KernelInterface { return parent::createKernel(['test_case' => 'AutowiringTypes'] + $options); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AnonymousBundle/AppCustomAuthenticator.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AnonymousBundle/AppCustomAuthenticator.php deleted file mode 100644 index 045b5d01a0cff..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/AnonymousBundle/AppCustomAuthenticator.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AnonymousBundle; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; - -class AppCustomAuthenticator extends AbstractGuardAuthenticator -{ - public function supports(Request $request): bool - { - return false; - } - - public function getCredentials(Request $request): mixed - { - } - - public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface - { - } - - public function checkCredentials($credentials, UserInterface $user): bool - { - } - - public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response - { - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response - { - } - - public function start(Request $request, AuthenticationException $authException = null): Response - { - return new Response($authException->getMessage(), Response::HTTP_UNAUTHORIZED); - } - - public function supportsRememberMe(): bool - { - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php deleted file mode 100644 index 52667cb28a50a..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AppCustomAuthenticator.php +++ /dev/null @@ -1,59 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; - -class AppCustomAuthenticator extends AbstractGuardAuthenticator -{ - public function supports(Request $request): bool - { - return '/manual_login' !== $request->getPathInfo() && '/profile' !== $request->getPathInfo(); - } - - public function getCredentials(Request $request): mixed - { - throw new AuthenticationException('This should be hit'); - } - - public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface - { - } - - public function checkCredentials($credentials, UserInterface $user): bool - { - } - - public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response - { - return new Response('', 418); - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response - { - } - - public function start(Request $request, AuthenticationException $authException = null): Response - { - return new Response($authException->getMessage(), Response::HTTP_UNAUTHORIZED); - } - - public function supportsRememberMe(): bool - { - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php deleted file mode 100644 index 21a2ea9e4b8f6..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/GuardedBundle/AuthenticationController.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; - -class AuthenticationController -{ - public function manualLoginAction(GuardAuthenticatorHandler $guardAuthenticatorHandler, Request $request) - { - $guardAuthenticatorHandler->authenticateWithToken(new PostAuthenticationGuardToken(new InMemoryUser('Jane', 'test', ['ROLE_USER']), 'secure', ['ROLE_USER']), $request, 'secure'); - - return new Response('Logged in.'); - } - - public function profileAction(UserInterface $user = null) - { - if (null === $user) { - return new Response('Not logged in.'); - } - - return new Response('Username: '.$user->getUserIdentifier()); - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php index 6d1323bc1c7a5..ad2fc0c63d1e0 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/CsrfFormLoginTest.php @@ -100,106 +100,9 @@ public function testFormLoginRedirectsToProtectedResourceAfterLogin($options) $this->assertStringContainsString('You\'re browsing to path "/protected-resource".', $text); } - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testLegacyFormLoginAndLogoutWithCsrfTokens($options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['user_login[username]'] = 'johannes'; - $form['user_login[password]'] = 'test'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/profile'); - - $crawler = $client->followRedirect(); - - $text = $crawler->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/profile".', $text); - - $logoutLinks = $crawler->selectLink('Log out')->links(); - $this->assertCount(2, $logoutLinks); - $this->assertStringContainsString('_csrf_token=', $logoutLinks[0]->getUri()); - - $client->click($logoutLinks[0]); - - $this->assertRedirect($client->getResponse(), '/'); - } - - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testLegacyFormLoginWithInvalidCsrfToken($options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['user_login[_token]'] = ''; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/login'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Invalid CSRF token.', $text); - } - - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testFormLegacyLoginWithCustomTargetPath($options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['user_login[username]'] = 'johannes'; - $form['user_login[password]'] = 'test'; - $form['user_login[_target_path]'] = '/foo'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/foo'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/foo".', $text); - } - - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testLegacyFormLoginRedirectsToProtectedResourceAfterLogin($options) - { - $client = $this->createClient($options); - - $client->request('GET', '/protected-resource'); - $this->assertRedirect($client->getResponse(), '/login'); - - $form = $client->followRedirect()->selectButton('login')->form(); - $form['user_login[username]'] = 'johannes'; - $form['user_login[password]'] = 'test'; - $client->submit($form); - $this->assertRedirect($client->getResponse(), '/protected-resource'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/protected-resource".', $text); - } - public function provideClientOptions() { - yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'config.yml', 'enable_authenticator_manager' => true]]; - yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; - } - - public function provideLegacyClientOptions() - { - yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'legacy_config.yml', 'enable_authenticator_manager' => false]]; - yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'legacy_routes_as_path.yml', 'enable_authenticator_manager' => false]]; + yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'config.yml']]; + yield [['test_case' => 'CsrfFormLogin', 'root_config' => 'routes_as_path.yml']]; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/EventAliasTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/EventAliasTest.php index 55f7906e22d30..6b1a54caa0100 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/EventAliasTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/EventAliasTest.php @@ -14,9 +14,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\AuthenticationEvents; -use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent; -use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\Event\SwitchUserEvent; @@ -43,21 +41,4 @@ public function testAliasedEvents() $container->get('test_subscriber')->calledMethods ); } - - /** - * @group legacy - */ - public function testAliasedLegacyEvent() - { - $client = $this->createClient(['test_case' => 'AliasedEvents', 'root_config' => 'config.yml']); - $container = $client->getContainer(); - $dispatcher = $container->get('event_dispatcher'); - - $dispatcher->dispatch(new AuthenticationFailureEvent($this->createMock(TokenInterface::class), new AuthenticationException()), AuthenticationEvents::AUTHENTICATION_FAILURE); - - $this->assertEquals( - ['onAuthenticationFailure' => 1], - $container->get('test_subscriber')->calledMethods - ); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FirewallEntryPointTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FirewallEntryPointTest.php index c2399cb652214..7b6f4fb249135 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FirewallEntryPointTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FirewallEntryPointTest.php @@ -27,39 +27,4 @@ public function testItUsesTheConfiguredEntryPointFromTheExceptionListenerWithFor "Custom entry point wasn't started" ); } - - /** - * @group legacy - */ - public function testItUsesTheConfiguredEntryPointWhenUsingUnknownCredentials() - { - $client = $this->createClient(['test_case' => 'FirewallEntryPoint', 'root_config' => 'legacy_config.yml']); - - $client->request('GET', '/secure/resource', [], [], [ - 'PHP_AUTH_USER' => 'unknown', - 'PHP_AUTH_PW' => 'credentials', - ]); - - $this->assertEquals( - EntryPointStub::RESPONSE_TEXT, - $client->getResponse()->getContent(), - "Custom entry point wasn't started" - ); - } - - /** - * @group legacy - */ - public function testLegacyItUsesTheConfiguredEntryPointFromTheExceptionListenerWithFormLoginAndNoCredentials() - { - $client = $this->createClient(['test_case' => 'FirewallEntryPoint', 'root_config' => 'legacy_config_form_login.yml']); - - $client->request('GET', '/secure/resource'); - - $this->assertEquals( - EntryPointStub::RESPONSE_TEXT, - $client->getResponse()->getContent(), - "Custom entry point wasn't started" - ); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php index b1d38f40ef1c8..790ec3554d6ce 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php @@ -11,8 +11,6 @@ namespace Symfony\Bundle\SecurityBundle\Tests\Functional; -use Symfony\Component\Security\Http\EventListener\LoginThrottlingListener; - class FormLoginTest extends AbstractWebTestCase { /** @@ -113,10 +111,6 @@ public function testFormLoginRedirectsToProtectedResourceAfterLogin(array $optio */ public function testLoginThrottling() { - if (!class_exists(LoginThrottlingListener::class)) { - $this->markTestSkipped('Login throttling requires symfony/security-http:^5.2'); - } - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'login_throttling.yml', 'enable_authenticator_manager' => true]); $attempts = [ @@ -153,158 +147,9 @@ public function testLoginThrottling() } } - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyFormLogin(array $options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/profile'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/profile".', $text); - } - - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyFormLogout(array $options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/profile'); - - $crawler = $client->followRedirect(); - $text = $crawler->text(null, true); - - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/profile".', $text); - - $logoutLinks = $crawler->selectLink('Log out')->links(); - $this->assertCount(6, $logoutLinks); - $this->assertSame($logoutLinks[0]->getUri(), $logoutLinks[1]->getUri()); - $this->assertSame($logoutLinks[2]->getUri(), $logoutLinks[3]->getUri()); - $this->assertSame($logoutLinks[4]->getUri(), $logoutLinks[5]->getUri()); - - $this->assertNotSame($logoutLinks[0]->getUri(), $logoutLinks[2]->getUri()); - $this->assertNotSame($logoutLinks[1]->getUri(), $logoutLinks[3]->getUri()); - - $this->assertSame($logoutLinks[0]->getUri(), $logoutLinks[4]->getUri()); - $this->assertSame($logoutLinks[1]->getUri(), $logoutLinks[5]->getUri()); - } - - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyFormLoginWithCustomTargetPath(array $options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $form['_target_path'] = '/foo'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/foo'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/foo".', $text); - } - - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyFormLoginRedirectsToProtectedResourceAfterLogin(array $options) - { - $client = $this->createClient($options); - - $client->request('GET', '/protected_resource'); - $this->assertRedirect($client->getResponse(), '/login'); - - $form = $client->followRedirect()->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $client->submit($form); - $this->assertRedirect($client->getResponse(), '/protected_resource'); - - $text = $client->followRedirect()->text(null, true); - $this->assertStringContainsString('Hello johannes!', $text); - $this->assertStringContainsString('You\'re browsing to path "/protected_resource".', $text); - } - - /** - * @group time-sensitive - * @group legacy - */ - public function testLegacyLoginThrottling() - { - if (!class_exists(LoginThrottlingListener::class)) { - $this->markTestSkipped('Login throttling requires symfony/security-http:^5.2'); - } - - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_login_throttling.yml', 'enable_authenticator_manager' => true]); - - $attempts = [ - ['johannes', 'wrong'], - ['johannes', 'also_wrong'], - ['wrong', 'wrong'], - ['johannes', 'wrong_again'], - ]; - foreach ($attempts as $i => $attempt) { - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['_username'] = $attempt[0]; - $form['_password'] = $attempt[1]; - $client->submit($form); - - $text = $client->followRedirect()->text(null, true); - switch ($i) { - case 0: // First attempt : Invalid credentials (OK) - $this->assertStringContainsString('Invalid credentials', $text, 'Invalid response on 1st attempt'); - - break; - case 1: // Second attempt : login throttling ! - $this->assertStringContainsString('Too many failed login attempts, please try again in 8 minutes.', $text, 'Invalid response on 2nd attempt'); - - break; - case 2: // Third attempt with unexisting username - $this->assertStringContainsString('Invalid credentials.', $text, 'Invalid response on 3rd attempt'); - - break; - case 3: // Fourth attempt : still login throttling ! - $this->assertStringContainsString('Too many failed login attempts, please try again in 8 minutes.', $text, 'Invalid response on 4th attempt'); - - break; - } - } - } - public function provideClientOptions() { - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml', 'enable_authenticator_manager' => true]]; - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; - } - - public function provideLegacyClientOptions() - { - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_config.yml', 'enable_authenticator_manager' => false]]; - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_routes_as_path.yml', 'enable_authenticator_manager' => false]]; + yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml']]; + yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml']]; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php deleted file mode 100644 index 6816442a232b2..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/GuardedTest.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\SecurityBundle\Tests\Functional; - -/** - * @group legacy - */ -class GuardedTest extends AbstractWebTestCase -{ - public function testGuarded() - { - $client = $this->createClient(['test_case' => 'Guarded', 'root_config' => 'config.yml']); - - $client->request('GET', '/'); - - $this->assertSame(418, $client->getResponse()->getStatusCode()); - } - - public function testManualLogin() - { - $client = $this->createClient(['debug' => true, 'test_case' => 'Guarded', 'root_config' => 'config.yml']); - - $client->request('GET', '/manual_login'); - $client->request('GET', '/profile'); - - $this->assertSame('Username: Jane', $client->getResponse()->getContent()); - } -} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/JsonLoginTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/JsonLoginTest.php index 133c294b09db2..5828a0c3b1b9b 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/JsonLoginTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/JsonLoginTest.php @@ -13,9 +13,6 @@ use Symfony\Component\HttpFoundation\JsonResponse; -/** - * @author Kévin Dunglas - */ class JsonLoginTest extends AbstractWebTestCase { public function testDefaultJsonLoginSuccess() @@ -61,88 +58,4 @@ public function testCustomJsonLoginFailure() $this->assertSame(500, $response->getStatusCode()); $this->assertSame(['message' => 'Something went wrong'], json_decode($response->getContent(), true)); } - - /** - * @group legacy - */ - public function testDefaultJsonLoginBadRequest() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_config.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], 'Not a json content'); - $response = $client->getResponse(); - - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame('application/json', $response->headers->get('Content-Type')); - $this->assertSame(['type' => 'https://tools.ietf.org/html/rfc2616#section-10', 'title' => 'An error occurred', 'status' => 400, 'detail' => 'Bad Request'], json_decode($response->getContent(), true)); - } - - /** - * @group legacy - */ - public function testLegacyDefaultJsonLoginSuccess() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_config.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], '{"user": {"login": "dunglas", "password": "foo"}}'); - $response = $client->getResponse(); - - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame(['message' => 'Welcome @dunglas!'], json_decode($response->getContent(), true)); - } - - /** - * @group legacy - */ - public function testLegacyDefaultJsonLoginFailure() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_config.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], '{"user": {"login": "dunglas", "password": "bad"}}'); - $response = $client->getResponse(); - - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertSame(401, $response->getStatusCode()); - $this->assertSame(['error' => 'Invalid credentials.'], json_decode($response->getContent(), true)); - } - - /** - * @group legacy - */ - public function testLegacyCustomJsonLoginSuccess() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_custom_handlers.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], '{"user": {"login": "dunglas", "password": "foo"}}'); - $response = $client->getResponse(); - - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertSame(200, $response->getStatusCode()); - $this->assertSame(['message' => 'Good game @dunglas!'], json_decode($response->getContent(), true)); - } - - /** - * @group legacy - */ - public function testLegacyCustomJsonLoginFailure() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_custom_handlers.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], '{"user": {"login": "dunglas", "password": "bad"}}'); - $response = $client->getResponse(); - - $this->assertInstanceOf(JsonResponse::class, $response); - $this->assertSame(500, $response->getStatusCode()); - $this->assertSame(['message' => 'Something went wrong'], json_decode($response->getContent(), true)); - } - - /** - * @group legacy - */ - public function testLegacyDefaultJsonLoginBadRequest() - { - $client = $this->createClient(['test_case' => 'JsonLogin', 'root_config' => 'legacy_config.yml']); - $client->request('POST', '/chk', [], [], ['CONTENT_TYPE' => 'application/json'], 'Not a json content'); - $response = $client->getResponse(); - - $this->assertSame(400, $response->getStatusCode()); - $this->assertSame('application/json', $response->headers->get('Content-Type')); - $this->assertSame(['type' => 'https://tools.ietf.org/html/rfc2616#section-10', 'title' => 'An error occurred', 'status' => 400, 'detail' => 'Bad Request'], json_decode($response->getContent(), true)); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php index a6efa746a372a..0c356662c39a7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php @@ -14,11 +14,11 @@ class LocalizedRoutesAsPathTest extends AbstractWebTestCase { /** - * @dataProvider getLocalesAndClientConfig + * @dataProvider getLocales */ - public function testLoginLogoutProcedure($locale, array $options) + public function testLoginLogoutProcedure(string $locale) { - $client = $this->createClient(['test_case' => 'StandardFormLogin'] + $options); + $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml']); $crawler = $client->request('GET', '/'.$locale.'/login'); $form = $crawler->selectButton('login')->form(); @@ -36,11 +36,11 @@ public function testLoginLogoutProcedure($locale, array $options) /** * @group issue-32995 - * @dataProvider getLocalesAndClientConfig + * @dataProvider getLocales */ - public function testLoginFailureWithLocalizedFailurePath($locale, array $options) + public function testLoginFailureWithLocalizedFailurePath(string $locale) { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_form_failure_handler.yml'] + $options); + $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_form_failure_handler.yml']); $crawler = $client->request('GET', '/'.$locale.'/login'); $form = $crawler->selectButton('login')->form(); @@ -52,100 +52,30 @@ public function testLoginFailureWithLocalizedFailurePath($locale, array $options } /** - * @dataProvider getLocalesAndClientConfig + * @dataProvider getLocales */ - public function testAccessRestrictedResource($locale, array $options) + public function testAccessRestrictedResource(string $locale) { - $client = $this->createClient(['test_case' => 'StandardFormLogin'] + $options); + $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes.yml']); $client->request('GET', '/'.$locale.'/secure/'); $this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); } /** - * @dataProvider getLocalesAndClientConfig + * @dataProvider getLocales */ - public function testAccessRestrictedResourceWithForward($locale, array $options) + public function testAccessRestrictedResourceWithForward(string $locale) { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml'] + $options); + $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'localized_routes_with_forward.yml']); $crawler = $client->request('GET', '/'.$locale.'/secure/'); $this->assertCount(1, $crawler->selectButton('login'), (string) $client->getResponse()); } - /** - * @group legacy - * @dataProvider getLegacyLocalesAndClientConfig - */ - public function testLegacyLoginLogoutProcedure($locale, array $options) - { - $client = $this->createClient(['test_case' => 'StandardFormLogin'] + $options); - - $crawler = $client->request('GET', '/'.$locale.'/login'); - $form = $crawler->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/'.$locale.'/profile'); - $this->assertEquals('Profile', $client->followRedirect()->text()); - - $client->request('GET', '/'.$locale.'/logout'); - $this->assertRedirect($client->getResponse(), '/'.$locale.'/'); - $this->assertEquals('Homepage', $client->followRedirect()->text()); - } - - /** - * @group issue-32995 - * @group legacy - * @dataProvider getLegacyLocalesAndClientConfig - */ - public function testLegacyLoginFailureWithLocalizedFailurePath($locale, array $options) - { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_localized_form_failure_handler.yml'] + $options); - - $crawler = $client->request('GET', '/'.$locale.'/login'); - $form = $crawler->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'foobar'; - $client->submit($form); - - $this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); - } - - /** - * @group legacy - * @dataProvider getLegacyLocalesAndClientConfig - */ - public function testLegacyAccessRestrictedResource($locale, array $options) - { - $client = $this->createClient(['test_case' => 'StandardFormLogin'] + $options); - - $client->request('GET', '/'.$locale.'/secure/'); - $this->assertRedirect($client->getResponse(), '/'.$locale.'/login'); - } - - /** - * @group legacy - * @dataProvider getLegacyLocalesAndClientConfig - */ - public function testLegacyAccessRestrictedResourceWithForward($locale, array $options) - { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_localized_routes_with_forward.yml'] + $options); - - $crawler = $client->request('GET', '/'.$locale.'/secure/'); - $this->assertCount(1, $crawler->selectButton('login'), (string) $client->getResponse()); - } - - public function getLocalesAndClientConfig() - { - yield ['en', ['root_config' => 'localized_routes.yml']]; - yield ['de', ['root_config' => 'localized_routes.yml']]; - } - - public function getLegacyLocalesAndClientConfig() + public function getLocales() { - yield ['en', ['root_config' => 'legacy_localized_routes.yml']]; - yield ['de', ['root_config' => 'legacy_localized_routes.yml']]; + yield ['en']; + yield ['de']; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LoginLinkAuthenticationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LoginLinkAuthenticationTest.php index 2c767349287d8..1457d20e303e2 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LoginLinkAuthenticationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LoginLinkAuthenticationTest.php @@ -14,7 +14,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Http\LoginLink\LoginLinkHandler; use Symfony\Component\Security\Http\LoginLink\LoginLinkHandlerInterface; /** @@ -24,10 +23,6 @@ class LoginLinkAuthenticationTest extends AbstractWebTestCase { public function testLoginLinkSuccess() { - if (!class_exists(LoginLinkHandler::class)) { - $this->markTestSkipped('Login link auth requires symfony/security-http:^5.2'); - } - $client = $this->createClient(['test_case' => 'LoginLink', 'root_config' => 'config.yml', 'debug' => true]); // we need an active request that is under the firewall to use the linker diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php index 9076b0ff28a77..5da52d9602a49 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php @@ -22,7 +22,7 @@ class LogoutTest extends AbstractWebTestCase { public function testCsrfTokensAreClearedOnLogout() { - $client = $this->createClient(['enable_authenticator_manager' => true, 'test_case' => 'LogoutWithoutSessionInvalidation', 'root_config' => 'config.yml']); + $client = $this->createClient(['test_case' => 'LogoutWithoutSessionInvalidation', 'root_config' => 'config.yml']); $client->disableReboot(); $this->callInRequestContext($client, function () { static::getContainer()->get('security.csrf.token_storage')->setToken('foo', 'bar'); @@ -47,20 +47,7 @@ public function testCsrfTokensAreClearedOnLogout() public function testAccessControlDoesNotApplyOnLogout() { - $client = $this->createClient(['enable_authenticator_manager' => true, 'test_case' => 'Logout', 'root_config' => 'config_access.yml']); - - $client->request('POST', '/login', ['_username' => 'johannes', '_password' => 'test']); - $client->request('GET', '/logout'); - - $this->assertRedirect($client->getResponse(), '/'); - } - - /** - * @group legacy - */ - public function testLegacyAccessControlDoesNotApplyOnLogout() - { - $client = $this->createClient(['enable_authenticator_manager' => false, 'test_case' => 'Logout', 'root_config' => 'config_access.yml']); + $client = $this->createClient(['test_case' => 'Logout', 'root_config' => 'config_access.yml']); $client->request('POST', '/login', ['_username' => 'johannes', '_password' => 'test']); $client->request('GET', '/logout'); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php index 7308de85362fd..a5029c954189a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/MissingUserProviderTest.php @@ -17,7 +17,7 @@ class MissingUserProviderTest extends AbstractWebTestCase { public function testUserProviderIsNeeded() { - $client = $this->createClient(['enable_authenticator_manager' => true, 'test_case' => 'MissingUserProvider', 'root_config' => 'config.yml', 'debug' => true]); + $client = $this->createClient(['test_case' => 'MissingUserProvider', 'root_config' => 'config.yml']); $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage('"default" firewall requires a user provider but none was defined'); @@ -27,22 +27,4 @@ public function testUserProviderIsNeeded() 'PHP_AUTH_PW' => 'pa$$word', ]); } - - /** - * @group legacy - */ - public function testLegacyUserProviderIsNeeded() - { - $client = $this->createClient(['test_case' => 'MissingUserProvider', 'root_config' => 'config.yml', 'debug' => true]); - - $client->request('GET', '/', [], [], [ - 'PHP_AUTH_USER' => 'username', - 'PHP_AUTH_PW' => 'pa$$word', - ]); - - $response = $client->getResponse(); - $this->assertSame(500, $response->getStatusCode()); - $this->assertStringContainsString('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException', $response->getContent()); - $this->assertStringContainsString('"default" firewall requires a user provider but none was defined', html_entity_decode($response->getContent())); - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php index 7af43e1154a42..d9dd477b15b68 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/RememberMeTest.php @@ -78,88 +78,9 @@ public function testSessionLessRememberMeLogout() $this->assertNull($cookieJar->get('REMEMBERME')); } - /** - * @dataProvider provideLegacyConfigs - * @group legacy - */ - public function testLegacyRememberMe(array $options) - { - $client = $this->createClient(array_merge_recursive(['root_config' => 'config.yml', 'test_case' => 'RememberMe'], $options)); - - $client->request('POST', '/login', [ - '_username' => 'johannes', - '_password' => 'test', - ]); - $this->assertSame(302, $client->getResponse()->getStatusCode()); - - $client->request('GET', '/profile'); - $this->assertSame('johannes', $client->getResponse()->getContent()); - - // clear session, this should trigger remember me on the next request - $client->getCookieJar()->expire('MOCKSESSID'); - - $client->request('GET', '/profile'); - $this->assertSame('johannes', $client->getResponse()->getContent(), 'Not logged in after resetting session.'); - - // logout, this should clear the remember-me cookie - $client->request('GET', '/logout'); - $this->assertSame(302, $client->getResponse()->getStatusCode(), 'Logout unsuccessful.'); - $this->assertNull($client->getCookieJar()->get('REMEMBERME')); - } - - /** - * @group legacy - */ - public function testLegacyUserChangeClearsCookie() - { - $client = $this->createClient(['test_case' => 'RememberMe', 'root_config' => 'clear_on_change_config.yml']); - - $client->request('POST', '/login', [ - '_username' => 'johannes', - '_password' => 'test', - ]); - - $this->assertSame(302, $client->getResponse()->getStatusCode()); - $cookieJar = $client->getCookieJar(); - $this->assertNotNull($cookieJar->get('REMEMBERME')); - - $client->request('GET', '/profile'); - $this->assertRedirect($client->getResponse(), '/login'); - $this->assertNull($cookieJar->get('REMEMBERME')); - } - - /** - * @group legacy - */ - public function testLegacySessionLessRememberMeLogout() - { - $client = $this->createClient(['test_case' => 'RememberMe', 'root_config' => 'stateless_config.yml']); - - $client->request('POST', '/login', [ - '_username' => 'johannes', - '_password' => 'test', - ]); - - $cookieJar = $client->getCookieJar(); - $cookieJar->expire(session_name()); - - $this->assertNotNull($cookieJar->get('REMEMBERME')); - $this->assertSame('lax', $cookieJar->get('REMEMBERME')->getSameSite()); - - $client->request('GET', '/logout'); - $this->assertSame(302, $client->getResponse()->getStatusCode(), 'Logout unsuccessful.'); - $this->assertNull($cookieJar->get('REMEMBERME')); - } - public function provideConfigs() { yield [['root_config' => 'config_session.yml']]; yield [['root_config' => 'config_persistent.yml']]; } - - public function provideLegacyConfigs() - { - yield [['root_config' => 'legacy_config_session.yml']]; - yield [['root_config' => 'legacy_config_persistent.yml']]; - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php index 788599224e47e..7c1f3dc0679a4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php @@ -14,7 +14,7 @@ class SecurityRoutingIntegrationTest extends AbstractWebTestCase { /** - * @dataProvider provideClientOptions + * @dataProvider provideConfigs */ public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous(array $options) { @@ -25,7 +25,7 @@ public function testRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous(ar } /** - * @dataProvider provideClientOptions + * @dataProvider provideConfigs */ public function testRoutingErrorIsExposedWhenNotProtected(array $options) { @@ -36,7 +36,7 @@ public function testRoutingErrorIsExposedWhenNotProtected(array $options) } /** - * @dataProvider provideClientOptions + * @dataProvider provideConfigs */ public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights(array $options) { @@ -53,7 +53,7 @@ public function testRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWith } /** - * @dataProvider provideClientOptions + * @dataProvider provideConfigs */ public function testSecurityConfigurationForSingleIPAddress(array $options) { @@ -68,7 +68,7 @@ public function testSecurityConfigurationForSingleIPAddress(array $options) } /** - * @dataProvider provideClientOptions + * @dataProvider provideConfigs */ public function testSecurityConfigurationForMultipleIPAddresses(array $options) { @@ -139,144 +139,6 @@ public function testPublicHomepage() $this->assertSame(0, self::getContainer()->get('request_tracker_subscriber')->getLastRequest()->getSession()->getUsageIndex()); } - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyRoutingErrorIsNotExposedForProtectedResourceWhenAnonymous(array $options) - { - $client = $this->createClient($options); - $client->request('GET', '/protected_resource'); - - $this->assertRedirect($client->getResponse(), '/login'); - } - - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyRoutingErrorIsExposedWhenNotProtected(array $options) - { - $client = $this->createClient($options); - $client->request('GET', '/unprotected_resource'); - - $this->assertEquals(404, $client->getResponse()->getStatusCode(), (string) $client->getResponse()); - } - - /** - * @dataProvider provideLegacyClientOptions - * @group legacy - */ - public function testLegacyRoutingErrorIsNotExposedForProtectedResourceWhenLoggedInWithInsufficientRights(array $options) - { - $client = $this->createClient($options); - - $form = $client->request('GET', '/login')->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $client->submit($form); - - $client->request('GET', '/highly_protected_resource'); - - $this->assertNotEquals(404, $client->getResponse()->getStatusCode()); - } - - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testLegacySecurityConfigurationForSingleIPAddress(array $options) - { - $allowedClient = $this->createClient($options, ['REMOTE_ADDR' => '10.10.10.10']); - - $this->ensureKernelShutdown(); - - $barredClient = $this->createClient($options, ['REMOTE_ADDR' => '10.10.20.10']); - - $this->assertAllowed($allowedClient, '/secured-by-one-ip'); - $this->assertRestricted($barredClient, '/secured-by-one-ip'); - } - - /** - * @group legacy - * @dataProvider provideLegacyClientOptions - */ - public function testLegacySecurityConfigurationForMultipleIPAddresses(array $options) - { - $allowedClientA = $this->createClient($options, ['REMOTE_ADDR' => '1.1.1.1']); - - $this->ensureKernelShutdown(); - - $allowedClientB = $this->createClient($options, ['REMOTE_ADDR' => '2.2.2.2']); - - $this->ensureKernelShutdown(); - - $allowedClientC = $this->createClient($options, ['REMOTE_ADDR' => '203.0.113.0']); - - $this->ensureKernelShutdown(); - - $barredClient = $this->createClient($options, ['REMOTE_ADDR' => '192.168.1.1']); - - $this->assertAllowed($allowedClientA, '/secured-by-two-ips'); - $this->assertAllowed($allowedClientB, '/secured-by-two-ips'); - - $this->assertRestricted($allowedClientA, '/secured-by-one-real-ip'); - $this->assertRestricted($allowedClientA, '/secured-by-one-real-ipv6'); - $this->assertAllowed($allowedClientC, '/secured-by-one-real-ip-with-mask'); - - $this->assertRestricted($barredClient, '/secured-by-two-ips'); - } - - /** - * @group legacy - * @dataProvider provideLegacyConfigs - */ - public function testLegacySecurityConfigurationForExpression(array $options) - { - $allowedClient = $this->createClient($options, ['HTTP_USER_AGENT' => 'Firefox 1.0']); - $this->assertAllowed($allowedClient, '/protected-via-expression'); - $this->ensureKernelShutdown(); - - $barredClient = $this->createClient($options, []); - $this->assertRestricted($barredClient, '/protected-via-expression'); - $this->ensureKernelShutdown(); - - $allowedClient = $this->createClient($options, []); - - $allowedClient->request('GET', '/protected-via-expression'); - $form = $allowedClient->followRedirect()->selectButton('login')->form(); - $form['_username'] = 'johannes'; - $form['_password'] = 'test'; - $allowedClient->submit($form); - $this->assertRedirect($allowedClient->getResponse(), '/protected-via-expression'); - $this->assertAllowed($allowedClient, '/protected-via-expression'); - } - - /** - * @group legacy - */ - public function testLegacyInvalidIpsInAccessControl() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The given value "256.357.458.559" in the "security.access_control" config option is not a valid IP address.'); - - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'invalid_ip_access_control.yml', 'enable_authenticator_manager' => false]); - $client->request('GET', '/unprotected_resource'); - } - - /** - * @group legacy - */ - public function testLegacyPublicHomepage() - { - $client = $this->createClient(['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_config.yml']); - $client->request('GET', '/en/'); - - $this->assertEquals(200, $client->getResponse()->getStatusCode(), (string) $client->getResponse()); - $this->assertTrue($client->getResponse()->headers->getCacheControlDirective('public')); - $this->assertSame(0, self::getContainer()->get('request_tracker_subscriber')->getLastRequest()->getSession()->getUsageIndex()); - } - private function assertAllowed($client, $path) { $client->request('GET', $path); @@ -289,27 +151,9 @@ private function assertRestricted($client, $path) $this->assertEquals(302, $client->getResponse()->getStatusCode()); } - public function provideClientOptions() - { - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml', 'enable_authenticator_manager' => true]]; - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; - } - - public function provideLegacyClientOptions() - { - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml', 'enable_authenticator_manager' => true]]; - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml', 'enable_authenticator_manager' => true]]; - } - public function provideConfigs() { yield [['test_case' => 'StandardFormLogin', 'root_config' => 'base_config.yml']]; yield [['test_case' => 'StandardFormLogin', 'root_config' => 'routes_as_path.yml']]; } - - public function provideLegacyConfigs() - { - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_config.yml']]; - yield [['test_case' => 'StandardFormLogin', 'root_config' => 'legacy_routes_as_path.yml']]; - } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php index a5b2a3822d365..76c5e807232b7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityTest.php @@ -64,55 +64,6 @@ public function testUserWillBeMarkedAsChangedIfRolesHasChanged(UserInterface $us $this->assertEquals(302, $client->getResponse()->getStatusCode()); } - /** - * @dataProvider userWillBeMarkedAsChangedIfRolesHasChangedProvider - * @group legacy - */ - public function testLegacyUserWillBeMarkedAsChangedIfRolesHasChanged(UserInterface $userWithAdminRole, UserInterface $userWithoutAdminRole) - { - $client = $this->createClient(['test_case' => 'AbstractTokenCompareRoles', 'root_config' => 'legacy_config.yml']); - $client->disableReboot(); - - /** @var ArrayUserProvider $userProvider */ - $userProvider = static::$kernel->getContainer()->get('security.user.provider.array'); - $userProvider->addUser($userWithAdminRole); - - $client->request('POST', '/login', [ - '_username' => 'user1', - '_password' => 'test', - ]); - - // user1 has ROLE_ADMIN and can visit secure page - $client->request('GET', '/admin'); - $this->assertEquals(200, $client->getResponse()->getStatusCode()); - - // updating user provider with same user but revoked ROLE_ADMIN from user1 - $userProvider->setUser('user1', $userWithoutAdminRole); - - // user1 has lost ROLE_ADMIN and MUST be redirected away from secure page - $client->request('GET', '/admin'); - $this->assertEquals(302, $client->getResponse()->getStatusCode()); - } - - /** - * @group legacy - */ - public function testLegacyServiceIsFunctional() - { - $kernel = self::createKernel(['test_case' => 'SecurityHelper', 'root_config' => 'legacy_config.yml']); - $kernel->boot(); - $container = $kernel->getContainer(); - - // put a token into the storage so the final calls can function - $user = new InMemoryUser('foo', 'pass'); - $token = new UsernamePasswordToken($user, 'provider', ['ROLE_USER']); - $container->get('functional.test.security.token_storage')->setToken($token); - - $security = $container->get('functional_test.security.helper'); - $this->assertTrue($security->isGranted('ROLE_USER')); - $this->assertSame($token, $security->getToken()); - } - public function userWillBeMarkedAsChangedIfRolesHasChangedProvider() { return [ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/bundles.php deleted file mode 100644 index d1e9eb7e0d36a..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/bundles.php +++ /dev/null @@ -1,15 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -return [ - new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), - new Symfony\Bundle\SecurityBundle\SecurityBundle(), -]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml deleted file mode 100644 index 9d804818d8885..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/config.yml +++ /dev/null @@ -1,24 +0,0 @@ -framework: - secret: test - router: { resource: "%kernel.project_dir%/%kernel.test_case%/routing.yml", utf8: true } - validation: { enabled: true, enable_annotations: true } - csrf_protection: true - form: true - test: ~ - default_locale: en - session: - storage_factory_id: session.storage.factory.mock_file - profiler: { only_exceptions: false } - -services: - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AnonymousBundle\AppCustomAuthenticator: ~ - -security: - firewalls: - secure: - pattern: ^/ - anonymous: false - stateless: true - guard: - authenticators: - - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AnonymousBundle\AppCustomAuthenticator diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/routing.yml deleted file mode 100644 index 4d11154375219..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Anonymous/routing.yml +++ /dev/null @@ -1,5 +0,0 @@ -main: - path: / - defaults: - _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction - path: /app diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php index 96670d1322b2d..2839d5dfaff60 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AppKernel.php @@ -25,9 +25,8 @@ class AppKernel extends Kernel private $varDir; private $testCase; private $rootConfig; - private $authenticatorManagerEnabled; - public function __construct($varDir, $testCase, $rootConfig, $environment, $debug, $authenticatorManagerEnabled = false) + public function __construct($varDir, $testCase, $rootConfig, $environment, $debug) { if (!is_dir(__DIR__.'/'.$testCase)) { throw new \InvalidArgumentException(sprintf('The test case "%s" does not exist.', $testCase)); @@ -43,7 +42,6 @@ public function __construct($varDir, $testCase, $rootConfig, $environment, $debu $this->rootConfig[] = $config; } - $this->authenticatorManagerEnabled = $authenticatorManagerEnabled; parent::__construct($environment, $debug); } @@ -53,7 +51,7 @@ public function __construct($varDir, $testCase, $rootConfig, $environment, $debu */ public function getContainerClass(): string { - return parent::getContainerClass().substr(md5(implode('', $this->rootConfig).$this->authenticatorManagerEnabled), -16); + return parent::getContainerClass().substr(md5(implode('', $this->rootConfig)), -16); } public function registerBundles(): iterable @@ -85,14 +83,6 @@ public function registerContainerConfiguration(LoaderInterface $loader) foreach ($this->rootConfig as $config) { $loader->load($config); } - - if ($this->authenticatorManagerEnabled) { - $loader->load(function ($container) { - $container->loadFromExtension('security', [ - 'enable_authenticator_manager' => true, - ]); - }); - } } public function serialize() diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_base_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_base_config.yml deleted file mode 100644 index 069fece61756f..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_base_config.yml +++ /dev/null @@ -1,49 +0,0 @@ -imports: - - { resource: ./../config/default.yml } - -services: - csrf_form_login.form.type: - class: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Form\UserLoginType - arguments: - - '@request_stack' - tags: - - { name: form.type } - - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\Controller\LoginController: - public: true - tags: - - { name: container.service_subscriber } - -security: - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext - - providers: - in_memory: - memory: - users: - johannes: { password: test, roles: [ROLE_USER] } - - firewalls: - # This firewall doesn't make sense in combination with the rest of the - # configuration file, but it's here for testing purposes (do not use - # this file in a real world scenario though) - login_form: - pattern: ^/login$ - security: false - - default: - form_login: - check_path: /login_check - default_target_path: /profile - target_path_parameter: "user_login[_target_path]" - failure_path_parameter: "user_login[_failure_path]" - username_parameter: "user_login[username]" - password_parameter: "user_login[password]" - logout: - path: /logout_path - target: / - csrf_token_generator: security.csrf.token_manager - - access_control: - - { path: .*, roles: IS_AUTHENTICATED_FULLY } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_config.yml deleted file mode 100644 index b5764bd00e732..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_config.yml +++ /dev/null @@ -1,10 +0,0 @@ -imports: - - { resource: ./legacy_base_config.yml } - -security: - firewalls: - default: - form_login: - csrf_token_generator: security.csrf.token_manager - csrf_parameter: "user_login[_token]" - anonymous: ~ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_routes_as_path.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_routes_as_path.yml deleted file mode 100644 index 14ea6c0e5f1e8..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/legacy_routes_as_path.yml +++ /dev/null @@ -1,13 +0,0 @@ -imports: - - { resource: ./legacy_config.yml } - -security: - firewalls: - default: - form_login: - login_path: form_login - check_path: form_login_check - default_target_path: form_login_default_target_path - logout: - path: form_logout - target: form_login_homepage diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config_form_login.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config_form_login.yml index 28bcb1942180b..8763b08110b4e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config_form_login.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config_form_login.yml @@ -2,7 +2,6 @@ imports: - { resource: ./config.yml } security: - enable_authenticator_manager: true firewalls: secure: pattern: ^/ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config.yml deleted file mode 100644 index 7fb035db6b2ad..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config.yml +++ /dev/null @@ -1,32 +0,0 @@ -framework: - secret: test - router: { resource: "%kernel.project_dir%/%kernel.test_case%/routing.yml", utf8: true } - validation: { enabled: true, enable_annotations: true } - csrf_protection: true - form: - enabled: true - legacy_error_messages: false - test: ~ - default_locale: en - session: - storage_factory_id: session.storage.factory.mock_file - profiler: { only_exceptions: false } - -services: - logger: { class: Psr\Log\NullLogger } - -security: - firewalls: - secure: - pattern: ^/secure/ - http_basic: { realm: "Secure Gateway API" } - entry_point: firewall_entry_point.entry_point.stub - access_control: - - { path: ^/secure/, roles: ROLE_SECURE } - providers: - in_memory: - memory: - users: - john: { password: doe, roles: [ROLE_SECURE] } - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config_form_login.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config_form_login.yml deleted file mode 100644 index efd4d78ed7a24..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/legacy_config_form_login.yml +++ /dev/null @@ -1,9 +0,0 @@ -imports: - - { resource: ./legacy_config.yml } - -security: - firewalls: - secure: - pattern: ^/ - form_login: - check_path: /login_check diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/bundles.php deleted file mode 100644 index d1e9eb7e0d36a..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/bundles.php +++ /dev/null @@ -1,15 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -return [ - new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), - new Symfony\Bundle\SecurityBundle\SecurityBundle(), -]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml deleted file mode 100644 index 3b815702a907a..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/config.yml +++ /dev/null @@ -1,34 +0,0 @@ -framework: - secret: test - router: { resource: "%kernel.project_dir%/%kernel.test_case%/routing.yml", utf8: true } - test: ~ - default_locale: en - profiler: false - session: - storage_factory_id: session.storage.factory.mock_file - -services: - logger: { class: Psr\Log\NullLogger } - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AppCustomAuthenticator: ~ - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController: - tags: [controller.service_arguments] - -security: - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext - - providers: - in_memory: - memory: - users: - Jane: { password: test, roles: [ROLE_USER] } - - firewalls: - secure: - pattern: ^/ - anonymous: ~ - lazy: true - stateless: false - guard: - authenticators: - - Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AppCustomAuthenticator diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml deleted file mode 100644 index 146aa811a143d..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Guarded/routing.yml +++ /dev/null @@ -1,14 +0,0 @@ -main: - path: / - defaults: - _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction - path: /app -profile: - path: /profile - defaults: - _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController::profileAction - -manual_login: - path: /manual_login - defaults: - _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\GuardedBundle\AuthenticationController::manualLoginAction diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_access.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_access.yml index 31ecfb6897c42..fbcb7e6defc79 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_access.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Logout/config_access.yml @@ -2,6 +2,8 @@ imports: - { resource: ./../config/framework.yml } security: + enable_authenticator_manager: true + password_hashers: Symfony\Component\Security\Core\User\InMemoryUser: plaintext diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml index f28924e4518d9..1dd8b8e507d36 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/config.yml @@ -2,6 +2,8 @@ imports: - { resource: ./../config/framework.yml } security: + enable_authenticator_manager: true + password_hashers: Symfony\Component\Security\Core\User\InMemoryUser: plaintext diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml index 501a673b4fdea..ec3839a76adcb 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/config.yml @@ -2,6 +2,7 @@ imports: - { resource: ./../config/framework.yml } security: + enable_authenticator_manager: true firewalls: default: http_basic: ~ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_base_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_base_config.yml deleted file mode 100644 index 66178b50f3ffc..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_base_config.yml +++ /dev/null @@ -1,56 +0,0 @@ -imports: - - { resource: ./../config/default.yml } - -parameters: - env(APP_IP): '127.0.0.1' - env(APP_IPS): '127.0.0.1, ::1' - -security: - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext - - providers: - in_memory: - memory: - users: - johannes: { password: test, roles: [ROLE_USER] } - - firewalls: - # This firewall doesn't make sense in combination with the rest of the - # configuration file, but it's here for testing purposes (do not use - # this file in a real world scenario though) - login_form: - pattern: ^/login$ - security: false - - default: - form_login: - check_path: /login_check - default_target_path: /profile - logout: ~ - lazy: true - - # This firewall is here just to check its the logout functionality - second_area: - http_basic: ~ - logout: - target: /second/target - path: /second/logout - - access_control: - - { path: ^/en/$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/unprotected_resource$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secure-but-not-covered-by-access-control$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-ip$, ip: 10.10.10.10, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-two-ips$, ips: [1.1.1.1, 2.2.2.2], roles: IS_AUTHENTICATED_ANONYMOUSLY } - # these real IP addresses are reserved for docs/examples (https://tools.ietf.org/search/rfc5737) - - { path: ^/secured-by-one-real-ip$, ips: 198.51.100.0, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-real-ip-with-mask$, ips: '203.0.113.0/24', roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-real-ipv6$, ips: 0:0:0:0:0:ffff:c633:6400, roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-env-placeholder$, ips: '%env(APP_IP)%', roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-env-placeholder-multiple-ips$, ips: '%env(APP_IPS)%', roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-env-placeholder-and-one-real-ip$, ips: ['%env(APP_IP)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/secured-by-one-env-placeholder-multiple-ips-and-one-real-ip$, ips: ['%env(APP_IPS)%', 198.51.100.0], roles: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: ^/highly_protected_resource$, roles: IS_ADMIN } - - { path: ^/protected-via-expression$, allow_if: "(is_anonymous() and request.headers.get('user-agent') matches '/Firefox/i') or is_granted('ROLE_USER')" } - - { path: .*, roles: IS_AUTHENTICATED_FULLY } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_config.yml deleted file mode 100644 index e393772ae4b21..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_config.yml +++ /dev/null @@ -1,9 +0,0 @@ -imports: - - { resource: ./legacy_base_config.yml } - -security: - firewalls: - default: - anonymous: ~ - second_area: - anonymous: ~ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_form_failure_handler.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_form_failure_handler.yml deleted file mode 100644 index 51ae007f38d57..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_form_failure_handler.yml +++ /dev/null @@ -1,20 +0,0 @@ -imports: - - { resource: ./../config/default.yml } - -security: - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext - - providers: - in_memory: - memory: - users: - johannes: { password: test, roles: [ROLE_USER] } - - firewalls: - default: - form_login: - login_path: localized_login_path - check_path: localized_check_path - failure_handler: localized_form_failure_handler - anonymous: ~ diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes.yml deleted file mode 100644 index 2c552175e6d20..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes.yml +++ /dev/null @@ -1,26 +0,0 @@ -imports: - - { resource: ./../config/default.yml } - -security: - password_hashers: - Symfony\Component\Security\Core\User\InMemoryUser: plaintext - - providers: - in_memory: - memory: - users: - johannes: { password: test, roles: [ROLE_USER] } - - firewalls: - default: - form_login: - login_path: localized_login_path - check_path: localized_check_path - default_target_path: localized_default_target_path - logout: - path: localized_logout_path - target: localized_logout_target_path - anonymous: ~ - - access_control: - - { path: '^/(?:[a-z]{2})/secure/.*', roles: ROLE_USER } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes_with_forward.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes_with_forward.yml deleted file mode 100644 index c8875e0d0794c..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_localized_routes_with_forward.yml +++ /dev/null @@ -1,9 +0,0 @@ -imports: - - { resource: ./legacy_localized_routes.yml } - -security: - firewalls: - default: - form_login: - use_forward: true - failure_forward: true diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_login_throttling.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_login_throttling.yml deleted file mode 100644 index 90648d0730f9b..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_login_throttling.yml +++ /dev/null @@ -1,13 +0,0 @@ -imports: - - { resource: ./legacy_base_config.yml } - -framework: - lock: ~ - rate_limiter: ~ - -security: - firewalls: - default: - login_throttling: - max_attempts: 1 - interval: '8 minutes' diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_routes_as_path.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_routes_as_path.yml deleted file mode 100644 index 14ea6c0e5f1e8..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_routes_as_path.yml +++ /dev/null @@ -1,13 +0,0 @@ -imports: - - { resource: ./legacy_config.yml } - -security: - firewalls: - default: - form_login: - login_path: form_login - check_path: form_login_check - default_target_path: form_login_default_target_path - logout: - path: form_logout - target: form_login_homepage diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_switchuser.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_switchuser.yml deleted file mode 100644 index bd6f56d2c74da..0000000000000 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/legacy_switchuser.yml +++ /dev/null @@ -1,14 +0,0 @@ -imports: - - { resource: ./base_config.yml } - -security: - providers: - in_memory: - memory: - users: - user_can_switch: { password: test, roles: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH] } - user_cannot_switch_1: { password: test, roles: [ROLE_USER] } - user_cannot_switch_2: { password: test, roles: [ROLE_USER] } - firewalls: - default: - switch_user: true diff --git a/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php b/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php index 649e4a20a197d..99b965c4d05c0 100644 --- a/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php +++ b/src/Symfony/Component/Ldap/Security/CheckLdapCredentialsListener.php @@ -18,7 +18,6 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\LogicException; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\CheckPassportEvent; /** @@ -49,8 +48,8 @@ public function onCheckPassport(CheckPassportEvent $event) return; } - if (!$passport instanceof UserPassportInterface || !$passport->hasBadge(PasswordCredentials::class)) { - throw new \LogicException(sprintf('LDAP authentication requires a passport containing a user and password credentials, authenticator "%s" does not fulfill these requirements.', \get_class($event->getAuthenticator()))); + if (!$passport->hasBadge(PasswordCredentials::class)) { + throw new \LogicException(sprintf('LDAP authentication requires a passport containing password credentials, authenticator "%s" does not fulfill these requirements.', \get_class($event->getAuthenticator()))); } /** @var PasswordCredentials $passwordCredentials */ diff --git a/src/Symfony/Component/Ldap/Security/LdapAuthenticator.php b/src/Symfony/Component/Ldap/Security/LdapAuthenticator.php index 319df248b5d00..4211d792b2574 100644 --- a/src/Symfony/Component/Ldap/Security/LdapAuthenticator.php +++ b/src/Symfony/Component/Ldap/Security/LdapAuthenticator.php @@ -62,23 +62,9 @@ public function authenticate(Request $request): Passport return $passport; } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/ldap', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { - // @deprecated since Symfony 5.4, in 6.0 change to: - // return $this->authenticator->createToken($passport, $firewallName); - return method_exists($this->authenticator, 'createToken') - ? $this->authenticator->createToken($passport, $firewallName) - : $this->authenticator->createAuthenticatedToken($passport, $firewallName); + return $this->authenticator->createToken($passport, $firewallName); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response diff --git a/src/Symfony/Component/Ldap/Security/LdapUser.php b/src/Symfony/Component/Ldap/Security/LdapUser.php index 5188cbad4c0ca..b29429bb023ba 100644 --- a/src/Symfony/Component/Ldap/Security/LdapUser.php +++ b/src/Symfony/Component/Ldap/Security/LdapUser.php @@ -72,13 +72,11 @@ public function getSalt(): ?string } /** - * {@inheritdoc} + * @internal for compatibility with Symfony 5.4 */ public function getUsername(): string { - trigger_deprecation('symfony/ldap', '5.3', 'Method "%s()" is deprecated and will be removed in 6.0, use getUserIdentifier() instead.', __METHOD__); - - return $this->username; + return $this->getUserIdentifier(); } public function getUserIdentifier(): string diff --git a/src/Symfony/Component/Ldap/Security/LdapUserProvider.php b/src/Symfony/Component/Ldap/Security/LdapUserProvider.php index 2d0055cc9d6bf..cb6a177ce8a44 100644 --- a/src/Symfony/Component/Ldap/Security/LdapUserProvider.php +++ b/src/Symfony/Component/Ldap/Security/LdapUserProvider.php @@ -64,12 +64,10 @@ public function __construct(LdapInterface $ldap, string $baseDn, string $searchD } /** - * {@inheritdoc} + * @internal for compatibility with Symfony 5.4 */ public function loadUserByUsername(string $username): UserInterface { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__); - return $this->loadUserByIdentifier($username); } diff --git a/src/Symfony/Component/Ldap/Tests/Security/CheckLdapCredentialsListenerTest.php b/src/Symfony/Component/Ldap/Tests/Security/CheckLdapCredentialsListenerTest.php index f93178d279c30..6c54071bd0c09 100644 --- a/src/Symfony/Component/Ldap/Tests/Security/CheckLdapCredentialsListenerTest.php +++ b/src/Symfony/Component/Ldap/Tests/Security/CheckLdapCredentialsListenerTest.php @@ -30,7 +30,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\Event\CheckPassportEvent; use Symfony\Contracts\Service\ServiceLocatorTrait; @@ -102,7 +101,7 @@ public function testInvalidLdapServiceId() public function testWrongPassport($passport) { $this->expectException(\LogicException::class); - $this->expectExceptionMessage('LDAP authentication requires a passport containing a user and password credentials, authenticator "'.TestAuthenticator::class.'" does not fulfill these requirements.'); + $this->expectExceptionMessage('LDAP authentication requires a passport containing password credentials, authenticator "'.TestAuthenticator::class.'" does not fulfill these requirements.'); $listener = $this->createListener(); $listener->onCheckPassport(new CheckPassportEvent(new TestAuthenticator(), $passport)); @@ -118,23 +117,6 @@ public function provideWrongPassportData() yield [new SelfValidatingPassport(new UserBadge('test'), [new LdapBadge('app.ldap')])]; } - /** - * @group legacy - */ - public function testLegacyWrongPassport() - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('LDAP authentication requires a passport containing a user and password credentials, authenticator "'.TestAuthenticator::class.'" does not fulfill these requirements.'); - - // no user passport - $passport = $this->createMock(PassportInterface::class); - $passport->expects($this->any())->method('hasBadge')->with(LdapBadge::class)->willReturn(true); - $passport->expects($this->any())->method('getBadge')->with(LdapBadge::class)->willReturn(new LdapBadge('app.ldap')); - - $listener = $this->createListener(); - $listener->onCheckPassport(new CheckPassportEvent(new TestAuthenticator(), $passport)); - } - public function testEmptyPasswordShouldThrowAnException() { $this->expectException(BadCredentialsException::class); @@ -229,11 +211,11 @@ public function supports(Request $request): ?bool { } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { } - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface + public function createAuthenticatedToken(Passport $passport, string $firewallName): TokenInterface { } diff --git a/src/Symfony/Component/PasswordHasher/Tests/Hasher/UserPasswordHasherTest.php b/src/Symfony/Component/PasswordHasher/Tests/Hasher/UserPasswordHasherTest.php index 274272583c321..ad858f8f9376e 100644 --- a/src/Symfony/Component/PasswordHasher/Tests/Hasher/UserPasswordHasherTest.php +++ b/src/Symfony/Component/PasswordHasher/Tests/Hasher/UserPasswordHasherTest.php @@ -18,8 +18,8 @@ use Symfony\Component\PasswordHasher\PasswordHasherInterface; use Symfony\Component\PasswordHasher\Tests\Fixtures\TestLegacyPasswordAuthenticatedUser; use Symfony\Component\PasswordHasher\Tests\Fixtures\TestPasswordAuthenticatedUser; -use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Core\User\User; +use Symfony\Component\Security\Core\User\InMemoryUser; class UserPasswordHasherTest extends TestCase { diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationManagerInterface.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationManagerInterface.php deleted file mode 100644 index bb908fd3340d2..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationManagerInterface.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication; - -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; - -/** - * AuthenticationManagerInterface is the interface for authentication managers, - * which process Token authentication. - * - * @author Fabien Potencier - * - * @internal - */ -interface AuthenticationManagerInterface -{ - /** - * Attempts to authenticate a TokenInterface object. - * - * @return TokenInterface - * - * @throws AuthenticationException if the authentication fails - */ - public function authenticate(TokenInterface $token); -} diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php deleted file mode 100644 index 76be0f4da328b..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.php +++ /dev/null @@ -1,133 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication; - -use Symfony\Component\PasswordHasher\Exception\InvalidPasswordException; -use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\AuthenticationEvents; -use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; -use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent; -use Symfony\Component\Security\Core\Exception\AccountStatusException; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AuthenticationProviderManager::class); - -// Help opcache.preload discover always-needed symbols -class_exists(AuthenticationEvents::class); -class_exists(AuthenticationFailureEvent::class); -class_exists(AuthenticationSuccessEvent::class); - -/** - * AuthenticationProviderManager uses a list of AuthenticationProviderInterface - * instances to authenticate a Token. - * - * @author Fabien Potencier - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class AuthenticationProviderManager implements AuthenticationManagerInterface -{ - private $providers; - private $eraseCredentials; - private $eventDispatcher; - - /** - * @param iterable|AuthenticationProviderInterface[] $providers An iterable with AuthenticationProviderInterface instances as values - * @param bool $eraseCredentials Whether to erase credentials after authentication or not - * - * @throws \InvalidArgumentException - */ - public function __construct(iterable $providers, bool $eraseCredentials = true) - { - if (!$providers) { - throw new \InvalidArgumentException('You must at least add one authentication provider.'); - } - - $this->providers = $providers; - $this->eraseCredentials = $eraseCredentials; - } - - public function setEventDispatcher(EventDispatcherInterface $dispatcher) - { - $this->eventDispatcher = $dispatcher; - } - - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - $lastException = null; - $result = null; - - foreach ($this->providers as $provider) { - if (!$provider instanceof AuthenticationProviderInterface) { - throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_debug_type($provider))); - } - - if (!$provider->supports($token)) { - continue; - } - - try { - $result = $provider->authenticate($token); - - if (null !== $result) { - break; - } - } catch (AccountStatusException $e) { - $lastException = $e; - - break; - } catch (AuthenticationException $e) { - $lastException = $e; - } catch (InvalidPasswordException $e) { - $lastException = new BadCredentialsException('Bad credentials.', 0, $e); - } - } - - if (null !== $result) { - if (true === $this->eraseCredentials) { - $result->eraseCredentials(); - } - - if (null !== $this->eventDispatcher) { - $this->eventDispatcher->dispatch(new AuthenticationSuccessEvent($result), AuthenticationEvents::AUTHENTICATION_SUCCESS); - } - - // @deprecated since Symfony 5.3 - if ($user = $result->getUser() instanceof UserInterface && !method_exists($result->getUser(), 'getUserIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($result->getUser())); - } - - return $result; - } - - if (null === $lastException) { - $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', \get_class($token))); - } - - if (null !== $this->eventDispatcher) { - $this->eventDispatcher->dispatch(new AuthenticationFailureEvent($token, $lastException), AuthenticationEvents::AUTHENTICATION_FAILURE); - } - - $lastException->setToken($token); - - throw $lastException; - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php index c8fa3f54b9b2e..0336688603efa 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolver.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Security\Core\Authentication; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\NullToken; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -25,25 +24,7 @@ class AuthenticationTrustResolver implements AuthenticationTrustResolverInterfac { public function isAuthenticated(TokenInterface $token = null): bool { - return null !== $token && !$token instanceof NullToken - // @deprecated since Symfony 5.4, TokenInterface::isAuthenticated() and AnonymousToken no longer exists in 6.0 - && !$token instanceof AnonymousToken && $token->isAuthenticated(false); - } - - /** - * {@inheritdoc} - */ - public function isAnonymous(TokenInterface $token = null/*, $deprecation = true*/) - { - if (1 === \func_num_args() || false !== func_get_arg(1)) { - trigger_deprecation('symfony/security-core', '5.4', 'The "%s()" method is deprecated, use "isAuthenticated()" or "isFullFledged()" if you want to check if the request is (fully) authenticated.', __METHOD__); - } - - if (null === $token) { - return false; - } - - return $token instanceof AnonymousToken || $token instanceof NullToken; + return null !== $token && !$token instanceof NullToken; } /** @@ -63,10 +44,10 @@ public function isRememberMe(TokenInterface $token = null) */ public function isFullFledged(TokenInterface $token = null) { - if (null === $token) { + if (null === $token || $token instanceof NullToken) { return false; } - return !$this->isAnonymous($token, false) && !$this->isRememberMe($token); + return !$this->isRememberMe($token); } } diff --git a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php index 1122ffef629af..16723d8883b5d 100644 --- a/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/AuthenticationTrustResolverInterface.php @@ -22,18 +22,6 @@ */ interface AuthenticationTrustResolverInterface { - /** - * Resolves whether the passed token implementation is authenticated - * anonymously. - * - * If null is passed, the method must return false. - * - * @return bool - * - * @deprecated since Symfony 5.4, use !isAuthenticated() instead - */ - public function isAnonymous(TokenInterface $token = null); - /** * Resolves whether the passed token implementation is authenticated * using remember-me capabilities. diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/AnonymousAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/AnonymousAuthenticationProvider.php deleted file mode 100644 index 53f8cf18bff2a..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/AnonymousAuthenticationProvider.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AnonymousAuthenticationProvider::class); - -/** - * AnonymousAuthenticationProvider validates AnonymousToken instances. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class AnonymousAuthenticationProvider implements AuthenticationProviderInterface -{ - /** - * Used to determine if the token is created by the application - * instead of a malicious client. - * - * @var string - */ - private $secret; - - /** - * @param string $secret The secret shared with the AnonymousToken - */ - public function __construct(string $secret) - { - $this->secret = $secret; - } - - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - if (!$this->supports($token)) { - throw new AuthenticationException('The token is not supported by this authentication provider.'); - } - - if ($this->secret !== $token->getSecret()) { - throw new BadCredentialsException('The Token does not contain the expected key.'); - } - - return $token; - } - - /** - * {@inheritdoc} - */ - public function supports(TokenInterface $token) - { - return $token instanceof AnonymousToken; - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php b/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php deleted file mode 100644 index fb57ed8096fab..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/AuthenticationProviderInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" interface is deprecated, use the new authenticator system instead.', AuthenticationProviderInterface::class); - -/** - * AuthenticationProviderInterface is the interface for all authentication - * providers. - * - * Concrete implementations processes specific Token instances. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -interface AuthenticationProviderInterface extends AuthenticationManagerInterface -{ - /** - * Use this constant for not provided username. - * - * @var string - */ - public const USERNAME_NONE_PROVIDED = 'NONE_PROVIDED'; - - /** - * Checks whether this provider supports the given token. - * - * @return bool - */ - public function supports(TokenInterface $token); -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php deleted file mode 100644 index c9286b3fe787e..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php +++ /dev/null @@ -1,121 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\InvalidArgumentException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\LegacyPasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', DaoAuthenticationProvider::class); - -/** - * DaoAuthenticationProvider uses a UserProviderInterface to retrieve the user - * for a UsernamePasswordToken. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class DaoAuthenticationProvider extends UserAuthenticationProvider -{ - private $hasherFactory; - private $userProvider; - - public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, PasswordHasherFactoryInterface $hasherFactory, bool $hideUserNotFoundExceptions = true) - { - parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions); - - $this->hasherFactory = $hasherFactory; - $this->userProvider = $userProvider; - } - - /** - * {@inheritdoc} - */ - protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token) - { - if (!$user instanceof PasswordAuthenticatedUserInterface) { - throw new InvalidArgumentException(sprintf('Class "%s" must implement "%s" for using password-based authentication.', get_debug_type($user), PasswordAuthenticatedUserInterface::class)); - } - - $currentUser = $token->getUser(); - - if ($currentUser instanceof PasswordAuthenticatedUserInterface) { - if ($currentUser->getPassword() !== $user->getPassword()) { - throw new BadCredentialsException('The credentials were changed from another session.'); - } - } else { - if ('' === ($presentedPassword = $token->getCredentials())) { - throw new BadCredentialsException('The presented password cannot be empty.'); - } - - if (null === $user->getPassword()) { - throw new BadCredentialsException('The presented password is invalid.'); - } - - $salt = $user instanceof LegacyPasswordAuthenticatedUserInterface ? $user->getSalt() : null; - $hasher = $this->hasherFactory->getPasswordHasher($user); - - if (!$hasher->verify($user->getPassword(), $presentedPassword, $salt)) { - throw new BadCredentialsException('The presented password is invalid.'); - } - - if ($this->userProvider instanceof PasswordUpgraderInterface && $hasher->needsRehash($user->getPassword())) { - $this->userProvider->upgradePassword($user, $hasher->hash($presentedPassword, $salt)); - } - } - } - - /** - * {@inheritdoc} - */ - protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token) - { - $user = $token->getUser(); - if ($user instanceof UserInterface) { - return $user; - } - - try { - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($this->userProvider, 'loadUserByIdentifier')) { - $user = $this->userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $user = $this->userProvider->loadUserByUsername($userIdentifier); - } - - if (!$user instanceof UserInterface) { - throw new AuthenticationServiceException('The user provider must return a UserInterface object.'); - } - - return $user; - } catch (UserNotFoundException $e) { - $e->setUserIdentifier($userIdentifier); - throw $e; - } catch (\Exception $e) { - $e = new AuthenticationServiceException($e->getMessage(), 0, $e); - $e->setToken($token); - throw $e; - } - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php deleted file mode 100644 index 7de715d70a122..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/LdapBindAuthenticationProvider.php +++ /dev/null @@ -1,121 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Ldap\Exception\ConnectionException; -use Symfony\Component\Ldap\LdapInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\LogicException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', LdapBindAuthenticationProvider::class); - -/** - * LdapBindAuthenticationProvider authenticates a user against an LDAP server. - * - * The only way to check user credentials is to try to connect the user with its - * credentials to the ldap. - * - * @author Charles Sarrazin - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class LdapBindAuthenticationProvider extends UserAuthenticationProvider -{ - private $userProvider; - private $ldap; - private $dnString; - private $queryString; - private $searchDn; - private $searchPassword; - - public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey, LdapInterface $ldap, string $dnString = '{user_identifier}', bool $hideUserNotFoundExceptions = true, string $searchDn = '', string $searchPassword = '') - { - parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions); - - $this->userProvider = $userProvider; - $this->ldap = $ldap; - $this->dnString = $dnString; - $this->searchDn = $searchDn; - $this->searchPassword = $searchPassword; - } - - /** - * Set a query string to use in order to find a DN for the user identifier. - */ - public function setQueryString(string $queryString) - { - $this->queryString = $queryString; - } - - /** - * {@inheritdoc} - */ - protected function retrieveUser(string $userIdentifier, UsernamePasswordToken $token) - { - if (AuthenticationProviderInterface::USERNAME_NONE_PROVIDED === $userIdentifier) { - throw new UserNotFoundException('User identifier can not be null.'); - } - - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($this->userProvider, 'loadUserByIdentifier')) { - return $this->userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - return $this->userProvider->loadUserByUsername($userIdentifier); - } - } - - /** - * {@inheritdoc} - */ - protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token) - { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); - $password = $token->getCredentials(); - - if ('' === (string) $password) { - throw new BadCredentialsException('The presented password must not be empty.'); - } - - try { - if ($this->queryString) { - if ('' !== $this->searchDn && '' !== $this->searchPassword) { - $this->ldap->bind($this->searchDn, $this->searchPassword); - } else { - throw new LogicException('Using the "query_string" config without using a "search_dn" and a "search_password" is not supported.'); - } - $userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_FILTER); - $query = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->queryString); - $result = $this->ldap->query($this->dnString, $query)->execute(); - if (1 !== $result->count()) { - throw new BadCredentialsException('The presented username is invalid.'); - } - - $dn = $result[0]->getDn(); - } else { - $userIdentifier = $this->ldap->escape($userIdentifier, '', LdapInterface::ESCAPE_DN); - $dn = str_replace(['{username}', '{user_identifier}'], $userIdentifier, $this->dnString); - } - - $this->ldap->bind($dn, $password); - } catch (ConnectionException $e) { - throw new BadCredentialsException('The presented password is invalid.'); - } - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php deleted file mode 100644 index d81e31bb07b75..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/PreAuthenticatedAuthenticationProvider.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', PreAuthenticatedAuthenticationProvider::class); - -/** - * Processes a pre-authenticated authentication request. - * - * This authentication provider will not perform any checks on authentication - * requests, as they should already be pre-authenticated. However, the - * UserProviderInterface implementation may still throw a - * UserNotFoundException, for example. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class PreAuthenticatedAuthenticationProvider implements AuthenticationProviderInterface -{ - private $userProvider; - private $userChecker; - private $providerKey; - - public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, string $providerKey) - { - $this->userProvider = $userProvider; - $this->userChecker = $userChecker; - $this->providerKey = $providerKey; - } - - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - if (!$this->supports($token)) { - throw new AuthenticationException('The token is not supported by this authentication provider.'); - } - - if (!$user = $token->getUser()) { - throw new BadCredentialsException('No pre-authenticated principal found in request.'); - } - - $userIdentifier = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($this->userProvider, 'loadUserByIdentifier')) { - $user = $this->userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $user = $this->userProvider->loadUserByUsername($userIdentifier); - } - - $this->userChecker->checkPostAuth($user); - - $authenticatedToken = new PreAuthenticatedToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); - $authenticatedToken->setAttributes($token->getAttributes()); - - return $authenticatedToken; - } - - /** - * {@inheritdoc} - */ - public function supports(TokenInterface $token) - { - return $token instanceof PreAuthenticatedToken && $this->providerKey === $token->getFirewallName(); - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/RememberMeAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/RememberMeAuthenticationProvider.php deleted file mode 100644 index 2fd52f2ddd75a..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/RememberMeAuthenticationProvider.php +++ /dev/null @@ -1,79 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\LogicException; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', RememberMeAuthenticationProvider::class); - -/** - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class RememberMeAuthenticationProvider implements AuthenticationProviderInterface -{ - private $userChecker; - private $secret; - private $providerKey; - - /** - * @param string $secret A secret - * @param string $providerKey A provider secret - */ - public function __construct(UserCheckerInterface $userChecker, string $secret, string $providerKey) - { - $this->userChecker = $userChecker; - $this->secret = $secret; - $this->providerKey = $providerKey; - } - - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - if (!$this->supports($token)) { - throw new AuthenticationException('The token is not supported by this authentication provider.'); - } - - if ($this->secret !== $token->getSecret()) { - throw new BadCredentialsException('The presented secret does not match.'); - } - - $user = $token->getUser(); - - if (!$user instanceof UserInterface) { - throw new LogicException(sprintf('Method "%s::getUser()" must return a "%s" instance, "%s" returned.', get_debug_type($token), UserInterface::class, get_debug_type($user))); - } - - $this->userChecker->checkPreAuth($user); - $this->userChecker->checkPostAuth($user); - - $authenticatedToken = new RememberMeToken($user, $this->providerKey, $this->secret); - $authenticatedToken->setAttributes($token->getAttributes()); - - return $authenticatedToken; - } - - /** - * {@inheritdoc} - */ - public function supports(TokenInterface $token) - { - return $token instanceof RememberMeToken && $token->getFirewallName() === $this->providerKey; - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php deleted file mode 100644 index aa123ac9aa942..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php +++ /dev/null @@ -1,131 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Provider; - -use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AccountStatusException; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', UserAuthenticationProvider::class); - -/** - * UserProviderInterface retrieves users for UsernamePasswordToken tokens. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -abstract class UserAuthenticationProvider implements AuthenticationProviderInterface -{ - private $hideUserNotFoundExceptions; - private $userChecker; - private $providerKey; - - /** - * @throws \InvalidArgumentException - */ - public function __construct(UserCheckerInterface $userChecker, string $providerKey, bool $hideUserNotFoundExceptions = true) - { - if (empty($providerKey)) { - throw new \InvalidArgumentException('$providerKey must not be empty.'); - } - - $this->userChecker = $userChecker; - $this->providerKey = $providerKey; - $this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions; - } - - /** - * {@inheritdoc} - */ - public function authenticate(TokenInterface $token) - { - if (!$this->supports($token)) { - throw new AuthenticationException('The token is not supported by this authentication provider.'); - } - - $username = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); - if ('' === $username || null === $username) { - $username = AuthenticationProviderInterface::USERNAME_NONE_PROVIDED; - } - - try { - $user = $this->retrieveUser($username, $token); - } catch (UserNotFoundException $e) { - if ($this->hideUserNotFoundExceptions) { - throw new BadCredentialsException('Bad credentials.', 0, $e); - } - $e->setUserIdentifier($username); - - throw $e; - } - - if (!$user instanceof UserInterface) { - throw new AuthenticationServiceException('retrieveUser() must return a UserInterface.'); - } - - try { - $this->userChecker->checkPreAuth($user); - $this->checkAuthentication($user, $token); - $this->userChecker->checkPostAuth($user); - } catch (AccountStatusException | BadCredentialsException $e) { - if ($this->hideUserNotFoundExceptions && !$e instanceof CustomUserMessageAccountStatusException) { - throw new BadCredentialsException('Bad credentials.', 0, $e); - } - - throw $e; - } - - if ($token instanceof SwitchUserToken) { - $authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles(), $token->getOriginalToken()); - } else { - $authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles()); - } - - $authenticatedToken->setAttributes($token->getAttributes()); - - return $authenticatedToken; - } - - /** - * {@inheritdoc} - */ - public function supports(TokenInterface $token) - { - return $token instanceof UsernamePasswordToken && $this->providerKey === $token->getFirewallName(); - } - - /** - * Retrieves the user from an implementation-specific location. - * - * @return UserInterface - * - * @throws AuthenticationException if the credentials could not be validated - */ - abstract protected function retrieveUser(string $username, UsernamePasswordToken $token); - - /** - * Does additional checks on the user and token (like validating the - * credentials). - * - * @throws AuthenticationException if the credentials could not be validated - */ - abstract protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token); -} diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php index b8337adff57f3..42d22bea8b0bd 100644 --- a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php @@ -54,16 +54,6 @@ public function getClass(): string return $this->class; } - /** - * {@inheritdoc} - */ - public function getUsername(): string - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__); - - return $this->userIdentifier; - } - public function getUserIdentifier(): string { return $this->userIdentifier; diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php index 18eea22587b98..cf73b0a0b56d9 100644 --- a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentTokenInterface.php @@ -15,8 +15,6 @@ * Interface to be implemented by persistent token classes (such as * Doctrine entities representing a remember-me token). * - * @method string getUserIdentifier() returns the identifier used to authenticate (e.g. their e-mailaddress or username) - * * @author Johannes M. Schmitt */ interface PersistentTokenInterface @@ -50,9 +48,7 @@ public function getTokenValue(); public function getLastUsed(); /** - * @return string - * - * @deprecated since Symfony 5.3, use getUserIdentifier() instead + * Returns the identifier used to authenticate (e.g. their e-mailaddress or username). */ - public function getUsername(); + public function getUserIdentifier(): string; } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index e4d097fccd914..4220ebafcbda4 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -26,7 +26,6 @@ abstract class AbstractToken implements TokenInterface, \Serializable { private $user; private $roleNames = []; - private $authenticated = false; private $attributes = []; /** @@ -49,38 +48,9 @@ public function getRoleNames(): array return $this->roleNames; } - /** - * {@inheritdoc} - */ - public function getUsername(/* $legacy = true */) - { - if (1 === \func_num_args() && false === func_get_arg(0)) { - return null; - } - - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__); - - if ($this->user instanceof UserInterface) { - return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername(); - } - - return (string) $this->user; - } - public function getUserIdentifier(): string { - // method returns "null" in non-legacy mode if not overridden - $username = $this->getUsername(false); - if (null !== $username) { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s::getUsername()" is deprecated, override "getUserIdentifier()" instead.', get_debug_type($this)); - } - - if ($this->user instanceof UserInterface) { - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - return method_exists($this->user, 'getUserIdentifier') ? $this->user->getUserIdentifier() : $this->user->getUsername(); - } - - return (string) $this->user; + return $this->user->getUserIdentifier(); } /** @@ -94,65 +64,11 @@ public function getUser() /** * {@inheritdoc} */ - public function setUser(string|\Stringable|UserInterface $user) + public function setUser(UserInterface $user) { - if (!$user instanceof UserInterface) { - trigger_deprecation('symfony/security-core', '5.4', 'Using an object that is not an instance of "%s" as $user in "%s" is deprecated.', UserInterface::class, static::class); - } - - // @deprecated since Symfony 5.4, remove the whole block if/elseif/else block in 6.0 - if (1 < \func_num_args() && !func_get_arg(1)) { - // ContextListener checks if the user has changed on its own and calls `setAuthenticated()` subsequently, - // avoid doing the same checks twice - $changed = false; - } elseif (null === $this->user) { - $changed = false; - } elseif ($this->user instanceof UserInterface) { - if (!$user instanceof UserInterface) { - $changed = true; - } else { - $changed = $this->hasUserChanged($user); - } - } elseif ($user instanceof UserInterface) { - $changed = true; - } else { - $changed = (string) $this->user !== (string) $user; - } - - // @deprecated since Symfony 5.4 - if ($changed) { - $this->setAuthenticated(false, false); - } - $this->user = $user; } - /** - * {@inheritdoc} - * - * @deprecated since Symfony 5.4 - */ - public function isAuthenticated() - { - if (1 > \func_num_args() || func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" flag anymore and will always be considered authenticated.', __METHOD__); - } - - return $this->authenticated; - } - - /** - * {@inheritdoc} - */ - public function setAuthenticated(bool $authenticated) - { - if (2 > \func_num_args() || func_get_arg(1)) { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" state anymore and will always be considered as authenticated.', __METHOD__); - } - - $this->authenticated = $authenticated; - } - /** * {@inheritdoc} */ @@ -180,7 +96,7 @@ public function eraseCredentials() */ public function __serialize(): array { - return [$this->user, $this->authenticated, null, $this->attributes, $this->roleNames]; + return [$this->user, true, null, $this->attributes, $this->roleNames]; } /** @@ -201,7 +117,7 @@ public function __serialize(): array */ public function __unserialize(array $data): void { - [$this->user, $this->authenticated, , $this->attributes, $this->roleNames] = $data; + [$this->user, , , $this->attributes, $this->roleNames] = $data; } /** @@ -265,7 +181,7 @@ public function __toString(): string $roles[] = $role; } - return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUserIdentifier(), json_encode($this->authenticated), implode(', ', $roles)); + return sprintf('%s(user="%s", roles="%s")', $class, $this->getUserIdentifier(), implode(', ', $roles)); } /** @@ -283,52 +199,4 @@ final public function unserialize(string $serialized) { $this->__unserialize(unserialize($serialized)); } - - /** - * @deprecated since Symfony 5.4 - */ - private function hasUserChanged(UserInterface $user): bool - { - if (!($this->user instanceof UserInterface)) { - throw new \BadMethodCallException('Method "hasUserChanged" should be called when current user class is instance of "UserInterface".'); - } - - if ($this->user instanceof EquatableInterface) { - return !(bool) $this->user->isEqualTo($user); - } - - if ($this->user instanceof PasswordAuthenticatedUserInterface || $user instanceof PasswordAuthenticatedUserInterface) { - if (!$this->user instanceof PasswordAuthenticatedUserInterface || !$user instanceof PasswordAuthenticatedUserInterface || $this->user->getPassword() !== $user->getPassword()) { - return true; - } - - if ($this->user instanceof LegacyPasswordAuthenticatedUserInterface xor $user instanceof LegacyPasswordAuthenticatedUserInterface) { - return true; - } - - if ($this->user instanceof LegacyPasswordAuthenticatedUserInterface && $user instanceof LegacyPasswordAuthenticatedUserInterface && $this->user->getSalt() !== $user->getSalt()) { - return true; - } - } - - $userRoles = array_map('strval', (array) $user->getRoles()); - - if ($this instanceof SwitchUserToken) { - $userRoles[] = 'ROLE_PREVIOUS_ADMIN'; - } - - if (\count($userRoles) !== \count($this->getRoleNames()) || \count($userRoles) !== \count(array_intersect($userRoles, $this->getRoleNames()))) { - return true; - } - - // @deprecated since Symfony 5.3, drop getUsername() in 6.0 - $userIdentifier = function ($user) { - return method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(); - }; - if ($userIdentifier($this->user) !== $userIdentifier($user)) { - return true; - } - - return false; - } } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php deleted file mode 100644 index 85316dba2e7e5..0000000000000 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php +++ /dev/null @@ -1,78 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Authentication\Token; - -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * AnonymousToken represents an anonymous token. - * - * @author Fabien Potencier - * - * @deprecated since 5.4, anonymous is now represented by the absence of a token - */ -class AnonymousToken extends AbstractToken -{ - private $secret; - - /** - * @param string $secret A secret used to make sure the token is created by the app and not by a malicious client - * @param string[] $roles - */ - public function __construct(string $secret, string|\Stringable|UserInterface $user, array $roles = []) - { - trigger_deprecation('symfony/security-core', '5.4', 'The "%s" class is deprecated.', __CLASS__); - - parent::__construct($roles); - - $this->secret = $secret; - $this->setUser($user); - // @deprecated since Symfony 5.4 - $this->setAuthenticated(true, false); - } - - /** - * {@inheritdoc} - */ - public function getCredentials() - { - return ''; - } - - /** - * Returns the secret. - * - * @return string - */ - public function getSecret() - { - return $this->secret; - } - - /** - * {@inheritdoc} - */ - public function __serialize(): array - { - return [$this->secret, parent::__serialize()]; - } - - /** - * {@inheritdoc} - */ - public function __unserialize(array $data): void - { - [$this->secret, $parentData] = $data; - $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); - parent::__unserialize($parentData); - } -} diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php index 4bfe0e9dc7500..4a2a7e13ea006 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/NullToken.php @@ -28,53 +28,21 @@ public function getRoleNames(): array return []; } - public function getCredentials() - { - return ''; - } - public function getUser() { return ''; } - public function setUser(string|\Stringable|UserInterface $user) + public function setUser(UserInterface $user) { throw new \BadMethodCallException('Cannot set user on a NullToken.'); } - public function getUsername() - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__); - - return ''; - } - public function getUserIdentifier(): string { return ''; } - /** - * @deprecated since Symfony 5.4 - */ - public function isAuthenticated() - { - if (0 === \func_num_args() || func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated. In version 6.0, security tokens won\'t have an "authenticated" flag anymore and will always be considered authenticated.', __METHOD__); - } - - return true; - } - - /** - * @deprecated since Symfony 5.4 - */ - public function setAuthenticated(bool $isAuthenticated) - { - throw new \BadMethodCallException('Cannot change authentication state of NullToken.'); - } - public function eraseCredentials() { } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php index 50159697ebf9e..30579c52fb52f 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php @@ -20,22 +20,13 @@ */ class PreAuthenticatedToken extends AbstractToken { - private $credentials; private $firewallName; /** * @param string[] $roles */ - public function __construct(string|\Stringable|UserInterface $user, /*string*/ $firewallName, /*array*/ $roles = []) + public function __construct(UserInterface $user, string $firewallName, array $roles = []) { - if (\is_string($roles)) { - trigger_deprecation('symfony/security-core', '5.4', 'Argument $credentials of "%s()" is deprecated.', __METHOD__); - - $credentials = $firewallName; - $firewallName = $roles; - $roles = \func_num_args() > 3 ? func_get_arg(3) : []; - } - parent::__construct($roles); if ('' === $firewallName) { @@ -43,53 +34,12 @@ public function __construct(string|\Stringable|UserInterface $user, /*string*/ $ } $this->setUser($user); - $this->credentials = $credentials ?? null; $this->firewallName = $firewallName; - - if ($roles) { - $this->setAuthenticated(true, false); - } - } - - /** - * Returns the provider key. - * - * @return string The provider key - * - * @deprecated since Symfony 5.2, use getFirewallName() instead - */ - public function getProviderKey() - { - if (1 !== \func_num_args() || true !== func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.2', 'Method "%s()" is deprecated, use "getFirewallName()" instead.', __METHOD__); - } - - return $this->firewallName; } public function getFirewallName(): string { - return $this->getProviderKey(true); - } - - /** - * {@inheritdoc} - */ - public function getCredentials() - { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated.', __METHOD__); - - return $this->credentials; - } - - /** - * {@inheritdoc} - */ - public function eraseCredentials() - { - parent::eraseCredentials(); - - $this->credentials = null; + return $this->firewallName; } /** @@ -97,7 +47,7 @@ public function eraseCredentials() */ public function __serialize(): array { - return [$this->credentials, $this->firewallName, parent::__serialize()]; + return [null, $this->firewallName, parent::__serialize()]; } /** @@ -105,7 +55,7 @@ public function __serialize(): array */ public function __unserialize(array $data): void { - [$this->credentials, $this->firewallName, $parentData] = $data; + [, $this->firewallName, $parentData] = $data; $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); parent::__unserialize($parentData); } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php index 48319a8e18a0c..e2a9da9e3e7b1 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php @@ -44,40 +44,11 @@ public function __construct(UserInterface $user, string $firewallName, string $s $this->secret = $secret; $this->setUser($user); - parent::setAuthenticated(true, false); - } - - /** - * {@inheritdoc} - */ - public function setAuthenticated(bool $authenticated) - { - if ($authenticated) { - throw new \LogicException('You cannot set this token to authenticated after creation.'); - } - - parent::setAuthenticated(false, false); - } - - /** - * Returns the provider secret. - * - * @return string The provider secret - * - * @deprecated since Symfony 5.2, use getFirewallName() instead - */ - public function getProviderKey() - { - if (1 !== \func_num_args() || true !== func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.2', 'Method "%s()" is deprecated, use "getFirewallName()" instead.', __METHOD__); - } - - return $this->firewallName; } public function getFirewallName(): string { - return $this->getProviderKey(true); + return $this->firewallName; } /** @@ -90,16 +61,6 @@ public function getSecret() return $this->secret; } - /** - * {@inheritdoc} - */ - public function getCredentials() - { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s()" is deprecated.', __METHOD__); - - return ''; - } - /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php index b479324498854..850c05e752672 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorage.php @@ -48,11 +48,6 @@ public function setToken(TokenInterface $token = null) if ($token) { // ensure any initializer is called $this->getToken(); - - // @deprecated since Symfony 5.3 - if (!method_exists($token, 'getUserIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in token class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($token)); - } } $this->initializer = null; diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/SwitchUserToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/SwitchUserToken.php index d6687343ddec6..2c934f07b0034 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/SwitchUserToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/SwitchUserToken.php @@ -29,24 +29,9 @@ class SwitchUserToken extends UsernamePasswordToken * * @throws \InvalidArgumentException */ - public function __construct(string|\Stringable|UserInterface $user, /*string*/ $firewallName, /*array*/ $roles, /*TokenInterface*/ $originalToken, /*string*/ $originatedFromUri = null) + public function __construct(UserInterface $user, string $firewallName, array $roles, TokenInterface $originalToken, string $originatedFromUri = null) { - if (\is_string($roles)) { - // @deprecated since 5.4, deprecation is triggered by UsernamePasswordToken::__construct() - $credentials = $firewallName; - $firewallName = $roles; - $roles = $originalToken; - $originalToken = $originatedFromUri; - $originatedFromUri = \func_num_args() > 5 ? func_get_arg(5) : null; - - parent::__construct($user, $credentials, $firewallName, $roles); - } else { - parent::__construct($user, $firewallName, $roles); - } - - if (!$originalToken instanceof TokenInterface) { - throw new \TypeError(sprintf('Argument $originalToken of "%s" must be an instance of "%s", "%s" given.', __METHOD__, TokenInterface::class, get_debug_type($originalToken))); - } + parent::__construct($user, $firewallName, $roles); $this->originalToken = $originalToken; $this->originatedFromUri = $originatedFromUri; diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php index f981068ed181d..0faf770f69e04 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php @@ -37,15 +37,6 @@ public function __toString(): string; */ public function getRoleNames(): array; - /** - * Returns the user credentials. - * - * @return mixed - * - * @deprecated since 5.4 - */ - public function getCredentials(); - /** * Returns a user representation. * @@ -60,23 +51,7 @@ public function getUser(); * * @throws \InvalidArgumentException */ - public function setUser(string|\Stringable|UserInterface $user); - - /** - * Returns whether the user is authenticated or not. - * - * @return bool true if the token has been authenticated, false otherwise - * - * @deprecated since Symfony 5.4. In 6.0, security tokens will always be considered authenticated - */ - public function isAuthenticated(); - - /** - * Sets the authenticated flag. - * - * @deprecated since Symfony 5.4. In 6.0, security tokens will always be considered authenticated - */ - public function setAuthenticated(bool $isAuthenticated); + public function setUser(UserInterface $user); /** * Removes sensitive information from the token. @@ -127,11 +102,4 @@ public function __serialize(): array; * Restores the object state from an array given by __serialize(). */ public function __unserialize(array $data): void; - - /** - * @return string - * - * @deprecated since Symfony 5.3, use getUserIdentifier() instead - */ - public function getUsername(); } diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php index 97189f1f78fad..6dae8ec90715c 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php @@ -20,19 +20,10 @@ */ class UsernamePasswordToken extends AbstractToken { - private $credentials; private $firewallName; - public function __construct(string|\Stringable|UserInterface $user, /*string*/ $firewallName, /*array*/ $roles = []) + public function __construct(UserInterface $user, string $firewallName, array $roles = []) { - if (\is_string($roles)) { - trigger_deprecation('symfony/security-core', '5.4', 'The $credentials argument of "%s" is deprecated.', static::class.'::__construct'); - - $credentials = $firewallName; - $firewallName = $roles; - $roles = \func_num_args() > 3 ? func_get_arg(3) : []; - } - parent::__construct($roles); if ('' === $firewallName) { @@ -40,63 +31,12 @@ public function __construct(string|\Stringable|UserInterface $user, /*string*/ $ } $this->setUser($user); - $this->credentials = $credentials ?? null; $this->firewallName = $firewallName; - - parent::setAuthenticated(\count($roles) > 0, false); - } - - /** - * {@inheritdoc} - */ - public function setAuthenticated(bool $isAuthenticated) - { - if ($isAuthenticated) { - throw new \LogicException('Cannot set this token to trusted after instantiation.'); - } - - parent::setAuthenticated(false, false); - } - - /** - * {@inheritdoc} - */ - public function getCredentials() - { - trigger_deprecation('symfony/security-core', '5.4', 'Method "%s" is deprecated.', __METHOD__); - - return $this->credentials; - } - - /** - * Returns the provider key. - * - * @return string The provider key - * - * @deprecated since Symfony 5.2, use getFirewallName() instead - */ - public function getProviderKey() - { - if (1 !== \func_num_args() || true !== func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.2', 'Method "%s" is deprecated, use "getFirewallName()" instead.', __METHOD__); - } - - return $this->firewallName; } public function getFirewallName(): string { - return $this->getProviderKey(true); - } - - /** - * {@inheritdoc} - */ - public function eraseCredentials() - { - parent::eraseCredentials(); - - $this->credentials = null; + return $this->firewallName; } /** @@ -104,7 +44,7 @@ public function eraseCredentials() */ public function __serialize(): array { - return [$this->credentials, $this->firewallName, parent::__serialize()]; + return [null, $this->firewallName, parent::__serialize()]; } /** @@ -112,7 +52,7 @@ public function __serialize(): array */ public function __unserialize(array $data): void { - [$this->credentials, $this->firewallName, $parentData] = $data; + [, $this->firewallName, $parentData] = $data; $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); parent::__unserialize($parentData); } diff --git a/src/Symfony/Component/Security/Core/AuthenticationEvents.php b/src/Symfony/Component/Security/Core/AuthenticationEvents.php index fc286d2a99807..30498d0a3ed5b 100644 --- a/src/Symfony/Component/Security/Core/AuthenticationEvents.php +++ b/src/Symfony/Component/Security/Core/AuthenticationEvents.php @@ -24,16 +24,6 @@ final class AuthenticationEvents */ public const AUTHENTICATION_SUCCESS = 'security.authentication.success'; - /** - * The AUTHENTICATION_FAILURE event occurs after a user cannot be - * authenticated by any of the providers. - * - * @Event("Symfony\Component\Security\Core\Event\AuthenticationFailureEvent") - * - * @deprecated since Symfony 5.4, use {@see Event\LoginFailureEvent} instead - */ - public const AUTHENTICATION_FAILURE = 'security.authentication.failure'; - /** * Event aliases. * @@ -41,6 +31,5 @@ final class AuthenticationEvents */ public const ALIASES = [ AuthenticationSuccessEvent::class => self::AUTHENTICATION_SUCCESS, - AuthenticationFailureEvent::class => self::AUTHENTICATION_FAILURE, ]; } diff --git a/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php b/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php index 8da482d3bfbac..94d8a35bd1e66 100644 --- a/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php +++ b/src/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.php @@ -88,7 +88,7 @@ private function decideAffirmative(TokenInterface $token, array $attributes, mix if (VoterInterface::ACCESS_DENIED === $result) { ++$deny; } elseif (VoterInterface::ACCESS_ABSTAIN !== $result) { - trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class); + throw new \LogicException(sprintf('"%s::vote()" must return one of "%s" constants ("ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN"), "%s" returned.', get_debug_type($voter), VoterInterface::class, var_export($result, true))); } } @@ -125,7 +125,7 @@ private function decideConsensus(TokenInterface $token, array $attributes, mixed } elseif (VoterInterface::ACCESS_DENIED === $result) { ++$deny; } elseif (VoterInterface::ACCESS_ABSTAIN !== $result) { - trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class); + throw new \LogicException(sprintf('"%s::vote()" must return one of "%s" constants ("ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN"), "%s" returned.', get_debug_type($voter), VoterInterface::class, var_export($result, true))); } } @@ -164,7 +164,7 @@ private function decideUnanimous(TokenInterface $token, array $attributes, mixed if (VoterInterface::ACCESS_GRANTED === $result) { ++$grant; } elseif (VoterInterface::ACCESS_ABSTAIN !== $result) { - trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class); + throw new \LogicException(sprintf('"%s::vote()" must return one of "%s" constants ("ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN"), "%s" returned.', get_debug_type($voter), VoterInterface::class, var_export($result, true))); } } } @@ -198,7 +198,7 @@ private function decidePriority(TokenInterface $token, array $attributes, mixed } if (VoterInterface::ACCESS_ABSTAIN !== $result) { - trigger_deprecation('symfony/security-core', '5.3', 'Returning "%s" in "%s::vote()" is deprecated, return one of "%s" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".', var_export($result, true), get_debug_type($voter), VoterInterface::class); + throw new \LogicException(sprintf('"%s::vote()" must return one of "%s" constants ("ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN"), "%s" returned.', get_debug_type($voter), VoterInterface::class, var_export($result, true))); } } diff --git a/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php b/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php index 8ee36f082a31f..e00d1f183e7b3 100644 --- a/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php +++ b/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php @@ -28,35 +28,16 @@ class AuthorizationChecker implements AuthorizationCheckerInterface { private $tokenStorage; private $accessDecisionManager; - private $authenticationManager; - private $alwaysAuthenticate; private $exceptionOnNoToken; - public function __construct(TokenStorageInterface $tokenStorage, /*AccessDecisionManagerInterface*/ $accessDecisionManager, /*bool*/ $alwaysAuthenticate = false, /*bool*/ $exceptionOnNoToken = true) + public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, bool $exceptionOnNoToken = false) { - if ($accessDecisionManager instanceof AuthenticationManagerInterface) { - trigger_deprecation('symfony/security-core', '5.4', 'The $autenticationManager argument of "%s" is deprecated.', __METHOD__); - - $this->authenticationManager = $accessDecisionManager; - $accessDecisionManager = $alwaysAuthenticate; - $alwaysAuthenticate = $exceptionOnNoToken; - $exceptionOnNoToken = \func_num_args() > 4 ? func_get_arg(4) : true; - } - - if (false !== $alwaysAuthenticate) { - trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 4th argument of "%s" to "false" is deprecated.', __METHOD__); - } if (false !== $exceptionOnNoToken) { - trigger_deprecation('symfony/security-core', '5.4', 'Not setting the 5th argument of "%s" to "false" is deprecated.', __METHOD__); - } - - if (!$accessDecisionManager instanceof AccessDecisionManagerInterface) { - throw new \TypeError(sprintf('Argument 2 of "%s" must be instance of "%s", "%s" given.', __METHOD__, AccessDecisionManagerInterface::class, get_debug_type($accessDecisionManager))); + throw new \LogicException('Argument $exceptionOnNoToken of "%s()" must be set to "false".', __METHOD__); } $this->tokenStorage = $tokenStorage; $this->accessDecisionManager = $accessDecisionManager; - $this->alwaysAuthenticate = $alwaysAuthenticate; $this->exceptionOnNoToken = $exceptionOnNoToken; } @@ -67,22 +48,7 @@ public function __construct(TokenStorageInterface $tokenStorage, /*AccessDecisio */ final public function isGranted(mixed $attribute, mixed $subject = null): bool { - if (null === ($token = $this->tokenStorage->getToken())) { - if ($this->exceptionOnNoToken) { - throw new AuthenticationCredentialsNotFoundException('The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL.'); - } - - $token = new NullToken(); - } else { - $authenticated = true; - // @deprecated since Symfony 5.4 - if ($this->alwaysAuthenticate || !$authenticated = $token->isAuthenticated(false)) { - if (!($authenticated ?? true)) { - trigger_deprecation('symfony/core', '5.4', 'Returning false from "%s()" is deprecated and won\'t have any effect in Symfony 6.0 as security tokens will always be considered authenticated.'); - } - $this->tokenStorage->setToken($token = $this->authenticationManager->authenticate($token)); - } - } + $token = $this->tokenStorage->getToken() ?? new NullToken(); return $this->accessDecisionManager->decide($token, [$attribute], $subject); } diff --git a/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php b/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php index ba2ba26462b91..7435003934a3b 100644 --- a/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php +++ b/src/Symfony/Component/Security/Core/Authorization/ExpressionLanguageProvider.php @@ -13,7 +13,6 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunction; use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; -use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; /** * Define some ExpressionLanguage functions. @@ -25,19 +24,10 @@ class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface public function getFunctions() { return [ - new ExpressionFunction('is_anonymous', function () { - return 'trigger_deprecation("symfony/security-core", "5.4", "The \"is_anonymous()\" expression function is deprecated.") || ($token && $auth_checker->isGranted("IS_ANONYMOUS"))'; - }, function (array $variables) { - trigger_deprecation('symfony/security-core', '5.4', 'The "is_anonymous()" expression function is deprecated.'); - - return $variables['token'] && $variables['auth_checker']->isGranted('IS_ANONYMOUS'); - }), - - // @deprecated remove the ternary and always use IS_AUTHENTICATED in 6.0 new ExpressionFunction('is_authenticated', function () { - return 'defined("'.AuthenticatedVoter::class.'::IS_AUTHENTICATED") ? $auth_checker->isGranted("IS_AUTHENTICATED") : ($token && !$auth_checker->isGranted("IS_ANONYMOUS"))'; + return '$auth_checker->isGranted("IS_AUTHENTICATED")'; }, function (array $variables) { - return \defined(AuthenticatedVoter::class.'::IS_AUTHENTICATED') ? $variables['auth_checker']->isGranted('IS_AUTHENTICATED') : ($variables['token'] && !$variables['auth_checker']->isGranted('IS_ANONYMOUS')); + return $variables['auth_checker']->isGranted('IS_AUTHENTICATED'); }), new ExpressionFunction('is_fully_authenticated', function () { diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php index d39ab0ad901e6..3d338526ba88e 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/AuthenticatedVoter.php @@ -29,14 +29,6 @@ class AuthenticatedVoter implements VoterInterface { public const IS_AUTHENTICATED_FULLY = 'IS_AUTHENTICATED_FULLY'; public const IS_AUTHENTICATED_REMEMBERED = 'IS_AUTHENTICATED_REMEMBERED'; - /** - * @deprecated since Symfony 5.4 - */ - public const IS_AUTHENTICATED_ANONYMOUSLY = 'IS_AUTHENTICATED_ANONYMOUSLY'; - /** - * @deprecated since Symfony 5.4 - */ - public const IS_ANONYMOUS = 'IS_ANONYMOUS'; public const IS_AUTHENTICATED = 'IS_AUTHENTICATED'; public const IS_IMPERSONATOR = 'IS_IMPERSONATOR'; public const IS_REMEMBERED = 'IS_REMEMBERED'; @@ -62,9 +54,7 @@ public function vote(TokenInterface $token, mixed $subject, array $attributes) foreach ($attributes as $attribute) { if (null === $attribute || (self::IS_AUTHENTICATED_FULLY !== $attribute && self::IS_AUTHENTICATED_REMEMBERED !== $attribute - && self::IS_AUTHENTICATED_ANONYMOUSLY !== $attribute && self::IS_AUTHENTICATED !== $attribute - && self::IS_ANONYMOUS !== $attribute && self::IS_IMPERSONATOR !== $attribute && self::IS_REMEMBERED !== $attribute)) { continue; @@ -83,20 +73,7 @@ public function vote(TokenInterface $token, mixed $subject, array $attributes) return VoterInterface::ACCESS_GRANTED; } - if (self::IS_AUTHENTICATED_ANONYMOUSLY === $attribute - && ($this->authenticationTrustResolver->isAnonymous($token) - || $this->authenticationTrustResolver->isRememberMe($token) - || $this->authenticationTrustResolver->isFullFledged($token))) { - trigger_deprecation('symfony/security-core', '5.4', 'The "IS_AUTHENTICATED_ANONYMOUSLY" security attribute is deprecated, use "IS_AUTHENTICATED" or "IS_AUTHENTICATED_FULLY" instead if you want to check if the request is (fully) authenticated.'); - - return VoterInterface::ACCESS_GRANTED; - } - - // @deprecated $this->authenticationTrustResolver must implement isAuthenticated() in 6.0 - if (self::IS_AUTHENTICATED === $attribute - && (method_exists($this->authenticationTrustResolver, 'isAuthenticated') - ? $this->authenticationTrustResolver->isAuthenticated($token) - : (null !== $token && !$token instanceof NullToken))) { + if (self::IS_AUTHENTICATED === $attribute && $this->authenticationTrustResolver->isAuthenticated($token)) { return VoterInterface::ACCESS_GRANTED; } @@ -104,12 +81,6 @@ public function vote(TokenInterface $token, mixed $subject, array $attributes) return VoterInterface::ACCESS_GRANTED; } - if (self::IS_ANONYMOUS === $attribute && $this->authenticationTrustResolver->isAnonymous($token)) { - trigger_deprecation('symfony/security-core', '5.4', 'The "IS_ANONYMOUSLY" security attribute is deprecated, anonymous no longer exists in version 6.'); - - return VoterInterface::ACCESS_GRANTED; - } - if (self::IS_IMPERSONATOR === $attribute && $token instanceof SwitchUserToken) { return VoterInterface::ACCESS_GRANTED; } diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php index 1f187a2f21ae4..b8437a3b4f626 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleVoter.php @@ -40,10 +40,6 @@ public function vote(TokenInterface $token, mixed $subject, array $attributes) continue; } - if ('ROLE_PREVIOUS_ADMIN' === $attribute) { - trigger_deprecation('symfony/security-core', '5.1', 'The ROLE_PREVIOUS_ADMIN role is deprecated and will be removed in version 6.0, use the IS_IMPERSONATOR attribute instead.'); - } - $result = VoterInterface::ACCESS_DENIED; foreach ($roles as $role) { if ($attribute === $role) { diff --git a/src/Symfony/Component/Security/Core/Event/AuthenticationFailureEvent.php b/src/Symfony/Component/Security/Core/Event/AuthenticationFailureEvent.php deleted file mode 100644 index 4e9562c2614dd..0000000000000 --- a/src/Symfony/Component/Security/Core/Event/AuthenticationFailureEvent.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Event; - -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Event\LoginFailureEvent; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" with the new authenticator system instead.', AuthenticationFailureEvent::class, LoginFailureEvent::class); - -/** - * This event is dispatched on authentication failure. - * - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.3, use LoginFailureEvent with the new authenticator system instead - */ -final class AuthenticationFailureEvent extends AuthenticationEvent -{ - private $authenticationException; - - public function __construct(TokenInterface $token, AuthenticationException $ex) - { - parent::__construct($token); - - $this->authenticationException = $ex; - } - - public function getAuthenticationException(): AuthenticationException - { - return $this->authenticationException; - } -} diff --git a/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php index 4f8b7ef77b192..a6df9636180bd 100644 --- a/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php +++ b/src/Symfony/Component/Security/Core/Exception/UserNotFoundException.php @@ -37,18 +37,6 @@ public function getUserIdentifier(): ?string return $this->identifier; } - /** - * @return string - * - * @deprecated - */ - public function getUsername() - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__); - - return $this->identifier; - } - /** * Set the user identifier (e.g. username or e-mailaddress). */ @@ -57,16 +45,6 @@ public function setUserIdentifier(string $identifier): void $this->identifier = $identifier; } - /** - * @deprecated - */ - public function setUsername(string $username) - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use setUserIdentifier() instead.', __METHOD__); - - $this->identifier = $username; - } - /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php b/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php deleted file mode 100644 index e0d2d4a2ef113..0000000000000 --- a/src/Symfony/Component/Security/Core/Exception/UsernameNotFoundException.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Exception; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" instead.', UsernameNotFoundException::class, UserNotFoundException::class); - -class_exists(UserNotFoundException::class); - -if (false) { - /** - * @deprecated since Symfony 5.3 to be removed in 6.0, use UserNotFoundException instead. - */ - class UsernameNotFoundException extends AuthenticationException - { - } -} diff --git a/src/Symfony/Component/Security/Core/Security.php b/src/Symfony/Component/Security/Core/Security.php index 4df0e339ee3da..ccd42813ae7e4 100644 --- a/src/Symfony/Component/Security/Core/Security.php +++ b/src/Symfony/Component/Security/Core/Security.php @@ -41,18 +41,7 @@ public function getUser(): ?UserInterface return null; } - $user = $token->getUser(); - // @deprecated since 5.4, $user will always be a UserInterface instance - if (!\is_object($user)) { - return null; - } - - // @deprecated since 5.4, $user will always be a UserInterface instance - if (!$user instanceof UserInterface) { - return null; - } - - return $user; + return $token->getUser(); } /** diff --git a/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php b/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php index 84b16b0147207..ec252e26972e9 100644 --- a/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php +++ b/src/Symfony/Component/Security/Core/Signature/SignatureHasher.php @@ -79,7 +79,7 @@ public function verifySignatureHash(UserInterface $user, int $expires, string $h */ public function computeSignatureHash(UserInterface $user, int $expires): string { - $signatureFields = [base64_encode(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername()), $expires]; + $signatureFields = [base64_encode($user->getUserIdentifier()), $expires]; foreach ($this->signatureProperties as $property) { $value = $this->propertyAccessor->getValue($user, $property) ?? ''; diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php deleted file mode 100644 index 661ffa4521dd2..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationProviderManagerTest.php +++ /dev/null @@ -1,210 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; -use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\AuthenticationEvents; -use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; -use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent; -use Symfony\Component\Security\Core\Exception\AccountStatusException; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\ProviderNotFoundException; -use Symfony\Component\Security\Core\User\InMemoryUser; - -/** - * @group legacy - */ -class AuthenticationProviderManagerTest extends TestCase -{ - public function testAuthenticateWithoutProviders() - { - $this->expectException(\InvalidArgumentException::class); - new AuthenticationProviderManager([]); - } - - public function testAuthenticateWithProvidersWithIncorrectInterface() - { - $this->expectException(\InvalidArgumentException::class); - (new AuthenticationProviderManager([ - new \stdClass(), - ]))->authenticate($this->createMock(TokenInterface::class)); - } - - public function testAuthenticateWhenNoProviderSupportsToken() - { - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(false), - ]); - - try { - $manager->authenticate($token = $this->createMock(TokenInterface::class)); - $this->fail(); - } catch (ProviderNotFoundException $e) { - $this->assertSame($token, $e->getToken()); - } - } - - public function testAuthenticateWhenProviderReturnsAccountStatusException() - { - $secondAuthenticationProvider = $this->createMock(AuthenticationProviderInterface::class); - - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, null, AccountStatusException::class), - $secondAuthenticationProvider, - ]); - - // AccountStatusException stops authentication - $secondAuthenticationProvider->expects($this->never())->method('supports'); - - try { - $manager->authenticate($token = $this->createMock(TokenInterface::class)); - $this->fail(); - } catch (AccountStatusException $e) { - $this->assertSame($token, $e->getToken()); - } - } - - public function testAuthenticateWhenProviderReturnsAuthenticationException() - { - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, null, AuthenticationException::class), - ]); - - try { - $manager->authenticate($token = $this->createMock(TokenInterface::class)); - $this->fail(); - } catch (AuthenticationException $e) { - $this->assertSame($token, $e->getToken()); - } - } - - public function testAuthenticateWhenOneReturnsAuthenticationExceptionButNotAll() - { - $expected = $this->createMock(TokenInterface::class); - $expected->expects($this->any())->method('getUser')->willReturn(new InMemoryUser('wouter', null)); - - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, null, AuthenticationException::class), - $this->getAuthenticationProvider(true, $expected), - ]); - - $token = $manager->authenticate($this->createMock(TokenInterface::class)); - $this->assertSame($expected, $token); - } - - public function testAuthenticateReturnsTokenOfTheFirstMatchingProvider() - { - $second = $this->createMock(AuthenticationProviderInterface::class); - $second - ->expects($this->never()) - ->method('supports') - ; - $expected = $this->createMock(TokenInterface::class); - $expected->expects($this->any())->method('getUser')->willReturn(new InMemoryUser('wouter', null)); - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, $expected), - $second, - ]); - - $token = $manager->authenticate($this->createMock(TokenInterface::class)); - $this->assertSame($expected, $token); - } - - public function testEraseCredentialFlag() - { - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, $token = new UsernamePasswordToken('foo', 'bar', 'key')), - ]); - - $token = $manager->authenticate($this->createMock(TokenInterface::class)); - $this->assertEquals('', $token->getCredentials()); - - $manager = new AuthenticationProviderManager([ - $this->getAuthenticationProvider(true, $token = new UsernamePasswordToken('foo', 'bar', 'key')), - ], false); - - $token = $manager->authenticate($this->createMock(TokenInterface::class)); - $this->assertEquals('bar', $token->getCredentials()); - } - - public function testAuthenticateDispatchesAuthenticationFailureEvent() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - $provider = $this->createMock(AuthenticationProviderInterface::class); - $provider->expects($this->once())->method('supports')->willReturn(true); - $provider->expects($this->once())->method('authenticate')->willThrowException($exception = new AuthenticationException()); - - $dispatcher = $this->createMock(EventDispatcherInterface::class); - $dispatcher - ->expects($this->once()) - ->method('dispatch') - ->with($this->equalTo(new AuthenticationFailureEvent($token, $exception)), AuthenticationEvents::AUTHENTICATION_FAILURE); - - $manager = new AuthenticationProviderManager([$provider]); - $manager->setEventDispatcher($dispatcher); - - try { - $manager->authenticate($token); - $this->fail('->authenticate() should rethrow exceptions'); - } catch (AuthenticationException $e) { - $this->assertSame($token, $exception->getToken()); - } - } - - public function testAuthenticateDispatchesAuthenticationSuccessEvent() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - - $provider = $this->createMock(AuthenticationProviderInterface::class); - $provider->expects($this->once())->method('supports')->willReturn(true); - $provider->expects($this->once())->method('authenticate')->willReturn($token); - - $dispatcher = $this->createMock(EventDispatcherInterface::class); - $dispatcher - ->expects($this->once()) - ->method('dispatch') - ->with($this->equalTo(new AuthenticationSuccessEvent($token)), AuthenticationEvents::AUTHENTICATION_SUCCESS); - - $manager = new AuthenticationProviderManager([$provider]); - $manager->setEventDispatcher($dispatcher); - - $this->assertSame($token, $manager->authenticate($token)); - } - - protected function getAuthenticationProvider($supports, $token = null, $exception = null) - { - $provider = $this->createMock(AuthenticationProviderInterface::class); - $provider->expects($this->once()) - ->method('supports') - ->willReturn($supports) - ; - - if (null !== $token) { - $provider->expects($this->once()) - ->method('authenticate') - ->willReturn($token) - ; - } elseif (null !== $exception) { - $provider->expects($this->once()) - ->method('authenticate') - ->willThrowException($this->getMockBuilder($exception)->setMethods(null)->getMock()) - ; - } - - return $provider; - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php index aeddb48d64790..aae11bcfe18cc 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/AuthenticationTrustResolverTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\User\InMemoryUser; @@ -21,18 +20,6 @@ class AuthenticationTrustResolverTest extends TestCase { - /** - * @group legacy - */ - public function testIsAnonymous() - { - $resolver = new AuthenticationTrustResolver(); - $this->assertFalse($resolver->isAnonymous(null)); - $this->assertFalse($resolver->isAnonymous($this->getToken())); - $this->assertFalse($resolver->isAnonymous($this->getRememberMeToken())); - $this->assertFalse($resolver->isAnonymous(new FakeCustomToken())); - } - public function testIsRememberMe() { $resolver = new AuthenticationTrustResolver(); @@ -63,87 +50,17 @@ public function testIsAuthenticated() $this->assertTrue($resolver->isAuthenticated(new FakeCustomToken())); } - /** - * @group legacy - */ - public function testIsAnonymousWithClassAsConstructorButStillExtending() - { - $resolver = $this->getResolver(); - - $this->assertFalse($resolver->isAnonymous(null)); - $this->assertFalse($resolver->isAnonymous($this->getToken())); - $this->assertFalse($resolver->isAnonymous($this->getRememberMeToken())); - } - - public function testIsRememberMeWithClassAsConstructorButStillExtending() - { - $resolver = $this->getResolver(); - - $this->assertFalse($resolver->isRememberMe(null)); - $this->assertFalse($resolver->isRememberMe($this->getToken())); - $this->assertTrue($resolver->isRememberMe($this->getRememberMeToken())); - $this->assertTrue($resolver->isRememberMe(new RealCustomRememberMeToken())); - } - - public function testisFullFledgedWithClassAsConstructorButStillExtending() - { - $resolver = $this->getResolver(); - - $this->assertFalse($resolver->isFullFledged(null)); - $this->assertFalse($resolver->isFullFledged($this->getRememberMeToken())); - $this->assertFalse($resolver->isFullFledged(new RealCustomRememberMeToken())); - $this->assertTrue($resolver->isFullFledged($this->getToken())); - } - - /** - * @group legacy - */ - public function testLegacy() - { - $resolver = $this->getResolver(); - - $this->assertTrue($resolver->isAnonymous($this->getAnonymousToken())); - $this->assertTrue($resolver->isAnonymous($this->getRealCustomAnonymousToken())); - - $this->assertFalse($resolver->isRememberMe($this->getAnonymousToken())); - - $this->assertFalse($resolver->isFullFledged($this->getAnonymousToken())); - $this->assertFalse($resolver->isFullFledged($this->getRealCustomAnonymousToken())); - } - protected function getToken() { return $this->createMock(TokenInterface::class); } - protected function getAnonymousToken() - { - return new AnonymousToken('secret', 'anon.'); - } - - private function getRealCustomAnonymousToken() - { - return new class() extends AnonymousToken { - public function __construct() - { - } - }; - } - protected function getRememberMeToken() { $user = new InMemoryUser('wouter', '', ['ROLE_USER']); return new RememberMeToken($user, 'main', 'secret'); } - - protected function getResolver() - { - return new AuthenticationTrustResolver( - AnonymousToken::class, - RememberMeToken::class - ); - } } class FakeCustomToken implements TokenInterface @@ -192,15 +109,6 @@ public function getUserIdentifier(): string { } - public function isAuthenticated(): bool - { - return true; - } - - public function setAuthenticated(bool $isAuthenticated) - { - } - public function eraseCredentials() { } diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php deleted file mode 100644 index 08127b6cbd807..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/AnonymousAuthenticationProviderTest.php +++ /dev/null @@ -1,74 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Authentication\Provider\AnonymousAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; - -/** - * @group legacy - */ -class AnonymousAuthenticationProviderTest extends TestCase -{ - public function testSupports() - { - $provider = $this->getProvider('foo'); - - $this->assertTrue($provider->supports($this->getSupportedToken('foo'))); - $this->assertFalse($provider->supports($this->createMock(TokenInterface::class))); - } - - public function testAuthenticateWhenTokenIsNotSupported() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessage('The token is not supported by this authentication provider.'); - $provider = $this->getProvider('foo'); - - $provider->authenticate($this->createMock(TokenInterface::class)); - } - - public function testAuthenticateWhenSecretIsNotValid() - { - $this->expectException(BadCredentialsException::class); - $provider = $this->getProvider('foo'); - - $provider->authenticate($this->getSupportedToken('bar')); - } - - public function testAuthenticate() - { - $provider = $this->getProvider('foo'); - $token = $this->getSupportedToken('foo'); - - $this->assertSame($token, $provider->authenticate($token)); - } - - protected function getSupportedToken($secret) - { - $token = $this->getMockBuilder(AnonymousToken::class)->setMethods(['getSecret'])->disableOriginalConstructor()->getMock(); - $token->expects($this->any()) - ->method('getSecret') - ->willReturn($secret) - ; - - return $token; - } - - protected function getProvider($secret) - { - return new AnonymousAuthenticationProvider($secret); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php deleted file mode 100644 index 8736b57c43d04..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/DaoAuthenticationProviderTest.php +++ /dev/null @@ -1,356 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; -use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface; -use Symfony\Component\PasswordHasher\Hasher\PlaintextPasswordHasher; -use Symfony\Component\PasswordHasher\PasswordHasherInterface; -use Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\InMemoryUserProvider; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -/** - * @group legacy - */ -class DaoAuthenticationProviderTest extends TestCase -{ - use ExpectDeprecationTrait; - - public function testRetrieveUserWhenUsernameIsNotFound() - { - $this->expectException(UserNotFoundException::class); - $userProvider = new InMemoryUserProvider(); - - $provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class)); - $method = new \ReflectionMethod($provider, 'retrieveUser'); - $method->setAccessible(true); - - $method->invoke($provider, 'fabien', $this->getSupportedToken()); - } - - public function testRetrieveUserWhenAnExceptionOccurs() - { - $this->expectException(AuthenticationServiceException::class); - $userProvider = $this->createMock(InMemoryUserProvider::class); - $userProvider->expects($this->once()) - ->method('loadUserByIdentifier') - ->willThrowException(new \RuntimeException()) - ; - - $provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class)); - $method = new \ReflectionMethod($provider, 'retrieveUser'); - $method->setAccessible(true); - - $method->invoke($provider, 'fabien', $this->getSupportedToken()); - } - - public function testRetrieveUserReturnsUserFromTokenOnReauthentication() - { - $userProvider = $this->createMock(InMemoryUserProvider::class); - $userProvider->expects($this->never()) - ->method('loadUserByIdentifier') - ; - - $user = new TestUser(); - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getUser') - ->willReturn($user) - ; - - $provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class)); - $reflection = new \ReflectionMethod($provider, 'retrieveUser'); - $reflection->setAccessible(true); - $result = $reflection->invoke($provider, 'someUser', $token); - - $this->assertSame($user, $result); - } - - public function testRetrieveUser() - { - $userProvider = new InMemoryUserProvider(['fabien' => []]); - - $provider = new DaoAuthenticationProvider($userProvider, $this->createMock(UserCheckerInterface::class), 'key', $this->createMock(PasswordHasherFactoryInterface::class)); - $method = new \ReflectionMethod($provider, 'retrieveUser'); - $method->setAccessible(true); - - $this->assertEquals('fabien', $method->invoke($provider, 'fabien', $this->getSupportedToken())->getUserIdentifier()); - } - - public function testCheckAuthenticationWhenCredentialsAreEmpty() - { - $this->expectException(BadCredentialsException::class); - $hasher = $this->getMockBuilder(PasswordHasherInterface::class)->getMock(); - $hasher - ->expects($this->never()) - ->method('verify') - ; - - $provider = $this->getProvider(null, null, $hasher); - $method = new \ReflectionMethod($provider, 'checkAuthentication'); - $method->setAccessible(true); - - $token = $this->getSupportedToken(); - $token - ->expects($this->once()) - ->method('getCredentials') - ->willReturn('') - ; - - $method->invoke($provider, new TestUser(), $token); - } - - public function testCheckAuthenticationWhenCredentialsAre0() - { - $hasher = $this->createMock(PasswordHasherInterface::class); - $hasher - ->expects($this->once()) - ->method('verify') - ->willReturn(true) - ; - - $provider = $this->getProvider(null, null, $hasher); - $method = new \ReflectionMethod($provider, 'checkAuthentication'); - $method->setAccessible(true); - - $token = $this->getSupportedToken(); - $token - ->expects($this->once()) - ->method('getCredentials') - ->willReturn('0') - ; - - $method->invoke( - $provider, - new InMemoryUser('username', 'password'), - $token - ); - } - - public function testCheckAuthenticationWhenCredentialsAreNotValid() - { - $this->expectException(BadCredentialsException::class); - $hasher = $this->createMock(PasswordHasherInterface::class); - $hasher->expects($this->once()) - ->method('verify') - ->willReturn(false) - ; - - $provider = $this->getProvider(null, null, $hasher); - $method = new \ReflectionMethod($provider, 'checkAuthentication'); - $method->setAccessible(true); - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getCredentials') - ->willReturn('foo') - ; - - $method->invoke($provider, new InMemoryUser('username', 'password'), $token); - } - - public function testCheckAuthenticationDoesNotReauthenticateWhenPasswordHasChanged() - { - $this->expectException(BadCredentialsException::class); - $user = $this->createMock(TestUser::class); - $user->expects($this->once()) - ->method('getPassword') - ->willReturn('foo') - ; - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getUser') - ->willReturn($user); - - $dbUser = $this->createMock(TestUser::class); - $dbUser->expects($this->once()) - ->method('getPassword') - ->willReturn('newFoo') - ; - - $provider = $this->getProvider(); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - $reflection->invoke($provider, $dbUser, $token); - } - - public function testCheckAuthenticationWhenTokenNeedsReauthenticationWorksWithoutOriginalCredentials() - { - $user = $this->createMock(TestUser::class); - $user->expects($this->once()) - ->method('getPassword') - ->willReturn('foo') - ; - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getUser') - ->willReturn($user); - - $dbUser = $this->createMock(TestUser::class); - $dbUser->expects($this->once()) - ->method('getPassword') - ->willReturn('foo') - ; - - $provider = $this->getProvider(); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - $reflection->invoke($provider, $dbUser, $token); - } - - public function testCheckAuthentication() - { - $hasher = $this->createMock(PasswordHasherInterface::class); - $hasher->expects($this->once()) - ->method('verify') - ->willReturn(true) - ; - - $provider = $this->getProvider(null, null, $hasher); - $method = new \ReflectionMethod($provider, 'checkAuthentication'); - $method->setAccessible(true); - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getCredentials') - ->willReturn('foo') - ; - - $method->invoke($provider, new InMemoryUser('username', 'password'), $token); - } - - public function testPasswordUpgrades() - { - $user = new InMemoryUser('user', 'pwd'); - - $hasher = $this->createMock(PasswordHasherInterface::class); - $hasher->expects($this->once()) - ->method('verify') - ->willReturn(true) - ; - $hasher->expects($this->once()) - ->method('hash') - ->willReturn('foobar') - ; - $hasher->expects($this->once()) - ->method('needsRehash') - ->willReturn(true) - ; - - $provider = $this->getProvider(null, null, $hasher); - - $userProvider = ((array) $provider)[sprintf("\0%s\0userProvider", DaoAuthenticationProvider::class)]; - $userProvider->expects($this->once()) - ->method('upgradePassword') - ->with($user, 'foobar') - ; - - $method = new \ReflectionMethod($provider, 'checkAuthentication'); - $method->setAccessible(true); - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getCredentials') - ->willReturn('foo') - ; - - $method->invoke($provider, $user, $token); - } - - protected function getSupportedToken() - { - $mock = $this->getMockBuilder(UsernamePasswordToken::class)->setMethods(['getCredentials', 'getUser', 'getProviderKey'])->disableOriginalConstructor()->getMock(); - $mock - ->expects($this->any()) - ->method('getProviderKey') - ->willReturn('key') - ; - - return $mock; - } - - protected function getProvider($user = null, $userChecker = null, $passwordHasher = null, $userProvider = null) - { - if (null === $userProvider) { - $userProvider = $this->createMock(PasswordUpgraderProvider::class); - if (null !== $user) { - $userProvider->expects($this->once()) - ->method('loadUserByIdentifier') - ->willReturn($user) - ; - } - } - - if (null === $userChecker) { - $userChecker = $this->createMock(UserCheckerInterface::class); - } - - if (null === $passwordHasher) { - $passwordHasher = new PlaintextPasswordHasher(); - } - - $hasherFactory = $this->createMock(PasswordHasherFactoryInterface::class); - $hasherFactory - ->expects($this->any()) - ->method('getPasswordHasher') - ->willReturn($passwordHasher) - ; - - return new DaoAuthenticationProvider($userProvider, $userChecker, 'key', $hasherFactory); - } -} - -class TestUser implements PasswordAuthenticatedUserInterface, UserInterface -{ - public function getRoles(): array - { - return []; - } - - public function getPassword(): ?string - { - return 'secret'; - } - - public function getUsername(): string - { - return 'jane_doe'; - } - - public function getUserIdentifier(): string - { - return 'jane_doe'; - } - - public function eraseCredentials() - { - } -} -interface PasswordUpgraderProvider extends UserProviderInterface, PasswordUpgraderInterface -{ - public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void; - - public function loadUserByIdentifier(string $identifier): UserInterface; -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php deleted file mode 100644 index 5bad9611dadef..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Ldap\Adapter\CollectionInterface; -use Symfony\Component\Ldap\Adapter\QueryInterface; -use Symfony\Component\Ldap\Entry; -use Symfony\Component\Ldap\Exception\ConnectionException; -use Symfony\Component\Ldap\LdapInterface; -use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\InMemoryUserProvider; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -/** - * @requires extension ldap - * @group legacy - */ -class LdapBindAuthenticationProviderTest extends TestCase -{ - public function testEmptyPasswordShouldThrowAnException() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('The presented password must not be empty.'); - $userProvider = $this->createMock(UserProviderInterface::class); - $ldap = $this->createMock(LdapInterface::class); - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', '', 'key')); - } - - public function testNullPasswordShouldThrowAnException() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('The presented password must not be empty.'); - $userProvider = $this->createMock(UserProviderInterface::class); - $ldap = $this->createMock(LdapInterface::class); - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', null, 'key')); - } - - public function testBindFailureShouldThrowAnException() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('The presented password is invalid.'); - $userProvider = $this->createMock(UserProviderInterface::class); - $ldap = $this->createMock(LdapInterface::class); - $ldap - ->expects($this->once()) - ->method('bind') - ->willThrowException(new ConnectionException()) - ; - $ldap->method('escape')->willReturnArgument(0); - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', 'bar', 'key')); - } - - public function testRetrieveUser() - { - $userProvider = $this->createMock(InMemoryUserProvider::class); - $userProvider - ->expects($this->once()) - ->method('loadUserByIdentifier') - ->with('foo') - ; - $ldap = $this->createMock(LdapInterface::class); - - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap); - $reflection = new \ReflectionMethod($provider, 'retrieveUser'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, 'foo', new UsernamePasswordToken('foo', 'bar', 'key')); - } - - public function testQueryForDn() - { - $userProvider = $this->createMock(UserProviderInterface::class); - - $collection = new class([new Entry('')]) extends \ArrayObject implements CollectionInterface { - public function toArray(): array - { - return $this->getArrayCopy(); - } - }; - - $query = $this->createMock(QueryInterface::class); - $query - ->expects($this->once()) - ->method('execute') - ->willReturn($collection) - ; - - $ldap = $this->createMock(LdapInterface::class); - $ldap - ->method('bind') - ->withConsecutive( - ['elsa', 'test1234A$'] - ); - $ldap - ->expects($this->once()) - ->method('escape') - ->with('foo', '') - ->willReturn('foo') - ; - $ldap - ->expects($this->once()) - ->method('query') - ->with('{username}', 'foobar') - ->willReturn($query) - ; - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap, '{username}', true, 'elsa', 'test1234A$'); - $provider->setQueryString('{username}bar'); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', 'bar', 'key')); - } - - public function testQueryWithUserForDn() - { - $userProvider = $this->createMock(UserProviderInterface::class); - - $collection = new class([new Entry('')]) extends \ArrayObject implements CollectionInterface { - public function toArray(): array - { - return $this->getArrayCopy(); - } - }; - - $query = $this->createMock(QueryInterface::class); - $query - ->expects($this->once()) - ->method('execute') - ->willReturn($collection) - ; - - $ldap = $this->createMock(LdapInterface::class); - $ldap - ->method('bind') - ->withConsecutive( - ['elsa', 'test1234A$'] - ); - $ldap - ->expects($this->once()) - ->method('escape') - ->with('foo', '') - ->willReturn('foo') - ; - $ldap - ->expects($this->once()) - ->method('query') - ->with('{username}', 'foobar') - ->willReturn($query) - ; - - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap, '{username}', true, 'elsa', 'test1234A$'); - $provider->setQueryString('{username}bar'); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', 'bar', 'key')); - } - - public function testEmptyQueryResultShouldThrowAnException() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('The presented username is invalid.'); - $userProvider = $this->createMock(UserProviderInterface::class); - - $collection = $this->createMock(CollectionInterface::class); - - $query = $this->createMock(QueryInterface::class); - $query - ->expects($this->once()) - ->method('execute') - ->willReturn($collection) - ; - - $ldap = $this->createMock(LdapInterface::class); - $ldap - ->method('bind') - ->withConsecutive( - ['elsa', 'test1234A$'] - ); - $ldap - ->expects($this->once()) - ->method('query') - ->willReturn($query) - ; - $ldap->method('escape')->willReturnArgument(0); - $userChecker = $this->createMock(UserCheckerInterface::class); - - $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap, '{username}', true, 'elsa', 'test1234A$'); - $provider->setQueryString('{username}bar'); - $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); - $reflection->setAccessible(true); - - $reflection->invoke($provider, new InMemoryUser('foo', null), new UsernamePasswordToken('foo', 'bar', 'key')); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php deleted file mode 100644 index e178d9c73993c..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/PreAuthenticatedAuthenticationProviderTest.php +++ /dev/null @@ -1,140 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Authentication\Provider\PreAuthenticatedAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\LockedException; -use Symfony\Component\Security\Core\User\InMemoryUserProvider; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * @group legacy - */ -class PreAuthenticatedAuthenticationProviderTest extends TestCase -{ - public function testSupports() - { - $provider = $this->getProvider(); - - $this->assertTrue($provider->supports($this->getSupportedToken())); - $this->assertFalse($provider->supports($this->createMock(TokenInterface::class))); - - $token = $this->createMock(PreAuthenticatedToken::class); - $token - ->expects($this->once()) - ->method('getFirewallName') - ->willReturn('foo') - ; - $this->assertFalse($provider->supports($token)); - } - - public function testAuthenticateWhenTokenIsNotSupported() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessage('The token is not supported by this authentication provider.'); - $provider = $this->getProvider(); - - $provider->authenticate($this->createMock(TokenInterface::class)); - } - - public function testAuthenticateWhenNoUserIsSet() - { - $this->expectException(BadCredentialsException::class); - $provider = $this->getProvider(); - $provider->authenticate($this->getSupportedToken('')); - } - - public function testAuthenticate() - { - $user = $this->createMock(UserInterface::class); - $user - ->expects($this->once()) - ->method('getRoles') - ->willReturn([]) - ; - $provider = $this->getProvider($user); - - $token = $provider->authenticate($this->getSupportedToken('fabien', 'pass')); - $this->assertInstanceOf(PreAuthenticatedToken::class, $token); - $this->assertEquals('pass', $token->getCredentials()); - $this->assertEquals('key', $token->getFirewallName()); - $this->assertEquals([], $token->getRoleNames()); - $this->assertEquals(['foo' => 'bar'], $token->getAttributes(), '->authenticate() copies token attributes'); - $this->assertSame($user, $token->getUser()); - } - - public function testAuthenticateWhenUserCheckerThrowsException() - { - $this->expectException(LockedException::class); - $user = $this->createMock(UserInterface::class); - - $userChecker = $this->createMock(UserCheckerInterface::class); - $userChecker->expects($this->once()) - ->method('checkPostAuth') - ->willThrowException(new LockedException()) - ; - - $provider = $this->getProvider($user, $userChecker); - - $provider->authenticate($this->getSupportedToken('fabien')); - } - - protected function getSupportedToken($user = false, $credentials = false) - { - $token = $this->getMockBuilder(PreAuthenticatedToken::class)->setMethods(['getUser', 'getCredentials', 'getFirewallName'])->disableOriginalConstructor()->getMock(); - if (false !== $user) { - $token->expects($this->once()) - ->method('getUser') - ->willReturn($user) - ; - } - if (false !== $credentials) { - $token->expects($this->once()) - ->method('getCredentials') - ->willReturn($credentials) - ; - } - - $token - ->expects($this->any()) - ->method('getFirewallName') - ->willReturn('key') - ; - - $token->setAttributes(['foo' => 'bar']); - - return $token; - } - - protected function getProvider($user = null, $userChecker = null) - { - $userProvider = $this->createMock(InMemoryUserProvider::class); - if (null !== $user) { - $userProvider->expects($this->once()) - ->method('loadUserByIdentifier') - ->willReturn($user) - ; - } - - if (null === $userChecker) { - $userChecker = $this->createMock(UserCheckerInterface::class); - } - - return new PreAuthenticatedAuthenticationProvider($userProvider, $userChecker, 'key'); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php deleted file mode 100644 index 9a6a417b0dff6..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/RememberMeAuthenticationProviderTest.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\DisabledException; -use Symfony\Component\Security\Core\Exception\LogicException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * @group legacy - */ -class RememberMeAuthenticationProviderTest extends TestCase -{ - public function testSupports() - { - $provider = $this->getProvider(); - - $this->assertTrue($provider->supports($this->getSupportedToken())); - $this->assertFalse($provider->supports($this->createMock(TokenInterface::class))); - $this->assertFalse($provider->supports($this->createMock(RememberMeToken::class))); - } - - public function testAuthenticateWhenTokenIsNotSupported() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessage('The token is not supported by this authentication provider.'); - $provider = $this->getProvider(); - - $token = $this->createMock(TokenInterface::class); - $provider->authenticate($token); - } - - public function testAuthenticateWhenSecretsDoNotMatch() - { - $this->expectException(BadCredentialsException::class); - $provider = $this->getProvider(null, 'secret1'); - $token = $this->getSupportedToken(null, 'secret2'); - - $provider->authenticate($token); - } - - public function testAuthenticateThrowsOnNonUserInterfaceInstance() - { - $this->expectException(LogicException::class); - $this->expectExceptionMessage('Method "Symfony\Component\Security\Core\Authentication\Token\RememberMeToken::getUser()" must return a "Symfony\Component\Security\Core\User\UserInterface" instance, "string" returned.'); - - $provider = $this->getProvider(); - $token = new RememberMeToken(new InMemoryUser('dummyuser', null), 'foo', 'test'); - $token->setUser('stringish-user'); - $provider->authenticate($token); - } - - public function testAuthenticateWhenPreChecksFails() - { - $this->expectException(DisabledException::class); - $userChecker = $this->createMock(UserCheckerInterface::class); - $userChecker->expects($this->once()) - ->method('checkPreAuth') - ->willThrowException(new DisabledException()); - - $provider = $this->getProvider($userChecker); - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticate() - { - $user = $this->createMock(UserInterface::class); - $user->expects($this->exactly(2)) - ->method('getRoles') - ->willReturn(['ROLE_FOO']); - - $provider = $this->getProvider(); - - $token = $this->getSupportedToken($user); - $authToken = $provider->authenticate($token); - - $this->assertInstanceOf(RememberMeToken::class, $authToken); - $this->assertSame($user, $authToken->getUser()); - $this->assertEquals(['ROLE_FOO'], $authToken->getRoleNames()); - $this->assertEquals('', $authToken->getCredentials()); - } - - protected function getSupportedToken($user = null, $secret = 'test') - { - if (null === $user) { - $user = $this->createMock(UserInterface::class); - $user - ->expects($this->any()) - ->method('getRoles') - ->willReturn([]); - } - - $token = $this->getMockBuilder(RememberMeToken::class)->setMethods(['getFirewallName'])->setConstructorArgs([$user, 'foo', $secret])->getMock(); - $token - ->expects($this->once()) - ->method('getFirewallName') - ->willReturn('foo'); - - return $token; - } - - protected function getProvider($userChecker = null, $key = 'test') - { - if (null === $userChecker) { - $userChecker = $this->createMock(UserCheckerInterface::class); - } - - return new RememberMeAuthenticationProvider($userChecker, $key, 'foo'); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php deleted file mode 100644 index c4bcd8f580100..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php +++ /dev/null @@ -1,254 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider; -use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AccountExpiredException; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * @group legacy - */ -class UserAuthenticationProviderTest extends TestCase -{ - public function testSupports() - { - $provider = $this->getProvider(); - - $this->assertTrue($provider->supports($this->getSupportedToken())); - $this->assertFalse($provider->supports($this->createMock(TokenInterface::class))); - } - - public function testAuthenticateWhenTokenIsNotSupported() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessage('The token is not supported by this authentication provider.'); - $provider = $this->getProvider(); - - $provider->authenticate($this->createMock(TokenInterface::class)); - } - - public function testAuthenticateWhenUsernameIsNotFound() - { - $this->expectException(UserNotFoundException::class); - $provider = $this->getProvider(false, false); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willThrowException(new UserNotFoundException()) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenUsernameIsNotFoundAndHideIsTrue() - { - $this->expectException(BadCredentialsException::class); - $provider = $this->getProvider(false, true); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willThrowException(new UserNotFoundException()) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenCredentialsAreInvalidAndHideIsTrue() - { - $provider = $this->getProvider(); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($this->createMock(UserInterface::class)) - ; - $provider->expects($this->once()) - ->method('checkAuthentication') - ->willThrowException(new BadCredentialsException()) - ; - - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('Bad credentials.'); - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenProviderDoesNotReturnAnUserInterface() - { - $this->expectException(AuthenticationServiceException::class); - $provider = $this->getProvider(false, true); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn(null) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenPreChecksFails() - { - $this->expectException(BadCredentialsException::class); - $userChecker = $this->createMock(UserCheckerInterface::class); - $userChecker->expects($this->once()) - ->method('checkPreAuth') - ->willThrowException(new CredentialsExpiredException()) - ; - - $provider = $this->getProvider($userChecker); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($this->createMock(UserInterface::class)) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenPostChecksFails() - { - $this->expectException(BadCredentialsException::class); - $userChecker = $this->createMock(UserCheckerInterface::class); - $userChecker->expects($this->once()) - ->method('checkPostAuth') - ->willThrowException(new AccountExpiredException()) - ; - - $provider = $this->getProvider($userChecker); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($this->createMock(UserInterface::class)) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenPostCheckAuthenticationFails() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('Bad credentials'); - $provider = $this->getProvider(); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($this->createMock(UserInterface::class)) - ; - $provider->expects($this->once()) - ->method('checkAuthentication') - ->willThrowException(new CredentialsExpiredException()) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticateWhenPostCheckAuthenticationFailsWithHideFalse() - { - $this->expectException(BadCredentialsException::class); - $this->expectExceptionMessage('Foo'); - $provider = $this->getProvider(false, false); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($this->createMock(UserInterface::class)) - ; - $provider->expects($this->once()) - ->method('checkAuthentication') - ->willThrowException(new BadCredentialsException('Foo')) - ; - - $provider->authenticate($this->getSupportedToken()); - } - - public function testAuthenticate() - { - $user = $this->createMock(UserInterface::class); - $user->expects($this->once()) - ->method('getRoles') - ->willReturn(['ROLE_FOO']) - ; - - $provider = $this->getProvider(); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($user) - ; - - $token = $this->getSupportedToken(); - $token->expects($this->once()) - ->method('getCredentials') - ->willReturn('foo') - ; - - $authToken = $provider->authenticate($token); - - $this->assertInstanceOf(UsernamePasswordToken::class, $authToken); - $this->assertSame($user, $authToken->getUser()); - $this->assertEquals(['ROLE_FOO'], $authToken->getRoleNames()); - $this->assertEquals('foo', $authToken->getCredentials()); - $this->assertEquals(['foo' => 'bar'], $authToken->getAttributes(), '->authenticate() copies token attributes'); - } - - public function testAuthenticatePreservesOriginalToken() - { - $user = $this->createMock(UserInterface::class); - $user->expects($this->once()) - ->method('getRoles') - ->willReturn(['ROLE_FOO']) - ; - - $provider = $this->getProvider(); - $provider->expects($this->once()) - ->method('retrieveUser') - ->willReturn($user) - ; - - $originalToken = $this->createMock(TokenInterface::class); - $token = new SwitchUserToken(new InMemoryUser('wouter', null), 'foo', 'key', [], $originalToken); - $token->setAttributes(['foo' => 'bar']); - - $authToken = $provider->authenticate($token); - - $this->assertInstanceOf(SwitchUserToken::class, $authToken); - $this->assertSame($originalToken, $authToken->getOriginalToken()); - $this->assertSame($user, $authToken->getUser()); - $this->assertContains('ROLE_FOO', $authToken->getRoleNames()); - $this->assertEquals('foo', $authToken->getCredentials()); - $this->assertEquals(['foo' => 'bar'], $authToken->getAttributes(), '->authenticate() copies token attributes'); - } - - protected function getSupportedToken() - { - $mock = $this->getMockBuilder(UsernamePasswordToken::class)->setMethods(['getCredentials', 'getFirewallName', 'getRoles'])->disableOriginalConstructor()->getMock(); - $mock - ->expects($this->any()) - ->method('getFirewallName') - ->willReturn('key') - ; - - $mock->setAttributes(['foo' => 'bar']); - - return $mock; - } - - protected function getProvider($userChecker = false, $hide = true) - { - if (false === $userChecker) { - $userChecker = $this->createMock(UserCheckerInterface::class); - } - - return $this->getMockForAbstractClass(UserAuthenticationProvider::class, [$userChecker, 'key', $hide]); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php index 9df545a4c0c6e..1b05dc412db53 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/RememberMe/PersistentTokenTest.php @@ -12,13 +12,10 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\RememberMe; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; class PersistentTokenTest extends TestCase { - use ExpectDeprecationTrait; - public function testConstructor() { $lastUsed = new \DateTime(); @@ -30,15 +27,4 @@ public function testConstructor() $this->assertEquals('footokenvalue', $token->getTokenValue()); $this->assertSame($lastUsed, $token->getLastUsed()); } - - /** - * @group legacy - */ - public function testLegacyGetUsername() - { - $token = new PersistentToken('fooclass', 'fooname', 'fooseries', 'footokenvalue', new \DateTime()); - - $this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken::getUsername()" is deprecated, use getUserIdentifier() instead.'); - $this->assertEquals('fooname', $token->getUsername()); - } } 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 5bb53d7dafafe..b8e41d458043d 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php @@ -21,48 +21,6 @@ class AbstractTokenTest extends TestCase { use ExpectDeprecationTrait; - /** - * @group legacy - */ - public function testLegacyGetUsername() - { - $token = new ConcreteToken(['ROLE_FOO']); - $token->setUser('fabien'); - $this->assertEquals('fabien', $token->getUsername()); - - $token->setUser(new TestUser('fabien')); - $this->assertEquals('fabien', $token->getUsername()); - - $legacyUser = new class() implements UserInterface { - public function getUsername() - { - return 'fabien'; - } - - public function getRoles() - { - return []; - } - - public function getPassword() - { - } - - public function getSalt() - { - } - - public function eraseCredentials() - { - } - }; - $token->setUser($legacyUser); - $this->assertEquals('fabien', $token->getUsername()); - - $token->setUser($legacyUser); - $this->assertEquals('fabien', $token->getUserIdentifier()); - } - /** * @dataProvider provideUsers */ @@ -78,25 +36,6 @@ public function provideUsers() yield [new InMemoryUser('fabien', null), 'fabien']; } - /** - * @dataProvider provideLegacyUsers - * @group legacy - */ - public function testLegacyGetUserIdentifier($user, string $username) - { - $token = new ConcreteToken(['ROLE_FOO']); - $token->setUser($user); - $this->assertEquals($username, $token->getUserIdentifier()); - } - - public function provideLegacyUsers() - { - return [ - [new TestUser('fabien'), 'fabien'], - ['fabien', 'fabien'], - ]; - } - public function testEraseCredentials() { $token = new ConcreteToken(['ROLE_FOO']); @@ -125,21 +64,6 @@ public function testConstructor() $this->assertEquals(['ROLE_FOO'], $token->getRoleNames()); } - /** - * @group legacy - */ - public function testAuthenticatedFlag() - { - $token = new ConcreteToken(); - $this->assertFalse($token->isAuthenticated()); - - $token->setAuthenticated(true); - $this->assertTrue($token->isAuthenticated()); - - $token->setAuthenticated(false); - $this->assertFalse($token->isAuthenticated()); - } - public function testAttributes() { $attributes = ['foo' => 'bar']; @@ -171,75 +95,6 @@ public function testSetUser($user) $token->setUser($user); $this->assertSame($user, $token->getUser()); } - - /** - * @group legacy - * @dataProvider getUserChanges - */ - public function testSetUserSetsAuthenticatedToFalseWhenUserChanges($firstUser, $secondUser) - { - $token = new ConcreteToken(); - $token->setAuthenticated(true); - $this->assertTrue($token->isAuthenticated()); - - $token->setUser($firstUser); - $this->assertTrue($token->isAuthenticated()); - - $token->setUser($secondUser); - $this->assertFalse($token->isAuthenticated()); - } - - public function getUserChanges() - { - $user = $this->createMock(UserInterface::class); - - return [ - ['foo', 'bar'], - ['foo', new TestUser('bar')], - ['foo', $user], - [$user, 'foo'], - [$user, new TestUser('foo')], - [new TestUser('foo'), new TestUser('bar')], - [new TestUser('foo'), 'bar'], - [new TestUser('foo'), $user], - ]; - } - - /** - * @group legacy - * @dataProvider provideUsers - * @dataProvider provideLegacyUsers - */ - public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user) - { - $token = new ConcreteToken(); - $token->setAuthenticated(true); - $this->assertTrue($token->isAuthenticated()); - - $token->setUser($user); - $this->assertTrue($token->isAuthenticated()); - - $token->setUser($user); - $this->assertTrue($token->isAuthenticated()); - } - - /** - * @group legacy - */ - 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 diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AnonymousTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AnonymousTokenTest.php deleted file mode 100644 index 678b2d763c194..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/AnonymousTokenTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\Authentication\Token; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; - -/** - * @group legacy - */ -class AnonymousTokenTest extends TestCase -{ - public function testConstructor() - { - $token = new AnonymousToken('foo', 'bar', ['ROLE_FOO']); - $this->assertEquals(['ROLE_FOO'], $token->getRoleNames()); - } - - public function testIsAuthenticated() - { - $token = new AnonymousToken('foo', 'bar'); - $this->assertTrue($token->isAuthenticated()); - } - - public function testGetKey() - { - $token = new AnonymousToken('foo', 'bar'); - $this->assertEquals('foo', $token->getSecret()); - } - - public function testGetCredentials() - { - $token = new AnonymousToken('foo', 'bar'); - $this->assertEquals('', $token->getCredentials()); - } - - public function testGetUser() - { - $token = new AnonymousToken('foo', 'bar'); - $this->assertEquals('bar', $token->getUser()); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php index e6da2964bf9fd..dbbb5f70a7325 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/PreAuthenticatedTokenTest.php @@ -24,47 +24,9 @@ public function testConstructor() $this->assertEquals('key', $token->getFirewallName()); } - /** - * @group legacy - */ - public function testLegacyConstructor() - { - $token = new PreAuthenticatedToken('foo', 'bar', 'key', ['ROLE_FOO']); - $this->assertEquals(['ROLE_FOO'], $token->getRoleNames()); - $this->assertEquals('key', $token->getFirewallName()); - } - - /** - * @group legacy - */ - public function testGetCredentials() - { - $token = new PreAuthenticatedToken('foo', 'bar', 'key'); - $this->assertEquals('bar', $token->getCredentials()); - } - public function testGetUser() { $token = new PreAuthenticatedToken($user = new InMemoryUser('foo', 'bar'), 'key'); $this->assertEquals($user, $token->getUser()); } - - /** - * @group legacy - */ - public function testEraseCredentials() - { - $token = new PreAuthenticatedToken('foo', 'bar', 'key'); - $token->eraseCredentials(); - $this->assertNull($token->getCredentials()); - } - - /** - * @group legacy - */ - public function testIsAuthenticated() - { - $token = new PreAuthenticatedToken('foo', 'bar', 'key'); - $this->assertFalse($token->isAuthenticated()); - } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/RememberMeTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/RememberMeTokenTest.php index 42df233712ec9..a63d481b97022 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/RememberMeTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/RememberMeTokenTest.php @@ -28,16 +28,6 @@ public function testConstructor() $this->assertSame($user, $token->getUser()); } - /** - * @group legacy - */ - public function testIsAuthenticated() - { - $user = $this->getUser(); - $token = new RememberMeToken($user, 'fookey', 'foo'); - $this->assertTrue($token->isAuthenticated()); - } - public function testConstructorSecretCannotBeEmptyString() { $this->expectException(\InvalidArgumentException::class); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/Storage/UsageTrackingTokenStorageTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/Storage/UsageTrackingTokenStorageTest.php index 0d074bd4b040f..1d28cb2c3bf25 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/Storage/UsageTrackingTokenStorageTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/Storage/UsageTrackingTokenStorageTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\SessionInterface; @@ -24,8 +23,6 @@ class UsageTrackingTokenStorageTest extends TestCase { - use ExpectDeprecationTrait; - public function testGetSetToken() { $sessionAccess = 0; @@ -68,22 +65,4 @@ public function testGetSetToken() $this->assertSame($token, $trackingStorage->getToken()); $this->assertSame(1, $sessionAccess); } - - /** - * @group legacy - */ - public function testWithoutMainRequest() - { - $locator = new class(['request_stack' => function () { - return new RequestStack(); - }]) implements ContainerInterface { - use ServiceLocatorTrait; - }; - $tokenStorage = new TokenStorage(); - $trackingStorage = new UsageTrackingTokenStorage($tokenStorage, $locator); - $trackingStorage->enableUsageTracking(); - - $this->expectDeprecation('Since symfony/security-core 5.3: Using "%s" (service ID: "security.token_storage") outside the request-response cycle is deprecated, use the "%s" class (service ID: "security.untracked_token_storage") instead or disable usage tracking using "disableUsageTracking()".'); - $trackingStorage->getToken(); - } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/SwitchUserTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/SwitchUserTokenTest.php index ba7fdceba296c..a6d29a89602bc 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/SwitchUserTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/SwitchUserTokenTest.php @@ -41,74 +41,6 @@ public function testSerialize() $this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames()); } - /** - * @group legacy - */ - public function testLegacySerialize() - { - $originalToken = new UsernamePasswordToken('user', 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']); - $token = new SwitchUserToken('admin', 'bar', 'provider-key', ['ROLE_USER'], $originalToken, 'https://symfony.com/blog'); - - $unserializedToken = unserialize(serialize($token)); - - $this->assertInstanceOf(SwitchUserToken::class, $unserializedToken); - $this->assertSame('admin', $unserializedToken->getUserIdentifier()); - $this->assertSame('bar', $unserializedToken->getCredentials()); - $this->assertSame('provider-key', $unserializedToken->getFirewallName()); - $this->assertEquals(['ROLE_USER'], $unserializedToken->getRoleNames()); - $this->assertSame('https://symfony.com/blog', $unserializedToken->getOriginatedFromUri()); - - $unserializedOriginalToken = $unserializedToken->getOriginalToken(); - - $this->assertInstanceOf(UsernamePasswordToken::class, $unserializedOriginalToken); - $this->assertSame('user', $unserializedOriginalToken->getUserIdentifier()); - $this->assertSame('foo', $unserializedOriginalToken->getCredentials()); - $this->assertSame('provider-key', $unserializedOriginalToken->getFirewallName()); - $this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames()); - } - - /** - * @group legacy - */ - public function testSetUserDoesNotDeauthenticate() - { - $impersonated = new class() implements UserInterface { - public function getUsername() - { - return 'impersonated'; - } - - public function getUserIdentifier() - { - return 'impersonated'; - } - - public function getPassword() - { - return null; - } - - public function eraseCredentials() - { - } - - public function getRoles() - { - return ['ROLE_USER']; - } - - public function getSalt() - { - return null; - } - }; - - $originalToken = new UsernamePasswordToken(new InMemoryUser('impersonator', '', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']), 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']); - $token = new SwitchUserToken($impersonated, 'bar', 'provider-key', ['ROLE_USER', 'ROLE_PREVIOUS_ADMIN'], $originalToken); - $token->setUser($impersonated); - $this->assertTrue($token->isAuthenticated()); - } - public function testSerializeNullImpersonateUrl() { $originalToken = new UsernamePasswordToken(new InMemoryUser('user', 'foo', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']), 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']); @@ -119,19 +51,6 @@ public function testSerializeNullImpersonateUrl() $this->assertNull($unserializedToken->getOriginatedFromUri()); } - /** - * @group legacy - */ - public function testLegacySerializeNullImpersonateUrl() - { - $originalToken = new UsernamePasswordToken('user', 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']); - $token = new SwitchUserToken('admin', 'bar', 'provider-key', ['ROLE_USER'], $originalToken); - - $unserializedToken = unserialize(serialize($token)); - - $this->assertNull($unserializedToken->getOriginatedFromUri()); - } - /** * Tests if an old version of SwitchUserToken can still be unserialized. * @@ -162,7 +81,6 @@ public function testUnserializeOldToken() self::assertInstanceOf(UsernamePasswordToken::class, $token->getOriginalToken()); self::assertInstanceOf(CustomUser::class, $token->getUser()); self::assertSame('john', $token->getUserIdentifier()); - self::assertSame(['foo' => 'bar'], $token->getCredentials()); self::assertSame('main', $token->getFirewallName()); self::assertEquals(['ROLE_USER'], $token->getRoleNames()); self::assertNull($token->getOriginatedFromUri()); diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php index 28b1a61fb5812..91faed0c69ebe 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Token/UsernamePasswordTokenTest.php @@ -24,62 +24,9 @@ public function testConstructor() $this->assertEquals('key', $token->getFirewallName()); } - /** - * @group legacy - */ - public function testLegacyConstructor() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key', ['ROLE_FOO']); - $this->assertEquals(['ROLE_FOO'], $token->getRoleNames()); - $this->assertEquals('bar', $token->getCredentials()); - $this->assertEquals('key', $token->getFirewallName()); - } - - /** - * @group legacy - */ - public function testIsAuthenticated() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - $this->assertFalse($token->isAuthenticated()); - - $token = new UsernamePasswordToken('foo', 'bar', 'key', ['ROLE_FOO']); - $this->assertTrue($token->isAuthenticated()); - } - - /** - * @group legacy - */ - public function testSetAuthenticatedToTrue() - { - $this->expectException(\LogicException::class); - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - $token->setAuthenticated(true); - } - - /** - * @group legacy - */ - public function testSetAuthenticatedToFalse() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - $token->setAuthenticated(false); - $this->assertFalse($token->isAuthenticated()); - } - - /** - * @group legacy - */ - public function testEraseCredentials() - { - $token = new UsernamePasswordToken('foo', 'bar', 'key'); - $token->eraseCredentials(); - $this->assertEquals('', $token->getCredentials()); - } - public function testToString() { $token = new UsernamePasswordToken(new InMemoryUser('foo', '', ['A', 'B']), 'foo', ['A', 'B']); - $this->assertEquals('UsernamePasswordToken(user="foo", authenticated=true, roles="A, B")', (string) $token); + $this->assertEquals('UsernamePasswordToken(user="foo", roles="A, B")', (string) $token); } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/AccessDecisionManagerTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/AccessDecisionManagerTest.php index 375fb6d6d49ef..b86811bb4a66f 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/AccessDecisionManagerTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/AccessDecisionManagerTest.php @@ -38,20 +38,6 @@ public function testStrategies($strategy, $voters, $allowIfAllAbstainDecisions, $this->assertSame($expected, $manager->decide($token, ['ROLE_FOO'])); } - /** - * @dataProvider provideStrategies - * @group legacy - */ - public function testDeprecatedVoter($strategy) - { - $token = $this->createMock(TokenInterface::class); - $manager = new AccessDecisionManager([$this->getVoter(3)], $strategy); - - $this->expectDeprecation('Since symfony/security-core 5.3: Returning "3" in "%s::vote()" is deprecated, return one of "Symfony\Component\Security\Core\Authorization\Voter\VoterInterface" constants: "ACCESS_GRANTED", "ACCESS_DENIED" or "ACCESS_ABSTAIN".'); - - $manager->decide($token, ['ROLE_FOO']); - } - public function getStrategyTests() { return [ @@ -112,14 +98,6 @@ public function getStrategyTests() ]; } - public function provideStrategies() - { - yield [AccessDecisionManager::STRATEGY_AFFIRMATIVE]; - yield [AccessDecisionManager::STRATEGY_CONSENSUS]; - yield [AccessDecisionManager::STRATEGY_UNANIMOUS]; - yield [AccessDecisionManager::STRATEGY_PRIORITY]; - } - protected function getVoters($grants, $denies, $abstains) { $voters = []; diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php index 160b921b3075c..a3dd46a19e0a2 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/AuthorizationCheckerTest.php @@ -23,7 +23,6 @@ class AuthorizationCheckerTest extends TestCase { - private $authenticationManager; private $accessDecisionManager; private $authorizationChecker; private $tokenStorage; @@ -33,75 +32,18 @@ protected function setUp(): void $this->accessDecisionManager = $this->createMock(AccessDecisionManagerInterface::class); $this->tokenStorage = new TokenStorage(); - $this->authorizationChecker = new AuthorizationChecker( - $this->tokenStorage, - $this->accessDecisionManager, - false, - false - ); + $this->authorizationChecker = new AuthorizationChecker($this->tokenStorage, $this->accessDecisionManager); } - /** - * @group legacy - */ - public function testVoteAuthenticatesTokenIfNecessary() - { - $token = new UsernamePasswordToken('username', 'password', 'provider'); - $this->tokenStorage->setToken($token); - - $newToken = new UsernamePasswordToken('username', 'password', 'provider'); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $this->authorizationChecker = new AuthorizationChecker($this->tokenStorage, $authenticationManager, $this->accessDecisionManager, false, false); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->equalTo($token)) - ->willReturn($newToken); - - // default with() isn't a strict check - $tokenComparison = function ($value) use ($newToken) { - // make sure that the new token is used in "decide()" and not the old one - return $value === $newToken; - }; - - $this->accessDecisionManager - ->expects($this->once()) - ->method('decide') - ->with($this->callback($tokenComparison)) - ->willReturn(true); - - // first run the token has not been re-authenticated yet, after isGranted is called, it should be equal - $this->assertNotSame($newToken, $this->tokenStorage->getToken()); - $this->assertTrue($this->authorizationChecker->isGranted('foo')); - $this->assertSame($newToken, $this->tokenStorage->getToken()); - } - - /** - * @group legacy - */ - public function testLegacyVoteWithoutAuthenticationToken() + public function testVoteWithoutAuthenticationToken() { $authorizationChecker = new AuthorizationChecker($this->tokenStorage, $this->accessDecisionManager); - $this->expectException(AuthenticationCredentialsNotFoundException::class); + $this->accessDecisionManager->expects($this->once())->method('decide')->with($this->isInstanceOf(NullToken::class))->willReturn(false); $authorizationChecker->isGranted('ROLE_FOO'); } - public function testVoteWithoutAuthenticationToken() - { - $authorizationChecker = new AuthorizationChecker($this->tokenStorage, $this->accessDecisionManager, false, false); - - $this->accessDecisionManager - ->expects($this->once()) - ->method('decide') - ->with($this->isInstanceOf(NullToken::class)) - ->willReturn(true); - - $this->assertTrue($authorizationChecker->isGranted('ANONYMOUS')); - } - /** * @dataProvider isGrantedProvider */ diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php index c76ca77dfbbf5..e13667329fbe4 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/ExpressionLanguageTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; @@ -36,7 +35,7 @@ public function testIsAuthenticated($token, $expression, $result) $tokenStorage = new TokenStorage(); $tokenStorage->setToken($token); $accessDecisionManager = new AccessDecisionManager([new RoleVoter(), new AuthenticatedVoter($trustResolver)]); - $authChecker = new AuthorizationChecker($tokenStorage, $accessDecisionManager, false, false); + $authChecker = new AuthorizationChecker($tokenStorage, $accessDecisionManager); $context = []; $context['auth_checker'] = $authChecker; @@ -72,35 +71,4 @@ public function provider() [$usernamePasswordToken, "is_granted('ROLE_USER')", true], ]; } - - /** - * @dataProvider legacyProvider - * @group legacy - */ - public function testLegacyIsAuthenticated($token, $expression, $result) - { - $this->testIsAuthenticated($token, $expression, $result); - } - - /** - * @group legacy - */ - public function legacyProvider() - { - $roles = ['ROLE_USER', 'ROLE_ADMIN']; - $user = new InMemoryUser('username', 'password', $roles); - $anonymousToken = new AnonymousToken('firewall', 'anon.'); - - return [ - [$anonymousToken, 'is_anonymous()', true], - [$anonymousToken, 'is_authenticated()', false], - [$anonymousToken, 'is_fully_authenticated()', false], - [$anonymousToken, 'is_remember_me()', false], - [$anonymousToken, "is_granted('ROLE_USER')", false], - - [null, 'is_anonymous()', false], - [new RememberMeToken($user, 'firewall-name', 'firewall'), 'is_anonymous()', false], - [new UsernamePasswordToken($user, 'firewall-name', $roles), 'is_anonymous()', false], - ]; - } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php index c2de6c1fca440..346568c2909cb 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/AuthenticatedVoterTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -52,36 +51,6 @@ public function getVoteTests() ]; } - /** - * @group legacy - * @dataProvider getLegacyVoteTests - */ - public function testLegacyVote($authenticated, $attributes, $expected) - { - $this->testVote($authenticated, $attributes, $expected); - } - - public function getLegacyVoteTests() - { - return [ - ['anonymously', [], VoterInterface::ACCESS_ABSTAIN], - ['anonymously', ['FOO'], VoterInterface::ACCESS_ABSTAIN], - ['anonymously', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ['anonymously', ['IS_AUTHENTICATED_REMEMBERED'], VoterInterface::ACCESS_DENIED], - ['anonymously', ['IS_AUTHENTICATED_FULLY'], VoterInterface::ACCESS_DENIED], - ['anonymously', ['IS_ANONYMOUS'], VoterInterface::ACCESS_GRANTED], - ['anonymously', ['IS_IMPERSONATOR'], VoterInterface::ACCESS_DENIED], - - ['fully', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], - ['remembered', ['IS_ANONYMOUS'], VoterInterface::ACCESS_DENIED], - ['anonymously', ['IS_ANONYMOUS'], VoterInterface::ACCESS_GRANTED], - - ['fully', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ['remembered', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ['anonymously', ['IS_AUTHENTICATED_ANONYMOUSLY'], VoterInterface::ACCESS_GRANTED], - ]; - } - protected function getToken($authenticated) { if ('fully' === $authenticated) { @@ -90,8 +59,6 @@ protected function getToken($authenticated) return $this->getMockBuilder(RememberMeToken::class)->setMethods(['setPersistent'])->disableOriginalConstructor()->getMock(); } elseif ('impersonated' === $authenticated) { return $this->getMockBuilder(SwitchUserToken::class)->disableOriginalConstructor()->getMock(); - } else { - return $this->getMockBuilder(AnonymousToken::class)->setConstructorArgs(['', ''])->getMock(); } } } diff --git a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php index 43f802481e413..c0a1389575970 100644 --- a/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Authorization/Voter/RoleVoterTest.php @@ -47,17 +47,6 @@ public function getVoteTests() ]; } - /** - * @group legacy - */ - public function testDeprecatedRolePreviousAdmin() - { - $this->expectDeprecation('Since symfony/security-core 5.1: The ROLE_PREVIOUS_ADMIN role is deprecated and will be removed in version 6.0, use the IS_IMPERSONATOR attribute instead.'); - $voter = new RoleVoter(); - - $voter->vote($this->getTokenWithRoleNames(['ROLE_USER', 'ROLE_PREVIOUS_ADMIN']), null, ['ROLE_PREVIOUS_ADMIN']); - } - protected function getTokenWithRoleNames(array $roles) { $token = $this->createMock(AbstractToken::class); diff --git a/src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php b/src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php index 2ed708508a4b5..a081034a3b397 100644 --- a/src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Exception/CustomUserMessageAuthenticationExceptionTest.php @@ -44,7 +44,7 @@ public function testConstructWithSAfeMessage() public function testSharedSerializedData() { - $token = new UsernamePasswordToken(new InMemoryUser('foo', ''), 'bar'); + $token = new UsernamePasswordToken(new InMemoryUser('foo', 'bar', ['ROLE_USER']), 'main', ['ROLE_USER']); $exception = new CustomUserMessageAuthenticationException(); $exception->setToken($token); @@ -58,7 +58,7 @@ public function testSharedSerializedData() public function testSharedSerializedDataFromChild() { - $token = new UsernamePasswordToken(new InMemoryUser('foo', ''), 'bar'); + $token = new UsernamePasswordToken(new InMemoryUser('foo', 'bar', ['ROLE_USER']), 'main', ['ROLE_USER']); $exception = new ChildCustomUserMessageAuthenticationException(); $exception->childMember = $token; diff --git a/src/Symfony/Component/Security/Core/Tests/Exception/UserNotFoundExceptionTest.php b/src/Symfony/Component/Security/Core/Tests/Exception/UserNotFoundExceptionTest.php index 3d9de8f14a2ef..f526b37f31e0b 100644 --- a/src/Symfony/Component/Security/Core/Tests/Exception/UserNotFoundExceptionTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Exception/UserNotFoundExceptionTest.php @@ -31,26 +31,4 @@ public function testUserIdentifierIsNotSetByDefault() $this->assertNull($exception->getUserIdentifier()); } - - /** - * @group legacy - */ - public function testUsernameIsNotSetByDefault() - { - $exception = new UserNotFoundException(); - - $this->assertNull($exception->getUsername()); - } - - /** - * @group legacy - */ - public function testUsernameNotFoundException() - { - $exception = new UsernameNotFoundException(); - $this->assertInstanceOf(UserNotFoundException::class, $exception); - - $exception->setUsername('username'); - $this->assertEquals('username', $exception->getUserIdentifier()); - } } diff --git a/src/Symfony/Component/Security/Core/Tests/SecurityTest.php b/src/Symfony/Component/Security/Core/Tests/SecurityTest.php index e1398fa45108d..53dd23b20b175 100644 --- a/src/Symfony/Component/Security/Core/Tests/SecurityTest.php +++ b/src/Symfony/Component/Security/Core/Tests/SecurityTest.php @@ -39,7 +39,6 @@ public function testGetToken() /** * @dataProvider getUserTests - * @dataProvider getLegacyUserTests */ public function testGetUser($userInToken, $expectedUser) { @@ -67,16 +66,6 @@ public function getUserTests() yield [$user, $user]; } - /** - * @group legacy - */ - public function getLegacyUserTests() - { - yield ['string_username', null]; - - yield [new StringishUser(), null]; - } - public function testIsGranted() { $authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class); diff --git a/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserProviderTest.php b/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserProviderTest.php index d4d4964c7be59..aa058bbaa24aa 100644 --- a/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserProviderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserProviderTest.php @@ -44,22 +44,6 @@ public function testRefresh() $this->assertFalse($refreshedUser->isEnabled()); } - /** - * @group legacy - */ - public function testRefreshWithLegacyUser() - { - $user = new User('fabien', 'bar'); - - $provider = $this->createProvider(); - - $refreshedUser = $provider->refreshUser($user); - $this->assertEquals('foo', $refreshedUser->getPassword()); - $this->assertEquals(['ROLE_USER'], $refreshedUser->getRoles()); - $this->assertFalse($refreshedUser->isEnabled()); - $this->assertFalse($refreshedUser->isCredentialsNonExpired()); - } - protected function createProvider(): InMemoryUserProvider { return new InMemoryUserProvider([ diff --git a/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserTest.php b/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserTest.php index a5496ef325b85..fb80374730f9c 100644 --- a/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserTest.php +++ b/src/Symfony/Component/Security/Core/Tests/User/InMemoryUserTest.php @@ -42,29 +42,12 @@ public function testGetPassword() $this->assertEquals('superpass', $user->getPassword()); } - /** - * @group legacy - */ - public function testGetUsername() - { - $user = new InMemoryUser('fabien', 'superpass'); - - $this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\User\User::getUsername()" is deprecated, use getUserIdentifier() instead.'); - $this->assertEquals('fabien', $user->getUsername()); - } - public function testGetUserIdentifier() { $user = new InMemoryUser('fabien', 'superpass'); $this->assertEquals('fabien', $user->getUserIdentifier()); } - public function testGetSalt() - { - $user = new InMemoryUser('fabien', 'superpass'); - $this->assertNull($user->getSalt()); - } - public function testIsEnabled() { $user = new InMemoryUser('mathilde', 'k'); @@ -90,9 +73,9 @@ public function testToString() /** * @dataProvider isEqualToData * - * @param bool $expectation - * @param EquatableInterface|UserInterface $a - * @param EquatableInterface|UserInterface $b + * @param bool $expectation + * @param UserInterface $a + * @param UserInterface $b */ public function testIsEqualTo($expectation, $a, $b) { diff --git a/src/Symfony/Component/Security/Core/Tests/User/UserCheckerTest.php b/src/Symfony/Component/Security/Core/Tests/User/UserCheckerTest.php deleted file mode 100644 index 728d935b3ffa8..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/User/UserCheckerTest.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\User; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Exception\AccountExpiredException; -use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; -use Symfony\Component\Security\Core\Exception\DisabledException; -use Symfony\Component\Security\Core\Exception\LockedException; -use Symfony\Component\Security\Core\User\User; -use Symfony\Component\Security\Core\User\UserChecker; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * @group legacy - */ -class UserCheckerTest extends TestCase -{ - public function testCheckPostAuthNotAdvancedUserInterface() - { - $checker = new UserChecker(); - - $this->assertNull($checker->checkPostAuth($this->createMock(UserInterface::class))); - } - - public function testCheckPostAuthPass() - { - $checker = new UserChecker(); - $this->assertNull($checker->checkPostAuth(new User('John', 'password'))); - } - - public function testCheckPostAuthCredentialsExpired() - { - $this->expectException(CredentialsExpiredException::class); - $checker = new UserChecker(); - $checker->checkPostAuth(new User('John', 'password', [], true, true, false, true)); - } - - public function testCheckPreAuthAccountLocked() - { - $this->expectException(LockedException::class); - $checker = new UserChecker(); - $checker->checkPreAuth(new User('John', 'password', [], true, true, false, false)); - } - - public function testCheckPreAuthDisabled() - { - $this->expectException(DisabledException::class); - $checker = new UserChecker(); - $checker->checkPreAuth(new User('John', 'password', [], false, true, false, true)); - } - - public function testCheckPreAuthAccountExpired() - { - $this->expectException(AccountExpiredException::class); - $checker = new UserChecker(); - $checker->checkPreAuth(new User('John', 'password', [], true, false, true, true)); - } -} diff --git a/src/Symfony/Component/Security/Core/Tests/User/UserTest.php b/src/Symfony/Component/Security/Core/Tests/User/UserTest.php deleted file mode 100644 index 81b8705d1041f..0000000000000 --- a/src/Symfony/Component/Security/Core/Tests/User/UserTest.php +++ /dev/null @@ -1,152 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Tests\User; - -use PHPUnit\Framework\TestCase; -use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; -use Symfony\Component\Security\Core\User\EquatableInterface; -use Symfony\Component\Security\Core\User\User; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * @group legacy - */ -class UserTest extends TestCase -{ - use ExpectDeprecationTrait; - - public function testConstructorException() - { - $this->expectException(\InvalidArgumentException::class); - new User('', 'superpass'); - } - - public function testGetRoles() - { - $user = new User('fabien', 'superpass'); - $this->assertEquals([], $user->getRoles()); - - $user = new User('fabien', 'superpass', ['ROLE_ADMIN']); - $this->assertEquals(['ROLE_ADMIN'], $user->getRoles()); - } - - public function testGetPassword() - { - $user = new User('fabien', 'superpass'); - $this->assertEquals('superpass', $user->getPassword()); - } - - /** - * @group legacy - */ - public function testGetUsername() - { - $user = new User('fabien', 'superpass'); - - $this->expectDeprecation('Since symfony/security-core 5.3: Method "Symfony\Component\Security\Core\User\User::getUsername()" is deprecated, use getUserIdentifier() instead.'); - $this->assertEquals('fabien', $user->getUsername()); - } - - public function testGetUserIdentifier() - { - $user = new User('fabien', 'superpass'); - $this->assertEquals('fabien', $user->getUserIdentifier()); - } - - public function testGetSalt() - { - $user = new User('fabien', 'superpass'); - $this->assertEquals('', $user->getSalt()); - } - - public function testIsAccountNonExpired() - { - $user = new User('fabien', 'superpass'); - $this->assertTrue($user->isAccountNonExpired()); - - $user = new User('fabien', 'superpass', [], true, false); - $this->assertFalse($user->isAccountNonExpired()); - } - - public function testIsCredentialsNonExpired() - { - $user = new User('fabien', 'superpass'); - $this->assertTrue($user->isCredentialsNonExpired()); - - $user = new User('fabien', 'superpass', [], true, true, false); - $this->assertFalse($user->isCredentialsNonExpired()); - } - - public function testIsAccountNonLocked() - { - $user = new User('fabien', 'superpass'); - $this->assertTrue($user->isAccountNonLocked()); - - $user = new User('fabien', 'superpass', [], true, true, true, false); - $this->assertFalse($user->isAccountNonLocked()); - } - - public function testIsEnabled() - { - $user = new User('fabien', 'superpass'); - $this->assertTrue($user->isEnabled()); - - $user = new User('fabien', 'superpass', [], false); - $this->assertFalse($user->isEnabled()); - } - - public function testEraseCredentials() - { - $user = new User('fabien', 'superpass'); - $user->eraseCredentials(); - $this->assertEquals('superpass', $user->getPassword()); - } - - public function testToString() - { - $user = new User('fabien', 'superpass'); - $this->assertEquals('fabien', (string) $user); - } - - /** - * @dataProvider isEqualToData - * - * @param bool $expectation - * @param EquatableInterface|UserInterface $a - * @param EquatableInterface|UserInterface $b - */ - public function testIsEqualTo($expectation, $a, $b) - { - $this->assertSame($expectation, $a->isEqualTo($b)); - $this->assertSame($expectation, $b->isEqualTo($a)); - } - - public static function isEqualToData() - { - return [ - [true, new User('username', 'password'), new User('username', 'password')], - [false, new User('username', 'password', ['ROLE']), new User('username', 'password')], - [false, new User('username', 'password', ['ROLE']), new User('username', 'password', ['NO ROLE'])], - [false, new User('diff', 'diff'), new User('username', 'password')], - [false, new User('diff', 'diff', [], false), new User('username', 'password')], - [false, new User('diff', 'diff', [], false, false), new User('username', 'password')], - [false, new User('diff', 'diff', [], false, false, false), new User('username', 'password')], - [false, new User('diff', 'diff', [], false, false, false, false), new User('username', 'password')], - ]; - } - - public function testIsEqualToWithDifferentUser() - { - $user = new User('username', 'password'); - $this->assertFalse($user->isEqualTo($this->createMock(UserInterface::class))); - } -} diff --git a/src/Symfony/Component/Security/Core/User/ChainUserProvider.php b/src/Symfony/Component/Security/Core/User/ChainUserProvider.php index 8ef3a5a0e5aac..6a6f28338f6b6 100644 --- a/src/Symfony/Component/Security/Core/User/ChainUserProvider.php +++ b/src/Symfony/Component/Security/Core/User/ChainUserProvider.php @@ -47,12 +47,10 @@ public function getProviders() } /** - * {@inheritdoc} + * @internal for compatibility with Symfony 5.4 */ public function loadUserByUsername(string $username) { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__); - return $this->loadUserByIdentifier($username); } @@ -60,13 +58,6 @@ public function loadUserByIdentifier(string $identifier): UserInterface { foreach ($this->providers as $provider) { try { - // @deprecated since Symfony 5.3, change to $provider->loadUserByIdentifier() in 6.0 - if (!method_exists($provider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($provider)); - - return $provider->loadUserByUsername($identifier); - } - return $provider->loadUserByIdentifier($identifier); } catch (UserNotFoundException $e) { // try next one @@ -101,8 +92,7 @@ public function refreshUser(UserInterface $user) } if ($supportedUserFound) { - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - $username = method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(); + $username = $user->getUserIdentifier(); $e = new UserNotFoundException(sprintf('There is no user with name "%s".', $username)); $e->setUserIdentifier($username); throw $e; diff --git a/src/Symfony/Component/Security/Core/User/InMemoryUser.php b/src/Symfony/Component/Security/Core/User/InMemoryUser.php index 39da71e37457e..c1595955c1abe 100644 --- a/src/Symfony/Component/Security/Core/User/InMemoryUser.php +++ b/src/Symfony/Component/Security/Core/User/InMemoryUser.php @@ -19,58 +19,104 @@ * @author Robin Chalas * @author Fabien Potencier */ -final class InMemoryUser extends User +final class InMemoryUser implements UserInterface, PasswordAuthenticatedUserInterface, EquatableInterface { + private $username; + private $password; + private $enabled; + private $roles; + + public function __construct(?string $username, ?string $password, array $roles = [], bool $enabled = true) + { + if ('' === $username || null === $username) { + throw new \InvalidArgumentException('The username cannot be empty.'); + } + + $this->username = $username; + $this->password = $password; + $this->enabled = $enabled; + $this->roles = $roles; + } + + public function __toString(): string + { + return $this->getUserIdentifier(); + } + /** * {@inheritdoc} - * - * @deprecated since Symfony 5.3 */ - public function isAccountNonExpired(): bool + public function getRoles(): array { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, you should stop using it.', __METHOD__); - - return parent::isAccountNonExpired(); + return $this->roles; } /** * {@inheritdoc} - * - * @deprecated since Symfony 5.3 */ - public function isAccountNonLocked(): bool + public function getPassword(): ?string { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, you should stop using it.', __METHOD__); + return $this->password; + } - return parent::isAccountNonLocked(); + /** + * Returns the identifier for this user (e.g. its username or e-mailaddress). + */ + public function getUserIdentifier(): string + { + return $this->username; } /** - * {@inheritdoc} + * Checks whether the user is enabled. + * + * Internally, if this method returns false, the authentication system + * will throw a DisabledException and prevent login. + * + * @return bool true if the user is enabled, false otherwise * - * @deprecated since Symfony 5.3 + * @see DisabledException */ - public function isCredentialsNonExpired(): bool + public function isEnabled(): bool { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, you should stop using it.', __METHOD__); - - return parent::isCredentialsNonExpired(); + return $this->enabled; } /** - * @deprecated since Symfony 5.3 + * {@inheritdoc} */ - public function getExtraFields(): array + public function eraseCredentials() { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, you should stop using it.', __METHOD__); - - return parent::getExtraFields(); } - public function setPassword(string $password) + /** + * {@inheritdoc} + */ + public function isEqualTo(UserInterface $user): bool { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, you should stop using it.', __METHOD__); + if (!$user instanceof self) { + return false; + } + + if ($this->getPassword() !== $user->getPassword()) { + return false; + } + + $currentRoles = array_map('strval', (array) $this->getRoles()); + $newRoles = array_map('strval', (array) $user->getRoles()); + $rolesChanged = \count($currentRoles) !== \count($newRoles) || \count($currentRoles) !== \count(array_intersect($currentRoles, $newRoles)); + if ($rolesChanged) { + return false; + } + + if ($this->getUserIdentifier() !== $user->getUserIdentifier()) { + return false; + } + + if ($this->isEnabled() !== $user->isEnabled()) { + return false; + } - parent::setPassword($password); + return true; } } diff --git a/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php b/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php index b35e6303f6f82..5649cc990e467 100644 --- a/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php +++ b/src/Symfony/Component/Security/Core/User/InMemoryUserChecker.php @@ -25,9 +25,7 @@ class InMemoryUserChecker implements UserCheckerInterface { public function checkPreAuth(UserInterface $user) { - // @deprecated since Symfony 5.3, in 6.0 change to: - // if (!$user instanceof InMemoryUser) { - if (!$user instanceof InMemoryUser && !$user instanceof User) { + if (!$user instanceof InMemoryUser) { return; } @@ -36,38 +34,9 @@ public function checkPreAuth(UserInterface $user) $ex->setUser($user); throw $ex; } - - // @deprecated since Symfony 5.3 - if (User::class === \get_class($user)) { - if (!$user->isAccountNonLocked()) { - $ex = new LockedException('User account is locked.'); - $ex->setUser($user); - throw $ex; - } - - if (!$user->isAccountNonExpired()) { - $ex = new AccountExpiredException('User account has expired.'); - $ex->setUser($user); - throw $ex; - } - } } public function checkPostAuth(UserInterface $user) { - // @deprecated since Symfony 5.3, noop in 6.0 - if (User::class !== \get_class($user)) { - return; - } - - if (!$user->isCredentialsNonExpired()) { - $ex = new CredentialsExpiredException('User credentials have expired.'); - $ex->setUser($user); - throw $ex; - } } } - -if (!class_exists(UserChecker::class, false)) { - class_alias(InMemoryUserChecker::class, UserChecker::class); -} diff --git a/src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php b/src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php index d077939471aa5..a472a6b160ff3 100644 --- a/src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php +++ b/src/Symfony/Component/Security/Core/User/InMemoryUserProvider.php @@ -51,8 +51,7 @@ public function __construct(array $users = []) */ public function createUser(UserInterface $user) { - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - $userIdentifier = strtolower(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername()); + $userIdentifier = strtolower($user->getUserIdentifier()); if (isset($this->users[$userIdentifier])) { throw new \LogicException('Another user with the same username already exists.'); } @@ -60,22 +59,11 @@ public function createUser(UserInterface $user) $this->users[$userIdentifier] = $user; } - /** - * {@inheritdoc} - */ - public function loadUserByUsername(string $username) - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use loadUserByIdentifier() instead.', __METHOD__); - - return $this->loadUserByIdentifier($username); - } - public function loadUserByIdentifier(string $identifier): UserInterface { $user = $this->getUser($identifier); - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - return new InMemoryUser(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $user->getPassword(), $user->getRoles(), $user->isEnabled()); + return new InMemoryUser($user->getUserIdentifier(), $user->getPassword(), $user->getRoles(), $user->isEnabled()); } /** @@ -83,28 +71,12 @@ public function loadUserByIdentifier(string $identifier): UserInterface */ public function refreshUser(UserInterface $user) { - if (!$user instanceof InMemoryUser && !$user instanceof User) { + if (!$user instanceof InMemoryUser) { throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user))); } - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - $storedUser = $this->getUser(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername()); - $userIdentifier = method_exists($storedUser, 'getUserIdentifier') ? $storedUser->getUserIdentifier() : $storedUser->getUsername(); - - // @deprecated since Symfony 5.3 - if (User::class === \get_class($user)) { - if (User::class !== \get_class($storedUser)) { - $accountNonExpired = true; - $credentialsNonExpired = $storedUser->getPassword() === $user->getPassword(); - $accountNonLocked = true; - } else { - $accountNonExpired = $storedUser->isAccountNonExpired(); - $credentialsNonExpired = $storedUser->isCredentialsNonExpired() && $storedUser->getPassword() === $user->getPassword(); - $accountNonLocked = $storedUser->isAccountNonLocked(); - } - - return new User($userIdentifier, $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled(), $accountNonExpired, $credentialsNonExpired, $accountNonLocked); - } + $storedUser = $this->getUser($user->getUserIdentifier()); + $userIdentifier = $storedUser->getUserIdentifier(); return new InMemoryUser($userIdentifier, $storedUser->getPassword(), $storedUser->getRoles(), $storedUser->isEnabled()); } @@ -114,11 +86,6 @@ public function refreshUser(UserInterface $user) */ public function supportsClass(string $class) { - // @deprecated since Symfony 5.3 - if (User::class === $class) { - return true; - } - return InMemoryUser::class == $class; } diff --git a/src/Symfony/Component/Security/Core/User/User.php b/src/Symfony/Component/Security/Core/User/User.php deleted file mode 100644 index f3efb231d5e67..0000000000000 --- a/src/Symfony/Component/Security/Core/User/User.php +++ /dev/null @@ -1,218 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\User; - -/** - * User is the user implementation used by the in-memory user provider. - * - * This should not be used for anything else. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use {@link InMemoryUser} instead - */ -class User implements UserInterface, PasswordAuthenticatedUserInterface, EquatableInterface -{ - private $username; - private $password; - private $enabled; - private $accountNonExpired; - private $credentialsNonExpired; - private $accountNonLocked; - private $roles; - private $extraFields; - - public function __construct(?string $username, ?string $password, array $roles = [], bool $enabled = true, bool $userNonExpired = true, bool $credentialsNonExpired = true, bool $userNonLocked = true, array $extraFields = []) - { - if (InMemoryUser::class !== static::class) { - trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" instead.', self::class, InMemoryUser::class); - } - - if ('' === $username || null === $username) { - throw new \InvalidArgumentException('The username cannot be empty.'); - } - - $this->username = $username; - $this->password = $password; - $this->enabled = $enabled; - $this->accountNonExpired = $userNonExpired; - $this->credentialsNonExpired = $credentialsNonExpired; - $this->accountNonLocked = $userNonLocked; - $this->roles = $roles; - $this->extraFields = $extraFields; - } - - public function __toString(): string - { - return $this->getUserIdentifier(); - } - - /** - * {@inheritdoc} - */ - public function getRoles(): array - { - return $this->roles; - } - - /** - * {@inheritdoc} - */ - public function getPassword(): ?string - { - return $this->password; - } - - /** - * {@inheritdoc} - */ - public function getSalt(): ?string - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getUsername(): string - { - trigger_deprecation('symfony/security-core', '5.3', 'Method "%s()" is deprecated, use getUserIdentifier() instead.', __METHOD__); - - return $this->username; - } - - /** - * Returns the identifier for this user (e.g. its username or e-mailaddress). - */ - public function getUserIdentifier(): string - { - return $this->username; - } - - /** - * Checks whether the user's account has expired. - * - * Internally, if this method returns false, the authentication system - * will throw an AccountExpiredException and prevent login. - * - * @see AccountExpiredException - */ - public function isAccountNonExpired(): bool - { - return $this->accountNonExpired; - } - - /** - * Checks whether the user is locked. - * - * Internally, if this method returns false, the authentication system - * will throw a LockedException and prevent login. - * - * @see LockedException - */ - public function isAccountNonLocked(): bool - { - return $this->accountNonLocked; - } - - /** - * Checks whether the user's credentials (password) has expired. - * - * Internally, if this method returns false, the authentication system - * will throw a CredentialsExpiredException and prevent login. - * - * @see CredentialsExpiredException - */ - public function isCredentialsNonExpired(): bool - { - return $this->credentialsNonExpired; - } - - /** - * Checks whether the user is enabled. - * - * Internally, if this method returns false, the authentication system - * will throw a DisabledException and prevent login. - * - * @see DisabledException - */ - public function isEnabled(): bool - { - return $this->enabled; - } - - /** - * {@inheritdoc} - */ - public function eraseCredentials() - { - } - - public function getExtraFields(): array - { - return $this->extraFields; - } - - /** - * {@inheritdoc} - */ - public function isEqualTo(UserInterface $user): bool - { - if (!$user instanceof self) { - return false; - } - - if ($this->getPassword() !== $user->getPassword()) { - return false; - } - - if ($this->getSalt() !== $user->getSalt()) { - return false; - } - - $currentRoles = array_map('strval', (array) $this->getRoles()); - $newRoles = array_map('strval', (array) $user->getRoles()); - $rolesChanged = \count($currentRoles) !== \count($newRoles) || \count($currentRoles) !== \count(array_intersect($currentRoles, $newRoles)); - if ($rolesChanged) { - return false; - } - - if ($this->getUserIdentifier() !== $user->getUserIdentifier()) { - return false; - } - - if (self::class === static::class) { - if ($this->isAccountNonExpired() !== $user->isAccountNonExpired()) { - return false; - } - - if ($this->isAccountNonLocked() !== $user->isAccountNonLocked()) { - return false; - } - - if ($this->isCredentialsNonExpired() !== $user->isCredentialsNonExpired()) { - return false; - } - } - - if ($this->isEnabled() !== $user->isEnabled()) { - return false; - } - - return true; - } - - public function setPassword(string $password) - { - $this->password = $password; - } -} diff --git a/src/Symfony/Component/Security/Core/User/UserChecker.php b/src/Symfony/Component/Security/Core/User/UserChecker.php deleted file mode 100644 index 8ffecf1752f91..0000000000000 --- a/src/Symfony/Component/Security/Core/User/UserChecker.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\User; - -trigger_deprecation('symfony/security-core', '5.3', 'The "%s" class is deprecated, use "%s" instead.', UserChecker::class, InMemoryUserChecker::class); - -class_exists(InMemoryUserChecker::class); - -if (false) { - /** - * UserChecker checks the user account flags. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use {@link InMemoryUserChecker} instead - */ - class UserChecker - { - } -} diff --git a/src/Symfony/Component/Security/Core/User/UserInterface.php b/src/Symfony/Component/Security/Core/User/UserInterface.php index e36ed07776f5b..e51ff5cfca2be 100644 --- a/src/Symfony/Component/Security/Core/User/UserInterface.php +++ b/src/Symfony/Component/Security/Core/User/UserInterface.php @@ -26,8 +26,6 @@ * * @see UserProviderInterface * - * @method string getUserIdentifier() returns the identifier for this user (e.g. its username or e-mailaddress) - * * @author Fabien Potencier */ interface UserInterface @@ -57,9 +55,7 @@ public function getRoles(); public function eraseCredentials(); /** - * @return string - * - * @deprecated since Symfony 5.3, use getUserIdentifier() instead + * Returns the identifier for this user (e.g. its username or e-mailaddress). */ - public function getUsername(); + public function getUserIdentifier(): string; } diff --git a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php index 2444bdfa242d6..54a167e764c67 100644 --- a/src/Symfony/Component/Security/Core/User/UserProviderInterface.php +++ b/src/Symfony/Component/Security/Core/User/UserProviderInterface.php @@ -29,8 +29,7 @@ * * @see UserInterface * - * @method UserInterface loadUserByIdentifier(string $identifier) loads the user for the given user identifier (e.g. username or email). - * This method must throw UserNotFoundException if the user is not found. + * @method UserInterface loadUserByIdentifier(string $identifier) * * @author Fabien Potencier */ @@ -59,11 +58,11 @@ public function refreshUser(UserInterface $user); public function supportsClass(string $class); /** - * @return UserInterface + * Loads the user for the given user identifier (e.g. username or email). * - * @throws UserNotFoundException + * This method must throw UserNotFoundException if the user is not found. * - * @deprecated since Symfony 5.3, use loadUserByIdentifier() instead + * @throws UserNotFoundException */ - public function loadUserByUsername(string $username); + public function loadUserByIdentifier(string $identifier): UserInterface; } diff --git a/src/Symfony/Component/Security/Guard/.gitattributes b/src/Symfony/Component/Security/Guard/.gitattributes deleted file mode 100644 index 84c7add058fb5..0000000000000 --- a/src/Symfony/Component/Security/Guard/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -/Tests export-ignore -/phpunit.xml.dist export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore diff --git a/src/Symfony/Component/Security/Guard/.gitignore b/src/Symfony/Component/Security/Guard/.gitignore deleted file mode 100644 index c49a5d8df5c65..0000000000000 --- a/src/Symfony/Component/Security/Guard/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -vendor/ -composer.lock -phpunit.xml diff --git a/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php b/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php deleted file mode 100644 index 13ada75f1dab6..0000000000000 --- a/src/Symfony/Component/Security/Guard/AbstractGuardAuthenticator.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard; - -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; - -/** - * An optional base class that creates a PostAuthenticationGuardToken for you. - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -abstract class AbstractGuardAuthenticator implements AuthenticatorInterface -{ - /** - * Shortcut to create a PostAuthenticationGuardToken for you, if you don't really - * care about which authenticated token you're using. - * - * @return PostAuthenticationGuardToken - */ - public function createAuthenticatedToken(UserInterface $user, string $providerKey) - { - return new PostAuthenticationGuardToken( - $user, - $providerKey, - $user->getRoles() - ); - } -} diff --git a/src/Symfony/Component/Security/Guard/Authenticator/AbstractFormLoginAuthenticator.php b/src/Symfony/Component/Security/Guard/Authenticator/AbstractFormLoginAuthenticator.php deleted file mode 100644 index a02fb13b831a8..0000000000000 --- a/src/Symfony/Component/Security/Guard/Authenticator/AbstractFormLoginAuthenticator.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Authenticator; - -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; - -/** - * A base class to make form login authentication easier! - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -abstract class AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator -{ - /** - * Return the URL to the login page. - * - * @return string - */ - abstract protected function getLoginUrl(); - - /** - * Override to change what happens after a bad username/password is submitted. - * - * @return RedirectResponse - */ - public function onAuthenticationFailure(Request $request, AuthenticationException $exception) - { - if ($request->hasSession()) { - $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); - } - - $url = $this->getLoginUrl(); - - return new RedirectResponse($url); - } - - public function supportsRememberMe() - { - return true; - } - - /** - * Override to control what happens when the user hits a secure page - * but isn't logged in yet. - * - * @return RedirectResponse - */ - public function start(Request $request, AuthenticationException $authException = null) - { - $url = $this->getLoginUrl(); - - return new RedirectResponse($url); - } -} diff --git a/src/Symfony/Component/Security/Guard/Authenticator/GuardBridgeAuthenticator.php b/src/Symfony/Component/Security/Guard/Authenticator/GuardBridgeAuthenticator.php deleted file mode 100644 index 9df5ad163bfc8..0000000000000 --- a/src/Symfony/Component/Security/Guard/Authenticator/GuardBridgeAuthenticator.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Authenticator; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AuthenticatorInterface as GuardAuthenticatorInterface; -use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; -use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface; -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials; -use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; -use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', GuardBridgeAuthenticator::class); - -/** - * This authenticator is used to bridge Guard authenticators with - * the Symfony Authenticator system. - * - * @author Wouter de Jong - * - * @internal - * - * @deprecated since Symfony 5.3 - */ -class GuardBridgeAuthenticator implements InteractiveAuthenticatorInterface, AuthenticationEntryPointInterface -{ - private $guard; - private $userProvider; - - public function __construct(GuardAuthenticatorInterface $guard, UserProviderInterface $userProvider) - { - $this->guard = $guard; - $this->userProvider = $userProvider; - } - - public function start(Request $request, AuthenticationException $authException = null): Response - { - return $this->guard->start($request, $authException); - } - - public function supports(Request $request): ?bool - { - return $this->guard->supports($request); - } - - public function authenticate(Request $request): PassportInterface - { - $credentials = $this->guard->getCredentials($request); - - if (null === $credentials) { - throw new \UnexpectedValueException(sprintf('The return value of "%1$s::getCredentials()" must not be null. Return false from "%1$s::supports()" instead.', get_debug_type($this->guard))); - } - - // get the user from the GuardAuthenticator - if (class_exists(UserBadge::class)) { - $user = new UserBadge('guard_authenticator_'.md5(serialize($credentials)), function () use ($credentials) { return $this->getUser($credentials); }); - } else { - // BC with symfony/security-http:5.1 - $user = $this->getUser($credentials); - } - - if ($this->guard instanceof PasswordAuthenticatedInterface && !$user instanceof PasswordAuthenticatedUserInterface) { - trigger_deprecation('symfony/security-guard', '5.3', 'Not implementing the "%s" interface in class "%s" while using password-based guard authenticators is deprecated.', PasswordAuthenticatedUserInterface::class, get_debug_type($user)); - } - - $passport = new Passport($user, new CustomCredentials([$this->guard, 'checkCredentials'], $credentials)); - if ($this->userProvider instanceof PasswordUpgraderInterface && $this->guard instanceof PasswordAuthenticatedInterface && (null !== $password = $this->guard->getPassword($credentials))) { - $passport->addBadge(new PasswordUpgradeBadge($password, $this->userProvider)); - } - - if ($this->guard->supportsRememberMe()) { - $passport->addBadge(new RememberMeBadge()); - } - - return $passport; - } - - private function getUser($credentials): UserInterface - { - $user = $this->guard->getUser($credentials, $this->userProvider); - - if (null === $user) { - throw new UserNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($this->guard))); - } - - if (!$user instanceof UserInterface) { - throw new \UnexpectedValueException(sprintf('The "%s::getUser()" method must return a UserInterface. You returned "%s".', get_debug_type($this->guard), get_debug_type($user))); - } - - return $user; - } - - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - if (!$passport instanceof UserPassportInterface) { - throw new \LogicException(sprintf('"%s" does not support non-user passports.', __CLASS__)); - } - - return $this->guard->createAuthenticatedToken($passport->getUser(), $firewallName); - } - - public function createToken(Passport $passport, string $firewallName): TokenInterface - { - return $this->guard->createAuthenticatedToken($passport->getUser(), $firewallName); - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response - { - return $this->guard->onAuthenticationSuccess($request, $token, $firewallName); - } - - public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response - { - return $this->guard->onAuthenticationFailure($request, $exception); - } - - public function isInteractive(): bool - { - // the GuardAuthenticationHandler always dispatches the InteractiveLoginEvent - return true; - } -} diff --git a/src/Symfony/Component/Security/Guard/AuthenticatorInterface.php b/src/Symfony/Component/Security/Guard/AuthenticatorInterface.php deleted file mode 100644 index d64350fa0c6c6..0000000000000 --- a/src/Symfony/Component/Security/Guard/AuthenticatorInterface.php +++ /dev/null @@ -1,151 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\Token\GuardTokenInterface; -use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; - -/** - * The interface for all "guard" authenticators. - * - * The methods on this interface are called throughout the guard authentication - * process to give you the power to control most parts of the process from - * one location. - * - * @author Ryan Weaver - * @author Amaury Leroux de Lens - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -interface AuthenticatorInterface extends AuthenticationEntryPointInterface -{ - /** - * Does the authenticator support the given Request? - * - * If this returns false, the authenticator will be skipped. - * - * @return bool - */ - public function supports(Request $request); - - /** - * Get the authentication credentials from the request and return them - * as any type (e.g. an associate array). - * - * Whatever value you return here will be passed to getUser() and checkCredentials() - * - * For example, for a form login, you might: - * - * return [ - * 'username' => $request->request->get('_username'), - * 'password' => $request->request->get('_password'), - * ]; - * - * Or for an API token that's on a header, you might use: - * - * return ['api_key' => $request->headers->get('X-API-TOKEN')]; - * - * @return mixed Any non-null value - * - * @throws \UnexpectedValueException If null is returned - */ - public function getCredentials(Request $request); - - /** - * Return a UserInterface object based on the credentials. - * - * The *credentials* are the return value from getCredentials() - * - * You may throw an AuthenticationException if you wish. If you return - * null, then a UserNotFoundException is thrown for you. - * - * @throws AuthenticationException - * - * @return UserInterface|null - */ - public function getUser(mixed $credentials, UserProviderInterface $userProvider); - - /** - * Returns true if the credentials are valid. - * - * If false is returned, authentication will fail. You may also throw - * an AuthenticationException if you wish to cause authentication to fail. - * - * The *credentials* are the return value from getCredentials() - * - * @return bool - * - * @throws AuthenticationException - */ - public function checkCredentials(mixed $credentials, UserInterface $user); - - /** - * Create an authenticated token for the given user. - * - * If you don't care about which token class is used or don't really - * understand what a "token" is, you can skip this method by extending - * the AbstractGuardAuthenticator class from your authenticator. - * - * @see AbstractGuardAuthenticator - * - * @return GuardTokenInterface - */ - public function createAuthenticatedToken(UserInterface $user, string $providerKey); - - /** - * Called when authentication executed, but failed (e.g. wrong username password). - * - * This should return the Response sent back to the user, like a - * RedirectResponse to the login page or a 401 response. - * - * If you return null, the request will continue, but the user will - * not be authenticated. This is probably not what you want to do. - * - * @return Response|null - */ - public function onAuthenticationFailure(Request $request, AuthenticationException $exception); - - /** - * Called when authentication executed and was successful! - * - * This should return the Response sent back to the user, like a - * RedirectResponse to the last page they visited. - * - * If you return null, the current request will continue, and the user - * will be authenticated. This makes sense, for example, with an API. - * - * @return Response|null - */ - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey); - - /** - * Does this method support remember me cookies? - * - * Remember me cookie will be set if *all* of the following are met: - * A) This method returns true - * B) The remember_me key under your firewall is configured - * C) The "remember me" functionality is activated. This is usually - * done by having a _remember_me checkbox in your form, but - * can be configured by the "always_remember_me" and "remember_me_parameter" - * parameters under the "remember_me" firewall key - * D) The onAuthenticationSuccess method returns a Response object - * - * @return bool - */ - public function supportsRememberMe(); -} diff --git a/src/Symfony/Component/Security/Guard/CHANGELOG.md b/src/Symfony/Component/Security/Guard/CHANGELOG.md deleted file mode 100644 index 22652b086195b..0000000000000 --- a/src/Symfony/Component/Security/Guard/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -CHANGELOG -========= - -5.3 ---- - -The CHANGELOG for version 5.3 and earlier can be found at https://github.com/symfony/symfony/blob/5.3/src/Symfony/Component/Security/CHANGELOG.md diff --git a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php deleted file mode 100644 index 7eba97b10747d..0000000000000 --- a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php +++ /dev/null @@ -1,242 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AccountStatusException; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; -use Symfony\Component\Security\Http\Firewall\AbstractListener; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', GuardAuthenticationListener::class); - -/** - * Authentication listener for the "guard" system. - * - * @author Ryan Weaver - * @author Amaury Leroux de Lens - * - * @final - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class GuardAuthenticationListener extends AbstractListener -{ - private $guardHandler; - private $authenticationManager; - private $providerKey; - private $guardAuthenticators; - private $logger; - private $rememberMeServices; - private $hideUserNotFoundExceptions; - - /** - * @param string $providerKey The provider (i.e. firewall) key - * @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider - */ - public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, string $providerKey, iterable $guardAuthenticators, LoggerInterface $logger = null, bool $hideUserNotFoundExceptions = true) - { - if (empty($providerKey)) { - throw new \InvalidArgumentException('$providerKey must not be empty.'); - } - - $this->guardHandler = $guardHandler; - $this->authenticationManager = $authenticationManager; - $this->providerKey = $providerKey; - $this->guardAuthenticators = $guardAuthenticators; - $this->logger = $logger; - $this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions; - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - if (null !== $this->logger) { - $context = ['firewall_key' => $this->providerKey]; - - if ($this->guardAuthenticators instanceof \Countable || \is_array($this->guardAuthenticators)) { - $context['authenticators'] = \count($this->guardAuthenticators); - } - - $this->logger->debug('Checking for guard authentication credentials.', $context); - } - - $guardAuthenticators = []; - - foreach ($this->guardAuthenticators as $key => $guardAuthenticator) { - if (null !== $this->logger) { - $this->logger->debug('Checking support on guard authenticator.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]); - } - - if ($guardAuthenticator->supports($request)) { - $guardAuthenticators[$key] = $guardAuthenticator; - } elseif (null !== $this->logger) { - $this->logger->debug('Guard authenticator does not support the request.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]); - } - } - - if (!$guardAuthenticators) { - return false; - } - - $request->attributes->set('_guard_authenticators', $guardAuthenticators); - - return true; - } - - /** - * Iterates over each authenticator to see if each wants to authenticate the request. - */ - public function authenticate(RequestEvent $event) - { - $request = $event->getRequest(); - $guardAuthenticators = $request->attributes->get('_guard_authenticators'); - $request->attributes->remove('_guard_authenticators'); - - foreach ($guardAuthenticators as $key => $guardAuthenticator) { - // get a key that's unique to *this* guard authenticator - // this MUST be the same as GuardAuthenticationProvider - $uniqueGuardKey = $this->providerKey.'_'.$key; - - $this->executeGuardAuthenticator($uniqueGuardKey, $guardAuthenticator, $event); - - if ($event->hasResponse()) { - if (null !== $this->logger) { - $this->logger->debug('The "{authenticator}" authenticator set the response. Any later authenticator will not be called', ['authenticator' => \get_class($guardAuthenticator)]); - } - - break; - } - } - } - - private function executeGuardAuthenticator(string $uniqueGuardKey, AuthenticatorInterface $guardAuthenticator, RequestEvent $event) - { - $request = $event->getRequest(); - try { - if (null !== $this->logger) { - $this->logger->debug('Calling getCredentials() on guard authenticator.', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]); - } - - // allow the authenticator to fetch authentication info from the request - $credentials = $guardAuthenticator->getCredentials($request); - - if (null === $credentials) { - throw new \UnexpectedValueException(sprintf('The return value of "%1$s::getCredentials()" must not be null. Return false from "%1$s::supports()" instead.', get_debug_type($guardAuthenticator))); - } - - // create a token with the unique key, so that the provider knows which authenticator to use - $token = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey); - - if (null !== $this->logger) { - $this->logger->debug('Passing guard token information to the GuardAuthenticationProvider', ['firewall_key' => $this->providerKey, 'authenticator' => \get_class($guardAuthenticator)]); - } - // pass the token into the AuthenticationManager system - // this indirectly calls GuardAuthenticationProvider::authenticate() - $token = $this->authenticationManager->authenticate($token); - - if (null !== $this->logger) { - $this->logger->info('Guard authentication successful!', ['token' => $token, 'authenticator' => \get_class($guardAuthenticator)]); - } - - // sets the token on the token storage, etc - $this->guardHandler->authenticateWithToken($token, $request, $this->providerKey); - } catch (AuthenticationException $e) { - // oh no! Authentication failed! - - if (null !== $this->logger) { - $this->logger->info('Guard authentication failed.', ['exception' => $e, 'authenticator' => \get_class($guardAuthenticator)]); - } - - // Avoid leaking error details in case of invalid user (e.g. user not found or invalid account status) - // to prevent user enumeration via response content - if ($this->hideUserNotFoundExceptions && ($e instanceof UsernameNotFoundException || ($e instanceof AccountStatusException && !$e instanceof CustomUserMessageAccountStatusException))) { - $e = new BadCredentialsException('Bad credentials.', 0, $e); - } - - $response = $this->guardHandler->handleAuthenticationFailure($e, $request, $guardAuthenticator, $this->providerKey); - - if ($response instanceof Response) { - $event->setResponse($response); - } - - return; - } - - // success! - $response = $this->guardHandler->handleAuthenticationSuccess($token, $request, $guardAuthenticator, $this->providerKey); - if ($response instanceof Response) { - if (null !== $this->logger) { - $this->logger->debug('Guard authenticator set success response.', ['response' => $response, 'authenticator' => \get_class($guardAuthenticator)]); - } - - $event->setResponse($response); - } else { - if (null !== $this->logger) { - $this->logger->debug('Guard authenticator set no success response: request continues.', ['authenticator' => \get_class($guardAuthenticator)]); - } - } - - // attempt to trigger the remember me functionality - $this->triggerRememberMe($guardAuthenticator, $request, $token, $response); - } - - /** - * Should be called if this listener will support remember me. - */ - public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices) - { - $this->rememberMeServices = $rememberMeServices; - } - - /** - * Checks to see if remember me is supported in the authenticator and - * on the firewall. If it is, the RememberMeServicesInterface is notified. - */ - private function triggerRememberMe(AuthenticatorInterface $guardAuthenticator, Request $request, TokenInterface $token, Response $response = null) - { - if (null === $this->rememberMeServices) { - if (null !== $this->logger) { - $this->logger->debug('Remember me skipped: it is not configured for the firewall.', ['authenticator' => \get_class($guardAuthenticator)]); - } - - return; - } - - if (!$guardAuthenticator->supportsRememberMe()) { - if (null !== $this->logger) { - $this->logger->debug('Remember me skipped: your authenticator does not support it.', ['authenticator' => \get_class($guardAuthenticator)]); - } - - return; - } - - if (!$response instanceof Response) { - throw new \LogicException(sprintf('"%s::onAuthenticationSuccess()" *must* return a Response if you want to use the remember me functionality. Return a Response, or set remember_me to false under the guard configuration.', get_debug_type($guardAuthenticator))); - } - - $this->rememberMeServices->loginSuccess($request, $response, $token); - } -} diff --git a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php deleted file mode 100644 index cbd5bdfc93c35..0000000000000 --- a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php +++ /dev/null @@ -1,133 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', GuardAuthenticatorHandler::class); - -/** - * A utility class that does much of the *work* during the guard authentication process. - * - * By having the logic here instead of the listener, more of the process - * can be called directly (e.g. for manual authentication) or overridden. - * - * @author Ryan Weaver - * - * @final - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class GuardAuthenticatorHandler -{ - private $tokenStorage; - private $dispatcher; - private $sessionStrategy; - private $statelessProviderKeys; - - /** - * @param array $statelessProviderKeys An array of provider/firewall keys that are "stateless" and so do not need the session migrated on success - */ - public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher = null, array $statelessProviderKeys = []) - { - $this->tokenStorage = $tokenStorage; - $this->dispatcher = $eventDispatcher; - $this->statelessProviderKeys = $statelessProviderKeys; - } - - /** - * Authenticates the given token in the system. - */ - public function authenticateWithToken(TokenInterface $token, Request $request, string $providerKey = null) - { - $this->migrateSession($request, $token, $providerKey); - $this->tokenStorage->setToken($token); - - if (null !== $this->dispatcher) { - $loginEvent = new InteractiveLoginEvent($request, $token); - $this->dispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN); - } - } - - /** - * Returns the "on success" response for the given GuardAuthenticator. - */ - public function handleAuthenticationSuccess(TokenInterface $token, Request $request, AuthenticatorInterface $guardAuthenticator, string $providerKey): ?Response - { - $response = $guardAuthenticator->onAuthenticationSuccess($request, $token, $providerKey); - - // check that it's a Response or null - if ($response instanceof Response || null === $response) { - return $response; - } - - throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationSuccess()" method must return null or a Response object. You returned "%s".', \get_class($guardAuthenticator), get_debug_type($response))); - } - - /** - * Convenience method for authenticating the user and returning the - * Response *if any* for success. - */ - public function authenticateUserAndHandleSuccess(UserInterface $user, Request $request, AuthenticatorInterface $authenticator, string $providerKey): ?Response - { - // create an authenticated token for the User - $token = $authenticator->createAuthenticatedToken($user, $providerKey); - // authenticate this in the system - $this->authenticateWithToken($token, $request, $providerKey); - - // return the success metric - return $this->handleAuthenticationSuccess($token, $request, $authenticator, $providerKey); - } - - /** - * Handles an authentication failure and returns the Response for the - * GuardAuthenticator. - */ - public function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, AuthenticatorInterface $guardAuthenticator, string $providerKey): ?Response - { - $response = $guardAuthenticator->onAuthenticationFailure($request, $authenticationException); - if ($response instanceof Response || null === $response) { - // returning null is ok, it means they want the request to continue - return $response; - } - - throw new \UnexpectedValueException(sprintf('The "%s::onAuthenticationFailure()" method must return null or a Response object. You returned "%s".', \get_class($guardAuthenticator), get_debug_type($response))); - } - - /** - * Call this method if your authentication token is stored to a session. - * - * @final - */ - public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy) - { - $this->sessionStrategy = $sessionStrategy; - } - - private function migrateSession(Request $request, TokenInterface $token, ?string $providerKey) - { - if (\in_array($providerKey, $this->statelessProviderKeys, true) || !$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) { - return; - } - - $this->sessionStrategy->onAuthentication($request, $token); - } -} diff --git a/src/Symfony/Component/Security/Guard/LICENSE b/src/Symfony/Component/Security/Guard/LICENSE deleted file mode 100644 index 9ff2d0d6306da..0000000000000 --- a/src/Symfony/Component/Security/Guard/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-2021 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php b/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php deleted file mode 100644 index 4eb86e738b434..0000000000000 --- a/src/Symfony/Component/Security/Guard/PasswordAuthenticatedInterface.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', PasswordAuthenticatedInterface::class); - -/** - * An optional interface for "guard" authenticators that deal with user passwords. - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -interface PasswordAuthenticatedInterface -{ - /** - * Returns the clear-text password contained in credentials if any. - */ - public function getPassword(mixed $credentials): ?string; -} diff --git a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php b/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php deleted file mode 100644 index fa29e6c5266cc..0000000000000 --- a/src/Symfony/Component/Security/Guard/Provider/GuardAuthenticationProvider.php +++ /dev/null @@ -1,178 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Provider; - -use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; -use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface; -use Symfony\Component\Security\Guard\Token\GuardTokenInterface; -use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', GuardAuthenticationProvider::class); - -/** - * Responsible for accepting the PreAuthenticationGuardToken and calling - * the correct authenticator to retrieve the authenticated token. - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class GuardAuthenticationProvider implements AuthenticationProviderInterface -{ - /** - * @var AuthenticatorInterface[] - */ - private $guardAuthenticators; - private $userProvider; - private $providerKey; - private $userChecker; - private $passwordHasher; - - /** - * @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationListener - * @param string $providerKey The provider (i.e. firewall) key - */ - public function __construct(iterable $guardAuthenticators, UserProviderInterface $userProvider, string $providerKey, UserCheckerInterface $userChecker, UserPasswordHasherInterface $passwordHasher = null) - { - $this->guardAuthenticators = $guardAuthenticators; - $this->userProvider = $userProvider; - $this->providerKey = $providerKey; - $this->userChecker = $userChecker; - $this->passwordHasher = $passwordHasher; - } - - /** - * Finds the correct authenticator for the token and calls it. - * - * @param GuardTokenInterface $token - * - * @return TokenInterface - */ - public function authenticate(TokenInterface $token) - { - if (!$token instanceof GuardTokenInterface) { - throw new \InvalidArgumentException('GuardAuthenticationProvider only supports GuardTokenInterface.'); - } - - if (!$token instanceof PreAuthenticationGuardToken) { - /* - * The listener *only* passes PreAuthenticationGuardToken instances. - * This means that an authenticated token (e.g. PostAuthenticationGuardToken) - * is being passed here, which happens if that token becomes - * "not authenticated" (e.g. happens if the user changes between - * requests). In this case, the user should be logged out, so - * we will return an AnonymousToken to accomplish that. - */ - - // this should never happen - but technically, the token is - // authenticated... so it could just be returned - if ($token->isAuthenticated(false)) { - return $token; - } - - // this causes the user to be logged out - throw new AuthenticationExpiredException(); - } - - $guardAuthenticator = $this->findOriginatingAuthenticator($token); - - if (null === $guardAuthenticator) { - throw new AuthenticationException(sprintf('Token with provider key "%s" did not originate from any of the guard authenticators of provider "%s".', $token->getGuardProviderKey(), $this->providerKey)); - } - - return $this->authenticateViaGuard($guardAuthenticator, $token); - } - - private function authenticateViaGuard(AuthenticatorInterface $guardAuthenticator, PreAuthenticationGuardToken $token): GuardTokenInterface - { - // get the user from the GuardAuthenticator - $user = $guardAuthenticator->getUser($token->getCredentials(), $this->userProvider); - - if (null === $user) { - $e = new UserNotFoundException(sprintf('Null returned from "%s::getUser()".', get_debug_type($guardAuthenticator))); - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $e->setUserIdentifier(method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()); - - throw $e; - } - - if (!$user instanceof UserInterface) { - throw new \UnexpectedValueException(sprintf('The "%s::getUser()" method must return a UserInterface. You returned "%s".', get_debug_type($guardAuthenticator), get_debug_type($user))); - } - - if ($guardAuthenticator instanceof PasswordAuthenticatedInterface && !$user instanceof PasswordAuthenticatedUserInterface) { - trigger_deprecation('symfony/security-guard', '5.3', 'Not implementing the "%s" interface in class "%s" while using password-based guard authenticators is deprecated.', PasswordAuthenticatedUserInterface::class, get_debug_type($user)); - } - - $this->userChecker->checkPreAuth($user); - if (true !== $checkCredentialsResult = $guardAuthenticator->checkCredentials($token->getCredentials(), $user)) { - if (false !== $checkCredentialsResult) { - throw new \TypeError(sprintf('"%s::checkCredentials()" must return a boolean value.', get_debug_type($guardAuthenticator))); - } - - throw new BadCredentialsException(sprintf('Authentication failed because "%s::checkCredentials()" did not return true.', get_debug_type($guardAuthenticator))); - } - - if ($user instanceof PasswordAuthenticatedUserInterface && $this->userProvider instanceof PasswordUpgraderInterface && $guardAuthenticator instanceof PasswordAuthenticatedInterface && null !== $this->passwordHasher && (null !== $password = $guardAuthenticator->getPassword($token->getCredentials())) && $this->passwordHasher->needsRehash($user)) { - $this->userProvider->upgradePassword($user, $this->passwordHasher->hashPassword($user, $password)); - } - $this->userChecker->checkPostAuth($user); - - // turn the UserInterface into a TokenInterface - $authenticatedToken = $guardAuthenticator->createAuthenticatedToken($user, $this->providerKey); - if (!$authenticatedToken instanceof TokenInterface) { - throw new \UnexpectedValueException(sprintf('The "%s::createAuthenticatedToken()" method must return a TokenInterface. You returned "%s".', get_debug_type($guardAuthenticator), get_debug_type($authenticatedToken))); - } - - return $authenticatedToken; - } - - private function findOriginatingAuthenticator(PreAuthenticationGuardToken $token): ?AuthenticatorInterface - { - // find the *one* GuardAuthenticator that this token originated from - foreach ($this->guardAuthenticators as $key => $guardAuthenticator) { - // get a key that's unique to *this* guard authenticator - // this MUST be the same as GuardAuthenticationListener - $uniqueGuardKey = $this->providerKey.'_'.$key; - - if ($uniqueGuardKey === $token->getGuardProviderKey()) { - return $guardAuthenticator; - } - } - - // no matching authenticator found - but there will be multiple GuardAuthenticationProvider - // instances that will be checked if you have multiple firewalls. - - return null; - } - - public function supports(TokenInterface $token) - { - if ($token instanceof PreAuthenticationGuardToken) { - return null !== $this->findOriginatingAuthenticator($token); - } - - return $token instanceof GuardTokenInterface; - } -} diff --git a/src/Symfony/Component/Security/Guard/README.md b/src/Symfony/Component/Security/Guard/README.md deleted file mode 100644 index 968558f79f86a..0000000000000 --- a/src/Symfony/Component/Security/Guard/README.md +++ /dev/null @@ -1,15 +0,0 @@ -Security Component - Guard -========================== - -The Guard component brings many layers of authentication together, making -it much easier to create complex authentication systems where you have -total control. - -Resources ---------- - - * [Documentation](https://symfony.com/doc/current/components/security.html) - * [Contributing](https://symfony.com/doc/current/contributing/index.html) - * [Report issues](https://github.com/symfony/symfony/issues) and - [send Pull Requests](https://github.com/symfony/symfony/pulls) - in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php b/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php deleted file mode 100644 index 2b7a00fa94918..0000000000000 --- a/src/Symfony/Component/Security/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php +++ /dev/null @@ -1,170 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests\Authenticator; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator; - -/** - * @author Jean Pasdeloup - * @group legacy - */ -class FormLoginAuthenticatorTest extends TestCase -{ - private $requestWithoutSession; - private $requestWithSession; - private $authenticator; - - private const LOGIN_URL = 'http://login'; - private const DEFAULT_SUCCESS_URL = 'http://defaultsuccess'; - - public function testAuthenticationFailureWithoutSession() - { - $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithoutSession, new AuthenticationException()); - - $this->assertInstanceOf(RedirectResponse::class, $failureResponse); - $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); - } - - public function testAuthenticationFailureWithSession() - { - $this->requestWithSession->getSession() - ->expects($this->once()) - ->method('set'); - - $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithSession, new AuthenticationException()); - - $this->assertInstanceOf(RedirectResponse::class, $failureResponse); - $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); - } - - public function testRememberMe() - { - $doSupport = $this->authenticator->supportsRememberMe(); - - $this->assertTrue($doSupport); - } - - public function testStartWithoutSession() - { - $failureResponse = $this->authenticator->start($this->requestWithoutSession, new AuthenticationException()); - - $this->assertInstanceOf(RedirectResponse::class, $failureResponse); - $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); - } - - public function testStartWithSession() - { - $failureResponse = $this->authenticator->start($this->requestWithSession, new AuthenticationException()); - - $this->assertInstanceOf(RedirectResponse::class, $failureResponse); - $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); - } - - protected function setUp(): void - { - $this->requestWithoutSession = new Request([], [], [], [], [], []); - $this->requestWithSession = new Request([], [], [], [], [], []); - - $session = $this->createMock(SessionInterface::class); - $this->requestWithSession->setSession($session); - - $this->authenticator = new TestFormLoginAuthenticator(); - $this->authenticator - ->setLoginUrl(self::LOGIN_URL) - ->setDefaultSuccessRedirectUrl(self::DEFAULT_SUCCESS_URL) - ; - } -} - -class TestFormLoginAuthenticator extends AbstractFormLoginAuthenticator -{ - private $loginUrl; - private $defaultSuccessRedirectUrl; - - public function supports(Request $request): bool - { - return true; - } - - public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey): ?Response - { - } - - /** - * @param mixed $defaultSuccessRedirectUrl - */ - public function setDefaultSuccessRedirectUrl($defaultSuccessRedirectUrl): self - { - $this->defaultSuccessRedirectUrl = $defaultSuccessRedirectUrl; - - return $this; - } - - /** - * @param mixed $loginUrl - */ - public function setLoginUrl($loginUrl): self - { - $this->loginUrl = $loginUrl; - - return $this; - } - - /** - * {@inheritdoc} - */ - protected function getLoginUrl(): string - { - return $this->loginUrl; - } - - /** - * {@inheritdoc} - */ - protected function getDefaultSuccessRedirectUrl() - { - return $this->defaultSuccessRedirectUrl; - } - - /** - * {@inheritdoc} - */ - public function getCredentials(Request $request): mixed - { - return 'credentials'; - } - - /** - * {@inheritdoc} - */ - public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface - { - return $userProvider->loadUserByUsername($credentials); - } - - /** - * {@inheritdoc} - */ - public function checkCredentials($credentials, UserInterface $user): bool - { - return true; - } -} diff --git a/src/Symfony/Component/Security/Guard/Tests/Authenticator/GuardBridgeAuthenticatorTest.php b/src/Symfony/Component/Security/Guard/Tests/Authenticator/GuardBridgeAuthenticatorTest.php deleted file mode 100644 index 3dd65a1715023..0000000000000 --- a/src/Symfony/Component/Security/Guard/Tests/Authenticator/GuardBridgeAuthenticatorTest.php +++ /dev/null @@ -1,189 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests\Authenticator; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\Authenticator\GuardBridgeAuthenticator; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials; -use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; - -/** - * @group legacy - */ -class GuardBridgeAuthenticatorTest extends TestCase -{ - private $guardAuthenticator; - private $userProvider; - private $authenticator; - - protected function setUp(): void - { - if (!interface_exists(\Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface::class)) { - $this->markTestSkipped('Authenticator system not installed.'); - } - - $this->guardAuthenticator = $this->createMock(AuthenticatorInterface::class); - $this->userProvider = $this->createMock(UserProviderInterface::class); - $this->authenticator = new GuardBridgeAuthenticator($this->guardAuthenticator, $this->userProvider); - } - - public function testSupports() - { - $request = new Request(); - - $this->guardAuthenticator->expects($this->once()) - ->method('supports') - ->with($request) - ->willReturn(true); - - $this->assertTrue($this->authenticator->supports($request)); - } - - public function testNoSupport() - { - $request = new Request(); - - $this->guardAuthenticator->expects($this->once()) - ->method('supports') - ->with($request) - ->willReturn(false); - - $this->assertFalse($this->authenticator->supports($request)); - } - - public function testAuthenticate() - { - $request = new Request(); - - $credentials = ['password' => 's3cr3t']; - $this->guardAuthenticator->expects($this->once()) - ->method('getCredentials') - ->with($request) - ->willReturn($credentials); - - $user = new InMemoryUser('test', null, ['ROLE_USER']); - $this->guardAuthenticator->expects($this->once()) - ->method('getUser') - ->with($credentials, $this->userProvider) - ->willReturn($user); - - $passport = $this->authenticator->authenticate($request); - $this->assertEquals($user, $passport->getUser()); - $this->assertTrue($passport->hasBadge(CustomCredentials::class)); - - $this->guardAuthenticator->expects($this->once()) - ->method('checkCredentials') - ->with($credentials, $user) - ->willReturn(true); - - $passport->getBadge(CustomCredentials::class)->executeCustomChecker($user); - } - - public function testAuthenticateNoUser() - { - $this->expectException(UserNotFoundException::class); - - $request = new Request(); - - $credentials = ['password' => 's3cr3t']; - $this->guardAuthenticator->expects($this->once()) - ->method('getCredentials') - ->with($request) - ->willReturn($credentials); - - $this->guardAuthenticator->expects($this->once()) - ->method('getUser') - ->with($credentials, $this->userProvider) - ->willReturn(null); - - $passport = $this->authenticator->authenticate($request); - $passport->getUser(); - } - - /** - * @dataProvider provideRememberMeData - */ - public function testAuthenticateRememberMe(bool $rememberMeSupported) - { - $request = new Request(); - - $credentials = ['password' => 's3cr3t']; - $this->guardAuthenticator->expects($this->once()) - ->method('getCredentials') - ->with($request) - ->willReturn($credentials); - - $this->guardAuthenticator->expects($this->once()) - ->method('supportsRememberMe') - ->willReturn($rememberMeSupported); - - $passport = $this->authenticator->authenticate($request); - $this->assertEquals($rememberMeSupported, $passport->hasBadge(RememberMeBadge::class)); - } - - public function provideRememberMeData() - { - yield [true]; - yield [false]; - } - - public function testCreateAuthenticatedToken() - { - $user = new InMemoryUser('test', null, ['ROLE_USER']); - - $token = new PostAuthenticationGuardToken($user, 'main', ['ROLE_USER']); - $this->guardAuthenticator->expects($this->once()) - ->method('createAuthenticatedToken') - ->with($user, 'main') - ->willReturn($token); - - $this->assertSame($token, $this->authenticator->createAuthenticatedToken(new SelfValidatingPassport(new UserBadge('test', function () use ($user) { return $user; })), 'main')); - } - - public function testHandleSuccess() - { - $request = new Request(); - $token = new PostAuthenticationGuardToken(new InMemoryUser('test', null, ['ROLE_USER']), 'main', ['ROLE_USER']); - - $response = new Response(); - $this->guardAuthenticator->expects($this->once()) - ->method('onAuthenticationSuccess') - ->with($request, $token) - ->willReturn($response); - - $this->assertSame($response, $this->authenticator->onAuthenticationSuccess($request, $token, 'main')); - } - - public function testOnFailure() - { - $request = new Request(); - $exception = new AuthenticationException(); - - $response = new Response(); - $this->guardAuthenticator->expects($this->once()) - ->method('onAuthenticationFailure') - ->with($request, $exception) - ->willReturn($response); - - $this->assertSame($response, $this->authenticator->onAuthenticationFailure($request, $exception)); - } -} diff --git a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php b/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php deleted file mode 100644 index a4ccf9291ecc3..0000000000000 --- a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php +++ /dev/null @@ -1,342 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\LockedException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener; -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; - -/** - * @author Ryan Weaver - * @author Amaury Leroux de Lens - * @group legacy - */ -class GuardAuthenticationListenerTest extends TestCase -{ - private $authenticationManager; - private $guardAuthenticatorHandler; - private $event; - private $logger; - private $request; - private $rememberMeServices; - - public function testHandleSuccess() - { - $authenticator = $this->createMock(AuthenticatorInterface::class); - $authenticateToken = $this->createMock(TokenInterface::class); - $providerKey = 'my_firewall'; - - $credentials = ['username' => 'weaverryan', 'password' => 'all_your_base']; - - $authenticator - ->expects($this->once()) - ->method('supports') - ->willReturn(true); - $authenticator - ->expects($this->once()) - ->method('getCredentials') - ->with($this->equalTo($this->request)) - ->willReturn($credentials); - - // a clone of the token that should be created internally - $uniqueGuardKey = 'my_firewall_0'; - $nonAuthedToken = new PreAuthenticationGuardToken($credentials, $uniqueGuardKey); - - $this->authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->equalTo($nonAuthedToken)) - ->willReturn($authenticateToken); - - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('authenticateWithToken') - ->with($authenticateToken, $this->request); - - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('handleAuthenticationSuccess') - ->with($authenticateToken, $this->request, $authenticator, $providerKey); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener->setRememberMeServices($this->rememberMeServices); - // should never be called - our handleAuthenticationSuccess() does not return a Response - $this->rememberMeServices - ->expects($this->never()) - ->method('loginSuccess'); - - $listener($this->event); - } - - public function testHandleSuccessStopsAfterResponseIsSet() - { - $authenticator1 = $this->createMock(AuthenticatorInterface::class); - $authenticator2 = $this->createMock(AuthenticatorInterface::class); - - // mock the first authenticator to fail, and set a Response - $authenticator1 - ->expects($this->once()) - ->method('supports') - ->willReturn(true); - $authenticator1 - ->expects($this->once()) - ->method('getCredentials') - ->willThrowException(new AuthenticationException()); - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('handleAuthenticationFailure') - ->willReturn(new Response()); - // the second authenticator should *never* be called - $authenticator2 - ->expects($this->never()) - ->method('getCredentials'); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - 'my_firewall', - [$authenticator1, $authenticator2], - $this->logger - ); - - $listener($this->event); - } - - public function testHandleSuccessWithRememberMe() - { - $authenticator = $this->createMock(AuthenticatorInterface::class); - $authenticateToken = $this->createMock(TokenInterface::class); - $providerKey = 'my_firewall_with_rememberme'; - - $authenticator - ->expects($this->once()) - ->method('supports') - ->with($this->equalTo($this->request)) - ->willReturn(true); - $authenticator - ->expects($this->once()) - ->method('getCredentials') - ->with($this->equalTo($this->request)) - ->willReturn(['username' => 'anything_not_empty']); - - $this->authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->willReturn($authenticateToken); - - $successResponse = new Response('Success!'); - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('handleAuthenticationSuccess') - ->willReturn($successResponse); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener->setRememberMeServices($this->rememberMeServices); - $authenticator->expects($this->once()) - ->method('supportsRememberMe') - ->willReturn(true); - // should be called - we do have a success Response - $this->rememberMeServices - ->expects($this->once()) - ->method('loginSuccess'); - - $listener($this->event); - } - - public function testHandleCatchesAuthenticationException() - { - $authenticator = $this->createMock(AuthenticatorInterface::class); - $providerKey = 'my_firewall2'; - - $authException = new AuthenticationException('Get outta here crazy user with a bad password!'); - $authenticator - ->expects($this->once()) - ->method('supports') - ->willReturn(true); - $authenticator - ->expects($this->once()) - ->method('getCredentials') - ->willThrowException($authException); - - // this is not called - $this->authenticationManager - ->expects($this->never()) - ->method('authenticate'); - - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('handleAuthenticationFailure') - ->with($authException, $this->request, $authenticator, $providerKey); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener($this->event); - } - - /** - * @dataProvider exceptionsToHide - */ - public function testHandleHidesInvalidUserExceptions(AuthenticationException $exceptionToHide) - { - $authenticator = $this->createMock(AuthenticatorInterface::class); - $providerKey = 'my_firewall2'; - - $authenticator - ->expects($this->once()) - ->method('supports') - ->willReturn(true); - $authenticator - ->expects($this->once()) - ->method('getCredentials') - ->willReturn(['username' => 'robin', 'password' => 'hood']); - - $this->authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->willThrowException($exceptionToHide); - - $this->guardAuthenticatorHandler - ->expects($this->once()) - ->method('handleAuthenticationFailure') - ->with($this->callback(function ($e) use ($exceptionToHide) { - return $e instanceof BadCredentialsException && $exceptionToHide === $e->getPrevious(); - }), $this->request, $authenticator, $providerKey); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener($this->event); - } - - public function exceptionsToHide() - { - return [ - [new UserNotFoundException()], - [new LockedException()], - ]; - } - - public function testSupportsReturnFalseSkipAuth() - { - $authenticator = $this->createMock(AuthenticatorInterface::class); - $providerKey = 'my_firewall4'; - - $authenticator - ->expects($this->once()) - ->method('supports') - ->willReturn(false); - - // this is not called - $authenticator - ->expects($this->never()) - ->method('getCredentials'); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener($this->event); - } - - public function testReturnNullFromGetCredentials() - { - $this->expectException(\UnexpectedValueException::class); - $authenticator = $this->createMock(AuthenticatorInterface::class); - $providerKey = 'my_firewall4'; - - $authenticator - ->expects($this->once()) - ->method('supports') - ->willReturn(true); - - // this will raise exception - $authenticator - ->expects($this->once()) - ->method('getCredentials') - ->willReturn(null); - - $listener = new GuardAuthenticationListener( - $this->guardAuthenticatorHandler, - $this->authenticationManager, - $providerKey, - [$authenticator], - $this->logger - ); - - $listener($this->event); - } - - protected function setUp(): void - { - $this->authenticationManager = $this->createMock(AuthenticationProviderManager::class); - $this->guardAuthenticatorHandler = $this->createMock(GuardAuthenticatorHandler::class); - $this->request = new Request([], [], [], [], [], []); - - $this->event = new RequestEvent($this->createMock(HttpKernelInterface::class), $this->request, HttpKernelInterface::MASTER_REQUEST); - - $this->logger = $this->createMock(LoggerInterface::class); - $this->rememberMeServices = $this->createMock(RememberMeServicesInterface::class); - } - - protected function tearDown(): void - { - $this->authenticationManager = null; - $this->guardAuthenticatorHandler = null; - $this->event = null; - $this->logger = null; - $this->request = null; - $this->rememberMeServices = null; - } -} diff --git a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php b/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php deleted file mode 100644 index d36cf666f32a9..0000000000000 --- a/src/Symfony/Component/Security/Guard/Tests/GuardAuthenticatorHandlerTest.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -/** - * @group legacy - */ -class GuardAuthenticatorHandlerTest extends TestCase -{ - private $tokenStorage; - private $dispatcher; - private $token; - private $request; - private $sessionStrategy; - private $guardAuthenticator; - - public function testAuthenticateWithToken() - { - $this->tokenStorage->expects($this->once()) - ->method('setToken') - ->with($this->token); - - $loginEvent = new InteractiveLoginEvent($this->request, $this->token); - - $this->dispatcher - ->expects($this->once()) - ->method('dispatch') - ->with($this->equalTo($loginEvent), $this->equalTo(SecurityEvents::INTERACTIVE_LOGIN)) - ; - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $handler->authenticateWithToken($this->token, $this->request); - } - - public function testHandleAuthenticationSuccess() - { - $providerKey = 'my_handleable_firewall'; - $response = new Response('Guard all the things!'); - $this->guardAuthenticator->expects($this->once()) - ->method('onAuthenticationSuccess') - ->with($this->request, $this->token, $providerKey) - ->willReturn($response); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $actualResponse = $handler->handleAuthenticationSuccess($this->token, $this->request, $this->guardAuthenticator, $providerKey); - $this->assertSame($response, $actualResponse); - } - - public function testHandleAuthenticationFailure() - { - // setToken() not called - getToken() will return null, so there's nothing to clear - $this->tokenStorage->expects($this->never()) - ->method('setToken') - ->with(null); - $authException = new AuthenticationException('Bad password!'); - - $response = new Response('Try again, but with the right password!'); - $this->guardAuthenticator->expects($this->once()) - ->method('onAuthenticationFailure') - ->with($this->request, $authException) - ->willReturn($response); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, 'firewall_provider_key'); - $this->assertSame($response, $actualResponse); - } - - /** - * @dataProvider getTokenClearingTests - */ - public function testHandleAuthenticationClearsToken($tokenProviderKey, $actualProviderKey) - { - $this->tokenStorage->expects($this->never()) - ->method('setToken') - ->with(null); - $authException = new AuthenticationException('Bad password!'); - - $response = new Response('Try again, but with the right password!'); - $this->guardAuthenticator->expects($this->once()) - ->method('onAuthenticationFailure') - ->with($this->request, $authException) - ->willReturn($response); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $actualResponse = $handler->handleAuthenticationFailure($authException, $this->request, $this->guardAuthenticator, $actualProviderKey); - $this->assertSame($response, $actualResponse); - } - - public function getTokenClearingTests() - { - $tests = []; - // matching firewall => clear the token - $tests[] = ['the_firewall_key', 'the_firewall_key']; - $tests[] = ['the_firewall_key', 'different_key']; - $tests[] = ['the_firewall_key', 'the_firewall_key']; - - return $tests; - } - - public function testNoFailureIfSessionStrategyNotPassed() - { - $this->configurePreviousSession(); - - $this->tokenStorage->expects($this->once()) - ->method('setToken') - ->with($this->token); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $handler->authenticateWithToken($this->token, $this->request); - } - - public function testSessionStrategyIsCalled() - { - $this->configurePreviousSession(); - - $this->sessionStrategy->expects($this->once()) - ->method('onAuthentication') - ->with($this->request, $this->token); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher); - $handler->setSessionAuthenticationStrategy($this->sessionStrategy); - $handler->authenticateWithToken($this->token, $this->request); - } - - public function testSessionStrategyIsNotCalledWhenStateless() - { - $this->configurePreviousSession(); - - $this->sessionStrategy->expects($this->never()) - ->method('onAuthentication'); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher, ['some_provider_key']); - $handler->setSessionAuthenticationStrategy($this->sessionStrategy); - $handler->authenticateWithToken($this->token, $this->request, 'some_provider_key'); - } - - public function testSessionIsNotInstantiatedOnStatelessFirewall() - { - $sessionFactory = $this->getMockBuilder(\stdClass::class) - ->setMethods(['__invoke']) - ->getMock(); - - $sessionFactory->expects($this->never()) - ->method('__invoke'); - - $this->request->setSessionFactory($sessionFactory); - - $handler = new GuardAuthenticatorHandler($this->tokenStorage, $this->dispatcher, ['stateless_provider_key']); - $handler->setSessionAuthenticationStrategy($this->sessionStrategy); - $handler->authenticateWithToken($this->token, $this->request, 'stateless_provider_key'); - } - - protected function setUp(): void - { - $this->tokenStorage = $this->createMock(TokenStorageInterface::class); - $this->dispatcher = $this->createMock(EventDispatcherInterface::class); - $this->token = $this->createMock(TokenInterface::class); - $this->request = new Request([], [], [], [], [], []); - $this->sessionStrategy = $this->createMock(SessionAuthenticationStrategyInterface::class); - $this->guardAuthenticator = $this->createMock(AuthenticatorInterface::class); - } - - protected function tearDown(): void - { - $this->tokenStorage = null; - $this->dispatcher = null; - $this->token = null; - $this->request = null; - $this->guardAuthenticator = null; - } - - private function configurePreviousSession() - { - $session = $this->createMock(SessionInterface::class); - $session->expects($this->any()) - ->method('getName') - ->willReturn('test_session_name'); - $this->request->setSession($session); - $this->request->cookies->set('test_session_name', 'session_cookie_val'); - } -} diff --git a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php b/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php deleted file mode 100644 index 61b70af13398b..0000000000000 --- a/src/Symfony/Component/Security/Guard/Tests/Provider/GuardAuthenticationProviderTest.php +++ /dev/null @@ -1,187 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests\Provider; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\AuthenticationExpiredException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\User\UserCheckerInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AuthenticatorInterface; -use Symfony\Component\Security\Guard\Provider\GuardAuthenticationProvider; -use Symfony\Component\Security\Guard\Token\GuardTokenInterface; -use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; -use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; - -/** - * @author Ryan Weaver - * @group legacy - */ -class GuardAuthenticationProviderTest extends TestCase -{ - private $userProvider; - private $userChecker; - private $preAuthenticationToken; - - public function testAuthenticate() - { - $providerKey = 'my_cool_firewall'; - - $authenticatorA = $this->createMock(AuthenticatorInterface::class); - $authenticatorB = $this->createMock(AuthenticatorInterface::class); - $authenticatorC = $this->createMock(AuthenticatorInterface::class); - $authenticators = [$authenticatorA, $authenticatorB, $authenticatorC]; - - // called 2 times - for authenticator A and B (stops on B because of match) - $this->preAuthenticationToken->expects($this->exactly(2)) - ->method('getGuardProviderKey') - // it will return the "1" index, which will match authenticatorB - ->willReturn('my_cool_firewall_1'); - - $enteredCredentials = [ - 'username' => '_weaverryan_test_user', - 'password' => 'guard_auth_ftw', - ]; - $this->preAuthenticationToken->expects($this->atLeastOnce()) - ->method('getCredentials') - ->willReturn($enteredCredentials); - - // authenticators A and C are never called - $authenticatorA->expects($this->never()) - ->method('getUser'); - $authenticatorC->expects($this->never()) - ->method('getUser'); - - $mockedUser = $this->createMock(UserInterface::class); - $authenticatorB->expects($this->once()) - ->method('getUser') - ->with($enteredCredentials, $this->userProvider) - ->willReturn($mockedUser); - // checkCredentials is called - $authenticatorB->expects($this->once()) - ->method('checkCredentials') - ->with($enteredCredentials, $mockedUser) - // authentication works! - ->willReturn(true); - $authedToken = $this->createMock(GuardTokenInterface::class); - $authenticatorB->expects($this->once()) - ->method('createAuthenticatedToken') - ->with($mockedUser, $providerKey) - ->willReturn($authedToken); - - // user checker should be called - $this->userChecker->expects($this->once()) - ->method('checkPreAuth') - ->with($mockedUser); - $this->userChecker->expects($this->once()) - ->method('checkPostAuth') - ->with($mockedUser); - - $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, $providerKey, $this->userChecker); - $actualAuthedToken = $provider->authenticate($this->preAuthenticationToken); - $this->assertSame($authedToken, $actualAuthedToken); - } - - public function testCheckCredentialsReturningFalseFailsAuthentication() - { - $this->expectException(BadCredentialsException::class); - $providerKey = 'my_uncool_firewall'; - - $authenticator = $this->createMock(AuthenticatorInterface::class); - - // make sure the authenticator is used - $this->preAuthenticationToken->expects($this->any()) - ->method('getGuardProviderKey') - // the 0 index, to match the only authenticator - ->willReturn('my_uncool_firewall_0'); - - $this->preAuthenticationToken->expects($this->atLeastOnce()) - ->method('getCredentials') - ->willReturn('non-null-value'); - - $mockedUser = $this->createMock(UserInterface::class); - $authenticator->expects($this->once()) - ->method('getUser') - ->willReturn($mockedUser); - // checkCredentials is called - $authenticator->expects($this->once()) - ->method('checkCredentials') - // authentication fails :( - ->willReturn(false); - - $provider = new GuardAuthenticationProvider([$authenticator], $this->userProvider, $providerKey, $this->userChecker); - $provider->authenticate($this->preAuthenticationToken); - } - - public function testGuardWithNoLongerAuthenticatedTriggersLogout() - { - $this->expectException(AuthenticationExpiredException::class); - $providerKey = 'my_firewall_abc'; - - // create a token and mark it as NOT authenticated anymore - // this mimics what would happen if a user "changed" between request - $mockedUser = $this->createMock(UserInterface::class); - $token = new PostAuthenticationGuardToken($mockedUser, $providerKey, ['ROLE_USER']); - $token->setAuthenticated(false); - - $provider = new GuardAuthenticationProvider([], $this->userProvider, $providerKey, $this->userChecker); - $provider->authenticate($token); - } - - public function testSupportsChecksGuardAuthenticatorsTokenOrigin() - { - $authenticatorA = $this->createMock(AuthenticatorInterface::class); - $authenticatorB = $this->createMock(AuthenticatorInterface::class); - $authenticators = [$authenticatorA, $authenticatorB]; - - $mockedUser = $this->createMock(UserInterface::class); - $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); - - $token = new PreAuthenticationGuardToken($mockedUser, 'first_firewall_1'); - $supports = $provider->supports($token); - $this->assertTrue($supports); - - $token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); - $supports = $provider->supports($token); - $this->assertFalse($supports); - } - - public function testAuthenticateFailsOnNonOriginatingToken() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessageMatches('/second_firewall_0/'); - $authenticatorA = $this->createMock(AuthenticatorInterface::class); - $authenticators = [$authenticatorA]; - - $mockedUser = $this->createMock(UserInterface::class); - $provider = new GuardAuthenticationProvider($authenticators, $this->userProvider, 'first_firewall', $this->userChecker); - - $token = new PreAuthenticationGuardToken($mockedUser, 'second_firewall_0'); - $provider->authenticate($token); - } - - protected function setUp(): void - { - $this->userProvider = $this->createMock(UserProviderInterface::class); - $this->userChecker = $this->createMock(UserCheckerInterface::class); - $this->preAuthenticationToken = $this->createMock(PreAuthenticationGuardToken::class); - } - - protected function tearDown(): void - { - $this->userProvider = null; - $this->userChecker = null; - $this->preAuthenticationToken = null; - } -} diff --git a/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php b/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php deleted file mode 100644 index a44413bb33798..0000000000000 --- a/src/Symfony/Component/Security/Guard/Token/GuardTokenInterface.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Token; - -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', GuardTokenInterface::class); - -/** - * A marker interface that both guard tokens implement. - * - * Any tokens passed to GuardAuthenticationProvider (i.e. any tokens that - * are handled by the guard auth system) must implement this - * interface. - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -interface GuardTokenInterface extends TokenInterface -{ -} diff --git a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php deleted file mode 100644 index a9050a4d66041..0000000000000 --- a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Token; - -use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; -use Symfony\Component\Security\Core\User\UserInterface; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', PostAuthenticationGuardToken::class); - -/** - * Used as an "authenticated" token, though it could be set to not-authenticated later. - * - * If you're using Guard authentication, you *must* use a class that implements - * GuardTokenInterface as your authenticated token (like this class). - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface -{ - private $providerKey; - - /** - * @param string $providerKey The provider (firewall) key - * @param string[] $roles An array of roles - * - * @throws \InvalidArgumentException - */ - public function __construct(UserInterface $user, string $providerKey, array $roles) - { - parent::__construct($roles); - - if (empty($providerKey)) { - throw new \InvalidArgumentException('$providerKey (i.e. firewall key) must not be empty.'); - } - - $this->setUser($user); - $this->providerKey = $providerKey; - - // this token is meant to be used after authentication success, so it is always authenticated - // you could set it as non authenticated later if you need to - $this->setAuthenticated(true, false); - } - - /** - * This is meant to be only an authenticated token, where credentials - * have already been used and are thus cleared. - * - * {@inheritdoc} - */ - public function getCredentials() - { - return []; - } - - /** - * Returns the provider (firewall) key. - * - * @return string - */ - public function getProviderKey() - { - return $this->providerKey; - } - - public function getFirewallName(): string - { - return $this->getProviderKey(); - } - - /** - * {@inheritdoc} - */ - public function __serialize(): array - { - return [$this->providerKey, parent::__serialize()]; - } - - /** - * {@inheritdoc} - */ - public function __unserialize(array $data): void - { - [$this->providerKey, $parentData] = $data; - $parentData = \is_array($parentData) ? $parentData : unserialize($parentData); - parent::__unserialize($parentData); - } -} diff --git a/src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php deleted file mode 100644 index f35f71030c84a..0000000000000 --- a/src/Symfony/Component/Security/Guard/Token/PreAuthenticationGuardToken.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Token; - -use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; - -trigger_deprecation('symfony/security-guard', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', PreAuthenticationGuardToken::class); - -/** - * The token used by the guard auth system before authentication. - * - * The GuardAuthenticationListener creates this, which is then consumed - * immediately by the GuardAuthenticationProvider. If authentication is - * successful, a different authenticated token is returned - * - * @author Ryan Weaver - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class PreAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface -{ - private $credentials; - private $guardProviderKey; - - /** - * @param $guardProviderKey Unique key that bind this token to a specific AuthenticatorInterface - */ - public function __construct(mixed $credentials, string $guardProviderKey) - { - $this->credentials = $credentials; - $this->guardProviderKey = $guardProviderKey; - - parent::__construct([]); - - // @deprecated since Symfony 5.4 - parent::setAuthenticated(false); - } - - public function getGuardProviderKey() - { - return $this->guardProviderKey; - } - - /** - * Returns the user credentials, which might be an array of anything you - * wanted to put in there (e.g. username, password, favoriteColor). - * - * @return mixed - */ - public function getCredentials() - { - return $this->credentials; - } - - /** - * @deprecated since Symfony 5.4 - */ - public function setAuthenticated(bool $authenticated) - { - throw new \LogicException('The PreAuthenticationGuardToken is *never* authenticated.'); - } -} diff --git a/src/Symfony/Component/Security/Guard/composer.json b/src/Symfony/Component/Security/Guard/composer.json deleted file mode 100644 index db7a5d2d3afb8..0000000000000 --- a/src/Symfony/Component/Security/Guard/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "symfony/security-guard", - "type": "library", - "description": "Symfony Security Component - Guard", - "keywords": [], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=8.0.2", - "symfony/security-core": "^5.4|^6.0", - "symfony/security-http": "^5.4|^6.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3" - }, - "autoload": { - "psr-4": { "Symfony\\Component\\Security\\Guard\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "minimum-stability": "dev" -} diff --git a/src/Symfony/Component/Security/Guard/phpunit.xml.dist b/src/Symfony/Component/Security/Guard/phpunit.xml.dist deleted file mode 100644 index 74064299dc982..0000000000000 --- a/src/Symfony/Component/Security/Guard/phpunit.xml.dist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - ./Tests/ - - - - - - ./ - - - ./Resources - ./Tests - ./vendor - - - diff --git a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php index 734378288c8e1..8ec1d7c59a48d 100644 --- a/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php +++ b/src/Symfony/Component/Security/Http/Authentication/AuthenticatorManager.php @@ -28,7 +28,7 @@ use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\Event\AuthenticationTokenCreatedEvent; use Symfony\Component\Security\Http\Event\CheckPassportEvent; @@ -75,9 +75,8 @@ public function __construct(iterable $authenticators, TokenStorageInterface $tok public function authenticateUser(UserInterface $user, AuthenticatorInterface $authenticator, Request $request, array $badges = []): ?Response { // create an authentication token for the User - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - $passport = new SelfValidatingPassport(new UserBadge(method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), function () use ($user) { return $user; }), $badges); - $token = method_exists($authenticator, 'createToken') ? $authenticator->createToken($passport, $this->firewallName) : $authenticator->createAuthenticatedToken($passport, $this->firewallName); + $passport = new SelfValidatingPassport(new UserBadge($user->getUserIdentifier(), function () use ($user) { return $user; }), $badges); + $token = $authenticator->createToken($passport, $this->firewallName); // announce the authentication token $token = $this->eventDispatcher->dispatch(new AuthenticationTokenCreatedEvent($token, $passport))->getAuthenticatedToken(); @@ -191,7 +190,7 @@ private function executeAuthenticator(AuthenticatorInterface $authenticator, Req } // create the authentication token - $authenticatedToken = method_exists($authenticator, 'createToken') ? $authenticator->createToken($passport, $this->firewallName) : $authenticator->createAuthenticatedToken($passport, $this->firewallName); + $authenticatedToken = $authenticator->createToken($passport, $this->firewallName); // announce the authentication token $authenticatedToken = $this->eventDispatcher->dispatch(new AuthenticationTokenCreatedEvent($authenticatedToken, $passport))->getAuthenticatedToken(); @@ -228,14 +227,8 @@ private function executeAuthenticator(AuthenticatorInterface $authenticator, Req return null; } - private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, PassportInterface $passport, Request $request, AuthenticatorInterface $authenticator): ?Response + private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, Passport $passport, Request $request, AuthenticatorInterface $authenticator): ?Response { - // @deprecated since Symfony 5.3 - $user = $authenticatedToken->getUser(); - if ($user instanceof UserInterface && !method_exists($user, 'getUserIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier(): string" in user class "%s" is deprecated. This method will replace "getUsername()" in Symfony 6.0.', get_debug_type($authenticatedToken->getUser())); - } - $this->tokenStorage->setToken($authenticatedToken); $response = $authenticator->onAuthenticationSuccess($request, $authenticatedToken, $this->firewallName); @@ -252,7 +245,7 @@ private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, /** * Handles an authentication failure and returns the Response for the authenticator. */ - private function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, AuthenticatorInterface $authenticator, ?PassportInterface $passport): ?Response + private function handleAuthenticationFailure(AuthenticationException $authenticationException, Request $request, AuthenticatorInterface $authenticator, ?Passport $passport): ?Response { if (null !== $this->logger) { $this->logger->info('Authenticator failed.', ['exception' => $authenticationException, 'authenticator' => \get_class($authenticator)]); diff --git a/src/Symfony/Component/Security/Http/Authentication/CustomAuthenticationSuccessHandler.php b/src/Symfony/Component/Security/Http/Authentication/CustomAuthenticationSuccessHandler.php index fd318b420169a..36ca5d34b7054 100644 --- a/src/Symfony/Component/Security/Http/Authentication/CustomAuthenticationSuccessHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/CustomAuthenticationSuccessHandler.php @@ -33,10 +33,6 @@ public function __construct(AuthenticationSuccessHandlerInterface $handler, arra if (method_exists($handler, 'setFirewallName')) { $this->handler->setFirewallName($firewallName); - } elseif (method_exists($handler, 'setProviderKey')) { - trigger_deprecation('symfony/security-http', '5.2', 'Method "%s::setProviderKey()" is deprecated, rename the method to "setFirewallName()" instead.', \get_class($handler)); - - $this->handler->setProviderKey($firewallName); } } diff --git a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php index 0972af94be53a..d7819d6155486 100644 --- a/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php +++ b/src/Symfony/Component/Security/Http/Authentication/DefaultAuthenticationSuccessHandler.php @@ -30,8 +30,6 @@ class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandle protected $httpUtils; protected $options; - /** @deprecated since Symfony 5.2, use $firewallName instead */ - protected $providerKey; protected $firewallName; protected $defaultOptions = [ 'always_use_default_target_path' => false, @@ -73,46 +71,13 @@ public function setOptions(array $options) $this->options = array_merge($this->defaultOptions, $options); } - /** - * Get the provider key. - * - * @return string - * - * @deprecated since Symfony 5.2, use getFirewallName() instead - */ - public function getProviderKey() - { - if (1 !== \func_num_args() || true !== func_get_arg(0)) { - trigger_deprecation('symfony/security-core', '5.2', 'Method "%s()" is deprecated, use "getFirewallName()" instead.', __METHOD__); - } - - if ($this->providerKey !== $this->firewallName) { - trigger_deprecation('symfony/security-core', '5.2', 'The "%1$s::$providerKey" property is deprecated, use "%1$s::$firewallName" instead.', __CLASS__); - - return $this->providerKey; - } - - return $this->firewallName; - } - - public function setProviderKey(string $providerKey) - { - if (2 !== \func_num_args() || true !== func_get_arg(1)) { - trigger_deprecation('symfony/security-http', '5.2', 'Method "%s" is deprecated, use "setFirewallName()" instead.', __METHOD__); - } - - $this->providerKey = $providerKey; - } - public function getFirewallName(): ?string { - return $this->getProviderKey(true); + return $this->firewallName; } public function setFirewallName(string $firewallName): void { - $this->setProviderKey($firewallName, true); - $this->firewallName = $firewallName; } diff --git a/src/Symfony/Component/Security/Http/Authentication/NoopAuthenticationManager.php b/src/Symfony/Component/Security/Http/Authentication/NoopAuthenticationManager.php deleted file mode 100644 index 308b317c3b3d9..0000000000000 --- a/src/Symfony/Component/Security/Http/Authentication/NoopAuthenticationManager.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Authentication; - -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; - -/** - * This class is used when the authenticator system is activated. - * - * This is used to not break AuthenticationChecker and ContextListener when - * using the authenticator system. Once the authenticator system is no longer - * experimental, this class can be used to trigger deprecation notices. - * - * @internal - * - * @author Wouter de Jong - */ -class NoopAuthenticationManager implements AuthenticationManagerInterface -{ - public function authenticate(TokenInterface $token): TokenInterface - { - return $token; - } -} diff --git a/src/Symfony/Component/Security/Http/Authenticator/AbstractAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/AbstractAuthenticator.php index f01ab340224be..297cbbd70306b 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/AbstractAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/AbstractAuthenticator.php @@ -14,8 +14,6 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\LogicException; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken; /** @@ -33,19 +31,4 @@ public function createToken(Passport $passport, string $firewallName): TokenInte { return new PostAuthenticationToken($passport->getUser(), $firewallName, $passport->getUser()->getRoles()); } - - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - // @deprecated since Symfony 5.4 - if (!$passport instanceof UserPassportInterface) { - throw new LogicException(sprintf('Passport does not contain a user, overwrite "createToken()" in "%s" to create a custom authentication token.', static::class)); - } - - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } } diff --git a/src/Symfony/Component/Security/Http/Authenticator/AbstractPreAuthenticatedAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/AbstractPreAuthenticatedAuthenticator.php index 8e0e32d99f778..0f451fda5ba1e 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/AbstractPreAuthenticatedAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/AbstractPreAuthenticatedAuthenticator.php @@ -23,7 +23,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PreAuthenticatedUserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; /** @@ -87,30 +86,12 @@ public function supports(Request $request): ?bool public function authenticate(Request $request): Passport { - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - $method = 'loadUserByIdentifier'; - if (!method_exists($this->userProvider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $method = 'loadUserByUsername'; - } - return new SelfValidatingPassport( - new UserBadge($request->attributes->get('_pre_authenticated_username'), [$this->userProvider, $method]), + new UserBadge($request->attributes->get('_pre_authenticated_username'), [$this->userProvider, 'loadUserByIdentifier']), [new PreAuthenticatedUserBadge()] ); } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { return new PreAuthenticatedToken($passport->getUser(), $firewallName, $passport->getUser()->getRoles()); diff --git a/src/Symfony/Component/Security/Http/Authenticator/AuthenticatorInterface.php b/src/Symfony/Component/Security/Http/Authenticator/AuthenticatorInterface.php index 940448b6977ae..a57121a93ed71 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/AuthenticatorInterface.php +++ b/src/Symfony/Component/Security/Http/Authenticator/AuthenticatorInterface.php @@ -16,7 +16,6 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; /** * The interface for all authenticators. @@ -24,10 +23,6 @@ * @author Ryan Weaver * @author Amaury Leroux de Lens * @author Wouter de Jong - * - * @method TokenInterface createToken(Passport $passport, string $firewallName) Creates a token for the given user. - * If you don't care about which token class is used, you can skip this method by extending - * the AbstractAuthenticator class from your authenticator. */ interface AuthenticatorInterface { @@ -66,11 +61,9 @@ public function authenticate(Request $request); /*: Passport;*/ * * @see AbstractAuthenticator * - * @param PassportInterface $passport The passport returned from authenticate() - * - * @deprecated since Symfony 5.4, use {@link createToken()} instead + * @param Passport $passport The passport returned from authenticate() */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface; + public function createToken(Passport $passport, string $firewallName): TokenInterface; /** * Called when authentication executed and was successful! diff --git a/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php index c239efd8a26ac..c92a58be0880f 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php @@ -30,7 +30,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Http\ParameterBagUtils; @@ -81,16 +80,8 @@ public function authenticate(Request $request): Passport { $credentials = $this->getCredentials($request); - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - $method = 'loadUserByIdentifier'; - if (!method_exists($this->userProvider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $method = 'loadUserByUsername'; - } - $passport = new Passport( - new UserBadge($credentials['username'], [$this->userProvider, $method]), + new UserBadge($credentials['username'], [$this->userProvider, 'loadUserByIdentifier']), new PasswordCredentials($credentials['password']), [new RememberMeBadge()] ); @@ -105,16 +96,6 @@ public function authenticate(Request $request): Passport return $passport; } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - /** * @return UsernamePasswordToken */ diff --git a/src/Symfony/Component/Security/Http/Authenticator/HttpBasicAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/HttpBasicAuthenticator.php index 892fce40fe817..2c6bc181c1447 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/HttpBasicAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/HttpBasicAuthenticator.php @@ -23,7 +23,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; /** @@ -59,21 +58,13 @@ public function supports(Request $request): ?bool return $request->headers->has('PHP_AUTH_USER'); } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { $username = $request->headers->get('PHP_AUTH_USER'); $password = $request->headers->get('PHP_AUTH_PW', ''); - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - $method = 'loadUserByIdentifier'; - if (!method_exists($this->userProvider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $method = 'loadUserByUsername'; - } - $passport = new Passport( - new UserBadge($username, [$this->userProvider, $method]), + new UserBadge($username, [$this->userProvider, 'loadUserByIdentifier']), new PasswordCredentials($password) ); if ($this->userProvider instanceof PasswordUpgraderInterface) { @@ -83,16 +74,6 @@ public function authenticate(Request $request): PassportInterface return $passport; } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { return new UsernamePasswordToken($passport->getUser(), $firewallName, $passport->getUser()->getRoles()); diff --git a/src/Symfony/Component/Security/Http/Authenticator/JsonLoginAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/JsonLoginAuthenticator.php index 3cdb365e843e8..243fbca39b509 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/JsonLoginAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/JsonLoginAuthenticator.php @@ -31,7 +31,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Contracts\Translation\TranslatorInterface; @@ -81,7 +80,7 @@ public function supports(Request $request): ?bool return true; } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { try { $credentials = $this->getCredentials($request); @@ -91,16 +90,8 @@ public function authenticate(Request $request): PassportInterface throw $e; } - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - $method = 'loadUserByIdentifier'; - if (!method_exists($this->userProvider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $method = 'loadUserByUsername'; - } - $passport = new Passport( - new UserBadge($credentials['username'], [$this->userProvider, $method]), + new UserBadge($credentials['username'], [$this->userProvider, 'loadUserByIdentifier']), new PasswordCredentials($credentials['password']) ); if ($this->userProvider instanceof PasswordUpgraderInterface) { @@ -110,16 +101,6 @@ public function authenticate(Request $request): PassportInterface return $passport; } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { return new UsernamePasswordToken($passport->getUser(), $firewallName, $passport->getUser()->getRoles()); diff --git a/src/Symfony/Component/Security/Http/Authenticator/LoginLinkAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/LoginLinkAuthenticator.php index 098349c8640e3..7b333e87d4f53 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/LoginLinkAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/LoginLinkAuthenticator.php @@ -19,7 +19,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Http\LoginLink\Exception\InvalidLoginLinkAuthenticationException; @@ -52,7 +52,7 @@ public function supports(Request $request): ?bool && $this->httpUtils->checkRequestPath($request, $this->options['check_route']); } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { $username = $request->get('user'); if (!$username) { diff --git a/src/Symfony/Component/Security/Http/Authenticator/Passport/Passport.php b/src/Symfony/Component/Security/Http/Authenticator/Passport/Passport.php index e326df19bb1f6..45431ec4c6bac 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/Passport/Passport.php +++ b/src/Symfony/Component/Security/Http/Authenticator/Passport/Passport.php @@ -21,7 +21,7 @@ * * @author Wouter de Jong */ -class Passport implements UserPassportInterface +class Passport { protected $user; diff --git a/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportInterface.php b/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportInterface.php deleted file mode 100644 index 14198b807e1d2..0000000000000 --- a/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Authenticator\Passport; - -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface; - -/** - * A Passport contains all security-related information that needs to be - * validated during authentication. - * - * A passport badge can be used to add any additional information to the - * passport. - * - * @author Wouter de Jong - * - * @deprecated since Symfony 5.4, use {@link Passport} instead - */ -interface PassportInterface -{ - /** - * Adds a new security badge. - * - * A passport can hold only one instance of the same security badge. - * This method replaces the current badge if it is already set on this - * passport. - * - * @return $this - */ - public function addBadge(BadgeInterface $badge): self; - - public function hasBadge(string $badgeFqcn): bool; - - public function getBadge(string $badgeFqcn): ?BadgeInterface; - - /** - * @return array, BadgeInterface> - */ - public function getBadges(): array; -} diff --git a/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportTrait.php b/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportTrait.php deleted file mode 100644 index 2a000145d8d12..0000000000000 --- a/src/Symfony/Component/Security/Http/Authenticator/Passport/PassportTrait.php +++ /dev/null @@ -1,54 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Authenticator\Passport; - -use Symfony\Component\Security\Http\Authenticator\Passport\Badge\BadgeInterface; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" trait is deprecated, you must extend from "%s" instead.', PassportTrait::class, Passport::class); - -/** - * @author Wouter de Jong - * - * @deprecated since Symfony 5.4, use {@see Passport} instead - */ -trait PassportTrait -{ - private $badges = []; - - /** - * @return $this - */ - public function addBadge(BadgeInterface $badge): PassportInterface - { - $this->badges[\get_class($badge)] = $badge; - - return $this; - } - - public function hasBadge(string $badgeFqcn): bool - { - return isset($this->badges[$badgeFqcn]); - } - - public function getBadge(string $badgeFqcn): ?BadgeInterface - { - return $this->badges[$badgeFqcn] ?? null; - } - - /** - * @return array, BadgeInterface> - */ - public function getBadges(): array - { - return $this->badges; - } -} diff --git a/src/Symfony/Component/Security/Http/Authenticator/Passport/UserPassportInterface.php b/src/Symfony/Component/Security/Http/Authenticator/Passport/UserPassportInterface.php deleted file mode 100644 index 319c2952dfeae..0000000000000 --- a/src/Symfony/Component/Security/Http/Authenticator/Passport/UserPassportInterface.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Authenticator\Passport; - -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * Represents a passport for a Security User. - * - * @author Wouter de Jong - * - * @deprecated since Symfony 5.4, use {@link Passport} instead - */ -interface UserPassportInterface extends PassportInterface -{ - /** - * @throws AuthenticationException when the user cannot be found - */ - public function getUser(): UserInterface; -} diff --git a/src/Symfony/Component/Security/Http/Authenticator/RememberMeAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/RememberMeAuthenticator.php index cca50c8b2d82f..9546a98089188 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/RememberMeAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/RememberMeAuthenticator.php @@ -23,7 +23,6 @@ use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\RememberMe\RememberMeDetails; use Symfony\Component\Security\Http\RememberMe\RememberMeHandlerInterface; @@ -82,7 +81,7 @@ public function supports(Request $request): ?bool return null; } - public function authenticate(Request $request): PassportInterface + public function authenticate(Request $request): Passport { $rawCookie = $request->cookies->get($this->cookieName); if (!$rawCookie) { @@ -96,16 +95,6 @@ public function authenticate(Request $request): PassportInterface })); } - /** - * @deprecated since Symfony 5.4, use {@link createToken()} instead - */ - public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use "%s::createToken()" instead.', __METHOD__, __CLASS__); - - return $this->createToken($passport, $firewallName); - } - public function createToken(Passport $passport, string $firewallName): TokenInterface { return new RememberMeToken($passport->getUser(), $firewallName, $this->secret); diff --git a/src/Symfony/Component/Security/Http/Authenticator/Token/PostAuthenticationToken.php b/src/Symfony/Component/Security/Http/Authenticator/Token/PostAuthenticationToken.php index 6bbec6f32dadd..d5c0cf2df92f1 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/Token/PostAuthenticationToken.php +++ b/src/Symfony/Component/Security/Http/Authenticator/Token/PostAuthenticationToken.php @@ -34,7 +34,7 @@ public function __construct(UserInterface $user, string $firewallName, array $ro $this->setUser($user); $this->firewallName = $firewallName; - // @deprecated since Symfony 5.4 + // required for compatibility with Symfony 5.4 if (method_exists($this, 'setAuthenticated')) { // this token is meant to be used after authentication success, so it is always authenticated $this->setAuthenticated(true, false); diff --git a/src/Symfony/Component/Security/Http/Controller/UserValueResolver.php b/src/Symfony/Component/Security/Http/Controller/UserValueResolver.php index 9d10f3286f822..dbcdd3067d8aa 100644 --- a/src/Symfony/Component/Security/Http/Controller/UserValueResolver.php +++ b/src/Symfony/Component/Security/Http/Controller/UserValueResolver.php @@ -42,15 +42,8 @@ public function supports(Request $request, ArgumentMetadata $argument): bool } $token = $this->tokenStorage->getToken(); - if (!$token instanceof TokenInterface) { - return false; - } - - $user = $token->getUser(); - // in case it's not an object we cannot do anything with it; E.g. "anon." - // @deprecated since 5.4 - return $user instanceof UserInterface; + return $token instanceof TokenInterface; } public function resolve(Request $request, ArgumentMetadata $argument): iterable diff --git a/src/Symfony/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPoint.php deleted file mode 100644 index 53a029360b79d..0000000000000 --- a/src/Symfony/Component/Security/Http/EntryPoint/BasicAuthenticationEntryPoint.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\EntryPoint; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use the new security system with "%s" instead.', BasicAuthenticationEntryPoint::class, HttpBasicAuthenticator::class); - -/** - * BasicAuthenticationEntryPoint starts an HTTP Basic authentication. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.4 - */ -class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface -{ - private $realmName; - - public function __construct(string $realmName) - { - $this->realmName = $realmName; - } - - /** - * {@inheritdoc} - */ - public function start(Request $request, AuthenticationException $authException = null) - { - $response = new Response(); - $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realmName)); - $response->setStatusCode(401); - - return $response; - } -} diff --git a/src/Symfony/Component/Security/Http/EntryPoint/FormAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/FormAuthenticationEntryPoint.php deleted file mode 100644 index 32cc5a0e06db0..0000000000000 --- a/src/Symfony/Component/Security/Http/EntryPoint/FormAuthenticationEntryPoint.php +++ /dev/null @@ -1,66 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\EntryPoint; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator; -use Symfony\Component\Security\Http\HttpUtils; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use the new security system with "%s" instead.', FormAuthenticationEntryPoint::class, FormLoginAuthenticator::class); - -/** - * FormAuthenticationEntryPoint starts an authentication via a login form. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.4 - */ -class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface -{ - private $loginPath; - private $useForward; - private $httpKernel; - private $httpUtils; - - /** - * @param string $loginPath The path to the login form - * @param bool $useForward Whether to forward or redirect to the login form - */ - public function __construct(HttpKernelInterface $kernel, HttpUtils $httpUtils, string $loginPath, bool $useForward = false) - { - $this->httpKernel = $kernel; - $this->httpUtils = $httpUtils; - $this->loginPath = $loginPath; - $this->useForward = $useForward; - } - - /** - * {@inheritdoc} - */ - public function start(Request $request, AuthenticationException $authException = null) - { - if ($this->useForward) { - $subRequest = $this->httpUtils->createRequest($request, $this->loginPath); - - $response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST); - if (200 === $response->getStatusCode()) { - $response->setStatusCode(401); - } - - return $response; - } - - return $this->httpUtils->createRedirectResponse($request, $this->loginPath); - } -} diff --git a/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php b/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php deleted file mode 100644 index 55e86f96d6f4b..0000000000000 --- a/src/Symfony/Component/Security/Http/EntryPoint/RetryAuthenticationEntryPoint.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\EntryPoint; - -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Firewall\ChannelListener; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use "%s" directly (and optionally configure the HTTP(s) ports there).', RetryAuthenticationEntryPoint::class, ChannelListener::class); - -/** - * RetryAuthenticationEntryPoint redirects URL based on the configured scheme. - * - * This entry point is not intended to work with HTTP post requests. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.4 - */ -class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface -{ - private $httpPort; - private $httpsPort; - - public function __construct(int $httpPort = 80, int $httpsPort = 443) - { - $this->httpPort = $httpPort; - $this->httpsPort = $httpsPort; - } - - /** - * {@inheritdoc} - */ - public function start(Request $request, AuthenticationException $authException = null) - { - $scheme = $request->isSecure() ? 'http' : 'https'; - if ('http' === $scheme && 80 != $this->httpPort) { - $port = ':'.$this->httpPort; - } elseif ('https' === $scheme && 443 != $this->httpsPort) { - $port = ':'.$this->httpsPort; - } else { - $port = ''; - } - - $qs = $request->getQueryString(); - if (null !== $qs) { - $qs = '?'.$qs; - } - - $url = $scheme.'://'.$request->getHost().$port.$request->getBaseUrl().$request->getPathInfo().$qs; - - return new RedirectResponse($url, 301); - } -} diff --git a/src/Symfony/Component/Security/Http/Event/AuthenticationTokenCreatedEvent.php b/src/Symfony/Component/Security/Http/Event/AuthenticationTokenCreatedEvent.php index 632f3ec8d12b4..e9ed8aa49e176 100644 --- a/src/Symfony/Component/Security/Http/Event/AuthenticationTokenCreatedEvent.php +++ b/src/Symfony/Component/Security/Http/Event/AuthenticationTokenCreatedEvent.php @@ -13,7 +13,6 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Contracts\EventDispatcher\Event; /** @@ -26,15 +25,8 @@ class AuthenticationTokenCreatedEvent extends Event private $authenticatedToken; private $passport; - /** - * @param Passport $passport - */ - public function __construct(TokenInterface $token, PassportInterface $passport) + public function __construct(TokenInterface $token, Passport $passport) { - if (!$passport instanceof Passport) { - trigger_deprecation('symfony/security-http', '5.4', 'Not passing an instance of "%s" as "$passport" argument of "%s()" is deprecated, "%s" given.', Passport::class, __METHOD__, get_debug_type($passport)); - } - $this->authenticatedToken = $token; $this->passport = $passport; } @@ -49,7 +41,7 @@ public function setAuthenticatedToken(TokenInterface $authenticatedToken): void $this->authenticatedToken = $authenticatedToken; } - public function getPassport(): PassportInterface + public function getPassport(): Passport { return $this->passport; } diff --git a/src/Symfony/Component/Security/Http/Event/CheckPassportEvent.php b/src/Symfony/Component/Security/Http/Event/CheckPassportEvent.php index a3fe109b42cbc..b207552f5b955 100644 --- a/src/Symfony/Component/Security/Http/Event/CheckPassportEvent.php +++ b/src/Symfony/Component/Security/Http/Event/CheckPassportEvent.php @@ -13,7 +13,6 @@ use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Contracts\EventDispatcher\Event; /** @@ -30,15 +29,8 @@ class CheckPassportEvent extends Event private $authenticator; private $passport; - /** - * @param Passport $passport - */ - public function __construct(AuthenticatorInterface $authenticator, PassportInterface $passport) + public function __construct(AuthenticatorInterface $authenticator, Passport $passport) { - if (!$passport instanceof Passport) { - trigger_deprecation('symfony/security-http', '5.4', 'Not passing an instance of "%s" as "$passport" argument of "%s()" is deprecated, "%s" given.', Passport::class, __METHOD__, get_debug_type($passport)); - } - $this->authenticator = $authenticator; $this->passport = $passport; } @@ -48,7 +40,7 @@ public function getAuthenticator(): AuthenticatorInterface return $this->authenticator; } - public function getPassport(): PassportInterface + public function getPassport(): Passport { return $this->passport; } diff --git a/src/Symfony/Component/Security/Http/Event/DeauthenticatedEvent.php b/src/Symfony/Component/Security/Http/Event/DeauthenticatedEvent.php deleted file mode 100644 index f064cceaac56c..0000000000000 --- a/src/Symfony/Component/Security/Http/Event/DeauthenticatedEvent.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Event; - -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Contracts\EventDispatcher\Event; - -/** - * Deauthentication happens in case the user has changed when trying to - * refresh the token. - * - * Use {@see TokenDeauthenticatedEvent} if you want to cover all cases where - * a session is deauthenticated. - * - * @author Hamza Amrouche - * - * @deprecated since Symfony 5.4, use TokenDeauthenticatedEvent instead - */ -final class DeauthenticatedEvent extends Event -{ - private $originalToken; - private $refreshedToken; - - public function __construct(TokenInterface $originalToken, TokenInterface $refreshedToken, bool $triggerDeprecation = true) - { - if ($triggerDeprecation) { - @trigger_deprecation('symfony/security-http', '5.4', 'Class "%s" is deprecated, use "%s" instead.', __CLASS__, TokenDeauthenticatedEvent::class); - } - - $this->originalToken = $originalToken; - $this->refreshedToken = $refreshedToken; - } - - public function getRefreshedToken(): TokenInterface - { - @trigger_deprecation('symfony/security-http', '5.4', 'Class "%s" is deprecated, use "%s" instead.', __CLASS__, TokenDeauthenticatedEvent::class); - - return $this->refreshedToken; - } - - public function getOriginalToken(): TokenInterface - { - @trigger_deprecation('symfony/security-http', '5.4', 'Class "%s" is deprecated, use "%s" instead.', __CLASS__, TokenDeauthenticatedEvent::class); - - return $this->originalToken; - } -} diff --git a/src/Symfony/Component/Security/Http/Event/LazyResponseEvent.php b/src/Symfony/Component/Security/Http/Event/LazyResponseEvent.php index 319be376b635f..4ad312c115b5d 100644 --- a/src/Symfony/Component/Security/Http/Event/LazyResponseEvent.php +++ b/src/Symfony/Component/Security/Http/Event/LazyResponseEvent.php @@ -73,14 +73,4 @@ public function isMainRequest(): bool { return $this->event->isMainRequest(); } - - /** - * {@inheritdoc} - */ - public function isMasterRequest(): bool - { - trigger_deprecation('symfony/security-http', '5.3', '"%s()" is deprecated, use "isMainRequest()" instead.', __METHOD__); - - return $this->event->isMainRequest(); - } } diff --git a/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php b/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php index 1d58c1d4df241..5102877d8e224 100644 --- a/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php +++ b/src/Symfony/Component/Security/Http/Event/LoginFailureEvent.php @@ -16,7 +16,6 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Contracts\EventDispatcher\Event; /** @@ -36,15 +35,8 @@ class LoginFailureEvent extends Event private $firewallName; private $passport; - /** - * @param Passport|null $passport - */ - public function __construct(AuthenticationException $exception, AuthenticatorInterface $authenticator, Request $request, ?Response $response, string $firewallName, PassportInterface $passport = null) + public function __construct(AuthenticationException $exception, AuthenticatorInterface $authenticator, Request $request, ?Response $response, string $firewallName, Passport $passport = null) { - if (null !== $passport && !$passport instanceof Passport) { - trigger_deprecation('symfony/security-http', '5.4', 'Not passing an instance of "%s" or "null" as "$passport" argument of "%s()" is deprecated, "%s" given.', Passport::class, __METHOD__, get_debug_type($passport)); - } - $this->exception = $exception; $this->authenticator = $authenticator; $this->request = $request; @@ -83,7 +75,7 @@ public function getResponse(): ?Response return $this->response; } - public function getPassport(): ?PassportInterface + public function getPassport(): ?Passport { return $this->passport; } diff --git a/src/Symfony/Component/Security/Http/Event/LoginSuccessEvent.php b/src/Symfony/Component/Security/Http/Event/LoginSuccessEvent.php index d2272fe2c6f32..70bcb794af794 100644 --- a/src/Symfony/Component/Security/Http/Event/LoginSuccessEvent.php +++ b/src/Symfony/Component/Security/Http/Event/LoginSuccessEvent.php @@ -18,8 +18,6 @@ use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Contracts\EventDispatcher\Event; /** @@ -41,15 +39,8 @@ class LoginSuccessEvent extends Event private $response; private $firewallName; - /** - * @param Passport $passport - */ - public function __construct(AuthenticatorInterface $authenticator, PassportInterface $passport, TokenInterface $authenticatedToken, Request $request, ?Response $response, string $firewallName) + public function __construct(AuthenticatorInterface $authenticator, Passport $passport, TokenInterface $authenticatedToken, Request $request, ?Response $response, string $firewallName) { - if (!$passport instanceof Passport) { - trigger_deprecation('symfony/security-http', '5.4', 'Not passing an instance of "%s" as "$passport" argument of "%s()" is deprecated, "%s" given.', Passport::class, __METHOD__, get_debug_type($passport)); - } - $this->authenticator = $authenticator; $this->passport = $passport; $this->authenticatedToken = $authenticatedToken; @@ -63,18 +54,13 @@ public function getAuthenticator(): AuthenticatorInterface return $this->authenticator; } - public function getPassport(): PassportInterface + public function getPassport(): Passport { return $this->passport; } public function getUser(): UserInterface { - // @deprecated since Symfony 5.4, passport will always have a user in 6.0 - if (!$this->passport instanceof UserPassportInterface) { - throw new LogicException(sprintf('Cannot call "%s" as the authenticator ("%s") did not set a user.', __METHOD__, \get_class($this->authenticator))); - } - return $this->passport->getUser(); } diff --git a/src/Symfony/Component/Security/Http/EventListener/CheckCredentialsListener.php b/src/Symfony/Component/Security/Http/EventListener/CheckCredentialsListener.php index f968bfd552a70..c109694607167 100644 --- a/src/Symfony/Component/Security/Http/EventListener/CheckCredentialsListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/CheckCredentialsListener.php @@ -19,7 +19,6 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\CheckPassportEvent; /** @@ -42,7 +41,7 @@ public function __construct(PasswordHasherFactoryInterface $hasherFactory) public function checkPassport(CheckPassportEvent $event): void { $passport = $event->getPassport(); - if ($passport instanceof UserPassportInterface && $passport->hasBadge(PasswordCredentials::class)) { + if ($passport->hasBadge(PasswordCredentials::class)) { // Use the password hasher to validate the credentials $user = $passport->getUser(); diff --git a/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php b/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php index a68d1904a8f34..c63fcd74f1834 100644 --- a/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php @@ -18,7 +18,6 @@ use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; /** @@ -38,7 +37,7 @@ public function __construct(PasswordHasherFactoryInterface $hasherFactory) public function onLoginSuccess(LoginSuccessEvent $event): void { $passport = $event->getPassport(); - if (!$passport instanceof UserPassportInterface || !$passport->hasBadge(PasswordUpgradeBadge::class)) { + if (!$passport->hasBadge(PasswordUpgradeBadge::class)) { return; } diff --git a/src/Symfony/Component/Security/Http/EventListener/RememberMeLogoutListener.php b/src/Symfony/Component/Security/Http/EventListener/RememberMeLogoutListener.php deleted file mode 100644 index b97558f346d00..0000000000000 --- a/src/Symfony/Component/Security/Http/EventListener/RememberMeLogoutListener.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\EventListener; - -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Security\Core\Exception\LogicException; -use Symfony\Component\Security\Http\Event\LogoutEvent; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated.', RememberMeLogoutListener::class); - -/** - * @author Wouter de Jong - * - * @final - * - * @deprecated since Symfony 5.4 - */ -class RememberMeLogoutListener implements EventSubscriberInterface -{ - private $rememberMeServices; - - public function __construct(RememberMeServicesInterface $rememberMeServices) - { - if (!method_exists($rememberMeServices, 'logout')) { - trigger_deprecation('symfony/security-core', '5.1', '"%s" should implement the "logout(Request $request, Response $response, TokenInterface $token)" method, this method will be added to the "%s" in version 6.0.', \get_class($rememberMeServices), RememberMeServicesInterface::class); - } - - $this->rememberMeServices = $rememberMeServices; - } - - public function onLogout(LogoutEvent $event): void - { - if (!method_exists($this->rememberMeServices, 'logout')) { - return; - } - - if (!$event->getToken()) { - return; - } - - if (null === $event->getResponse()) { - throw new LogicException(sprintf('No response was set for this logout action. Make sure the DefaultLogoutListener or another listener has set the response before "%s" is called.', __CLASS__)); - } - - $this->rememberMeServices->logout($event->getRequest(), $event->getResponse(), $event->getToken()); - } - - public static function getSubscribedEvents(): array - { - return [ - LogoutEvent::class => 'onLogout', - ]; - } -} diff --git a/src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php b/src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php index 063098067a7b7..96152f41296bf 100644 --- a/src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/UserCheckerListener.php @@ -16,7 +16,6 @@ use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PreAuthenticatedUserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\CheckPassportEvent; /** @@ -36,7 +35,7 @@ public function __construct(UserCheckerInterface $userChecker) public function preCheckCredentials(CheckPassportEvent $event): void { $passport = $event->getPassport(); - if (!$passport instanceof UserPassportInterface || $passport->hasBadge(PreAuthenticatedUserBadge::class)) { + if ($passport->hasBadge(PreAuthenticatedUserBadge::class)) { return; } @@ -46,10 +45,6 @@ public function preCheckCredentials(CheckPassportEvent $event): void public function postCheckCredentials(AuthenticationSuccessEvent $event): void { $user = $event->getAuthenticationToken()->getUser(); - // @deprecated since 5.4, $user will always be an UserInterface instance - if (!$user instanceof UserInterface) { - return; - } $this->userChecker->checkPostAuth($user); } diff --git a/src/Symfony/Component/Security/Http/EventListener/UserProviderListener.php b/src/Symfony/Component/Security/Http/EventListener/UserProviderListener.php index a3408789d1c71..53144cedb5492 100644 --- a/src/Symfony/Component/Security/Http/EventListener/UserProviderListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/UserProviderListener.php @@ -45,13 +45,6 @@ public function checkPassport(CheckPassportEvent $event): void return; } - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($this->userProvider, 'loadUserByIdentifier')) { - $badge->setUserLoader([$this->userProvider, 'loadUserByIdentifier']); - } else { - trigger_deprecation('symfony/security-http', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $badge->setUserLoader([$this->userProvider, 'loadUserByUsername']); - } + $badge->setUserLoader([$this->userProvider, 'loadUserByIdentifier']); } } diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php deleted file mode 100644 index 33e2c08b64d86..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractAuthenticationListener.php +++ /dev/null @@ -1,229 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\SessionUnavailableException; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; -use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\HttpUtils; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AbstractAuthenticationListener::class); - -/** - * The AbstractAuthenticationListener is the preferred base class for all - * browser-/HTTP-based authentication requests. - * - * Subclasses likely have to implement the following: - * - an TokenInterface to hold authentication related data - * - an AuthenticationProvider to perform the actual authentication of the - * token, retrieve the UserInterface implementation from a database, and - * perform the specific account checks using the UserChecker - * - * By default, this listener only is active for a specific path, e.g. - * /login_check. If you want to change this behavior, you can overwrite the - * requiresAuthentication() method. - * - * @author Fabien Potencier - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -abstract class AbstractAuthenticationListener extends AbstractListener -{ - protected $options; - protected $logger; - protected $authenticationManager; - protected $providerKey; - protected $httpUtils; - - private $tokenStorage; - private $sessionStrategy; - private $dispatcher; - private $successHandler; - private $failureHandler; - private $rememberMeServices; - - /** - * @throws \InvalidArgumentException - */ - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, string $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) - { - if (empty($providerKey)) { - throw new \InvalidArgumentException('$providerKey must not be empty.'); - } - - $this->tokenStorage = $tokenStorage; - $this->authenticationManager = $authenticationManager; - $this->sessionStrategy = $sessionStrategy; - $this->providerKey = $providerKey; - $this->successHandler = $successHandler; - $this->failureHandler = $failureHandler; - $this->options = array_merge([ - 'check_path' => '/login_check', - 'login_path' => '/login', - 'always_use_default_target_path' => false, - 'default_target_path' => '/', - 'target_path_parameter' => '_target_path', - 'use_referer' => false, - 'failure_path' => null, - 'failure_forward' => false, - 'require_previous_session' => true, - ], $options); - $this->logger = $logger; - $this->dispatcher = $dispatcher; - $this->httpUtils = $httpUtils; - } - - /** - * Sets the RememberMeServices implementation to use. - */ - public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices) - { - $this->rememberMeServices = $rememberMeServices; - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - return $this->requiresAuthentication($request); - } - - /** - * Handles form based authentication. - * - * @throws \RuntimeException - * @throws SessionUnavailableException - */ - public function authenticate(RequestEvent $event) - { - $request = $event->getRequest(); - - if (!$request->hasSession()) { - throw new \RuntimeException('This authentication method requires a session.'); - } - - try { - if ($this->options['require_previous_session'] && !$request->hasPreviousSession()) { - throw new SessionUnavailableException('Your session has timed out, or you have disabled cookies.'); - } - - if (null === $returnValue = $this->attemptAuthentication($request)) { - return; - } - - if ($returnValue instanceof TokenInterface) { - $this->sessionStrategy->onAuthentication($request, $returnValue); - - $response = $this->onSuccess($request, $returnValue); - } elseif ($returnValue instanceof Response) { - $response = $returnValue; - } else { - throw new \RuntimeException('attemptAuthentication() must either return a Response, an implementation of TokenInterface, or null.'); - } - } catch (AuthenticationException $e) { - $response = $this->onFailure($request, $e); - } - - $event->setResponse($response); - } - - /** - * Whether this request requires authentication. - * - * The default implementation only processes requests to a specific path, - * but a subclass could change this to only authenticate requests where a - * certain parameters is present. - * - * @return bool - */ - protected function requiresAuthentication(Request $request) - { - return $this->httpUtils->checkRequestPath($request, $this->options['check_path']); - } - - /** - * Performs authentication. - * - * @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response - * - * @throws AuthenticationException if the authentication fails - */ - abstract protected function attemptAuthentication(Request $request); - - private function onFailure(Request $request, AuthenticationException $failed): Response - { - if (null !== $this->logger) { - $this->logger->info('Authentication request failed.', ['exception' => $failed]); - } - - $token = $this->tokenStorage->getToken(); - if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getFirewallName()) { - $this->tokenStorage->setToken(null); - } - - $response = $this->failureHandler->onAuthenticationFailure($request, $failed); - - if (!$response instanceof Response) { - throw new \RuntimeException('Authentication Failure Handler did not return a Response.'); - } - - return $response; - } - - private function onSuccess(Request $request, TokenInterface $token): Response - { - if (null !== $this->logger) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $this->logger->info('User has been authenticated successfully.', ['username' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()]); - } - - $this->tokenStorage->setToken($token); - - $session = $request->getSession(); - $session->remove(Security::AUTHENTICATION_ERROR); - $session->remove(Security::LAST_USERNAME); - - if (null !== $this->dispatcher) { - $loginEvent = new InteractiveLoginEvent($request, $token); - $this->dispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN); - } - - $response = $this->successHandler->onAuthenticationSuccess($request, $token); - - if (!$response instanceof Response) { - throw new \RuntimeException('Authentication Success Handler did not return a Response.'); - } - - if (null !== $this->rememberMeServices) { - $this->rememberMeServices->loginSuccess($request, $response, $token); - } - - return $response; - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php b/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php deleted file mode 100644 index b698e1e4d7dca..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/AbstractPreAuthenticatedListener.php +++ /dev/null @@ -1,160 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AbstractPreAuthenticatedListener::class); - -/** - * AbstractPreAuthenticatedListener is the base class for all listener that - * authenticates users based on a pre-authenticated request (like a certificate - * for instance). - * - * @author Fabien Potencier - * - * @internal - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -abstract class AbstractPreAuthenticatedListener extends AbstractListener -{ - protected $logger; - private $tokenStorage; - private $authenticationManager; - private $providerKey; - private $dispatcher; - private $sessionStrategy; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) - { - $this->tokenStorage = $tokenStorage; - $this->authenticationManager = $authenticationManager; - $this->providerKey = $providerKey; - $this->logger = $logger; - $this->dispatcher = $dispatcher; - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - try { - $request->attributes->set('_pre_authenticated_data', $this->getPreAuthenticatedData($request)); - } catch (BadCredentialsException $e) { - $this->clearToken($e); - - return false; - } - - return true; - } - - /** - * Handles pre-authentication. - */ - public function authenticate(RequestEvent $event) - { - $request = $event->getRequest(); - - [$user, $credentials] = $request->attributes->get('_pre_authenticated_data'); - $request->attributes->remove('_pre_authenticated_data'); - - if (null !== $this->logger) { - $this->logger->debug('Checking current security token.', ['token' => (string) $this->tokenStorage->getToken()]); - } - - if (null !== $token = $this->tokenStorage->getToken()) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - if ($token instanceof PreAuthenticatedToken && $this->providerKey == $token->getFirewallName() && $token->isAuthenticated() && (method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $user) { - return; - } - } - - if (null !== $this->logger) { - $this->logger->debug('Trying to pre-authenticate user.', ['username' => (string) $user]); - } - - try { - $token = $this->authenticationManager->authenticate(new PreAuthenticatedToken($user, $credentials, $this->providerKey)); - - if (null !== $this->logger) { - $this->logger->info('Pre-authentication successful.', ['token' => (string) $token]); - } - - $this->migrateSession($request, $token); - - $this->tokenStorage->setToken($token); - - if (null !== $this->dispatcher) { - $loginEvent = new InteractiveLoginEvent($request, $token); - $this->dispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN); - } - } catch (AuthenticationException $e) { - $this->clearToken($e); - } - } - - /** - * Call this method if your authentication token is stored to a session. - * - * @final - */ - public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy) - { - $this->sessionStrategy = $sessionStrategy; - } - - /** - * Clears a PreAuthenticatedToken for this provider (if present). - */ - private function clearToken(AuthenticationException $exception) - { - $token = $this->tokenStorage->getToken(); - if ($token instanceof PreAuthenticatedToken && $this->providerKey === $token->getFirewallName()) { - $this->tokenStorage->setToken(null); - - if (null !== $this->logger) { - $this->logger->info('Cleared security token due to an exception.', ['exception' => $exception]); - } - } - } - - /** - * Gets the user and credentials from the Request. - * - * @return array An array composed of the user and the credentials - */ - abstract protected function getPreAuthenticatedData(Request $request); - - private function migrateSession(Request $request, TokenInterface $token) - { - if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) { - return; - } - - $this->sessionStrategy->onAuthentication($request, $token); - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php index 0e7033890238c..244f273ae0b37 100644 --- a/src/Symfony/Component/Security/Http/Firewall/AccessListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/AccessListener.php @@ -36,26 +36,16 @@ class AccessListener extends AbstractListener private $tokenStorage; private $accessDecisionManager; private $map; - private $authManager; - private $exceptionOnNoToken; - public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, /*bool*/ $exceptionOnNoToken = true) + public function __construct(TokenStorageInterface $tokenStorage, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, bool $exceptionOnNoToken = false) { - if ($exceptionOnNoToken instanceof AuthenticationManagerInterface) { - trigger_deprecation('symfony/security-http', '5.4', 'The $authManager argument of "%s" is deprecated.', __METHOD__); - $authManager = $exceptionOnNoToken; - $exceptionOnNoToken = \func_num_args() > 4 ? func_get_arg(4) : true; - } - if (false !== $exceptionOnNoToken) { - trigger_deprecation('symfony/security-http', '5.4', 'Not setting the $exceptionOnNoToken argument of "%s" to "false" is deprecated.', __METHOD__); + throw new \LogicException('Argument $exceptionOnNoToken of "%s()" must be set to "false".', __METHOD__); } $this->tokenStorage = $tokenStorage; $this->accessDecisionManager = $accessDecisionManager; $this->map = $map; - $this->authManager = $authManager ?? (class_exists(AuthenticationManagerInterface::class) ? new NoopAuthenticationManager() : null); - $this->exceptionOnNoToken = $exceptionOnNoToken; } /** @@ -80,14 +70,9 @@ public function supports(Request $request): ?bool * Handles access authorization. * * @throws AccessDeniedException - * @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token and $exceptionOnNoToken is set to true */ public function authenticate(RequestEvent $event) { - if (!$event instanceof LazyResponseEvent && null === ($token = $this->tokenStorage->getToken()) && $this->exceptionOnNoToken) { - throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.'); - } - $request = $event->getRequest(); $attributes = $request->attributes->get('_access_control_attributes'); @@ -100,28 +85,11 @@ public function authenticate(RequestEvent $event) return; } - if ($event instanceof LazyResponseEvent) { - $token = $this->tokenStorage->getToken(); - } - + $token = $this->tokenStorage->getToken(); if (null === $token) { - if ($this->exceptionOnNoToken) { - throw new AuthenticationCredentialsNotFoundException('A Token was not found in the TokenStorage.'); - } - $token = new NullToken(); } - // @deprecated since Symfony 5.4 - if (method_exists($token, 'isAuthenticated') && !$token->isAuthenticated(false)) { - trigger_deprecation('symfony/core', '5.4', 'Returning false from "%s()" is deprecated and won\'t have any effect in Symfony 6.0 as security tokens will always be considered authenticated.'); - - if ($this->authManager) { - $token = $this->authManager->authenticate($token); - $this->tokenStorage->setToken($token); - } - } - if (!$this->accessDecisionManager->decide($token, $attributes, $request, true)) { throw $this->createAccessDeniedException($request, $attributes); } diff --git a/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php deleted file mode 100644 index 8f175ae7987a4..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/AnonymousAuthenticationListener.php +++ /dev/null @@ -1,84 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AnonymousAuthenticationListener::class); - -// Help opcache.preload discover always-needed symbols -class_exists(AnonymousToken::class); - -/** - * AnonymousAuthenticationListener automatically adds a Token if none is - * already present. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class AnonymousAuthenticationListener extends AbstractListener -{ - private $tokenStorage; - private $secret; - private $authenticationManager; - private $logger; - - public function __construct(TokenStorageInterface $tokenStorage, string $secret, LoggerInterface $logger = null, AuthenticationManagerInterface $authenticationManager = null) - { - $this->tokenStorage = $tokenStorage; - $this->secret = $secret; - $this->authenticationManager = $authenticationManager; - $this->logger = $logger; - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - return null; // always run authenticate() lazily with lazy firewalls - } - - /** - * Handles anonymous authentication. - */ - public function authenticate(RequestEvent $event) - { - if (null !== $this->tokenStorage->getToken()) { - return; - } - - try { - $token = new AnonymousToken($this->secret, 'anon.', []); - if (null !== $this->authenticationManager) { - $token = $this->authenticationManager->authenticate($token); - } - - $this->tokenStorage->setToken($token); - - if (null !== $this->logger) { - $this->logger->info('Populated the TokenStorage with an anonymous Token.'); - } - } catch (AuthenticationException $failed) { - if (null !== $this->logger) { - $this->logger->info('Anonymous authentication failed.', ['exception' => $failed]); - } - } - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php deleted file mode 100644 index 8113e9f1ad267..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/BasicAuthenticationListener.php +++ /dev/null @@ -1,132 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', AnonymousAuthenticationListener::class); - -/** - * BasicAuthenticationListener implements Basic HTTP authentication. - * - * @author Fabien Potencier - * - * @final - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class BasicAuthenticationListener extends AbstractListener -{ - private $tokenStorage; - private $authenticationManager; - private $providerKey; - private $authenticationEntryPoint; - private $logger; - private $ignoreFailure; - private $sessionStrategy; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, AuthenticationEntryPointInterface $authenticationEntryPoint, LoggerInterface $logger = null) - { - if (empty($providerKey)) { - throw new \InvalidArgumentException('$providerKey must not be empty.'); - } - - $this->tokenStorage = $tokenStorage; - $this->authenticationManager = $authenticationManager; - $this->providerKey = $providerKey; - $this->authenticationEntryPoint = $authenticationEntryPoint; - $this->logger = $logger; - $this->ignoreFailure = false; - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - return null !== $request->headers->get('PHP_AUTH_USER'); - } - - /** - * Handles basic authentication. - */ - public function authenticate(RequestEvent $event) - { - $request = $event->getRequest(); - - if (null === $username = $request->headers->get('PHP_AUTH_USER')) { - return; - } - - if (null !== $token = $this->tokenStorage->getToken()) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - if ($token instanceof UsernamePasswordToken && $token->isAuthenticated(false) && (method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $username) { - return; - } - } - - if (null !== $this->logger) { - $this->logger->info('Basic authentication Authorization header found for user.', ['username' => $username]); - } - - try { - $token = $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $request->headers->get('PHP_AUTH_PW'), $this->providerKey)); - - $this->migrateSession($request, $token); - - $this->tokenStorage->setToken($token); - } catch (AuthenticationException $e) { - $token = $this->tokenStorage->getToken(); - if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getFirewallName()) { - $this->tokenStorage->setToken(null); - } - - if (null !== $this->logger) { - $this->logger->info('Basic authentication failed for user.', ['username' => $username, 'exception' => $e]); - } - - if ($this->ignoreFailure) { - return; - } - - $event->setResponse($this->authenticationEntryPoint->start($request, $e)); - } - } - - /** - * Call this method if your authentication token is stored to a session. - * - * @final - */ - public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy) - { - $this->sessionStrategy = $sessionStrategy; - } - - private function migrateSession(Request $request, TokenInterface $token) - { - if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) { - return; - } - - $this->sessionStrategy->onAuthentication($request, $token); - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php index 67bb2ae337f82..6453a0fa9c43c 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ChannelListener.php @@ -34,22 +34,8 @@ class ChannelListener extends AbstractListener private $httpPort; private $httpsPort; - public function __construct(AccessMapInterface $map, /*LoggerInterface*/ $logger = null, /*int*/ $httpPort = 80, /*int*/ $httpsPort = 443) + public function __construct(AccessMapInterface $map, LoggerInterface $logger = null, int $httpPort = 80, int $httpsPort = 443) { - if ($logger instanceof AuthenticationEntryPointInterface) { - trigger_deprecation('symfony/security-http', '5.4', 'The "$authenticationEntryPoint" argument of "%s()" is deprecated.', __METHOD__); - - $this->authenticationEntryPoint = $logger; - $nrOfArgs = \func_num_args(); - $logger = $nrOfArgs > 2 ? func_get_arg(2) : null; - $httpPort = $nrOfArgs > 3 ? func_get_arg(3) : 80; - $httpPort = $nrOfArgs > 4 ? func_get_arg(4) : 443; - } - - if (null !== $logger && !$logger instanceof LoggerInterface) { - throw new \TypeError(sprintf('Argument "$logger" of "%s()" must be instance of "%s", "%s" given.', __METHOD__, LoggerInterface::class, get_debug_type($logger))); - } - $this->map = $map; $this->logger = $logger; $this->httpPort = $httpPort; diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 48d21e27a110d..619bb80affaab 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -19,8 +19,6 @@ use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver; use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; @@ -33,7 +31,6 @@ use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Http\Event\DeauthenticatedEvent; use Symfony\Component\Security\Http\Event\TokenDeauthenticatedEvent; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -53,7 +50,6 @@ class ContextListener extends AbstractListener private $dispatcher; private $registered; private $trustResolver; - private $rememberMeServices; private $sessionTrackerEnabler; /** @@ -71,7 +67,7 @@ public function __construct(TokenStorageInterface $tokenStorage, iterable $userP $this->logger = $logger; $this->dispatcher = $dispatcher; - $this->trustResolver = $trustResolver ?? new AuthenticationTrustResolver(AnonymousToken::class, RememberMeToken::class); + $this->trustResolver = $trustResolver ?? new AuthenticationTrustResolver(); $this->sessionTrackerEnabler = $sessionTrackerEnabler; } @@ -143,10 +139,6 @@ public function authenticate(RequestEvent $event) if ($this->dispatcher) { $this->dispatcher->dispatch(new TokenDeauthenticatedEvent($originalToken, $request)); } - - if ($this->rememberMeServices) { - $this->rememberMeServices->loginFail($request); - } } } elseif (null !== $token) { if (null !== $this->logger) { @@ -187,9 +179,7 @@ public function onKernelResponse(ResponseEvent $event) $usageIndexValue = $session instanceof Session ? $usageIndexReference = &$session->getUsageIndex() : null; $token = $this->tokenStorage->getToken(); - // @deprecated always use isAuthenticated() in 6.0 - $notAuthenticated = method_exists($this->trustResolver, 'isAuthenticated') ? !$this->trustResolver->isAuthenticated($token) : (null === $token || $this->trustResolver->isAnonymous($token)); - if ($notAuthenticated) { + if (!$this->trustResolver->isAuthenticated($token)) { if ($request->hasPreviousSession()) { $session->remove($this->sessionKey); } @@ -214,9 +204,6 @@ public function onKernelResponse(ResponseEvent $event) protected function refreshUser(TokenInterface $token): ?TokenInterface { $user = $token->getUser(); - if (!$user instanceof UserInterface) { - return $token; - } $userNotFoundByProvider = false; $userDeauthenticated = false; @@ -239,14 +226,9 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface // tokens can be deauthenticated if the user has been changed. if ($this->hasUserChanged($user, $newToken)) { $userDeauthenticated = true; - // @deprecated since Symfony 5.4 - if (method_exists($newToken, 'setAuthenticated')) { - $newToken->setAuthenticated(false, false); - } if (null !== $this->logger) { - // @deprecated since Symfony 5.3, change to $refreshedUser->getUserIdentifier() in 6.0 - $this->logger->debug('Cannot refresh token because user has changed.', ['username' => method_exists($refreshedUser, 'getUserIdentifier') ? $refreshedUser->getUserIdentifier() : $refreshedUser->getUsername(), 'provider' => \get_class($provider)]); + $this->logger->debug('Cannot refresh token because user has changed.', ['username' => $refreshedUser->getUserIdentifier(), 'provider' => \get_class($provider)]); } continue; @@ -255,12 +237,10 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface $token->setUser($refreshedUser); if (null !== $this->logger) { - // @deprecated since Symfony 5.3, change to $refreshedUser->getUserIdentifier() in 6.0 - $context = ['provider' => \get_class($provider), 'username' => method_exists($refreshedUser, 'getUserIdentifier') ? $refreshedUser->getUserIdentifier() : $refreshedUser->getUsername()]; + $context = ['provider' => \get_class($provider), 'username' => $refreshedUser->getUserIdentifier()]; if ($token instanceof SwitchUserToken) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $context['impersonator_username'] = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getOriginalToken()->getUsername(); + $context['impersonator_username'] = $token->getUserIdentifier(); } $this->logger->debug('User was reloaded from a user provider.', $context); @@ -271,7 +251,7 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface // let's try the next user provider } catch (UserNotFoundException $e) { if (null !== $this->logger) { - $this->logger->warning('Username could not be found in the selected user provider.', ['username' => method_exists($e, 'getUserIdentifier') ? $e->getUserIdentifier() : $e->getUsername(), 'provider' => \get_class($provider)]); + $this->logger->warning('Username could not be found in the selected user provider.', ['username' => $e->getUserIdentifier(), 'provider' => \get_class($provider)]); } $userNotFoundByProvider = true; @@ -279,11 +259,6 @@ protected function refreshUser(TokenInterface $token): ?TokenInterface } if ($userDeauthenticated) { - // @deprecated since Symfony 5.4 - if ($this->dispatcher) { - $this->dispatcher->dispatch(new DeauthenticatedEvent($token, $newToken, false), DeauthenticatedEvent::class); - } - return null; } @@ -325,24 +300,12 @@ private function safelyUnserialize(string $serializedToken) } /** - * @param string|\Stringable|UserInterface $originalUser + * @param UserInterface $originalUser */ - private static function hasUserChanged($originalUser, TokenInterface $refreshedToken): bool + private static function hasUserChanged(UserInterface $originalUser, TokenInterface $refreshedToken): bool { $refreshedUser = $refreshedToken->getUser(); - if ($originalUser instanceof UserInterface) { - if (!$refreshedUser instanceof UserInterface) { - return true; - } else { - // noop - } - } elseif ($refreshedUser instanceof UserInterface) { - return true; - } else { - return (string) $originalUser !== (string) $refreshedUser; - } - if ($originalUser instanceof EquatableInterface) { return !(bool) $originalUser->isEqualTo($refreshedUser); } @@ -374,11 +337,7 @@ private static function hasUserChanged($originalUser, TokenInterface $refreshedT return true; } - // @deprecated since Symfony 5.3, drop getUsername() in 6.0 - $userIdentifier = function ($refreshedUser) { - return method_exists($refreshedUser, 'getUserIdentifier') ? $refreshedUser->getUserIdentifier() : $refreshedUser->getUsername(); - }; - if ($userIdentifier($originalUser) !== $userIdentifier($refreshedUser)) { + if ($originalUser->getUserIdentifier() !== $refreshedUser->getUserIdentifier()) { return true; } @@ -392,14 +351,4 @@ public static function handleUnserializeCallback(string $class) { throw new \ErrorException('Class not found: '.$class, 0x37313bc); } - - /** - * @deprecated since Symfony 5.4 - */ - public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices) - { - trigger_deprecation('symfony/security-http', '5.4', 'Method "%s()" is deprecated, use the new remember me handlers instead.', __METHOD__); - - $this->rememberMeServices = $rememberMeServices; - } } diff --git a/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php b/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php deleted file mode 100644 index fe59505a5fedc..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php +++ /dev/null @@ -1,130 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', RememberMeListener::class); - -/** - * RememberMeListener implements authentication capabilities via a cookie. - * - * @author Johannes M. Schmitt - * - * @final - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class RememberMeListener extends AbstractListener -{ - private $tokenStorage; - private $rememberMeServices; - private $authenticationManager; - private $logger; - private $dispatcher; - private $catchExceptions = true; - private $sessionStrategy; - - public function __construct(TokenStorageInterface $tokenStorage, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, bool $catchExceptions = true, SessionAuthenticationStrategyInterface $sessionStrategy = null) - { - $this->tokenStorage = $tokenStorage; - $this->rememberMeServices = $rememberMeServices; - $this->authenticationManager = $authenticationManager; - $this->logger = $logger; - $this->dispatcher = $dispatcher; - $this->catchExceptions = $catchExceptions; - $this->sessionStrategy = $sessionStrategy ?? new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE); - } - - /** - * {@inheritdoc} - */ - public function supports(Request $request): ?bool - { - return null; // always run authenticate() lazily with lazy firewalls - } - - /** - * Handles remember-me cookie based authentication. - */ - public function authenticate(RequestEvent $event) - { - if (null !== $this->tokenStorage->getToken()) { - return; - } - - $request = $event->getRequest(); - try { - if (null === $token = $this->rememberMeServices->autoLogin($request)) { - return; - } - } catch (AuthenticationException $e) { - if (null !== $this->logger) { - $this->logger->warning( - 'The token storage was not populated with remember-me token as the' - .' RememberMeServices was not able to create a token from the remember' - .' me information.', ['exception' => $e] - ); - } - - $this->rememberMeServices->loginFail($request); - - if (!$this->catchExceptions) { - throw $e; - } - - return; - } - - try { - $token = $this->authenticationManager->authenticate($token); - if ($request->hasSession() && $request->getSession()->isStarted()) { - $this->sessionStrategy->onAuthentication($request, $token); - } - $this->tokenStorage->setToken($token); - - if (null !== $this->dispatcher) { - $loginEvent = new InteractiveLoginEvent($request, $token); - $this->dispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN); - } - - if (null !== $this->logger) { - $this->logger->debug('Populated the token storage with a remember-me token.'); - } - } catch (AuthenticationException $e) { - if (null !== $this->logger) { - $this->logger->warning( - 'The token storage was not populated with remember-me token as the' - .' AuthenticationManager rejected the AuthenticationToken returned' - .' by the RememberMeServices.', ['exception' => $e] - ); - } - - $this->rememberMeServices->loginFail($request, $e); - - if (!$this->catchExceptions) { - throw $e; - } - } - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/RemoteUserAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/RemoteUserAuthenticationListener.php deleted file mode 100644 index d4b0389784d26..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/RemoteUserAuthenticationListener.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', RemoteUserAuthenticationListener::class); - -/** - * REMOTE_USER authentication listener. - * - * @author Fabien Potencier - * @author Maxime Douailin - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class RemoteUserAuthenticationListener extends AbstractPreAuthenticatedListener -{ - private $userKey; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, string $userKey = 'REMOTE_USER', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) - { - parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher); - - $this->userKey = $userKey; - } - - /** - * {@inheritdoc} - */ - protected function getPreAuthenticatedData(Request $request) - { - if (!$request->server->has($this->userKey)) { - throw new BadCredentialsException(sprintf('User key was not found: "%s".', $this->userKey)); - } - - return [$request->server->get($this->userKey), null]; - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index 250d9ef215aee..739137477d340 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -140,8 +140,7 @@ private function attemptSwitchUser(Request $request, string $username): ?TokenIn $originalToken = $this->getOriginalToken($token); if (null !== $originalToken) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - if ((method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()) === $username) { + if ($token->getUserIdentifier() === $username) { return $token; } @@ -149,27 +148,20 @@ private function attemptSwitchUser(Request $request, string $username): ?TokenIn $token = $this->attemptExitUser($request); } - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $currentUsername = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername(); + $currentUsername = $token->getUserIdentifier(); $nonExistentUsername = '_'.md5(random_bytes(8).$username); // To protect against user enumeration via timing measurements // we always load both successfully and unsuccessfully - $methodName = 'loadUserByIdentifier'; - if (!method_exists($this->provider, $methodName)) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->provider)); - - $methodName = 'loadUserByUsername'; - } try { - $user = $this->provider->$methodName($username); + $user = $this->provider->loadUserByIdentifier($username); try { - $this->provider->$methodName($nonExistentUsername); + $this->provider->loadUserByIdentifier($nonExistentUsername); } catch (\Exception $e) { } } catch (AuthenticationException $e) { - $this->provider->$methodName($currentUsername); + $this->provider->loadUserByIdentifier($currentUsername); throw $e; } diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php deleted file mode 100644 index 53a561648ac8f..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Csrf\CsrfToken; -use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; -use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; -use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; -use Symfony\Component\Security\Http\HttpUtils; -use Symfony\Component\Security\Http\ParameterBagUtils; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', UsernamePasswordFormAuthenticationListener::class); - -/** - * UsernamePasswordFormAuthenticationListener is the default implementation of - * an authentication via a simple form composed of a username and a password. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationListener -{ - private $csrfTokenManager; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, string $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, CsrfTokenManagerInterface $csrfTokenManager = null) - { - parent::__construct($tokenStorage, $authenticationManager, $sessionStrategy, $httpUtils, $providerKey, $successHandler, $failureHandler, array_merge([ - 'username_parameter' => '_username', - 'password_parameter' => '_password', - 'csrf_parameter' => '_csrf_token', - 'csrf_token_id' => 'authenticate', - 'post_only' => true, - ], $options), $logger, $dispatcher); - - $this->csrfTokenManager = $csrfTokenManager; - } - - /** - * {@inheritdoc} - */ - protected function requiresAuthentication(Request $request) - { - if ($this->options['post_only'] && !$request->isMethod('POST')) { - return false; - } - - return parent::requiresAuthentication($request); - } - - /** - * {@inheritdoc} - */ - protected function attemptAuthentication(Request $request) - { - if (null !== $this->csrfTokenManager) { - $csrfToken = ParameterBagUtils::getRequestParameterValue($request, $this->options['csrf_parameter']); - - if (false === $this->csrfTokenManager->isTokenValid(new CsrfToken($this->options['csrf_token_id'], $csrfToken))) { - throw new InvalidCsrfTokenException('Invalid CSRF token.'); - } - } - - if ($this->options['post_only']) { - $username = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']); - $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']); - } else { - $username = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']); - $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']); - } - - if (!\is_string($username) && !$username instanceof \Stringable) { - throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], get_debug_type($username))); - } - - $username = trim($username); - - if (\strlen($username) > Security::MAX_USERNAME_LENGTH) { - throw new BadCredentialsException('Invalid username.'); - } - - if (null === $password) { - throw new \LogicException(sprintf('The key "%s" cannot be null; check that the password field name of the form matches.', $this->options['password_parameter'])); - } - - $request->getSession()->set(Security::LAST_USERNAME, $username); - - return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey)); - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordJsonAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordJsonAuthenticationListener.php deleted file mode 100644 index 9679b33ff92a5..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordJsonAuthenticationListener.php +++ /dev/null @@ -1,235 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\PropertyAccess\Exception\AccessException; -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; -use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\HttpUtils; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -use Symfony\Contracts\Translation\TranslatorInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', UsernamePasswordJsonAuthenticationListener::class); - -/** - * UsernamePasswordJsonAuthenticationListener is a stateless implementation of - * an authentication via a JSON document composed of a username and a password. - * - * @author Kévin Dunglas - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class UsernamePasswordJsonAuthenticationListener extends AbstractListener -{ - private $tokenStorage; - private $authenticationManager; - private $httpUtils; - private $providerKey; - private $successHandler; - private $failureHandler; - private $options; - private $logger; - private $eventDispatcher; - private $propertyAccessor; - private $sessionStrategy; - - /** - * @var TranslatorInterface|null - */ - private $translator; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, HttpUtils $httpUtils, string $providerKey, AuthenticationSuccessHandlerInterface $successHandler = null, AuthenticationFailureHandlerInterface $failureHandler = null, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $eventDispatcher = null, PropertyAccessorInterface $propertyAccessor = null) - { - $this->tokenStorage = $tokenStorage; - $this->authenticationManager = $authenticationManager; - $this->httpUtils = $httpUtils; - $this->providerKey = $providerKey; - $this->successHandler = $successHandler; - $this->failureHandler = $failureHandler; - $this->logger = $logger; - $this->eventDispatcher = $eventDispatcher; - $this->options = array_merge(['username_path' => 'username', 'password_path' => 'password'], $options); - $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); - } - - public function supports(Request $request): ?bool - { - if (!str_contains($request->getRequestFormat() ?? '', 'json') - && !str_contains($request->getContentType() ?? '', 'json') - ) { - return false; - } - - if (isset($this->options['check_path']) && !$this->httpUtils->checkRequestPath($request, $this->options['check_path'])) { - return false; - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function authenticate(RequestEvent $event) - { - $request = $event->getRequest(); - $data = json_decode($request->getContent()); - - try { - if (!$data instanceof \stdClass) { - throw new BadRequestHttpException('Invalid JSON.'); - } - - try { - $username = $this->propertyAccessor->getValue($data, $this->options['username_path']); - } catch (AccessException $e) { - throw new BadRequestHttpException(sprintf('The key "%s" must be provided.', $this->options['username_path']), $e); - } - - try { - $password = $this->propertyAccessor->getValue($data, $this->options['password_path']); - } catch (AccessException $e) { - throw new BadRequestHttpException(sprintf('The key "%s" must be provided.', $this->options['password_path']), $e); - } - - if (!\is_string($username)) { - throw new BadRequestHttpException(sprintf('The key "%s" must be a string.', $this->options['username_path'])); - } - - if (\strlen($username) > Security::MAX_USERNAME_LENGTH) { - throw new BadCredentialsException('Invalid username.'); - } - - if (!\is_string($password)) { - throw new BadRequestHttpException(sprintf('The key "%s" must be a string.', $this->options['password_path'])); - } - - $token = new UsernamePasswordToken($username, $password, $this->providerKey); - - $authenticatedToken = $this->authenticationManager->authenticate($token); - $response = $this->onSuccess($request, $authenticatedToken); - } catch (AuthenticationException $e) { - $response = $this->onFailure($request, $e); - } catch (BadRequestHttpException $e) { - $request->setRequestFormat('json'); - - throw $e; - } - - if (null === $response) { - return; - } - - $event->setResponse($response); - } - - private function onSuccess(Request $request, TokenInterface $token): ?Response - { - if (null !== $this->logger) { - // @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 6.0 - $this->logger->info('User has been authenticated successfully.', ['username' => method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername()]); - } - - $this->migrateSession($request, $token); - - $this->tokenStorage->setToken($token); - - if (null !== $this->eventDispatcher) { - $loginEvent = new InteractiveLoginEvent($request, $token); - $this->eventDispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN); - } - - if (!$this->successHandler) { - return null; // let the original request succeeds - } - - $response = $this->successHandler->onAuthenticationSuccess($request, $token); - - if (!$response instanceof Response) { - throw new \RuntimeException('Authentication Success Handler did not return a Response.'); - } - - return $response; - } - - private function onFailure(Request $request, AuthenticationException $failed): Response - { - if (null !== $this->logger) { - $this->logger->info('Authentication request failed.', ['exception' => $failed]); - } - - $token = $this->tokenStorage->getToken(); - if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getFirewallName()) { - $this->tokenStorage->setToken(null); - } - - if (!$this->failureHandler) { - if (null !== $this->translator) { - $errorMessage = $this->translator->trans($failed->getMessageKey(), $failed->getMessageData(), 'security'); - } else { - $errorMessage = strtr($failed->getMessageKey(), $failed->getMessageData()); - } - - return new JsonResponse(['error' => $errorMessage], 401); - } - - $response = $this->failureHandler->onAuthenticationFailure($request, $failed); - - if (!$response instanceof Response) { - throw new \RuntimeException('Authentication Failure Handler did not return a Response.'); - } - - return $response; - } - - /** - * Call this method if your authentication token is stored to a session. - * - * @final - */ - public function setSessionAuthenticationStrategy(SessionAuthenticationStrategyInterface $sessionStrategy) - { - $this->sessionStrategy = $sessionStrategy; - } - - public function setTranslator(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - private function migrateSession(Request $request, TokenInterface $token) - { - if (!$this->sessionStrategy || !$request->hasSession() || !$request->hasPreviousSession()) { - return; - } - - $this->sessionStrategy->onAuthentication($request, $token); - } -} diff --git a/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php deleted file mode 100644 index 07a287e5450f2..0000000000000 --- a/src/Symfony/Component/Security/Http/Firewall/X509AuthenticationListener.php +++ /dev/null @@ -1,64 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Firewall; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -trigger_deprecation('symfony/security-http', '5.3', 'The "%s" class is deprecated, use the new authenticator system instead.', X509AuthenticationListener::class); - -/** - * X509 authentication listener. - * - * @author Fabien Potencier - * - * @deprecated since Symfony 5.3, use the new authenticator system instead - */ -class X509AuthenticationListener extends AbstractPreAuthenticatedListener -{ - private $userKey; - private $credentialKey; - - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, string $providerKey, string $userKey = 'SSL_CLIENT_S_DN_Email', string $credentialKey = 'SSL_CLIENT_S_DN', LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null) - { - parent::__construct($tokenStorage, $authenticationManager, $providerKey, $logger, $dispatcher); - - $this->userKey = $userKey; - $this->credentialKey = $credentialKey; - } - - /** - * {@inheritdoc} - */ - protected function getPreAuthenticatedData(Request $request) - { - $user = null; - if ($request->server->has($this->userKey)) { - $user = $request->server->get($this->userKey); - } elseif ( - $request->server->has($this->credentialKey) - && preg_match('#emailAddress=([^,/@]++@[^,/]++)#', $request->server->get($this->credentialKey), $matches) - ) { - $user = $matches[1]; - } - - if (null === $user) { - throw new BadCredentialsException(sprintf('SSL credentials not found: "%s", "%s".', $this->userKey, $this->credentialKey)); - } - - return [$user, $request->server->get($this->credentialKey, '')]; - } -} diff --git a/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php b/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php index b49fd8b1ea31b..b51f372c8b41e 100644 --- a/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php +++ b/src/Symfony/Component/Security/Http/LoginLink/LoginLinkHandler.php @@ -50,8 +50,7 @@ public function createLoginLink(UserInterface $user, Request $request = null): L $expires = $expiresAt->format('U'); $parameters = [ - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - 'user' => method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), + 'user' => $user->getUserIdentifier(), 'expires' => $expires, 'hash' => $this->signatureHashUtil->computeSignatureHash($user, $expires), ]; @@ -85,14 +84,7 @@ public function consumeLoginLink(Request $request): UserInterface $userIdentifier = $request->get('user'); try { - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($this->userProvider, 'loadUserByIdentifier')) { - $user = $this->userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $user = $this->userProvider->loadUserByUsername($userIdentifier); - } + $user = $this->userProvider->loadUserByIdentifier($userIdentifier); } catch (UserNotFoundException $exception) { throw new InvalidLoginLinkException('User not found.', 0, $exception); } diff --git a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php index ac45e25c320b6..4b4bab9cebf23 100644 --- a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php +++ b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php @@ -13,7 +13,6 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; @@ -130,19 +129,8 @@ private function getListener(?string $key): array if (null !== $this->tokenStorage) { $token = $this->tokenStorage->getToken(); - // @deprecated since 5.4 - if ($token instanceof AnonymousToken) { - throw new \InvalidArgumentException('Unable to generate a logout url for an anonymous token.'); - } - - if (null !== $token) { - if (method_exists($token, 'getFirewallName')) { - $key = $token->getFirewallName(); - } elseif (method_exists($token, 'getProviderKey')) { - trigger_deprecation('symfony/security-http', '5.2', 'Method "%s::getProviderKey()" has been deprecated, rename it to "getFirewallName()" instead.', \get_class($token)); - - $key = $token->getProviderKey(); - } + if (null !== $token && method_exists($token, 'getFirewallName')) { + $key = $token->getFirewallName(); if (isset($this->listeners[$key])) { return $this->listeners[$key]; diff --git a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeHandler.php b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeHandler.php index 97918c86cb8b4..3b0de2d7e7865 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeHandler.php +++ b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeHandler.php @@ -63,15 +63,7 @@ abstract protected function processRememberMe(RememberMeDetails $rememberMeDetai public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): UserInterface { try { - // @deprecated since Symfony 5.3, change to $this->userProvider->loadUserByIdentifier() in 6.0 - $method = 'loadUserByIdentifier'; - if (!method_exists($this->userProvider, 'loadUserByIdentifier')) { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($this->userProvider)); - - $method = 'loadUserByUsername'; - } - - $user = $this->userProvider->$method($rememberMeDetails->getUserIdentifier()); + $user = $this->userProvider->loadUserByIdentifier($rememberMeDetails->getUserIdentifier()); } catch (AuthenticationException $e) { throw $e; } diff --git a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php deleted file mode 100644 index da5b2d92f350c..0000000000000 --- a/src/Symfony/Component/Security/Http/RememberMe/AbstractRememberMeServices.php +++ /dev/null @@ -1,305 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\RememberMe; - -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\CookieTheftException; -use Symfony\Component\Security\Core\Exception\UnsupportedUserException; -use Symfony\Component\Security\Core\Exception\UserNotFoundException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Http\ParameterBagUtils; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use "%s" instead.', AbstractRememberMeServices::class, AbstractRememberMeHandler::class); - -/** - * Base class implementing the RememberMeServicesInterface. - * - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.4, use {@see AbstractRememberMeHandler} instead - */ -abstract class AbstractRememberMeServices implements RememberMeServicesInterface -{ - public const COOKIE_DELIMITER = ':'; - - protected $logger; - protected $options = [ - 'secure' => false, - 'httponly' => true, - 'samesite' => null, - 'path' => null, - 'domain' => null, - ]; - private $firewallName; - private $secret; - private $userProviders; - - /** - * @throws \InvalidArgumentException - */ - public function __construct(iterable $userProviders, string $secret, string $firewallName, array $options = [], LoggerInterface $logger = null) - { - if (empty($secret)) { - throw new \InvalidArgumentException('$secret must not be empty.'); - } - if ('' === $firewallName) { - throw new \InvalidArgumentException('$firewallName must not be empty.'); - } - if (!\is_array($userProviders) && !$userProviders instanceof \Countable) { - $userProviders = iterator_to_array($userProviders, false); - } - if (0 === \count($userProviders)) { - throw new \InvalidArgumentException('You must provide at least one user provider.'); - } - - $this->userProviders = $userProviders; - $this->secret = $secret; - $this->firewallName = $firewallName; - $this->options = array_merge($this->options, $options); - $this->logger = $logger; - } - - /** - * Returns the parameter that is used for checking whether remember-me - * services have been requested. - * - * @return string - */ - public function getRememberMeParameter() - { - return $this->options['remember_me_parameter']; - } - - /** - * @return string - */ - public function getSecret() - { - return $this->secret; - } - - /** - * Implementation of RememberMeServicesInterface. Detects whether a remember-me - * cookie was set, decodes it, and hands it to subclasses for further processing. - * - * @throws CookieTheftException - * @throws \RuntimeException - */ - final public function autoLogin(Request $request): ?TokenInterface - { - if (($cookie = $request->attributes->get(self::COOKIE_ATTR_NAME)) && null === $cookie->getValue()) { - return null; - } - - if (null === $cookie = $request->cookies->get($this->options['name'])) { - return null; - } - - if (null !== $this->logger) { - $this->logger->debug('Remember-me cookie detected.'); - } - - $cookieParts = $this->decodeCookie($cookie); - - try { - $user = $this->processAutoLoginCookie($cookieParts, $request); - - if (!$user instanceof UserInterface) { - throw new \RuntimeException('processAutoLoginCookie() must return a UserInterface implementation.'); - } - - if (null !== $this->logger) { - $this->logger->info('Remember-me cookie accepted.'); - } - - return new RememberMeToken($user, $this->firewallName, $this->secret); - } catch (CookieTheftException $e) { - $this->loginFail($request, $e); - - throw $e; - } catch (UserNotFoundException $e) { - if (null !== $this->logger) { - $this->logger->info('User for remember-me cookie not found.', ['exception' => $e]); - } - - $this->loginFail($request, $e); - } catch (UnsupportedUserException $e) { - if (null !== $this->logger) { - $this->logger->warning('User class for remember-me cookie not supported.', ['exception' => $e]); - } - - $this->loginFail($request, $e); - } catch (AuthenticationException $e) { - if (null !== $this->logger) { - $this->logger->debug('Remember-Me authentication failed.', ['exception' => $e]); - } - - $this->loginFail($request, $e); - } catch (\Exception $e) { - $this->loginFail($request, $e); - - throw $e; - } - - return null; - } - - public function logout(Request $request, Response $response, TokenInterface $token) - { - $this->cancelCookie($request); - } - - /** - * Implementation for RememberMeServicesInterface. Deletes the cookie when - * an attempted authentication fails. - */ - final public function loginFail(Request $request, \Exception $exception = null) - { - $this->cancelCookie($request); - $this->onLoginFail($request, $exception); - } - - /** - * Implementation for RememberMeServicesInterface. This is called when an - * authentication is successful. - */ - final public function loginSuccess(Request $request, Response $response, TokenInterface $token) - { - // Make sure any old remember-me cookies are cancelled - $this->cancelCookie($request); - - if (!$token->getUser() instanceof UserInterface) { - if (null !== $this->logger) { - $this->logger->debug('Remember-me ignores token since it does not contain a UserInterface implementation.'); - } - - return; - } - - if (!$this->isRememberMeRequested($request)) { - if (null !== $this->logger) { - $this->logger->debug('Remember-me was not requested.'); - } - - return; - } - - if (null !== $this->logger) { - $this->logger->debug('Remember-me was requested; setting cookie.'); - } - - // Remove attribute from request that sets a NULL cookie. - // It was set by $this->cancelCookie() - // (cancelCookie does other things too for some RememberMeServices - // so we should still call it at the start of this method) - $request->attributes->remove(self::COOKIE_ATTR_NAME); - - $this->onLoginSuccess($request, $response, $token); - } - - /** - * Subclasses should validate the cookie and do any additional processing - * that is required. This is called from autoLogin(). - * - * @return UserInterface - */ - abstract protected function processAutoLoginCookie(array $cookieParts, Request $request); - - protected function onLoginFail(Request $request, \Exception $exception = null) - { - } - - /** - * This is called after a user has been logged in successfully, and has - * requested remember-me capabilities. The implementation usually sets a - * cookie and possibly stores a persistent record of it. - */ - abstract protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token); - - final protected function getUserProvider(string $class): UserProviderInterface - { - foreach ($this->userProviders as $provider) { - if ($provider->supportsClass($class)) { - return $provider; - } - } - - throw new UnsupportedUserException(sprintf('There is no user provider for user "%s". Shouldn\'t the "supportsClass()" method of your user provider return true for this classname?', $class)); - } - - /** - * Decodes the raw cookie value. - * - * @return array - */ - protected function decodeCookie(string $rawCookie) - { - return explode(self::COOKIE_DELIMITER, base64_decode($rawCookie)); - } - - /** - * Encodes the cookie parts. - * - * @return string - * - * @throws \InvalidArgumentException When $cookieParts contain the cookie delimiter. Extending class should either remove or escape it. - */ - protected function encodeCookie(array $cookieParts) - { - foreach ($cookieParts as $cookiePart) { - if (str_contains($cookiePart, self::COOKIE_DELIMITER)) { - throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s".', self::COOKIE_DELIMITER)); - } - } - - return base64_encode(implode(self::COOKIE_DELIMITER, $cookieParts)); - } - - /** - * Deletes the remember-me cookie. - */ - protected function cancelCookie(Request $request) - { - if (null !== $this->logger) { - $this->logger->debug('Clearing remember-me cookie.', ['name' => $this->options['name']]); - } - - $request->attributes->set(self::COOKIE_ATTR_NAME, new Cookie($this->options['name'], null, 1, $this->options['path'], $this->options['domain'], $this->options['secure'] ?? $request->isSecure(), $this->options['httponly'], false, $this->options['samesite'])); - } - - /** - * Checks whether remember-me capabilities were requested. - * - * @return bool - */ - protected function isRememberMeRequested(Request $request) - { - if (true === $this->options['always_remember_me']) { - return true; - } - - $parameter = ParameterBagUtils::getRequestParameterValue($request, $this->options['remember_me_parameter']); - - if (null === $parameter && null !== $this->logger) { - $this->logger->debug('Did not send remember-me cookie.', ['parameter' => $this->options['remember_me_parameter']]); - } - - return 'true' === $parameter || 'on' === $parameter || '1' === $parameter || 'yes' === $parameter || true === $parameter; - } -} diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php index 191d2ede852b8..06f1a12c75a31 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php +++ b/src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php @@ -55,7 +55,7 @@ public function createRememberMeCookie(UserInterface $user): void { $series = base64_encode(random_bytes(64)); $tokenValue = $this->generateHash(base64_encode(random_bytes(64))); - $token = new PersistentToken(\get_class($user), method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $series, $tokenValue, new \DateTime()); + $token = new PersistentToken(\get_class($user), $user->getUserIdentifier(), $series, $tokenValue, new \DateTime()); $this->tokenProvider->createNewToken($token); $this->createCookie(RememberMeDetails::fromPersistentToken($token, time() + $this->options['lifetime'])); diff --git a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php deleted file mode 100644 index 2bf9d3c6a968a..0000000000000 --- a/src/Symfony/Component/Security/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ /dev/null @@ -1,167 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\RememberMe; - -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; -use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface; -use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Exception\CookieTheftException; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use "%s" instead.', PersistentTokenBasedRememberMeServices::class, PersistentRememberMeHandler::class); - -/** - * Concrete implementation of the RememberMeServicesInterface which needs - * an implementation of TokenProviderInterface for providing remember-me - * capabilities. - * - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.4, use {@see PersistentRememberMeHandler} instead - */ -class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices -{ - private const HASHED_TOKEN_PREFIX = 'sha256_'; - - /** @var TokenProviderInterface */ - private $tokenProvider; - - public function setTokenProvider(TokenProviderInterface $tokenProvider) - { - $this->tokenProvider = $tokenProvider; - } - - /** - * {@inheritdoc} - */ - protected function cancelCookie(Request $request) - { - // Delete cookie on the client - parent::cancelCookie($request); - - // Delete cookie from the tokenProvider - if (null !== ($cookie = $request->cookies->get($this->options['name'])) - && 2 === \count($parts = $this->decodeCookie($cookie)) - ) { - [$series] = $parts; - $this->tokenProvider->deleteTokenBySeries($series); - } - } - - /** - * {@inheritdoc} - */ - protected function processAutoLoginCookie(array $cookieParts, Request $request) - { - if (2 !== \count($cookieParts)) { - throw new AuthenticationException('The cookie is invalid.'); - } - - [$series, $tokenValue] = $cookieParts; - $persistentToken = $this->tokenProvider->loadTokenBySeries($series); - - if (!$this->isTokenValueValid($persistentToken, $tokenValue)) { - throw new CookieTheftException('This token was already used. The account is possibly compromised.'); - } - - if ($persistentToken->getLastUsed()->getTimestamp() + $this->options['lifetime'] < time()) { - throw new AuthenticationException('The cookie has expired.'); - } - - $tokenValue = base64_encode(random_bytes(64)); - $this->tokenProvider->updateToken($series, $this->generateHash($tokenValue), new \DateTime()); - $request->attributes->set(self::COOKIE_ATTR_NAME, - new Cookie( - $this->options['name'], - $this->encodeCookie([$series, $tokenValue]), - time() + $this->options['lifetime'], - $this->options['path'], - $this->options['domain'], - $this->options['secure'] ?? $request->isSecure(), - $this->options['httponly'], - false, - $this->options['samesite'] - ) - ); - - $userProvider = $this->getUserProvider($persistentToken->getClass()); - // @deprecated since Symfony 5.3, change to $persistentToken->getUserIdentifier() in 6.0 - if (method_exists($persistentToken, 'getUserIdentifier')) { - $userIdentifier = $persistentToken->getUserIdentifier(); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "getUserIdentifier()" in persistent token "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($persistentToken)); - - $userIdentifier = $persistentToken->getUsername(); - } - - // @deprecated since Symfony 5.3, change to $userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($userProvider, 'loadUserByIdentifier')) { - return $userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($userProvider)); - - return $userProvider->loadUserByUsername($userIdentifier); - } - } - - /** - * {@inheritdoc} - */ - protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) - { - $series = base64_encode(random_bytes(64)); - $tokenValue = base64_encode(random_bytes(64)); - - $this->tokenProvider->createNewToken( - new PersistentToken( - \get_class($user = $token->getUser()), - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), - $series, - $this->generateHash($tokenValue), - new \DateTime() - ) - ); - - $response->headers->setCookie( - new Cookie( - $this->options['name'], - $this->encodeCookie([$series, $tokenValue]), - time() + $this->options['lifetime'], - $this->options['path'], - $this->options['domain'], - $this->options['secure'] ?? $request->isSecure(), - $this->options['httponly'], - false, - $this->options['samesite'] - ) - ); - } - - private function generateHash(string $tokenValue): string - { - return self::HASHED_TOKEN_PREFIX.hash_hmac('sha256', $tokenValue, $this->getSecret()); - } - - private function isTokenValueValid(PersistentTokenInterface $persistentToken, string $tokenValue): bool - { - if (0 === strpos($persistentToken->getTokenValue(), self::HASHED_TOKEN_PREFIX)) { - return hash_equals($persistentToken->getTokenValue(), $this->generateHash($tokenValue)); - } - - return hash_equals($persistentToken->getTokenValue(), $tokenValue); - } -} diff --git a/src/Symfony/Component/Security/Http/RememberMe/RememberMeServicesInterface.php b/src/Symfony/Component/Security/Http/RememberMe/RememberMeServicesInterface.php deleted file mode 100644 index c2503f0d61759..0000000000000 --- a/src/Symfony/Component/Security/Http/RememberMe/RememberMeServicesInterface.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\RememberMe; - -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" interface is deprecated, use "%s" instead.', RememberMeServicesInterface::class, RememberMeHandlerInterface::class); - -/** - * Interface that needs to be implemented by classes which provide remember-me - * capabilities. - * - * We provide two implementations out-of-the-box: - * - TokenBasedRememberMeServices (does not require a TokenProvider) - * - PersistentTokenBasedRememberMeServices (requires a TokenProvider) - * - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.4, use {@see RememberMeHandlerInterface} instead - */ -interface RememberMeServicesInterface -{ - /** - * This attribute name can be used by the implementation if it needs to set - * a cookie on the Request when there is no actual Response, yet. - */ - public const COOKIE_ATTR_NAME = '_security_remember_me_cookie'; - - /** - * This method will be called whenever the TokenStorage does not contain - * a TokenInterface object and the framework wishes to provide an implementation - * with an opportunity to authenticate the request using remember-me capabilities. - * - * No attempt whatsoever is made to determine whether the browser has requested - * remember-me services or presented a valid cookie. Any and all such determinations - * are left to the implementation of this method. - * - * If a browser has presented an unauthorised cookie for whatever reason, - * make sure to throw an AuthenticationException as this will consequentially - * result in a call to loginFail() and therefore an invalidation of the cookie. - * - * @return TokenInterface|null - */ - public function autoLogin(Request $request); - - /** - * Called whenever an interactive authentication attempt was made, but the - * credentials supplied by the user were missing or otherwise invalid. - * - * This method needs to take care of invalidating the cookie. - */ - public function loginFail(Request $request, \Exception $exception = null); - - /** - * Called whenever an interactive authentication attempt is successful - * (e.g. a form login). - * - * An implementation may always set a remember-me cookie in the Response, - * although this is not recommended. - * - * Instead, implementations should typically look for a request parameter - * (such as an HTTP POST parameter) that indicates the browser has explicitly - * requested for the authentication to be remembered. - */ - public function loginSuccess(Request $request, Response $response, TokenInterface $token); - - /** - * Called whenever a logout occurs to e.g. remove any remember-me cookie. - */ - public function logout(Request $request, Response $response, TokenInterface $token); -} diff --git a/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php b/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php index 834b3e14df6b1..6e783a20ffcc2 100644 --- a/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php +++ b/src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php @@ -49,7 +49,7 @@ public function createRememberMeCookie(UserInterface $user): void $expires = time() + $this->options['lifetime']; $value = $this->signatureHasher->computeSignatureHash($user, $expires); - $details = new RememberMeDetails(\get_class($user), method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $expires, $value); + $details = new RememberMeDetails(\get_class($user), $user->getUserIdentifier(), $expires, $value); $this->createCookie($details); } diff --git a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php b/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php deleted file mode 100644 index 0172e5274c32a..0000000000000 --- a/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php +++ /dev/null @@ -1,141 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\RememberMe; - -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -trigger_deprecation('symfony/security-http', '5.4', 'The "%s" class is deprecated, use "%s" instead.', TokenBasedRememberMeServices::class, SignatureRememberMeHandler::class); - -/** - * Concrete implementation of the RememberMeServicesInterface providing - * remember-me capabilities without requiring a TokenProvider. - * - * @author Johannes M. Schmitt - * - * @deprecated since Symfony 5.4, use {@see SignatureRememberMeHandler} instead - */ -class TokenBasedRememberMeServices extends AbstractRememberMeServices -{ - /** - * {@inheritdoc} - */ - protected function processAutoLoginCookie(array $cookieParts, Request $request) - { - if (4 !== \count($cookieParts)) { - throw new AuthenticationException('The cookie is invalid.'); - } - - [$class, $userIdentifier, $expires, $hash] = $cookieParts; - if (false === $userIdentifier = base64_decode($userIdentifier, true)) { - throw new AuthenticationException('$userIdentifier contains a character from outside the base64 alphabet.'); - } - try { - $userProvider = $this->getUserProvider($class); - // @deprecated since Symfony 5.3, change to $userProvider->loadUserByIdentifier() in 6.0 - if (method_exists($userProvider, 'loadUserByIdentifier')) { - $user = $userProvider->loadUserByIdentifier($userIdentifier); - } else { - trigger_deprecation('symfony/security-core', '5.3', 'Not implementing method "loadUserByIdentifier()" in user provider "%s" is deprecated. This method will replace "loadUserByUsername()" in Symfony 6.0.', get_debug_type($userProvider)); - - $user = $userProvider->loadUserByUsername($userIdentifier); - } - } catch (\Exception $e) { - if (!$e instanceof AuthenticationException) { - $e = new AuthenticationException($e->getMessage(), $e->getCode(), $e); - } - - throw $e; - } - - if (!$user instanceof UserInterface) { - throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_debug_type($user))); - } - - if (!$user instanceof PasswordAuthenticatedUserInterface) { - throw new \RuntimeException(sprintf('Class "%s" must implement "%s" for using "%s".', get_debug_type($user), PasswordAuthenticatedUserInterface::class, __CLASS__)); - } - - if (true !== hash_equals($this->generateCookieHash($class, $userIdentifier, $expires, $user->getPassword()), $hash)) { - throw new AuthenticationException('The cookie\'s hash is invalid.'); - } - - if ($expires < time()) { - throw new AuthenticationException('The cookie has expired.'); - } - - return $user; - } - - /** - * {@inheritdoc} - */ - protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) - { - $user = $token->getUser(); - $expires = time() + $this->options['lifetime']; - // @deprecated since Symfony 5.3, change to $user->getUserIdentifier() in 6.0 - $value = $this->generateCookieValue(\get_class($user), method_exists($user, 'getUserIdentifier') ? $user->getUserIdentifier() : $user->getUsername(), $expires, $user->getPassword()); - - $response->headers->setCookie( - new Cookie( - $this->options['name'], - $value, - $expires, - $this->options['path'], - $this->options['domain'], - $this->options['secure'] ?? $request->isSecure(), - $this->options['httponly'], - false, - $this->options['samesite'] - ) - ); - } - - /** - * Generates the cookie value. - * - * @param int $expires The Unix timestamp when the cookie expires - * @param string|null $password The encoded password - * - * @return string - */ - protected function generateCookieValue(string $class, string $userIdentifier, int $expires, ?string $password) - { - // $userIdentifier is encoded because it might contain COOKIE_DELIMITER, - // we assume other values don't - return $this->encodeCookie([ - $class, - base64_encode($userIdentifier), - $expires, - $this->generateCookieHash($class, $userIdentifier, $expires, $password), - ]); - } - - /** - * Generates a hash for the cookie to ensure it is not being tampered with. - * - * @param int $expires The Unix timestamp when the cookie expires - * @param string|null $password The encoded password - * - * @return string - */ - protected function generateCookieHash(string $class, string $userIdentifier, int $expires, ?string $password) - { - return hash_hmac('sha256', $class.self::COOKIE_DELIMITER.$userIdentifier.self::COOKIE_DELIMITER.$expires.self::COOKIE_DELIMITER.$password, $this->getSecret()); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Authentication/AuthenticatorManagerTest.php b/src/Symfony/Component/Security/Http/Tests/Authentication/AuthenticatorManagerTest.php index f00009134eaaa..d2120a8152f03 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authentication/AuthenticatorManagerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authentication/AuthenticatorManagerTest.php @@ -276,7 +276,7 @@ public function testLegacyInteractiveAuthenticator() $this->request->attributes->set('_security_authenticators', [$authenticator]); $authenticator->expects($this->any())->method('authenticate')->willReturn(new SelfValidatingPassport(new UserBadge('wouter', function () { return $this->user; }))); - $authenticator->expects($this->any())->method('createAuthenticatedToken')->willReturn($this->token); + $authenticator->expects($this->any())->method('createToken')->willReturn($this->token); $this->tokenStorage->expects($this->once())->method('setToken')->with($this->token); diff --git a/src/Symfony/Component/Security/Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php b/src/Symfony/Component/Security/Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php deleted file mode 100644 index 5bf711235a7da..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/EntryPoint/BasicAuthenticationEntryPointTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\EntryPoint; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\EntryPoint\BasicAuthenticationEntryPoint; - -/** - * @group legacy - */ -class BasicAuthenticationEntryPointTest extends TestCase -{ - public function testStart() - { - $request = $this->createMock(Request::class); - - $authException = new AuthenticationException('The exception message'); - - $entryPoint = new BasicAuthenticationEntryPoint('TheRealmName'); - $response = $entryPoint->start($request, $authException); - - $this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $response->getStatusCode()); - } - - public function testStartWithoutAuthException() - { - $request = $this->createMock(Request::class); - - $entryPoint = new BasicAuthenticationEntryPoint('TheRealmName'); - - $response = $entryPoint->start($request); - - $this->assertEquals('Basic realm="TheRealmName"', $response->headers->get('WWW-Authenticate')); - $this->assertEquals(401, $response->getStatusCode()); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php b/src/Symfony/Component/Security/Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php deleted file mode 100644 index 565201736d3d4..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/EntryPoint/FormAuthenticationEntryPointTest.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\EntryPoint; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Http\EntryPoint\FormAuthenticationEntryPoint; -use Symfony\Component\Security\Http\HttpUtils; - -/** - * @group legacy - */ -class FormAuthenticationEntryPointTest extends TestCase -{ - public function testStart() - { - $request = $this->createMock(Request::class); - $response = new RedirectResponse('/the/login/path'); - - $httpKernel = $this->createMock(HttpKernelInterface::class); - $httpUtils = $this->createMock(HttpUtils::class); - $httpUtils - ->expects($this->once()) - ->method('createRedirectResponse') - ->with($this->equalTo($request), $this->equalTo('/the/login/path')) - ->willReturn($response) - ; - - $entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', false); - - $this->assertEquals($response, $entryPoint->start($request)); - } - - public function testStartWithUseForward() - { - $request = $this->createMock(Request::class); - $subRequest = $this->createMock(Request::class); - $response = new Response('', 200); - - $httpUtils = $this->createMock(HttpUtils::class); - $httpUtils - ->expects($this->once()) - ->method('createRequest') - ->with($this->equalTo($request), $this->equalTo('/the/login/path')) - ->willReturn($subRequest) - ; - - $httpKernel = $this->createMock(HttpKernelInterface::class); - $httpKernel - ->expects($this->once()) - ->method('handle') - ->with($this->equalTo($subRequest), $this->equalTo(HttpKernelInterface::SUB_REQUEST)) - ->willReturn($response) - ; - - $entryPoint = new FormAuthenticationEntryPoint($httpKernel, $httpUtils, '/the/login/path', true); - - $entryPointResponse = $entryPoint->start($request); - - $this->assertEquals($response, $entryPointResponse); - $this->assertEquals(401, $entryPointResponse->getStatusCode()); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php b/src/Symfony/Component/Security/Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php deleted file mode 100644 index e9e5ddd54aba4..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/EntryPoint/RetryAuthenticationEntryPointTest.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\EntryPoint; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Http\EntryPoint\RetryAuthenticationEntryPoint; - -/** - * @group legacy - */ -class RetryAuthenticationEntryPointTest extends TestCase -{ - /** - * @dataProvider dataForStart - */ - public function testStart($httpPort, $httpsPort, $request, $expectedUrl) - { - $entryPoint = new RetryAuthenticationEntryPoint($httpPort, $httpsPort); - $response = $entryPoint->start($request); - - $this->assertInstanceOf(RedirectResponse::class, $response); - $this->assertEquals($expectedUrl, $response->headers->get('Location')); - } - - public function dataForStart() - { - if (!class_exists(Request::class)) { - return [[]]; - } - - return [ - [ - 80, - 443, - Request::create('http://localhost/foo/bar?baz=bat'), - 'https://localhost/foo/bar?baz=bat', - ], - [ - 80, - 443, - Request::create('https://localhost/foo/bar?baz=bat'), - 'http://localhost/foo/bar?baz=bat', - ], - [ - 80, - 123, - Request::create('http://localhost/foo/bar?baz=bat'), - 'https://localhost:123/foo/bar?baz=bat', - ], - [ - 8080, - 443, - Request::create('https://localhost/foo/bar?baz=bat'), - 'http://localhost:8080/foo/bar?baz=bat', - ], - ]; - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/CheckRememberMeConditionsListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/CheckRememberMeConditionsListenerTest.php index adc4a51251ded..b46536462b1fd 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/CheckRememberMeConditionsListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/CheckRememberMeConditionsListenerTest.php @@ -15,11 +15,11 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\User\User; +use Symfony\Component\Security\Core\User\InMemoryUser; use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\EventListener\CheckRememberMeConditionsListener; @@ -89,13 +89,13 @@ public function provideRememberMeOptInValues() yield [true]; } - private function createLoginSuccessfulEvent(PassportInterface $passport) + private function createLoginSuccessfulEvent(Passport $passport) { return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), $passport, $this->createMock(TokenInterface::class), $this->request, $this->response, 'main_firewall'); } private function createPassport(array $badges = null) { - return new SelfValidatingPassport(new UserBadge('test', function ($username) { return new User($username, null); }), $badges ?? [new RememberMeBadge()]); + return new SelfValidatingPassport(new UserBadge('test', function ($username) { return new InMemoryUser($username, null); }), $badges ?? [new RememberMeBadge()]); } } diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php index da61fa59166fb..d9a96ddf46c10 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php @@ -24,9 +24,8 @@ use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; -use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\EventListener\PasswordMigratingListener; @@ -67,33 +66,6 @@ public function provideUnsupportedEvents() yield [$this->createEvent(new SelfValidatingPassport(new UserBadge('test', function () { return $this->createMock(TestPasswordAuthenticatedUser::class); }), [new PasswordUpgradeBadge('', $this->createPasswordUpgrader())]))]; } - /** - * @group legacy - */ - public function testLegacyUnsupportedEvents() - { - $this->hasherFactory->expects($this->never())->method('getPasswordHasher'); - - $this->listener->onLoginSuccess($this->createEvent($this->createMock(PassportInterface::class))); - } - - /** - * @group legacy - */ - public function testUnsupportedPassport() - { - // A custom Passport, without an UserBadge - $passport = $this->createMock(UserPassportInterface::class); - $passport->method('getUser')->willReturn($this->user); - $passport->method('hasBadge')->withConsecutive([PasswordUpgradeBadge::class], [UserBadge::class])->willReturnOnConsecutiveCalls(true, false); - $passport->expects($this->once())->method('getBadge')->with(PasswordUpgradeBadge::class)->willReturn(new PasswordUpgradeBadge('pa$$word')); - // We should never "getBadge" for "UserBadge::class" - - $event = $this->createEvent($passport); - - $this->listener->onLoginSuccess($event); - } - public function testUpgradeWithUpgrader() { $passwordUpgrader = $this->createPasswordUpgrader(); @@ -135,7 +107,7 @@ private function createPasswordUpgrader() return $this->getMockForAbstractClass(TestMigratingUserProvider::class); } - private function createEvent(PassportInterface $passport) + private function createEvent(Passport $passport) { return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), $passport, $this->createMock(TokenInterface::class), new Request(), null, 'main'); } diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeListenerTest.php index 8851f5b34c8aa..73bb3265fb438 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeListenerTest.php @@ -19,7 +19,7 @@ use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\EventListener\RememberMeListener; @@ -64,7 +64,7 @@ public function testCredentialsInvalid() $this->listener->clearCookie(); } - private function createLoginSuccessfulEvent(PassportInterface $passport = null) + private function createLoginSuccessfulEvent(Passport $passport = null) { if (null === $passport) { $passport = $this->createPassport(); diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeLogoutListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeLogoutListenerTest.php deleted file mode 100644 index 4e13262bc2944..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/RememberMeLogoutListenerTest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\EventListener; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Http\Event\LogoutEvent; -use Symfony\Component\Security\Http\EventListener\RememberMeLogoutListener; -use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices; - -/** - * @group legacy - */ -class RememberMeLogoutListenerTest extends TestCase -{ - public function testOnLogoutDoesNothingIfNoToken() - { - $rememberMeServices = $this->createMock(AbstractRememberMeServices::class); - $rememberMeServices->expects($this->never())->method('logout'); - - $rememberMeLogoutListener = new RememberMeLogoutListener($rememberMeServices); - $rememberMeLogoutListener->onLogout(new LogoutEvent(new Request(), null)); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/UserCheckerListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/UserCheckerListenerTest.php index a0077f75c9b6f..b639da8434875 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/UserCheckerListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/UserCheckerListenerTest.php @@ -19,7 +19,7 @@ use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PreAuthenticatedUserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; -use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken; use Symfony\Component\Security\Http\Event\CheckPassportEvent; @@ -45,16 +45,6 @@ public function testPreAuth() $this->listener->preCheckCredentials($this->createCheckPassportEvent()); } - /** - * @group legacy - */ - public function testPreAuthNoUser() - { - $this->userChecker->expects($this->never())->method('checkPreAuth'); - - $this->listener->preCheckCredentials($this->createCheckPassportEvent($this->createMock(PassportInterface::class))); - } - public function testPreAuthenticatedBadge() { $this->userChecker->expects($this->never())->method('checkPreAuth'); @@ -69,16 +59,6 @@ public function testPostAuthValidCredentials() $this->listener->postCheckCredentials(new AuthenticationSuccessEvent(new PostAuthenticationToken($this->user, 'main', []))); } - /** - * @group legacy - */ - public function testPostAuthNoUser() - { - $this->userChecker->expects($this->never())->method('checkPostAuth'); - - $this->listener->postCheckCredentials(new AuthenticationSuccessEvent(new PreAuthenticatedToken('nobody', 'main'))); - } - private function createCheckPassportEvent($passport = null) { if (null === $passport) { diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php deleted file mode 100644 index 673ae997061d5..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/AbstractPreAuthenticatedListenerTest.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Firewall\AbstractPreAuthenticatedListener; - -/** - * @group legacy - */ -class AbstractPreAuthenticatedListenerTest extends TestCase -{ - public function testHandleWithValidValues() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $request = new Request([], [], [], [], [], []); - - $token = $this->createMock(TokenInterface::class); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->isInstanceOf(PreAuthenticatedToken::class)) - ->willReturn($token) - ; - - $listener = $this->getMockForAbstractClass(AbstractPreAuthenticatedListener::class, [ - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - ]); - $listener - ->expects($this->once()) - ->method('getPreAuthenticatedData') - ->willReturn($userCredentials); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWhenAuthenticationFails() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $request = new Request([], [], [], [], [], []); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $exception = new AuthenticationException('Authentication failed.'); - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->isInstanceOf(PreAuthenticatedToken::class)) - ->willThrowException($exception) - ; - - $listener = $this->getMockForAbstractClass( - AbstractPreAuthenticatedListener::class, [ - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - ]); - $listener - ->expects($this->once()) - ->method('getPreAuthenticatedData') - ->willReturn($userCredentials); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWhenAuthenticationFailsWithDifferentToken() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', ['ROLE_FOO']); - - $request = new Request([], [], [], [], [], []); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($token) - ; - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $exception = new AuthenticationException('Authentication failed.'); - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->isInstanceOf(PreAuthenticatedToken::class)) - ->willThrowException($exception) - ; - - $listener = $this->getMockForAbstractClass( - AbstractPreAuthenticatedListener::class, [ - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - ]); - $listener - ->expects($this->once()) - ->method('getPreAuthenticatedData') - ->willReturn($userCredentials); - - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - - $listener($event); - } - - public function testHandleWithASimilarAuthenticatedToken() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $request = new Request([], [], [], [], [], []); - - $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($token) - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->never()) - ->method('authenticate') - ; - - $listener = $this->getMockForAbstractClass( - AbstractPreAuthenticatedListener::class, [ - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - ]); - $listener - ->expects($this->once()) - ->method('getPreAuthenticatedData') - ->willReturn($userCredentials); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWithAnInvalidSimilarToken() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $request = new Request([], [], [], [], [], []); - - $token = new PreAuthenticatedToken('AnotherUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($token) - ; - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo(null)) - ; - - $exception = new AuthenticationException('Authentication failed.'); - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->isInstanceOf(PreAuthenticatedToken::class)) - ->willThrowException($exception) - ; - - $listener = $this->getMockForAbstractClass( - AbstractPreAuthenticatedListener::class, [ - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - ]); - $listener - ->expects($this->once()) - ->method('getPreAuthenticatedData') - ->willReturn($userCredentials); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php index e0beb89211418..7cb545a1211e8 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/AccessListenerTest.php @@ -15,7 +15,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; use Symfony\Component\Security\Core\Authentication\Token\NullToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; @@ -47,11 +46,6 @@ public function testHandleWhenTheAccessDecisionManagerDecidesToRefuseAccess() ; $token = new class() extends AbstractToken { - public function isAuthenticated(): bool - { - return true; - } - public function getCredentials(): mixed { } @@ -75,76 +69,7 @@ public function getCredentials(): mixed $listener = new AccessListener( $tokenStorage, $accessDecisionManager, - $accessMap, - false - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - /** - * @group legacy - */ - public function testHandleWhenTheTokenIsNotAuthenticated() - { - $request = new Request(); - - $accessMap = $this->createMock(AccessMapInterface::class); - $accessMap - ->expects($this->any()) - ->method('getPatterns') - ->with($this->equalTo($request)) - ->willReturn([['foo' => 'bar'], null]) - ; - - $notAuthenticatedToken = $this->createMock(TokenInterface::class); - $notAuthenticatedToken - ->expects($this->any()) - ->method('isAuthenticated') - ->willReturn(false) - ; - - $authenticatedToken = $this->createMock(TokenInterface::class); - $authenticatedToken - ->expects($this->any()) - ->method('isAuthenticated') - ->willReturn(true) - ; - - $authManager = $this->createMock(AuthenticationManagerInterface::class); - $authManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->equalTo($notAuthenticatedToken)) - ->willReturn($authenticatedToken) - ; - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($notAuthenticatedToken) - ; - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($authenticatedToken)) - ; - - $accessDecisionManager = $this->createMock(AccessDecisionManagerInterface::class); - $accessDecisionManager - ->expects($this->once()) - ->method('decide') - ->with($this->equalTo($authenticatedToken), $this->equalTo(['foo' => 'bar']), $this->equalTo($request)) - ->willReturn(true) - ; - - $listener = new AccessListener( - $tokenStorage, - $accessDecisionManager, - $accessMap, - $authManager, - false + $accessMap ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -163,12 +88,6 @@ public function testHandleWhenThereIsNoAccessMapEntryMatchingTheRequest() ; $token = $this->createMock(TokenInterface::class); - if (method_exists(TokenInterface::class, 'isAuthenticated')) { - $token - ->expects($this->never()) - ->method('isAuthenticated') - ; - } $tokenStorage = $this->createMock(TokenStorageInterface::class); $tokenStorage @@ -180,8 +99,7 @@ public function testHandleWhenThereIsNoAccessMapEntryMatchingTheRequest() $listener = new AccessListener( $tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), - $accessMap, - false + $accessMap ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -208,8 +126,7 @@ public function testHandleWhenAccessMapReturnsEmptyAttributes() $listener = new AccessListener( $tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), - $accessMap, - false + $accessMap ); $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); @@ -217,39 +134,6 @@ public function testHandleWhenAccessMapReturnsEmptyAttributes() $listener(new LazyResponseEvent($event)); } - /** - * @group legacy - */ - public function testLegacyHandleWhenTheSecurityTokenStorageHasNoToken() - { - $this->expectException(AuthenticationCredentialsNotFoundException::class); - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $request = new Request(); - - $accessMap = $this->createMock(AccessMapInterface::class); - $accessMap - ->expects($this->any()) - ->method('getPatterns') - ->with($this->equalTo($request)) - ->willReturn([['foo' => 'bar'], null]) - ; - - $listener = new AccessListener( - $tokenStorage, - $this->createMock(AccessDecisionManagerInterface::class), - $accessMap, - $this->createMock(AuthenticationManagerInterface::class) - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - public function testHandleWhenTheSecurityTokenStorageHasNoToken() { $this->expectException(AccessDeniedException::class); @@ -365,8 +249,7 @@ public function testHandleMWithultipleAttributesShouldBeHandledAsAnd() $listener = new AccessListener( $tokenStorage, $accessDecisionManager, - $accessMap, - false + $accessMap ); $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); @@ -388,24 +271,4 @@ public function testLazyPublicPagesShouldNotAccessTokenStorage() $listener = new AccessListener($tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), $accessMap, false); $listener(new LazyResponseEvent(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST))); } - - /** - * @group legacy - */ - public function testLegacyLazyPublicPagesShouldNotAccessTokenStorage() - { - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage->expects($this->never())->method('getToken'); - - $request = new Request(); - $accessMap = $this->createMock(AccessMapInterface::class); - $accessMap->expects($this->any()) - ->method('getPatterns') - ->with($this->equalTo($request)) - ->willReturn([[AuthenticatedVoter::IS_AUTHENTICATED_ANONYMOUSLY], null]) - ; - - $listener = new AccessListener($tokenStorage, $this->createMock(AccessDecisionManagerInterface::class), $accessMap, false); - $listener(new LazyResponseEvent(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST))); - } } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php deleted file mode 100644 index 235f667014d1f..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/AnonymousAuthenticationListenerTest.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Http\Firewall\AnonymousAuthenticationListener; - -/** - * @group legacy - */ -class AnonymousAuthenticationListenerTest extends TestCase -{ - public function testHandleWithTokenStorageHavingAToken() - { - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($this->createMock(TokenInterface::class)) - ; - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->never()) - ->method('authenticate') - ; - - $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager); - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWithTokenStorageHavingNoToken() - { - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $anonymousToken = new AnonymousToken('TheSecret', 'anon.', []); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->callback(function ($token) { - return 'TheSecret' === $token->getSecret(); - })) - ->willReturn($anonymousToken) - ; - - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($anonymousToken) - ; - - $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', null, $authenticationManager); - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandledEventIsLogged() - { - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $logger = $this->createMock(LoggerInterface::class); - $logger->expects($this->once()) - ->method('info') - ->with('Populated the TokenStorage with an anonymous Token.') - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new AnonymousAuthenticationListener($tokenStorage, 'TheSecret', $logger, $authenticationManager); - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MAIN_REQUEST)); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/BasicAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/BasicAuthenticationListenerTest.php deleted file mode 100644 index 36db0b5ac312b..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/BasicAuthenticationListenerTest.php +++ /dev/null @@ -1,220 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; -use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; -use Symfony\Component\Security\Http\Firewall\BasicAuthenticationListener; - -/** - * @group legacy - */ -class BasicAuthenticationListenerTest extends TestCase -{ - public function testHandleWithValidUsernameAndPasswordServerParameters() - { - $request = new Request([], [], [], [], [], [ - 'PHP_AUTH_USER' => 'TheUsername', - 'PHP_AUTH_PW' => 'ThePassword', - ]); - - $token = $this->createMock(TokenInterface::class); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->once()) - ->method('authenticate') - ->with($this->isInstanceOf(UsernamePasswordToken::class)) - ->willReturn($token) - ; - - $listener = new BasicAuthenticationListener( - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - $this->createMock(AuthenticationEntryPointInterface::class) - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWhenAuthenticationFails() - { - $request = new Request([], [], [], [], [], [ - 'PHP_AUTH_USER' => 'TheUsername', - 'PHP_AUTH_PW' => 'ThePassword', - ]); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $response = new Response(); - - $authenticationEntryPoint = $this->createMock(AuthenticationEntryPointInterface::class); - $authenticationEntryPoint - ->expects($this->any()) - ->method('start') - ->with($this->equalTo($request), $this->isInstanceOf(AuthenticationException::class)) - ->willReturn($response) - ; - - $listener = new BasicAuthenticationListener( - $tokenStorage, - new AuthenticationProviderManager([$this->createMock(AuthenticationProviderInterface::class)]), - 'TheProviderKey', - $authenticationEntryPoint - ); - - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - - $listener($event); - - $this->assertSame($response, $event->getResponse()); - } - - public function testHandleWithNoUsernameServerParameter() - { - $request = new Request(); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->never()) - ->method('getToken') - ; - - $listener = new BasicAuthenticationListener( - $tokenStorage, - $this->createMock(AuthenticationManagerInterface::class), - 'TheProviderKey', - $this->createMock(AuthenticationEntryPointInterface::class) - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testHandleWithASimilarAuthenticatedToken() - { - $request = new Request([], [], [], [], [], ['PHP_AUTH_USER' => 'TheUsername']); - - $token = new UsernamePasswordToken('TheUsername', 'ThePassword', 'TheProviderKey', ['ROLE_FOO']); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($token) - ; - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - $authenticationManager - ->expects($this->never()) - ->method('authenticate') - ; - - $listener = new BasicAuthenticationListener( - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - $this->createMock(AuthenticationEntryPointInterface::class) - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - public function testItRequiresProviderKey() - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('$providerKey must not be empty'); - new BasicAuthenticationListener( - $this->createMock(TokenStorageInterface::class), - $this->createMock(AuthenticationManagerInterface::class), - '', - $this->createMock(AuthenticationEntryPointInterface::class) - ); - } - - public function testHandleWithADifferentAuthenticatedToken() - { - $request = new Request([], [], [], [], [], [ - 'PHP_AUTH_USER' => 'TheUsername', - 'PHP_AUTH_PW' => 'ThePassword', - ]); - - $token = new PreAuthenticatedToken('TheUser', 'TheCredentials', 'TheProviderKey', ['ROLE_FOO']); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($token) - ; - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $response = new Response(); - - $authenticationEntryPoint = $this->createMock(AuthenticationEntryPointInterface::class); - $authenticationEntryPoint - ->expects($this->any()) - ->method('start') - ->with($this->equalTo($request), $this->isInstanceOf(AuthenticationException::class)) - ->willReturn($response) - ; - - $listener = new BasicAuthenticationListener( - $tokenStorage, - new AuthenticationProviderManager([$this->createMock(AuthenticationProviderInterface::class)]), - 'TheProviderKey', - $authenticationEntryPoint - ); - - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - - $listener($event); - - $this->assertSame($response, $event->getResponse()); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ChannelListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ChannelListenerTest.php index ee025f55cbac0..adb66807d89e7 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ChannelListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ChannelListenerTest.php @@ -149,42 +149,4 @@ public function testSupportsWithoutHeaders() $this->assertTrue($listener->supports($request)); } - - /** - * @group legacy - */ - public function testLegacyHandleWithEntryPoint() - { - $request = $this->createMock(Request::class); - $request - ->expects($this->any()) - ->method('isSecure') - ->willReturn(false) - ; - - $accessMap = $this->createMock(AccessMapInterface::class); - $accessMap - ->expects($this->any()) - ->method('getPatterns') - ->with($this->equalTo($request)) - ->willReturn([[], 'https']) - ; - - $response = new RedirectResponse('/redirected'); - - $entryPoint = $this->createMock(AuthenticationEntryPointInterface::class); - $entryPoint - ->expects($this->once()) - ->method('start') - ->with($this->equalTo($request)) - ->willReturn($response) - ; - - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - - $listener = new ChannelListener($accessMap, $entryPoint); - $listener($event); - - $this->assertSame($response, $event->getResponse()); - } } diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php index b59cc7d0e7e2e..60473236fb681 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php @@ -25,7 +25,6 @@ use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage; @@ -37,7 +36,6 @@ use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Http\Event\DeauthenticatedEvent; use Symfony\Component\Security\Http\Firewall\ContextListener; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; use Symfony\Contracts\Service\ServiceLocatorTrait; class ContextListenerTest extends TestCase @@ -94,16 +92,6 @@ public function testOnKernelResponseWillRemoveSession() $this->assertFalse($session->has('_security_session')); } - /** - * @group legacy - */ - public function testOnKernelResponseWillRemoveSessionOnAnonymousToken() - { - $session = $this->runSessionOnKernelResponse(new AnonymousToken('secret', 'anon.'), 'C:10:"serialized"'); - - $this->assertFalse($session->has('_security_session')); - } - public function testOnKernelResponseWithoutSession() { $tokenStorage = new TokenStorage(); @@ -242,22 +230,6 @@ public function testIfTokenIsNotDeauthenticated() $this->assertSame($goodRefreshedUser, $tokenStorage->getToken()->getUser()); } - /** - * @group legacy - */ - public function testRememberMeGetsCanceledIfTokenIsDeauthenticated() - { - $tokenStorage = new TokenStorage(); - $refreshedUser = new InMemoryUser('foobar', 'baz'); - - $rememberMeServices = $this->createMock(RememberMeServicesInterface::class); - $rememberMeServices->expects($this->once())->method('loginFail'); - - $tokenStorage = $this->handleEventWithPreviousSession([new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], null, $rememberMeServices); - - $this->assertNull($tokenStorage->getToken()); - } - public function testTryAllUserProvidersUntilASupportingUserProviderIsFound() { $refreshedUser = new InMemoryUser('foobar', 'baz'); @@ -295,36 +267,6 @@ public function testAcceptsProvidersAsTraversable() $this->assertSame($refreshedUser, $tokenStorage->getToken()->getUser()); } - /** - * @group legacy - */ - public function testDeauthenticatedEvent() - { - $tokenStorage = new TokenStorage(); - $refreshedUser = new InMemoryUser('foobar', 'baz'); - - $user = new InMemoryUser('foo', 'bar'); - $session = new Session(new MockArraySessionStorage()); - $session->set('_security_context_key', serialize(new UsernamePasswordToken($user, 'context_key', ['ROLE_USER']))); - - $request = new Request(); - $request->setSession($session); - $request->cookies->set('MOCKSESSID', true); - - $eventDispatcher = new EventDispatcher(); - $eventDispatcher->addListener(DeauthenticatedEvent::class, function (DeauthenticatedEvent $event) use ($user) { - $this->assertTrue($event->getOriginalToken()->isAuthenticated()); - $this->assertEquals($event->getOriginalToken()->getUser(), $user); - $this->assertFalse($event->getRefreshedToken()->isAuthenticated()); - $this->assertNotEquals($event->getRefreshedToken()->getUser(), $user); - }); - - $listener = new ContextListener($tokenStorage, [new NotSupportingUserProvider(true), new NotSupportingUserProvider(false), new SupportingUserProvider($refreshedUser)], 'context_key', null, $eventDispatcher); - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - - $this->assertNull($tokenStorage->getToken()); - } - public function testWithPreviousNotStartedSession() { $session = new Session(new MockArraySessionStorage()); @@ -405,7 +347,7 @@ protected function runSessionOnKernelResponse($newToken, $original = null) return $session; } - private function handleEventWithPreviousSession($userProviders, UserInterface $user = null, RememberMeServicesInterface $rememberMeServices = null) + private function handleEventWithPreviousSession($userProviders, UserInterface $user = null) { $tokenUser = $user ?? new InMemoryUser('foo', 'bar'); $session = new Session(new MockArraySessionStorage()); @@ -436,9 +378,6 @@ private function handleEventWithPreviousSession($userProviders, UserInterface $u $listener = new ContextListener($tokenStorage, $userProviders, 'context_key', null, null, null, $sessionTrackerEnabler); - if ($rememberMeServices) { - $listener->setRememberMeServices($rememberMeServices); - } $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); if (null !== $user) { diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php deleted file mode 100644 index 7902d46568638..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php +++ /dev/null @@ -1,380 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\Firewall\RememberMeListener; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; -use Symfony\Component\Security\Http\SecurityEvents; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -/** - * @group legacy - */ -class RememberMeListenerTest extends TestCase -{ - public function testOnCoreSecurityDoesNotTryToPopulateNonEmptyTokenStorage() - { - [$listener, $tokenStorage] = $this->getListener(); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn($this->createMock(TokenInterface::class)) - ; - - $tokenStorage - ->expects($this->never()) - ->method('setToken') - ; - - $this->assertNull($listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MASTER_REQUEST))); - } - - public function testOnCoreSecurityDoesNothingWhenNoCookieIsSet() - { - [$listener, $tokenStorage, $service] = $this->getListener(); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn(null) - ; - - $this->assertNull($listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MASTER_REQUEST))); - } - - public function testOnCoreSecurityIgnoresAuthenticationExceptionThrownByAuthenticationManagerImplementation() - { - [$listener, $tokenStorage, $service, $manager] = $this->getListener(); - $request = new Request(); - $exception = new AuthenticationException('Authentication failed.'); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($this->createMock(TokenInterface::class)) - ; - - $service - ->expects($this->once()) - ->method('loginFail') - ->with($request, $exception) - ; - - $manager - ->expects($this->once()) - ->method('authenticate') - ->willThrowException($exception) - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST)); - } - - public function testOnCoreSecurityIgnoresAuthenticationOptionallyRethrowsExceptionThrownAuthenticationManagerImplementation() - { - $this->expectException(AuthenticationException::class); - $this->expectExceptionMessage('Authentication failed.'); - [$listener, $tokenStorage, $service, $manager] = $this->getListener(false, false); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($this->createMock(TokenInterface::class)) - ; - - $service - ->expects($this->once()) - ->method('loginFail') - ; - - $exception = new AuthenticationException('Authentication failed.'); - $manager - ->expects($this->once()) - ->method('authenticate') - ->willThrowException($exception) - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MASTER_REQUEST)); - } - - public function testOnCoreSecurityAuthenticationExceptionDuringAutoLoginTriggersLoginFail() - { - [$listener, $tokenStorage, $service, $manager] = $this->getListener(); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $exception = new AuthenticationException('Authentication failed.'); - $service - ->expects($this->once()) - ->method('autoLogin') - ->willThrowException($exception) - ; - - $service - ->expects($this->once()) - ->method('loginFail') - ; - - $manager - ->expects($this->never()) - ->method('authenticate') - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MASTER_REQUEST)); - } - - public function testOnCoreSecurity() - { - [$listener, $tokenStorage, $service, $manager] = $this->getListener(); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $token = $this->createMock(TokenInterface::class); - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($token) - ; - - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $manager - ->expects($this->once()) - ->method('authenticate') - ->willReturn($token) - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MASTER_REQUEST)); - } - - public function testSessionStrategy() - { - [$listener, $tokenStorage, $service, $manager, , , $sessionStrategy] = $this->getListener(false, true, true); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $token = $this->createMock(TokenInterface::class); - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($token) - ; - - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $manager - ->expects($this->once()) - ->method('authenticate') - ->willReturn($token) - ; - - $session = $this->createMock(SessionInterface::class); - $session - ->expects($this->once()) - ->method('isStarted') - ->willReturn(true) - ; - - $request = new Request(); - $request->setSession($session); - - $sessionStrategy - ->expects($this->once()) - ->method('onAuthentication') - ->willReturn(null) - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST)); - } - - public function testSessionIsMigratedByDefault() - { - [$listener, $tokenStorage, $service, $manager] = $this->getListener(false, true, false); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $token = $this->createMock(TokenInterface::class); - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($token) - ; - - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $manager - ->expects($this->once()) - ->method('authenticate') - ->willReturn($token) - ; - - $session = $this->createMock(SessionInterface::class); - $session - ->expects($this->once()) - ->method('isStarted') - ->willReturn(true) - ; - $session - ->expects($this->once()) - ->method('migrate') - ; - - $request = new Request(); - $request->setSession($session); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MASTER_REQUEST)); - } - - public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent() - { - [$listener, $tokenStorage, $service, $manager, , $dispatcher] = $this->getListener(true); - - $tokenStorage - ->expects($this->any()) - ->method('getToken') - ->willReturn(null) - ; - - $token = $this->createMock(TokenInterface::class); - $service - ->expects($this->once()) - ->method('autoLogin') - ->willReturn($token) - ; - - $tokenStorage - ->expects($this->once()) - ->method('setToken') - ->with($this->equalTo($token)) - ; - - $manager - ->expects($this->once()) - ->method('authenticate') - ->willReturn($token) - ; - - $dispatcher - ->expects($this->once()) - ->method('dispatch') - ->with( - $this->isInstanceOf(InteractiveLoginEvent::class), - SecurityEvents::INTERACTIVE_LOGIN - ) - ; - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), new Request(), HttpKernelInterface::MAIN_REQUEST)); - } - - protected function getListener($withDispatcher = false, $catchExceptions = true, $withSessionStrategy = false) - { - $listener = new RememberMeListener( - $tokenStorage = $this->getTokenStorage(), - $service = $this->getService(), - $manager = $this->getManager(), - $logger = $this->getLogger(), - $dispatcher = ($withDispatcher ? $this->getDispatcher() : null), - $catchExceptions, - $sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null) - ); - - return [$listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy]; - } - - protected function getLogger() - { - return $this->createMock(LoggerInterface::class); - } - - protected function getManager() - { - return $this->createMock(AuthenticationManagerInterface::class); - } - - protected function getService() - { - return $this->createMock(RememberMeServicesInterface::class); - } - - protected function getTokenStorage() - { - return $this->createMock(TokenStorageInterface::class); - } - - protected function getDispatcher() - { - return $this->createMock(EventDispatcherInterface::class); - } - - private function getSessionStrategy() - { - return $this->createMock(SessionAuthenticationStrategyInterface::class); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php deleted file mode 100644 index 2dac33fcd2f3a..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/RemoteUserAuthenticationListenerTest.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Http\Firewall\RemoteUserAuthenticationListener; - -/** - * @group legacy - */ -class RemoteUserAuthenticationListenerTest extends TestCase -{ - public function testGetPreAuthenticatedData() - { - $serverVars = [ - 'REMOTE_USER' => 'TheUser', - ]; - - $request = new Request([], [], [], [], [], $serverVars); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new RemoteUserAuthenticationListener( - $tokenStorage, - $authenticationManager, - 'TheProviderKey' - ); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $result = $method->invokeArgs($listener, [$request]); - $this->assertSame($result, ['TheUser', null]); - } - - public function testGetPreAuthenticatedDataNoUser() - { - $this->expectException(BadCredentialsException::class); - $request = new Request([], [], [], [], [], []); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new RemoteUserAuthenticationListener( - $tokenStorage, - $authenticationManager, - 'TheProviderKey' - ); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $method->invokeArgs($listener, [$request]); - } - - public function testGetPreAuthenticatedDataWithDifferentKeys() - { - $userCredentials = ['TheUser', null]; - - $request = new Request([], [], [], [], [], [ - 'TheUserKey' => 'TheUser', - ]); - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new RemoteUserAuthenticationListener( - $tokenStorage, - $authenticationManager, - 'TheProviderKey', - 'TheUserKey' - ); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $result = $method->invokeArgs($listener, [$request]); - $this->assertSame($result, $userCredentials); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php index 0338af0017e8a..9ccbf741c4214 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php @@ -138,30 +138,6 @@ public function testExitUserDispatchesEventWithRefreshedUser() $listener($this->event); } - /** - * @group legacy - */ - public function testExitUserDoesNotDispatchEventWithStringUser() - { - $originalUser = 'anon.'; - $userProvider = $this->createMock(InMemoryUserProvider::class); - $userProvider - ->expects($this->never()) - ->method('refreshUser'); - $originalToken = new UsernamePasswordToken($originalUser, 'key'); - $this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', ['ROLE_USER'], $originalToken)); - $this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE); - - $dispatcher = $this->createMock(EventDispatcherInterface::class); - $dispatcher - ->expects($this->never()) - ->method('dispatch') - ; - - $listener = new SwitchUserListener($this->tokenStorage, $userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager, null, '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', $dispatcher); - $listener($this->event); - } - public function testSwitchUserIsDisallowed() { $this->expectException(AccessDeniedException::class); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php deleted file mode 100644 index 6b742c07b3452..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php +++ /dev/null @@ -1,230 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; -use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler; -use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler; -use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener; -use Symfony\Component\Security\Http\HttpUtils; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; - -/** - * @group legacy - */ -class UsernamePasswordFormAuthenticationListenerTest extends TestCase -{ - /** - * @dataProvider getUsernameForLength - */ - public function testHandleWhenUsernameLength($username, $ok) - { - $request = Request::create('/login_check', 'POST', ['_username' => $username, '_password' => 'symfony']); - $request->setSession($this->createMock(SessionInterface::class)); - - $httpUtils = $this->createMock(HttpUtils::class); - $httpUtils - ->expects($this->any()) - ->method('checkRequestPath') - ->willReturn(true) - ; - $httpUtils - ->method('createRedirectResponse') - ->willReturn(new RedirectResponse('/hello')) - ; - - $failureHandler = $this->createMock(AuthenticationFailureHandlerInterface::class); - $failureHandler - ->expects($ok ? $this->never() : $this->once()) - ->method('onAuthenticationFailure') - ->willReturn(new Response()) - ; - - $authenticationManager = $this->createMock(AuthenticationProviderManager::class); - $authenticationManager - ->expects($ok ? $this->once() : $this->never()) - ->method('authenticate') - ->willReturnArgument(0) - ; - - $listener = new UsernamePasswordFormAuthenticationListener( - $this->createMock(TokenStorageInterface::class), - $authenticationManager, - $this->createMock(SessionAuthenticationStrategyInterface::class), - $httpUtils, - 'TheProviderKey', - new DefaultAuthenticationSuccessHandler($httpUtils), - $failureHandler, - ['require_previous_session' => false] - ); - - $listener(new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST)); - } - - /** - * @dataProvider postOnlyDataProvider - */ - public function testHandleNonStringUsernameWithArray($postOnly) - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "_username" must be a string, "array" given.'); - $request = Request::create('/login_check', 'POST', ['_username' => []]); - $request->setSession($this->createMock(SessionInterface::class)); - $listener = new UsernamePasswordFormAuthenticationListener( - new TokenStorage(), - $this->createMock(AuthenticationManagerInterface::class), - new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE), - $httpUtils = new HttpUtils(), - 'foo', - new DefaultAuthenticationSuccessHandler($httpUtils), - new DefaultAuthenticationFailureHandler($this->createMock(HttpKernelInterface::class), $httpUtils), - ['require_previous_session' => false, 'post_only' => $postOnly] - ); - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - $listener($event); - } - - /** - * @dataProvider postOnlyDataProvider - */ - public function testHandleNonStringUsernameWithInt($postOnly) - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "_username" must be a string, "int" given.'); - $request = Request::create('/login_check', 'POST', ['_username' => 42]); - $request->setSession($this->createMock(SessionInterface::class)); - $listener = new UsernamePasswordFormAuthenticationListener( - new TokenStorage(), - $this->createMock(AuthenticationManagerInterface::class), - new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE), - $httpUtils = new HttpUtils(), - 'foo', - new DefaultAuthenticationSuccessHandler($httpUtils), - new DefaultAuthenticationFailureHandler($this->createMock(HttpKernelInterface::class), $httpUtils), - ['require_previous_session' => false, 'post_only' => $postOnly] - ); - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - $listener($event); - } - - /** - * @dataProvider postOnlyDataProvider - */ - public function testHandleNonStringUsernameWithObject($postOnly) - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "_username" must be a string, "stdClass" given.'); - $request = Request::create('/login_check', 'POST', ['_username' => new \stdClass()]); - $request->setSession($this->createMock(SessionInterface::class)); - $listener = new UsernamePasswordFormAuthenticationListener( - new TokenStorage(), - $this->createMock(AuthenticationManagerInterface::class), - new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE), - $httpUtils = new HttpUtils(), - 'foo', - new DefaultAuthenticationSuccessHandler($httpUtils), - new DefaultAuthenticationFailureHandler($this->createMock(HttpKernelInterface::class), $httpUtils), - ['require_previous_session' => false, 'post_only' => $postOnly] - ); - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - $listener($event); - } - - /** - * @dataProvider postOnlyDataProvider - */ - public function testHandleNonStringUsernameWith__toString($postOnly) - { - $usernameClass = $this->createMock(DummyUserClass::class); - $usernameClass - ->expects($this->atLeastOnce()) - ->method('__toString') - ->willReturn('someUsername'); - - $request = Request::create('/login_check', 'POST', ['_username' => $usernameClass, '_password' => 'symfony']); - $request->setSession($this->createMock(SessionInterface::class)); - $listener = new UsernamePasswordFormAuthenticationListener( - new TokenStorage(), - $this->createMock(AuthenticationManagerInterface::class), - new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE), - $httpUtils = new HttpUtils(), - 'foo', - new DefaultAuthenticationSuccessHandler($httpUtils), - new DefaultAuthenticationFailureHandler($this->createMock(HttpKernelInterface::class), $httpUtils), - ['require_previous_session' => false, 'post_only' => $postOnly] - ); - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - $listener($event); - } - - /** - * @dataProvider postOnlyDataProvider - */ - public function testHandleWhenPasswordAreNull($postOnly) - { - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('The key "_password" cannot be null; check that the password field name of the form matches.'); - - $request = Request::create('/login_check', 'POST', ['_username' => 'symfony', 'password' => 'symfony']); - $request->setSession($this->createMock(SessionInterface::class)); - $listener = new UsernamePasswordFormAuthenticationListener( - new TokenStorage(), - $this->createMock(AuthenticationManagerInterface::class), - new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE), - $httpUtils = new HttpUtils(), - 'foo', - new DefaultAuthenticationSuccessHandler($httpUtils), - new DefaultAuthenticationFailureHandler($this->createMock(HttpKernelInterface::class), $httpUtils), - ['require_previous_session' => false, 'post_only' => $postOnly] - ); - $event = new RequestEvent($this->createMock(HttpKernelInterface::class), $request, HttpKernelInterface::MAIN_REQUEST); - $listener($event); - } - - public function postOnlyDataProvider() - { - return [ - [true], - [false], - ]; - } - - public function getUsernameForLength() - { - return [ - [str_repeat('x', Security::MAX_USERNAME_LENGTH + 1), false], - [str_repeat('x', Security::MAX_USERNAME_LENGTH - 1), true], - ]; - } -} - -class DummyUserClass -{ - public function __toString(): string - { - return ''; - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php deleted file mode 100644 index e13a7362d3485..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordJsonAuthenticationListenerTest.php +++ /dev/null @@ -1,271 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\KernelInterface; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Core\Security; -use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; -use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; -use Symfony\Component\Security\Http\Firewall\UsernamePasswordJsonAuthenticationListener; -use Symfony\Component\Security\Http\HttpUtils; -use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface; -use Symfony\Component\Translation\Loader\ArrayLoader; -use Symfony\Component\Translation\Translator; - -/** - * @author Kévin Dunglas - * - * @group legacy - */ -class UsernamePasswordJsonAuthenticationListenerTest extends TestCase -{ - /** - * @var UsernamePasswordJsonAuthenticationListener - */ - private $listener; - - private function createListener(array $options = [], $success = true, $matchCheckPath = true, $withMockedHandler = true) - { - $tokenStorage = $this->createMock(TokenStorageInterface::class); - $httpUtils = $this->createMock(HttpUtils::class); - $httpUtils - ->expects($this->any()) - ->method('checkRequestPath') - ->willReturn($matchCheckPath) - ; - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $authenticatedToken = $this->createMock(TokenInterface::class); - - if ($success) { - $authenticationManager->method('authenticate')->willReturn($authenticatedToken); - } else { - $authenticationManager->method('authenticate')->willThrowException(new AuthenticationException()); - } - - $authenticationSuccessHandler = null; - $authenticationFailureHandler = null; - - if ($withMockedHandler) { - $authenticationSuccessHandler = $this->createMock(AuthenticationSuccessHandlerInterface::class); - $authenticationSuccessHandler->method('onAuthenticationSuccess')->willReturn(new Response('ok')); - $authenticationFailureHandler = $this->createMock(AuthenticationFailureHandlerInterface::class); - $authenticationFailureHandler->method('onAuthenticationFailure')->willReturn(new Response('ko')); - } - - $this->listener = new UsernamePasswordJsonAuthenticationListener($tokenStorage, $authenticationManager, $httpUtils, 'providerKey', $authenticationSuccessHandler, $authenticationFailureHandler, $options); - } - - public function testHandleSuccessIfRequestContentTypeIsJson() - { - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertEquals('ok', $event->getResponse()->getContent()); - } - - public function testSuccessIfRequestFormatIsJsonLD() - { - $this->createListener(); - $request = new Request([], [], [], [], [], [], '{"username": "dunglas", "password": "foo"}'); - $request->setRequestFormat('json-ld'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertEquals('ok', $event->getResponse()->getContent()); - } - - public function testHandleFailure() - { - $this->createListener([], false, true, false); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertSame(['error' => 'An authentication exception occurred.'], json_decode($event->getResponse()->getContent(), true)); - } - - public function testTranslatedHandleFailure() - { - $translator = new Translator('en'); - $translator->addLoader('array', new ArrayLoader()); - $translator->addResource('array', ['An authentication exception occurred.' => 'foo'], 'en', 'security'); - - $this->createListener([], false, true, false); - $this->listener->setTranslator($translator); - - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertSame(['error' => 'foo'], json_decode($event->getResponse()->getContent(), true)); - } - - public function testUsePath() - { - $this->createListener(['username_path' => 'user.login', 'password_path' => 'user.pwd']); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"user": {"login": "dunglas", "pwd": "foo"}}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertEquals('ok', $event->getResponse()->getContent()); - } - - public function testAttemptAuthenticationNoJson() - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('Invalid JSON'); - $this->createListener(); - $request = new Request(); - $request->setRequestFormat('json'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - } - - public function testAttemptAuthenticationNoUsername() - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "username" must be provided'); - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"usr": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - } - - public function testAttemptAuthenticationNoPassword() - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "password" must be provided'); - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "pass": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - } - - public function testAttemptAuthenticationUsernameNotAString() - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "username" must be a string.'); - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": 1, "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - } - - public function testAttemptAuthenticationPasswordNotAString() - { - $this->expectException(BadRequestHttpException::class); - $this->expectExceptionMessage('The key "password" must be a string.'); - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": 1}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - } - - public function testAttemptAuthenticationUsernameTooLong() - { - $this->createListener(); - $username = str_repeat('x', Security::MAX_USERNAME_LENGTH + 1); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], sprintf('{"username": "%s", "password": 1}', $username)); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertSame('ko', $event->getResponse()->getContent()); - } - - public function testDoesNotAttemptAuthenticationIfRequestPathDoesNotMatchCheckPath() - { - $this->createListener(['check_path' => '/'], true, false); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json']); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - $event->setResponse(new Response('original')); - - ($this->listener)($event); - $this->assertSame('original', $event->getResponse()->getContent()); - } - - public function testDoesNotAttemptAuthenticationIfRequestContentTypeIsNotJson() - { - $this->createListener(); - $request = new Request([], [], [], [], [], [], '{"username": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - $event->setResponse(new Response('original')); - - ($this->listener)($event); - $this->assertSame('original', $event->getResponse()->getContent()); - } - - public function testAttemptAuthenticationIfRequestPathMatchesCheckPath() - { - $this->createListener(['check_path' => '/']); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertSame('ok', $event->getResponse()->getContent()); - } - - public function testNoErrorOnMissingSessionStrategy() - { - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $this->configurePreviousSession($request); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - ($this->listener)($event); - $this->assertEquals('ok', $event->getResponse()->getContent()); - } - - public function testMigratesViaSessionStrategy() - { - $this->createListener(); - $request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], '{"username": "dunglas", "password": "foo"}'); - $this->configurePreviousSession($request); - $event = new RequestEvent($this->createMock(KernelInterface::class), $request, KernelInterface::MAIN_REQUEST); - - $sessionStrategy = $this->createMock(SessionAuthenticationStrategyInterface::class); - $sessionStrategy->expects($this->once()) - ->method('onAuthentication') - ->with($request, $this->isInstanceOf(TokenInterface::class)); - $this->listener->setSessionAuthenticationStrategy($sessionStrategy); - - ($this->listener)($event); - $this->assertEquals('ok', $event->getResponse()->getContent()); - } - - private function configurePreviousSession(Request $request) - { - $session = $this->createMock(SessionInterface::class); - $session->expects($this->any()) - ->method('getName') - ->willReturn('test_session_name'); - $request->setSession($session); - $request->cookies->set('test_session_name', 'session_cookie_val'); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php deleted file mode 100644 index c0b3026d425b9..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/X509AuthenticationListenerTest.php +++ /dev/null @@ -1,130 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\Firewall; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -use Symfony\Component\Security\Core\Exception\BadCredentialsException; -use Symfony\Component\Security\Http\Firewall\X509AuthenticationListener; - -/** - * @group legacy - */ -class X509AuthenticationListenerTest extends TestCase -{ - /** - * @dataProvider dataProviderGetPreAuthenticatedData - */ - public function testGetPreAuthenticatedData($user, $credentials) - { - $serverVars = []; - if ('' !== $user) { - $serverVars['SSL_CLIENT_S_DN_Email'] = $user; - } - if ('' !== $credentials) { - $serverVars['SSL_CLIENT_S_DN'] = $credentials; - } - - $request = new Request([], [], [], [], [], $serverVars); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $result = $method->invokeArgs($listener, [$request]); - $this->assertSame($result, [$user, $credentials]); - } - - public static function dataProviderGetPreAuthenticatedData() - { - return [ - 'validValues' => ['TheUser', 'TheCredentials'], - 'noCredentials' => ['TheUser', ''], - ]; - } - - /** - * @dataProvider dataProviderGetPreAuthenticatedDataNoUser - */ - public function testGetPreAuthenticatedDataNoUser($emailAddress, $credentials) - { - $request = new Request([], [], [], [], [], ['SSL_CLIENT_S_DN' => $credentials]); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $result = $method->invokeArgs($listener, [$request]); - $this->assertSame($result, [$emailAddress, $credentials]); - } - - public static function dataProviderGetPreAuthenticatedDataNoUser() - { - yield ['cert@example.com', 'CN=Sample certificate DN/emailAddress=cert@example.com']; - yield ['cert+something@example.com', 'CN=Sample certificate DN/emailAddress=cert+something@example.com']; - yield ['cert@example.com', 'CN=Sample certificate DN,emailAddress=cert@example.com']; - yield ['cert+something@example.com', 'CN=Sample certificate DN,emailAddress=cert+something@example.com']; - yield ['cert+something@example.com', 'emailAddress=cert+something@example.com,CN=Sample certificate DN']; - yield ['cert+something@example.com', 'emailAddress=cert+something@example.com']; - yield ['firstname.lastname@mycompany.co.uk', 'emailAddress=firstname.lastname@mycompany.co.uk,CN=Firstname.Lastname,OU=london,OU=company design and engineering,OU=Issuer London,OU=Roaming,OU=Interactive,OU=Users,OU=Standard,OU=Business,DC=england,DC=core,DC=company,DC=co,DC=uk']; - } - - public function testGetPreAuthenticatedDataNoData() - { - $this->expectException(BadCredentialsException::class); - $request = new Request([], [], [], [], [], []); - - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey'); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $method->invokeArgs($listener, [$request]); - } - - public function testGetPreAuthenticatedDataWithDifferentKeys() - { - $userCredentials = ['TheUser', 'TheCredentials']; - - $request = new Request([], [], [], [], [], [ - 'TheUserKey' => 'TheUser', - 'TheCredentialsKey' => 'TheCredentials', - ]); - $tokenStorage = $this->createMock(TokenStorageInterface::class); - - $authenticationManager = $this->createMock(AuthenticationManagerInterface::class); - - $listener = new X509AuthenticationListener($tokenStorage, $authenticationManager, 'TheProviderKey', 'TheUserKey', 'TheCredentialsKey'); - - $method = new \ReflectionMethod($listener, 'getPreAuthenticatedData'); - $method->setAccessible(true); - - $result = $method->invokeArgs($listener, [$request]); - $this->assertSame($result, $userCredentials); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/Logout/LogoutUrlGeneratorTest.php b/src/Symfony/Component/Security/Http/Tests/Logout/LogoutUrlGeneratorTest.php index 65992131a2f3b..9f1a63f65b0df 100644 --- a/src/Symfony/Component/Security/Http/Tests/Logout/LogoutUrlGeneratorTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Logout/LogoutUrlGeneratorTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Core\User\InMemoryUser; @@ -64,18 +63,6 @@ public function testGuessFromToken() $this->assertSame('/logout', $this->generator->getLogoutPath()); } - /** - * @group legacy - */ - public function testGuessFromAnonymousTokenThrowsException() - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Unable to generate a logout url for an anonymous token.'); - $this->tokenStorage->setToken(new AnonymousToken('default', 'anon.')); - - $this->generator->getLogoutPath(); - } - public function testGuessFromCurrentFirewallKey() { $this->generator->registerListener('secured_area', '/logout', null, null); diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php deleted file mode 100644 index 1cfec9bdca5eb..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/AbstractRememberMeServicesTest.php +++ /dev/null @@ -1,326 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\RememberMe; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; - -/** - * @group legacy - */ -class AbstractRememberMeServicesTest extends TestCase -{ - public function testGetRememberMeParameter() - { - $service = $this->getService(null, ['remember_me_parameter' => 'foo']); - - $this->assertEquals('foo', $service->getRememberMeParameter()); - } - - public function testGetSecret() - { - $service = $this->getService(); - $this->assertEquals('foosecret', $service->getSecret()); - } - - public function testAutoLoginReturnsNullWhenNoCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - - $this->assertNull($service->autoLogin(new Request())); - } - - public function testAutoLoginReturnsNullAfterLoginFail() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - - $request = new Request(); - $request->cookies->set('foo', 'foo'); - - $service->loginFail($request); - $this->assertNull($service->autoLogin($request)); - } - - public function testAutoLoginThrowsExceptionWhenImplementationDoesNotReturnUserInterface() - { - $this->expectException(\RuntimeException::class); - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - $request->cookies->set('foo', 'foo'); - - $service - ->expects($this->once()) - ->method('processAutoLoginCookie') - ->willReturn(null) - ; - - $service->autoLogin($request); - } - - public function testAutoLogin() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - $request->cookies->set('foo', 'foo'); - - $user = $this->createMock(UserInterface::class); - $user - ->expects($this->once()) - ->method('getRoles') - ->willReturn([]) - ; - - $service - ->expects($this->once()) - ->method('processAutoLoginCookie') - ->willReturn($user) - ; - - $returnedToken = $service->autoLogin($request); - - $this->assertSame($user, $returnedToken->getUser()); - $this->assertSame('foosecret', $returnedToken->getSecret()); - $this->assertSame('fookey', $returnedToken->getFirewallName()); - } - - /** - * @dataProvider provideOptionsForLogout - */ - public function testLogout(array $options) - { - $service = $this->getService(null, $options); - $request = new Request(); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - $service->logout($request, $response, $token); - $cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME); - $this->assertInstanceOf(Cookie::class, $cookie); - $this->assertTrue($cookie->isCleared()); - $this->assertSame($options['name'], $cookie->getName()); - $this->assertSame($options['path'], $cookie->getPath()); - $this->assertSame($options['domain'], $cookie->getDomain()); - $this->assertSame($options['secure'], $cookie->isSecure()); - $this->assertSame($options['httponly'], $cookie->isHttpOnly()); - } - - public function provideOptionsForLogout() - { - return [ - [['name' => 'foo', 'path' => '/', 'domain' => null, 'secure' => false, 'httponly' => true]], - [['name' => 'foo', 'path' => '/bar', 'domain' => 'baz.com', 'secure' => true, 'httponly' => false]], - ]; - } - - public function testLoginFail() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - - $service->loginFail($request); - - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testLoginSuccessIsNotProcessedWhenTokenDoesNotContainUserInterfaceImplementation() - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]); - $request = new Request(); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn('foo') - ; - - $service - ->expects($this->never()) - ->method('onLoginSuccess') - ; - - $this->assertFalse($request->request->has('foo')); - - $service->loginSuccess($request, $response, $token); - } - - public function testLoginSuccessIsNotProcessedWhenRememberMeIsNotRequested() - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - $response = new Response(); - $account = $this->createMock(UserInterface::class); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn($account) - ; - - $service - ->expects($this->never()) - ->method('onLoginSuccess') - ->willReturn(null) - ; - - $this->assertFalse($request->request->has('foo')); - - $service->loginSuccess($request, $response, $token); - } - - public function testLoginSuccessWhenRememberMeAlwaysIsTrue() - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]); - $request = new Request(); - $response = new Response(); - $account = $this->createMock(UserInterface::class); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn($account) - ; - - $service - ->expects($this->once()) - ->method('onLoginSuccess') - ->willReturn(null) - ; - - $service->loginSuccess($request, $response, $token); - } - - /** - * @dataProvider getPositiveRememberMeParameterValues - */ - public function testLoginSuccessWhenRememberMeParameterWithPathIsPositive($value) - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo[bar]', 'path' => null, 'domain' => null]); - - $request = new Request(); - $request->request->set('foo', ['bar' => $value]); - $response = new Response(); - $account = $this->createMock(UserInterface::class); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn($account) - ; - - $service - ->expects($this->once()) - ->method('onLoginSuccess') - ->willReturn(true) - ; - - $service->loginSuccess($request, $response, $token); - } - - /** - * @dataProvider getPositiveRememberMeParameterValues - */ - public function testLoginSuccessWhenRememberMeParameterIsPositive($value) - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => false, 'remember_me_parameter' => 'foo', 'path' => null, 'domain' => null]); - - $request = new Request(); - $request->request->set('foo', $value); - $response = new Response(); - $account = $this->createMock(UserInterface::class); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn($account) - ; - - $service - ->expects($this->once()) - ->method('onLoginSuccess') - ->willReturn(true) - ; - - $service->loginSuccess($request, $response, $token); - } - - public function getPositiveRememberMeParameterValues() - { - return [ - ['true'], - ['1'], - ['on'], - ['yes'], - [true], - ]; - } - - public function testEncodeCookieAndDecodeCookieAreInvertible() - { - $cookieParts = ['aa', 'bb', 'cc']; - $service = $this->getService(); - - $encoded = $this->callProtected($service, 'encodeCookie', [$cookieParts]); - $this->assertIsString($encoded); - - $decoded = $this->callProtected($service, 'decodeCookie', [$encoded]); - $this->assertSame($cookieParts, $decoded); - } - - public function testThereShouldBeNoCookieDelimiterInCookieParts() - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('cookie delimiter'); - $cookieParts = ['aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc']; - $service = $this->getService(); - - $this->callProtected($service, 'encodeCookie', [$cookieParts]); - } - - protected function getService($userProvider = null, $options = [], $logger = null) - { - if (null === $userProvider) { - $userProvider = $this->getProvider(); - } - - return $this->getMockForAbstractClass(AbstractRememberMeServices::class, [ - [$userProvider], 'foosecret', 'fookey', $options, $logger, - ]); - } - - protected function getProvider() - { - $provider = $this->createMock(UserProviderInterface::class); - $provider - ->expects($this->any()) - ->method('supportsClass') - ->willReturn(true) - ; - - return $provider; - } - - private function callProtected($object, $method, array $args) - { - $reflection = new \ReflectionClass(\get_class($object)); - $reflectionMethod = $reflection->getMethod($method); - $reflectionMethod->setAccessible(true); - - return $reflectionMethod->invokeArgs($object, $args); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php deleted file mode 100644 index 75b5b0cb303e0..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentTokenBasedRememberMeServicesTest.php +++ /dev/null @@ -1,331 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\RememberMe; - -use PHPUnit\Framework\SkippedTestSuiteError; -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\ResponseHeaderBag; -use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; -use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface; -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\CookieTheftException; -use Symfony\Component\Security\Core\Exception\TokenNotFoundException; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\InMemoryUserProvider; -use Symfony\Component\Security\Http\RememberMe\PersistentTokenBasedRememberMeServices; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; - -/** - * @group legacy - */ -class PersistentTokenBasedRememberMeServicesTest extends TestCase -{ - public static function setUpBeforeClass(): void - { - try { - random_bytes(1); - } catch (\Exception $e) { - throw new SkippedTestSuiteError($e->getMessage()); - } - } - - public function testAutoLoginReturnsNullWhenNoCookie() - { - $service = $this->getService(null, ['name' => 'foo']); - - $this->assertNull($service->autoLogin(new Request())); - } - - public function testAutoLoginThrowsExceptionOnInvalidCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']); - $request = new Request(); - $request->request->set('foo', 'true'); - $request->cookies->set('foo', 'foo'); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testAutoLoginThrowsExceptionOnNonExistentToken() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']); - $request = new Request(); - $request->request->set('foo', 'true'); - $request->cookies->set('foo', $this->encodeCookie([ - $series = 'fooseries', - $tokenValue = 'foovalue', - ])); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->once()) - ->method('loadTokenBySeries') - ->willThrowException(new TokenNotFoundException('Token not found.')) - ; - $service->setTokenProvider($tokenProvider); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testAutoLoginReturnsNullOnNonExistentUser() - { - $userProvider = $this->getProvider(); - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600, 'secure' => false, 'httponly' => false]); - $request = new Request(); - $request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue'])); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->once()) - ->method('loadTokenBySeries') - ->willReturn(new PersistentToken('fooclass', 'fooname', 'fooseries', $this->generateHash('foovalue'), new \DateTime())) - ; - $service->setTokenProvider($tokenProvider); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)); - } - - public function testAutoLoginThrowsExceptionOnStolenCookieAndRemovesItFromThePersistentBackend() - { - $userProvider = $this->getProvider(); - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true]); - $request = new Request(); - $request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue'])); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $service->setTokenProvider($tokenProvider); - - $tokenProvider - ->expects($this->once()) - ->method('loadTokenBySeries') - ->willReturn(new PersistentToken('fooclass', 'foouser', 'fooseries', 'anotherFooValue', new \DateTime())) - ; - - $tokenProvider - ->expects($this->once()) - ->method('deleteTokenBySeries') - ->with($this->equalTo('fooseries')) - ->willReturn(null) - ; - - try { - $service->autoLogin($request); - $this->fail('Expected CookieTheftException was not thrown.'); - } catch (CookieTheftException $e) { - } - - $this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)); - } - - public function testAutoLoginDoesNotAcceptAnExpiredCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue'])); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->once()) - ->method('loadTokenBySeries') - ->with($this->equalTo('fooseries')) - ->willReturn(new PersistentToken('fooclass', 'username', 'fooseries', $this->generateHash('foovalue'), new \DateTime('yesterday'))) - ; - $service->setTokenProvider($tokenProvider); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)); - } - - /** - * @testWith [true] - * [false] - */ - public function testAutoLogin(bool $hashTokenValue) - { - $user = new InMemoryUser('foouser', null, ['ROLE_FOO']); - - $userProvider = $this->getProvider(); - $userProvider->createUser($user); - - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'secure' => false, 'httponly' => false, 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue'])); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenValue = $hashTokenValue ? $this->generateHash('foovalue') : 'foovalue'; - $tokenProvider - ->expects($this->once()) - ->method('loadTokenBySeries') - ->with($this->equalTo('fooseries')) - ->willReturn(new PersistentToken(InMemoryUser::class, 'foouser', 'fooseries', $tokenValue, new \DateTime())) - ; - $service->setTokenProvider($tokenProvider); - - $returnedToken = $service->autoLogin($request); - - $this->assertInstanceOf(RememberMeToken::class, $returnedToken); - $this->assertTrue($user->isEqualTo($returnedToken->getUser())); - $this->assertEquals('foosecret', $returnedToken->getSecret()); - $this->assertTrue($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)); - } - - public function testLogout() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo', 'secure' => true, 'httponly' => false]); - $request = new Request(); - $request->cookies->set('foo', $this->encodeCookie(['fooseries', 'foovalue'])); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->once()) - ->method('deleteTokenBySeries') - ->with($this->equalTo('fooseries')) - ->willReturn(null) - ; - $service->setTokenProvider($tokenProvider); - - $service->logout($request, $response, $token); - - $cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME); - $this->assertTrue($cookie->isCleared()); - $this->assertEquals('/foo', $cookie->getPath()); - $this->assertEquals('foodomain.foo', $cookie->getDomain()); - $this->assertTrue($cookie->isSecure()); - $this->assertFalse($cookie->isHttpOnly()); - } - - public function testLogoutSimplyIgnoresNonSetRequestCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->never()) - ->method('deleteTokenBySeries') - ; - $service->setTokenProvider($tokenProvider); - - $service->logout($request, $response, $token); - - $cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME); - $this->assertTrue($cookie->isCleared()); - $this->assertEquals('/', $cookie->getPath()); - $this->assertNull($cookie->getDomain()); - } - - public function testLogoutSimplyIgnoresInvalidCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - $request->cookies->set('foo', 'somefoovalue'); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->never()) - ->method('deleteTokenBySeries') - ; - $service->setTokenProvider($tokenProvider); - - $service->logout($request, $response, $token); - - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testLoginFail() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null]); - $request = new Request(); - - $this->assertFalse($request->attributes->has(RememberMeServicesInterface::COOKIE_ATTR_NAME)); - $service->loginFail($request); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testLoginSuccessSetsCookieWhenLoggedInWithNonRememberMeTokenInterfaceImplementation() - { - $service = $this->getService(null, ['name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'samesite' => Cookie::SAMESITE_STRICT, 'lifetime' => 3600, 'always_remember_me' => true]); - $request = new Request(); - $response = new Response(); - - $account = new InMemoryUser('foo', null); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->any()) - ->method('getUser') - ->willReturn($account) - ; - - $tokenProvider = $this->createMock(TokenProviderInterface::class); - $tokenProvider - ->expects($this->once()) - ->method('createNewToken') - ; - $service->setTokenProvider($tokenProvider); - - $cookies = $response->headers->getCookies(); - $this->assertCount(0, $cookies); - - $service->loginSuccess($request, $response, $token); - - $cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY); - $cookie = $cookies['myfoodomain.foo']['/foo/path']['foo']; - $this->assertFalse($cookie->isCleared()); - $this->assertTrue($cookie->isSecure()); - $this->assertTrue($cookie->isHttpOnly()); - $this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610); - $this->assertEquals('myfoodomain.foo', $cookie->getDomain()); - $this->assertEquals('/foo/path', $cookie->getPath()); - $this->assertSame(Cookie::SAMESITE_STRICT, $cookie->getSameSite()); - } - - protected function encodeCookie(array $parts) - { - $service = $this->getService(); - $r = new \ReflectionMethod($service, 'encodeCookie'); - $r->setAccessible(true); - - return $r->invoke($service, $parts); - } - - protected function getService($userProvider = null, $options = [], $logger = null) - { - if (null === $userProvider) { - $userProvider = $this->getProvider(); - } - - return new PersistentTokenBasedRememberMeServices([$userProvider], 'foosecret', 'fookey', $options, $logger); - } - - protected function getProvider() - { - return new InMemoryUserProvider(); - } - - protected function generateHash(string $tokenValue): string - { - return 'sha256_'.hash_hmac('sha256', $tokenValue, $this->getService()->getSecret()); - } -} diff --git a/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php b/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php deleted file mode 100644 index ff774506f2a43..0000000000000 --- a/src/Symfony/Component/Security/Http/Tests/RememberMe/TokenBasedRememberMeServicesTest.php +++ /dev/null @@ -1,232 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Http\Tests\RememberMe; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\ResponseHeaderBag; -use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\InMemoryUserProvider; -use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface; -use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; - -/** - * @group legacy - */ -class TokenBasedRememberMeServicesTest extends TestCase -{ - public function testAutoLoginReturnsNullWhenNoCookie() - { - $service = $this->getService(null, ['name' => 'foo']); - - $this->assertNull($service->autoLogin(new Request())); - } - - public function testAutoLoginThrowsExceptionOnInvalidCookie() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => false, 'remember_me_parameter' => 'foo']); - $request = new Request(); - $request->request->set('foo', 'true'); - $request->cookies->set('foo', 'foo'); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testAutoLoginThrowsExceptionOnNonExistentUser() - { - $userProvider = $this->getProvider(); - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() + 3600, 'foopass')); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testAutoLoginDoesNotAcceptCookieWithInvalidHash() - { - $userProvider = $this->getProvider(); - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', base64_encode('class:'.base64_encode('foouser').':123456789:fooHash')); - - $user = new InMemoryUser('foouser', 'foopass'); - $userProvider->createUser($user); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - public function testAutoLoginDoesNotAcceptAnExpiredCookie() - { - $userProvider = $this->getProvider(); - $service = $this->getService($userProvider, ['name' => 'foo', 'path' => null, 'domain' => null, 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', $this->getCookie('fooclass', 'foouser', time() - 1, 'foopass')); - - $user = new InMemoryUser('foouser', 'foopass'); - $userProvider->createUser($user); - - $this->assertNull($service->autoLogin($request)); - $this->assertTrue($request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME)->isCleared()); - } - - /** - * @dataProvider provideUsernamesForAutoLogin - * - * @param string $username - */ - public function testAutoLogin($username) - { - $userProvider = $this->getProvider(); - $user = new InMemoryUser($username, 'foopass', ['ROLE_FOO']); - $userProvider->createUser($user); - - $service = $this->getService($userProvider, ['name' => 'foo', 'always_remember_me' => true, 'lifetime' => 3600]); - $request = new Request(); - $request->cookies->set('foo', $this->getCookie(InMemoryUser::class, $username, time() + 3600, 'foopass')); - - $returnedToken = $service->autoLogin($request); - - $this->assertInstanceOf(RememberMeToken::class, $returnedToken); - $this->assertTrue($user->isEqualTo($returnedToken->getUser())); - $this->assertEquals('foosecret', $returnedToken->getSecret()); - } - - public function provideUsernamesForAutoLogin() - { - return [ - ['foouser', 'Simple username'], - ['foo'.TokenBasedRememberMeServices::COOKIE_DELIMITER.'user', 'Username might contain the delimiter'], - ]; - } - - public function testLogout() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => null, 'domain' => null, 'secure' => true, 'httponly' => false]); - $request = new Request(); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - - $service->logout($request, $response, $token); - - $cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME); - $this->assertTrue($cookie->isCleared()); - $this->assertEquals('/', $cookie->getPath()); - $this->assertNull($cookie->getDomain()); - $this->assertTrue($cookie->isSecure()); - $this->assertFalse($cookie->isHttpOnly()); - } - - public function testLoginFail() - { - $service = $this->getService(null, ['name' => 'foo', 'path' => '/foo', 'domain' => 'foodomain.foo']); - $request = new Request(); - - $service->loginFail($request); - - $cookie = $request->attributes->get(RememberMeServicesInterface::COOKIE_ATTR_NAME); - $this->assertTrue($cookie->isCleared()); - $this->assertEquals('/foo', $cookie->getPath()); - $this->assertEquals('foodomain.foo', $cookie->getDomain()); - } - - public function testLoginSuccessIgnoresTokensWhichDoNotContainAnUserInterfaceImplementation() - { - $service = $this->getService(null, ['name' => 'foo', 'always_remember_me' => true, 'path' => null, 'domain' => null]); - $request = new Request(); - $response = new Response(); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->once()) - ->method('getUser') - ->willReturn('foo') - ; - - $cookies = $response->headers->getCookies(); - $this->assertCount(0, $cookies); - - $service->loginSuccess($request, $response, $token); - - $cookies = $response->headers->getCookies(); - $this->assertCount(0, $cookies); - } - - public function testLoginSuccess() - { - $service = $this->getService(null, ['name' => 'foo', 'domain' => 'myfoodomain.foo', 'path' => '/foo/path', 'secure' => true, 'httponly' => true, 'samesite' => Cookie::SAMESITE_STRICT, 'lifetime' => 3600, 'always_remember_me' => true]); - $request = new Request(); - $response = new Response(); - - $user = new InMemoryUser('foouser', 'foopass'); - $token = $this->createMock(TokenInterface::class); - $token - ->expects($this->atLeastOnce()) - ->method('getUser') - ->willReturn($user) - ; - - $cookies = $response->headers->getCookies(); - $this->assertCount(0, $cookies); - - $service->loginSuccess($request, $response, $token); - - $cookies = $response->headers->getCookies(ResponseHeaderBag::COOKIES_ARRAY); - $cookie = $cookies['myfoodomain.foo']['/foo/path']['foo']; - $this->assertFalse($cookie->isCleared()); - $this->assertTrue($cookie->isSecure()); - $this->assertTrue($cookie->isHttpOnly()); - $this->assertTrue($cookie->getExpiresTime() > time() + 3590 && $cookie->getExpiresTime() < time() + 3610); - $this->assertEquals('myfoodomain.foo', $cookie->getDomain()); - $this->assertEquals('/foo/path', $cookie->getPath()); - $this->assertSame(Cookie::SAMESITE_STRICT, $cookie->getSameSite()); - } - - protected function getCookie($class, $username, $expires, $password) - { - $service = $this->getService(); - $r = new \ReflectionMethod($service, 'generateCookieValue'); - $r->setAccessible(true); - - return $r->invoke($service, $class, $username, $expires, $password); - } - - protected function encodeCookie(array $parts) - { - $service = $this->getService(); - $r = new \ReflectionMethod($service, 'encodeCookie'); - $r->setAccessible(true); - - return $r->invoke($service, $parts); - } - - protected function getService($userProvider = null, $options = [], $logger = null) - { - if (null === $userProvider) { - $userProvider = $this->getProvider(); - } - - $service = new TokenBasedRememberMeServices([$userProvider], 'foosecret', 'fookey', $options, $logger); - - return $service; - } - - protected function getProvider() - { - return new InMemoryUserProvider(); - } -} diff --git a/src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php b/src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php index a0f6c4c4e43f0..a767ae5e5a537 100644 --- a/src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php +++ b/src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php @@ -9,7 +9,6 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Core\User\User; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -40,11 +39,7 @@ protected function setUp(): void ], ]; $expressionLanguage = new ExpressionLanguage(); - if (class_exists(InMemoryUser::class)) { - $token = new UsernamePasswordToken(new InMemoryUser('username', 'credentials', ['ROLE_USER']), 'provider', ['ROLE_USER']); - } else { - $token = new UsernamePasswordToken(new User('username', 'credentials', ['ROLE_USER']), null, 'provider', ['ROLE_USER']); - } + $token = new UsernamePasswordToken(new InMemoryUser('username', 'credentials', ['ROLE_USER']), 'provider', ['ROLE_USER']); $tokenStorage = $this->createMock(TokenStorageInterface::class); $tokenStorage->expects($this->any())->method('getToken')->willReturn($token); $this->authenticationChecker = $this->createMock(AuthorizationCheckerInterface::class); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy