From 4a6f5b9519ec3552a95faff161bc0157315466e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 15 Jul 2019 15:59:35 +0200 Subject: [PATCH 1/2] Login mutation does not appear if multiple providers are defined Because the UserProviderInterface does not exists if there are many User providers defined. --- Tests/GraphqliteTestingKernel.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Tests/GraphqliteTestingKernel.php b/Tests/GraphqliteTestingKernel.php index dc1c5cb..30c4d71 100644 --- a/Tests/GraphqliteTestingKernel.php +++ b/Tests/GraphqliteTestingKernel.php @@ -79,10 +79,21 @@ public function configureContainer(ContainerBuilder $c, LoaderInterface $loader) ], ], ], + 'in_memory_other' => [ + 'memory' => [ + 'users' => [ + 'foo' => [ + 'password' => 'bar', + 'roles' => 'ROLE_USER', + ], + ], + ], + ], ], 'firewalls' => [ 'main' => [ - 'anonymous' => true + 'anonymous' => true, + 'provider' => 'in_memory' ] ], 'encoders' => [ From 5d42441e65c1b8450a62b3a2ff8e65c35b2153b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 15 Jul 2019 16:00:30 +0200 Subject: [PATCH 2/2] Let's do some black magic to retrieve the correct provider instance at compile time. --- DependencyInjection/GraphqliteCompilerPass.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/GraphqliteCompilerPass.php b/DependencyInjection/GraphqliteCompilerPass.php index 7898460..202cd29 100644 --- a/DependencyInjection/GraphqliteCompilerPass.php +++ b/DependencyInjection/GraphqliteCompilerPass.php @@ -86,6 +86,9 @@ public function process(ContainerBuilder $container) $controllersNamespaces = $container->getParameter('graphqlite.namespace.controllers'); $typesNamespaces = $container->getParameter('graphqlite.namespace.types'); + $firewallName = $container->getParameter('graphqlite.security.firewall_name'); + $firewallConfigServiceName = 'security.firewall.map.config.'.$firewallName; + // 2 seconds of TTL in environment mode. Otherwise, let's cache forever! $schemaFactory = $container->getDefinition(SchemaFactory::class); @@ -99,7 +102,7 @@ public function process(ContainerBuilder $container) $disableLogin = false; if ($container->getParameter('graphqlite.security.enable_login') === 'auto' - && (!$container->has(UserProviderInterface::class) || + && (!$container->has($firewallConfigServiceName) || !$container->has(UserPasswordEncoderInterface::class) || !$container->has(TokenStorageInterface::class) || !$container->has(SessionInterface::class) @@ -119,11 +122,18 @@ public function process(ContainerBuilder $container) if (!$container->has(SessionInterface::class)) { throw new GraphQLException('In order to enable the login/logout mutations (via the graphqlite.security.enable_login parameter), you need to enable session support (via the "framework.session.enabled" config parameter).'); } - if (!$container->has(UserPasswordEncoderInterface::class) || !$container->has(TokenStorageInterface::class) || !$container->has(UserProviderInterface::class)) { + if (!$container->has(UserPasswordEncoderInterface::class) || !$container->has(TokenStorageInterface::class) || !$container->has($firewallConfigServiceName)) { throw new GraphQLException('In order to enable the login/logout mutations (via the graphqlite.security.enable_login parameter), you need to install the security bundle. Please be sure to correctly configure the user provider (in the security.providers configuration settings)'); } } + if ($disableLogin === false) { + // Let's do some dark magic. We need the user provider. We need its name. It is stored in the "config" object. + $provider = $container->findDefinition('security.firewall.map.config.'.$firewallName)->getArgument(5); + + $container->findDefinition(LoginController::class)->setArgument(0, new Reference($provider)); + } + foreach ($container->getDefinitions() as $id => $definition) { if ($definition->isAbstract() || $definition->getClass() === null) {