diff --git a/src/DependencyInjection/CompilerPass/ResourceOwnerMapCompilerPass.php b/src/DependencyInjection/CompilerPass/ResourceOwnerMapCompilerPass.php index 53e7c5ead..9e520f1ef 100644 --- a/src/DependencyInjection/CompilerPass/ResourceOwnerMapCompilerPass.php +++ b/src/DependencyInjection/CompilerPass/ResourceOwnerMapCompilerPass.php @@ -34,7 +34,12 @@ public function process(ContainerBuilder $container): void $oauthUtilsDef = $container->getDefinition('hwi_oauth.security.oauth_utils'); foreach ($firewallNames as $firewallName => $_) { - $resourceOwnerMapRef = new Reference('hwi_oauth.resource_ownermap.'.$firewallName); + $resourceOwnerMapId = 'hwi_oauth.resource_ownermap.'.$firewallName; + + $container->getDefinition($resourceOwnerMapId) + ->setArgument('$locator', new Reference('hwi_oauth.resource_owners.locator')); + + $resourceOwnerMapRef = new Reference($resourceOwnerMapId); $locatorDef->addMethodCall('set', [$firewallName, $resourceOwnerMapRef]); $oauthUtilsDef->addMethodCall('addResourceOwnerMap', [$resourceOwnerMapRef]); diff --git a/src/DependencyInjection/HWIOAuthExtension.php b/src/DependencyInjection/HWIOAuthExtension.php index fa589a4d9..c6f2e8605 100644 --- a/src/DependencyInjection/HWIOAuthExtension.php +++ b/src/DependencyInjection/HWIOAuthExtension.php @@ -29,6 +29,7 @@ function service($class): ReferenceConfigurator use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; @@ -102,15 +103,20 @@ public function load(array $configs, ContainerBuilder $container): void // setup services for all configured resource owners $resourceOwners = []; + $resourceOwnerReferenceMap = []; foreach ($config['resource_owners'] as $name => $options) { $resourceOwners[$name] = $name; - $this->createResourceOwnerService($container, $name, $options); + $resourceOwnerReferenceMap[$name] = $this->createResourceOwnerService($container, $name, $options); if (!$this->refreshTokenListenerEnabled) { $this->refreshTokenListenerEnabled = $options['options']['refresh_on_expire'] ?? false; } } $container->setParameter('hwi_oauth.resource_owners', $resourceOwners); + $container->setAlias( + 'hwi_oauth.resource_owners.locator', + (string) ServiceLocatorTagPass::register($container, $resourceOwnerReferenceMap) + ); $this->createConnectIntegration($container, $config); } @@ -126,14 +132,11 @@ public function load(array $configs, ContainerBuilder $container): void * @throws BadMethodCallException * @throws InvalidArgumentException */ - public function createResourceOwnerService(ContainerBuilder $container, string $name, array $options): void + public function createResourceOwnerService(ContainerBuilder $container, string $name, array $options): Reference { // alias services if (isset($options['service'])) { - // set the appropriate name for aliased services, compiler pass depends on it - $container->setAlias('hwi_oauth.resource_owner.'.$name, new Alias($options['service'], true)); - - return; + return new Reference($options['service']); } $type = $options['type']; @@ -156,9 +159,10 @@ public function createResourceOwnerService(ContainerBuilder $container, string $ $definition->setArgument('$options', $options); $definition->setArgument('$name', $name); $definition->setArgument('$storage', new Reference('hwi_oauth.storage.session')); - $definition->addTag('hwi_oauth.resource_owner', ['resource-name' => $name]); $container->setDefinition('hwi_oauth.resource_owner.'.$name, $definition); + + return new Reference('hwi_oauth.resource_owner.'.$name); } /** diff --git a/src/Resources/config/resource_owners.php b/src/Resources/config/resource_owners.php index df978d94c..e528b1046 100644 --- a/src/Resources/config/resource_owners.php +++ b/src/Resources/config/resource_owners.php @@ -92,8 +92,7 @@ ->abstract() ->arg('$httpUtils', service('security.http_utils')) ->arg('$possibleResourceOwners', '%hwi_oauth.resource_owners%') - ->arg('$resourceOwners', []) - ->arg('$locator', tagged_locator('hwi_oauth.resource_owner', 'resource-name', 'getDefaultResourceNameName', 'getDefaultResourceNamePriority')); + ->arg('$resourceOwners', []); $services->set('hwi_oauth.resource_ownermap_locator', ResourceOwnerMapLocator::class); }; diff --git a/tests/App/ResourceOwner/CustomResourceOwner.php b/tests/App/ResourceOwner/CustomResourceOwner.php new file mode 100644 index 000000000..102b4ed62 --- /dev/null +++ b/tests/App/ResourceOwner/CustomResourceOwner.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace HWI\Bundle\OAuthBundle\Tests\App\ResourceOwner; + +use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericOAuth2ResourceOwner; + +class CustomResourceOwner extends GenericOAuth2ResourceOwner +{ +} diff --git a/tests/App/config/config.yaml b/tests/App/config/config.yaml index 7952d177e..938461fc2 100644 --- a/tests/App/config/config.yaml +++ b/tests/App/config/config.yaml @@ -34,6 +34,19 @@ services: class: Symfony\Contracts\HttpClient\HttpClientInterface public: true + app.custom_resource_owner: + class: HWI\Bundle\OAuthBundle\Tests\App\ResourceOwner\CustomResourceOwner + arguments: + $options: { + access_token_url: 'http://custom/token', + authorization_url: 'http://custom/auth', + infos_url: 'http://custom/info', + client_id: 'client_id', + client_secret: 'client_secret', + } + $name: 'custom' + $storage: '@hwi_oauth.storage.session' + doctrine: dbal: driver: pdo_sqlite @@ -61,6 +74,8 @@ hwi_oauth: scope: 'scope=mail-r sdct-r' options: refresh_on_expire: true + custom: + service: 'app.custom_resource_owner' twig: strict_variables: '%kernel.debug%' diff --git a/tests/App/config/routing.yaml b/tests/App/config/routing.yaml index 21cf03993..a944c1aa0 100644 --- a/tests/App/config/routing.yaml +++ b/tests/App/config/routing.yaml @@ -27,3 +27,6 @@ google_login: yahoo_login: path: /check-login/yahoo + +custom_login: + path: /check-login/custom diff --git a/tests/App/config/security_v4.yaml b/tests/App/config/security_v4.yaml index ed6be36ab..31989da5d 100644 --- a/tests/App/config/security_v4.yaml +++ b/tests/App/config/security_v4.yaml @@ -18,6 +18,7 @@ security: resource_owners: google: '/check-login/google' yahoo: '/check-login/yahoo' + custom: '/check-login/custom' login_path: /login use_forward: false failure_path: /login diff --git a/tests/App/config/security_v5.yaml b/tests/App/config/security_v5.yaml index 70ddea655..15e35a5a4 100644 --- a/tests/App/config/security_v5.yaml +++ b/tests/App/config/security_v5.yaml @@ -16,6 +16,7 @@ security: resource_owners: google: '/check-login/google' yahoo: '/check-login/yahoo' + custom: '/check-login/custom' login_path: /login use_forward: false failure_path: /login diff --git a/tests/App/config/security_v5_bc.yaml b/tests/App/config/security_v5_bc.yaml index 9bcad1fa1..c80b09880 100644 --- a/tests/App/config/security_v5_bc.yaml +++ b/tests/App/config/security_v5_bc.yaml @@ -20,6 +20,7 @@ security: resource_owners: google: '/check-login/google' yahoo: '/check-login/yahoo' + custom: '/check-login/custom' login_path: /login use_forward: false failure_path: /login diff --git a/tests/App/config/security_v6.yaml b/tests/App/config/security_v6.yaml index 068f0fd96..94a47bebe 100644 --- a/tests/App/config/security_v6.yaml +++ b/tests/App/config/security_v6.yaml @@ -16,6 +16,7 @@ security: resource_owners: google: '/check-login/google' yahoo: '/check-login/yahoo' + custom: '/check-login/custom' login_path: /login use_forward: false failure_path: /login diff --git a/tests/DependencyInjection/HWIOAuthExtensionTest.php b/tests/DependencyInjection/HWIOAuthExtensionTest.php index caddbbd6b..845c238e9 100644 --- a/tests/DependencyInjection/HWIOAuthExtensionTest.php +++ b/tests/DependencyInjection/HWIOAuthExtensionTest.php @@ -16,8 +16,10 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Yaml\Parser; /** @@ -464,10 +466,26 @@ public function provideInvalidData(): array ]; } + public function testRegistersResourceOwnerServiceLocator(): void + { + $this->createEmptyConfiguration(); + + $this->assertTrue($this->containerBuilder->hasAlias('hwi_oauth.resource_owners.locator')); + $locatorDefinition = $this->containerBuilder->findDefinition('hwi_oauth.resource_owners.locator'); + + $this->assertEquals( + [ + 'any_name' => new ServiceClosureArgument(new Reference('hwi_oauth.resource_owner.any_name')), + 'some_service' => new ServiceClosureArgument(new Reference('hwi_oauth.abstract_resource_owner.generic')), + ], + $locatorDefinition->getArgument(0) + ); + } + public function testCreateResourceOwnerService(): void { $extension = new HWIOAuthExtension(); - $extension->createResourceOwnerService($this->containerBuilder, 'my_github', [ + $reference = $extension->createResourceOwnerService($this->containerBuilder, 'my_github', [ 'type' => 'github', 'client_id' => '42', 'client_secret' => 'foo', @@ -476,6 +494,8 @@ public function testCreateResourceOwnerService(): void /** @var array $definitions */ $definitions = $this->containerBuilder->getDefinitions(); + $this->assertSame('hwi_oauth.resource_owner.my_github', (string) $reference); + $this->assertArrayHasKey('hwi_oauth.resource_owner.my_github', $definitions); $this->assertEquals('%hwi_oauth.resource_owner.github.class%', $definitions['hwi_oauth.resource_owner.my_github']->getClass()); @@ -488,13 +508,11 @@ public function testCreateResourceOwnerService(): void public function testCreateResourceOwnerServiceWithService(): void { $extension = new HWIOAuthExtension(); - $extension->createResourceOwnerService($this->containerBuilder, 'external_ressource_owner', [ + $reference = $extension->createResourceOwnerService($this->containerBuilder, 'external_ressource_owner', [ 'service' => 'my.service', ]); - $aliases = $this->containerBuilder->getAliases(); - $this->assertArrayHasKey('hwi_oauth.resource_owner.external_ressource_owner', $aliases); - $this->assertEquals('my.service', $aliases['hwi_oauth.resource_owner.external_ressource_owner']); + $this->assertSame('my.service', (string) $reference); } public function testCreateResourceOwnerServiceWithWrongClass(): void @@ -540,13 +558,6 @@ protected function createEmptyConfiguration(): void $loader->load([$config], $this->containerBuilder); } - protected function createFullConfiguration(): void - { - $config = $this->getFullConfig(); - $loader = new HWIOAuthExtension(); - $loader->load([$config], $this->containerBuilder); - } - protected function getEmptyConfig(): array { $yaml = <<parse($yaml); } - protected function getFullConfig(): array - { - $yaml = <<parse($yaml); - } - private function assertAlias(string $value, string $key): void { $this->assertEquals($value, (string) $this->containerBuilder->getAlias($key), sprintf('%s alias is correct', $key)); diff --git a/tests/Functional/Controller/LoginControllerTest.php b/tests/Functional/Controller/LoginControllerTest.php index 8a0d5ca6b..cdab62af3 100644 --- a/tests/Functional/Controller/LoginControllerTest.php +++ b/tests/Functional/Controller/LoginControllerTest.php @@ -36,7 +36,9 @@ public function testLoginPage(): void $response = $client->getResponse(); $this->assertSame(200, $response->getStatusCode(), $response->getContent()); - $this->assertSame('google', $crawler->filter('a')->text(), $response->getContent()); + $this->assertSame('google', $crawler->filter('a:nth-child(1)')->text(), $response->getContent()); + $this->assertSame('yahoo', $crawler->filter('a:nth-child(3)')->text(), $response->getContent()); + $this->assertSame('custom', $crawler->filter('a:nth-child(5)')->text(), $response->getContent()); } public function testRedirectingToRegistrationFormWithError(): void