hwi / HWIOAuthBundle

OAuth client integration for Symfony. Supports both OAuth1.0a and OAuth2.
MIT License
2.26k stars 794 forks source link

Guidance on runtime dynamic Resource Owner configuration #1959

Open jeanetienne opened 11 months ago

jeanetienne commented 11 months ago
Q A
Bug? no
New Feature? no
Support question? yes
Version 2.x

Hi 👋

I'm working on a Symfony 6.3 project using HWIOAuthBundle 2.0.0, and I'm looking for guidance on making resource owner configurations dynamic and updatable at runtime.

I want to allow specific users ("Admin" users) to set the client_id and client_secret for built-in resource owners (e.g., GitHub, BitBucket, GitLab, LinkedIn). The client_id and client_secret pairs are stored in a database and will be updated infrequently, making them suitable for heavy caching.

At the moment I'm toying with a Compiler Pass that updates the definition for each resource owners, as necessary. This feels a bit over-engineered, and I don't know how to tell the service container to recompile the service when the values have been updated?

What's the best or simplest way to achieve this? Is this even a supported use case, or will I have to find a way around it for the time being?

Thanks for your help, and thanks for publishing this bundle 🙏 !

github-actions[bot] commented 7 months ago

Message to comment on stale issues. If none provided, will not mark issues stale

Gerben321 commented 4 months ago

Have you found anything about this? I would like to set the configuration in the database as well. I've got a use case where I have one codebase with different domains that need different configs.

jeanetienne commented 4 months ago

Have you found anything about this? I would like to set the configuration in the database as well. I've got a use case where I have one codebase with different domains that need different configs.

Yes, I found a way, it's not super elegant but it works:

I added an injection pass in the Kernel to pass the keys dynamically:

class OAuthResourceServersInjectionPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        $this->setupContainer($container, 'hwi_oauth.resource_owner.github', 'users.resource_server.github.client_id', 'users.resource_server.github.client_secret');
    }

    private function setupContainer(ContainerBuilder $container, string $resourceServerIdentifier, string $clientIdConfigurationKey, string $clientSecretConfigurationKey)
    {
        if ($container->has($resourceServerIdentifier)) {
            $definition = $container->findDefinition($resourceServerIdentifier);
            $definition->addMethodCall('setEntityManager', [new Reference('doctrine.orm.entity_manager')]);
            $definition->addMethodCall('setClientIdConfigurationKey', [$clientIdConfigurationKey]);
            $definition->addMethodCall('setClientSecretConfigurationKey', [$clientSecretConfigurationKey]);
        }
    }
}

Then I had to recreate (mostly copypaste and tweak) the "ResourceOwner" classes to accept dynamic values:

Hope that helps?

zerowebcorp commented 1 week ago

Looking for the same. Do you have the full code that we can review?