Make more use of Guice to reduce boiler plate code This also enforces a stricter adherence to naming conventions used by almost all implemented OAuth providers. Change-Id: I5e394c2e0062507b0e14a07cf67e216c18d3355a
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/AzureOAuthServiceModule.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/AzureOAuthServiceModule.java new file mode 100644 index 0000000..95563bf --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/AzureOAuthServiceModule.java
@@ -0,0 +1,60 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.oauth; + +import com.google.gerrit.extensions.annotations.Exports; +import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; +import com.google.gerrit.server.config.PluginConfig; +import com.google.inject.AbstractModule; +import com.google.inject.Inject; +import com.google.inject.ProvisionException; +import com.googlesource.gerrit.plugins.oauth.azure.AzureActiveDirectoryService; + +public class AzureOAuthServiceModule extends AbstractModule { + private final OAuthPluginConfigFactory cfgFactory; + + @Inject + public AzureOAuthServiceModule(OAuthPluginConfigFactory cfgFactory) { + this.cfgFactory = cfgFactory; + } + + @Override + public void configure() { + boolean office365LegacyProviderBound = false; + PluginConfig cfg = cfgFactory.create(AzureActiveDirectoryService.LEGACY_PROVIDER_NAME); + if (cfg.getString(InitOAuth.CLIENT_ID) != null) { + office365LegacyProviderBound = true; + bindOAuthServiceProvider(AzureActiveDirectoryService.LEGACY_PROVIDER_NAME); + } + cfg = cfgFactory.create(AzureActiveDirectoryService.PROVIDER_NAME); + if (cfg.getString(InitOAuth.CLIENT_ID) != null) { + // ?: Check if the legacy Office365 is already bound, we can only have one of these bound at + // one time + if (office365LegacyProviderBound) { + // -> Yes, the legacy Office365 is already bound and we are trying to bind the + // AzureActiveDirectoryService.CONFIG_SUFFIX at the same time. + throw new ProvisionException("Legacy Office365 OAuth provider is already bound!"); + } + bindOAuthServiceProvider(AzureActiveDirectoryService.PROVIDER_NAME); + } + } + + protected void bindOAuthServiceProvider(String serviceProviderName) { + String extIdScheme = OAuthServiceProviderExternalIdScheme.create(serviceProviderName); + bind(OAuthServiceProvider.class) + .annotatedWith(Exports.named(extIdScheme)) + .to(AzureActiveDirectoryService.class); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java index 3cf1564..9b826ed 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/HttpModule.java
@@ -14,18 +14,11 @@ package com.googlesource.gerrit.plugins.oauth; -import com.google.gerrit.extensions.annotations.Exports; -import com.google.gerrit.extensions.annotations.PluginName; -import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; -import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; +import com.google.inject.AbstractModule; import com.google.inject.Inject; -import com.google.inject.ProvisionException; -import com.google.inject.servlet.ServletModule; import com.googlesource.gerrit.plugins.oauth.airvantage.AirVantageOAuthService; import com.googlesource.gerrit.plugins.oauth.auth0.Auth0OAuthService; import com.googlesource.gerrit.plugins.oauth.authentik.AuthentikOAuthService; -import com.googlesource.gerrit.plugins.oauth.azure.AzureActiveDirectoryService; import com.googlesource.gerrit.plugins.oauth.bitbucket.BitbucketOAuthService; import com.googlesource.gerrit.plugins.oauth.cas.CasOAuthService; import com.googlesource.gerrit.plugins.oauth.cognito.CognitoOAuthService; @@ -39,147 +32,31 @@ import com.googlesource.gerrit.plugins.oauth.phabricator.PhabricatorOAuthService; import com.googlesource.gerrit.plugins.oauth.tuleap.TuleapOAuthService; -class HttpModule extends ServletModule { - - private final PluginConfigFactory cfgFactory; - private final String pluginName; +class HttpModule extends AbstractModule { + private final OAuthPluginConfigFactory cfgFactory; @Inject - HttpModule(PluginConfigFactory cfgFactory, @PluginName String pluginName) { + HttpModule(OAuthPluginConfigFactory cfgFactory) { this.cfgFactory = cfgFactory; - this.pluginName = pluginName; } @Override - protected void configureServlets() { - PluginConfig cfg = - cfgFactory.getFromGerritConfig(pluginName + GoogleOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(GoogleOAuthService.CONFIG_SUFFIX)) - .to(GoogleOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + GitHubOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(GitHubOAuthService.CONFIG_SUFFIX)) - .to(GitHubOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + BitbucketOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(BitbucketOAuthService.CONFIG_SUFFIX)) - .to(BitbucketOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + CasOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(CasOAuthService.CONFIG_SUFFIX)) - .to(CasOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + FacebookOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(FacebookOAuthService.CONFIG_SUFFIX)) - .to(FacebookOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + GitLabOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(GitLabOAuthService.CONFIG_SUFFIX)) - .to(GitLabOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + LemonLDAPOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(LemonLDAPOAuthService.CONFIG_SUFFIX)) - .to(LemonLDAPOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + DexOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(DexOAuthService.CONFIG_SUFFIX)) - .to(DexOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + KeycloakOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(KeycloakOAuthService.CONFIG_SUFFIX)) - .to(KeycloakOAuthService.class); - } - - boolean office365LegacyProviderBound = false; - cfg = - cfgFactory.getFromGerritConfig( - pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX_LEGACY); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - office365LegacyProviderBound = true; - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(AzureActiveDirectoryService.CONFIG_SUFFIX)) - .to(AzureActiveDirectoryService.class); - } - cfg = cfgFactory.getFromGerritConfig(pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - // ?: Check if the legacy Office365 is already bound, we can only have one of these bound at - // one time - if (office365LegacyProviderBound) { - // -> Yes, the legacy Office365 is already bound and we are trying to bind the - // AzureActiveDirectoryService.CONFIG_SUFFIX at the same time. - throw new ProvisionException("Legacy Office365 OAuth provider is already bound!"); - } - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(AzureActiveDirectoryService.CONFIG_SUFFIX)) - .to(AzureActiveDirectoryService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + AirVantageOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(AirVantageOAuthService.CONFIG_SUFFIX)) - .to(AirVantageOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + PhabricatorOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(PhabricatorOAuthService.CONFIG_SUFFIX)) - .to(PhabricatorOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + TuleapOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(TuleapOAuthService.CONFIG_SUFFIX)) - .to(TuleapOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + Auth0OAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(Auth0OAuthService.CONFIG_SUFFIX)) - .to(Auth0OAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + AuthentikOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(AuthentikOAuthService.CONFIG_SUFFIX)) - .to(AuthentikOAuthService.class); - } - - cfg = cfgFactory.getFromGerritConfig(pluginName + CognitoOAuthService.CONFIG_SUFFIX); - if (cfg.getString(InitOAuth.CLIENT_ID) != null) { - bind(OAuthServiceProvider.class) - .annotatedWith(Exports.named(CognitoOAuthService.CONFIG_SUFFIX)) - .to(CognitoOAuthService.class); - } + protected void configure() { + install(new OAuthServiceModule(cfgFactory, AirVantageOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, Auth0OAuthService.class)); + install(new OAuthServiceModule(cfgFactory, AuthentikOAuthService.class)); + install(new AzureOAuthServiceModule(cfgFactory)); + install(new OAuthServiceModule(cfgFactory, BitbucketOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, CasOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, CognitoOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, DexOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, FacebookOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, GitHubOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, GitLabOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, GoogleOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, KeycloakOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, LemonLDAPOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, PhabricatorOAuthService.class)); + install(new OAuthServiceModule(cfgFactory, TuleapOAuthService.class)); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java index 15986bd..b93fce5 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/InitOAuth.java
@@ -17,6 +17,7 @@ import com.google.common.base.Strings; import com.google.gerrit.extensions.annotations.PluginName; +import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.pgm.init.api.ConsoleUI; import com.google.gerrit.pgm.init.api.InitStep; import com.google.gerrit.pgm.init.api.Section; @@ -59,6 +60,8 @@ static String FIX_LEGACY_USER_ID_QUESTION = "Fix legacy user id, without oauth provider prefix?"; private final ConsoleUI ui; + private final Section.Factory sections; + private final String pluginName; private final Section googleOAuthProviderSection; private final Section githubOAuthProviderSection; private final Section bitbucketOAuthProviderSection; @@ -80,40 +83,27 @@ @Inject InitOAuth(ConsoleUI ui, Section.Factory sections, @PluginName String pluginName) { this.ui = ui; - this.googleOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + GoogleOAuthService.CONFIG_SUFFIX); - this.githubOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + GitHubOAuthService.CONFIG_SUFFIX); - this.bitbucketOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + BitbucketOAuthService.CONFIG_SUFFIX); - this.casOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + CasOAuthService.CONFIG_SUFFIX); - this.facebookOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + FacebookOAuthService.CONFIG_SUFFIX); - this.gitlabOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + GitLabOAuthService.CONFIG_SUFFIX); - this.lemonldapOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + LemonLDAPOAuthService.CONFIG_SUFFIX); - this.dexOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + DexOAuthService.CONFIG_SUFFIX); - this.keycloakOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + KeycloakOAuthService.CONFIG_SUFFIX); - this.office365OAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX_LEGACY); + this.sections = sections; + this.pluginName = pluginName; + this.googleOAuthProviderSection = getConfigSection(GoogleOAuthService.class); + this.githubOAuthProviderSection = getConfigSection(GitHubOAuthService.class); + this.bitbucketOAuthProviderSection = getConfigSection(BitbucketOAuthService.class); + this.casOAuthProviderSection = getConfigSection(CasOAuthService.class); + this.facebookOAuthProviderSection = getConfigSection(FacebookOAuthService.class); + this.gitlabOAuthProviderSection = getConfigSection(GitLabOAuthService.class); + this.lemonldapOAuthProviderSection = getConfigSection(LemonLDAPOAuthService.class); + this.dexOAuthProviderSection = getConfigSection(DexOAuthService.class); + this.keycloakOAuthProviderSection = getConfigSection(KeycloakOAuthService.class); this.azureActiveDirectoryAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + AzureActiveDirectoryService.CONFIG_SUFFIX); - this.airVantageOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + AirVantageOAuthService.CONFIG_SUFFIX); - this.phabricatorOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + PhabricatorOAuthService.CONFIG_SUFFIX); - this.tuleapOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + TuleapOAuthService.CONFIG_SUFFIX); - this.auth0OAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + Auth0OAuthService.CONFIG_SUFFIX); - this.authentikOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + AuthentikOAuthService.CONFIG_SUFFIX); - this.cognitoOAuthProviderSection = - sections.get(PLUGIN_SECTION, pluginName + CognitoOAuthService.CONFIG_SUFFIX); + getConfigSection(AzureActiveDirectoryService.class); + this.office365OAuthProviderSection = + getConfigSection(AzureActiveDirectoryService.LEGACY_PROVIDER_NAME); + this.airVantageOAuthProviderSection = getConfigSection(AirVantageOAuthService.class); + this.phabricatorOAuthProviderSection = getConfigSection(PhabricatorOAuthService.class); + this.tuleapOAuthProviderSection = getConfigSection(TuleapOAuthService.class); + this.auth0OAuthProviderSection = getConfigSection(Auth0OAuthService.class); + this.authentikOAuthProviderSection = getConfigSection(AuthentikOAuthService.class); + this.cognitoOAuthProviderSection = getConfigSection(CognitoOAuthService.class); } @Override @@ -307,6 +297,17 @@ } } + private Section getConfigSection(Class<? extends OAuthServiceProvider> serviceClass) { + String serviceProviderName = + serviceClass.getAnnotation(OAuthServiceProviderConfig.class).name(); + return getConfigSection(serviceProviderName); + } + + private Section getConfigSection(String serviceProviderName) { + String sectionName = pluginName + "-" + serviceProviderName + "-oauth"; + return sections.get(PLUGIN_SECTION, sectionName); + } + @Override public void postRun() throws Exception {} }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/Module.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/Module.java index 72d59d1..683602d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/Module.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/Module.java
@@ -14,24 +14,11 @@ package com.googlesource.gerrit.plugins.oauth; -import com.google.gerrit.extensions.annotations.Exports; -import com.google.gerrit.extensions.annotations.PluginName; -import com.google.gerrit.extensions.auth.oauth.OAuthLoginProvider; import com.google.inject.AbstractModule; -import com.google.inject.Inject; public class Module extends AbstractModule { - private final String pluginName; - - @Inject - Module(@PluginName String pluginName) { - this.pluginName = pluginName; - } - @Override protected void configure() { - bind(OAuthLoginProvider.class) - .annotatedWith(Exports.named(pluginName)) - .to(DisabledOAuthLoginProvider.class); + bind(OAuthPluginConfigFactory.class); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthPluginConfigFactory.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthPluginConfigFactory.java new file mode 100644 index 0000000..50f50d3 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthPluginConfigFactory.java
@@ -0,0 +1,41 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.oauth; + +import com.google.gerrit.extensions.annotations.PluginName; +import com.google.gerrit.server.config.PluginConfig; +import com.google.gerrit.server.config.PluginConfigFactory; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +public class OAuthPluginConfigFactory { + private final PluginConfigFactory cfgFactory; + private final String pluginName; + + @Inject + OAuthPluginConfigFactory(PluginConfigFactory cfgFactory, @PluginName String pluginName) { + this.cfgFactory = cfgFactory; + this.pluginName = pluginName; + } + + static String getConfigSuffix(String providerName) { + return String.format("-%s-oauth", providerName); + } + + public PluginConfig create(String providerName) { + return cfgFactory.getFromGerritConfig(pluginName + getConfigSuffix(providerName)); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceModule.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceModule.java new file mode 100644 index 0000000..78183db --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceModule.java
@@ -0,0 +1,56 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.oauth; + +import com.google.gerrit.extensions.annotations.Exports; +import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; +import com.google.gerrit.server.config.PluginConfig; +import com.google.inject.AbstractModule; +import com.google.inject.Inject; + +public class OAuthServiceModule extends AbstractModule { + private final OAuthPluginConfigFactory cfgFactory; + private final Class<? extends OAuthServiceProvider> serviceProviderClass; + private final String serviceProviderName; + + @Inject + public OAuthServiceModule( + OAuthPluginConfigFactory cfgFactory, + Class<? extends OAuthServiceProvider> serviceProviderClass) { + this.cfgFactory = cfgFactory; + this.serviceProviderClass = serviceProviderClass; + + serviceProviderName = + serviceProviderClass.getAnnotation(OAuthServiceProviderConfig.class).name(); + } + + @Override + public void configure() { + PluginConfig cfg = cfgFactory.create(serviceProviderName); + if (cfg.getString(InitOAuth.CLIENT_ID) != null) { + bindOAuthServiceProvider(); + configureAdditionalServiceComponents(); + } + } + + protected void bindOAuthServiceProvider() { + String extIdScheme = OAuthServiceProviderExternalIdScheme.create(serviceProviderName); + bind(OAuthServiceProvider.class) + .annotatedWith(Exports.named(extIdScheme)) + .to(serviceProviderClass); + } + + public void configureAdditionalServiceComponents() {} +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderConfig.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderConfig.java new file mode 100644 index 0000000..488101f --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderConfig.java
@@ -0,0 +1,23 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.oauth; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface OAuthServiceProviderConfig { + String name(); +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderExternalIdScheme.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderExternalIdScheme.java new file mode 100644 index 0000000..5c93b79 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/OAuthServiceProviderExternalIdScheme.java
@@ -0,0 +1,21 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.oauth; + +public class OAuthServiceProviderExternalIdScheme { + public static String create(String serviceProviderName) { + return serviceProviderName + "-oauth"; + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/airvantage/AirVantageOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/airvantage/AirVantageOAuthService.java index 0ee981d..07fefde 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/airvantage/AirVantageOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/airvantage/AirVantageOAuthService.java
@@ -26,39 +26,39 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.util.concurrent.ExecutionException; import org.slf4j.Logger; @Singleton +@OAuthServiceProviderConfig(name = AirVantageOAuthService.PROVIDER_NAME) public class AirVantageOAuthService implements OAuthServiceProvider { private static final Logger log = getLogger(AirVantageOAuthService.class); - public static final String CONFIG_SUFFIX = "-airvantage-oauth"; - private static final String AV_PROVIDER_PREFIX = "airvantage-oauth:"; + public static final String PROVIDER_NAME = "airvantage"; private static final String PROTECTED_RESOURCE_URL = "https://eu.airvantage.net/api/v1/users/current"; private final OAuth20Service service; + private final String extIdScheme; @Inject AirVantageOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; service = @@ -66,6 +66,7 @@ .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET)) .callback(canonicalWebUrl + "oauth") .build(new AirVantageApi()); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -95,7 +96,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - AV_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), null, email.getAsString(), name.getAsString(),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/auth0/Auth0OAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/auth0/Auth0OAuthService.java index 7133988..ac1934f 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/auth0/Auth0OAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/auth0/Auth0OAuthService.java
@@ -25,20 +25,22 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -46,21 +48,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton +@OAuthServiceProviderConfig(name = Auth0OAuthService.PROVIDER_NAME) public class Auth0OAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(Auth0OAuthService.class); - private static final String AUTH0_PROVIDER_PREFIX = "auth0-oauth:"; - public static final String CONFIG_SUFFIX = "-auth0-oauth"; + public static final String PROVIDER_NAME = "auth0"; private static final String PROTECTED_RESOURCE_URL = "%s/userinfo"; private final OAuth20Service service; private final String serviceName; private final String rootUrl; + private final String extIdScheme; @Inject Auth0OAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -75,6 +77,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope("openid profile email") .build(new Auth0Api(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -104,7 +107,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - AUTH0_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(username), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/authentik/AuthentikOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/authentik/AuthentikOAuthService.java index f0e57a9..fd1be49 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/authentik/AuthentikOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/authentik/AuthentikOAuthService.java
@@ -25,20 +25,22 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -46,22 +48,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton +@OAuthServiceProviderConfig(name = AuthentikOAuthService.PROVIDER_NAME) public class AuthentikOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(AuthentikOAuthService.class); - private static final String AUTHENTIK_PROVIDER_PREFIX = "authentik-oauth:"; - public static final String CONFIG_SUFFIX = "-authentik-oauth"; + public static final String PROVIDER_NAME = "authentik"; private static final String PROTECTED_RESOURCE_URL = "%s/application/o/userinfo/"; private final OAuth20Service service; private final String serviceName; private final String rootUrl; private final boolean linkExistingGerrit; + private final String extIdScheme; @Inject AuthentikOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -77,6 +79,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope("openid profile email") .build(new AuthentikApi(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -106,7 +109,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - AUTHENTIK_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(username), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/azure/AzureActiveDirectoryService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/azure/AzureActiveDirectoryService.java index 5fa1f27..6f89662 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/azure/AzureActiveDirectoryService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/azure/AzureActiveDirectoryService.java
@@ -28,14 +28,12 @@ import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; import com.google.common.collect.ImmutableSet; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -43,6 +41,9 @@ import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -52,12 +53,12 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = AzureActiveDirectoryService.PROVIDER_NAME) public class AzureActiveDirectoryService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(AzureActiveDirectoryService.class); - public static final String CONFIG_SUFFIX_LEGACY = "-office365-oauth"; - public static final String CONFIG_SUFFIX = "-azure-oauth"; - private static final String AZURE_PROVIDER_PREFIX = "azure-oauth:"; private static final String OFFICE365_PROVIDER_PREFIX = "office365-oauth:"; + public static final String PROVIDER_NAME = "azure"; + public static final String LEGACY_PROVIDER_NAME = "office365"; private static final String PROTECTED_RESOURCE_URL = "https://graph.microsoft.com/v1.0/me"; private static final String SCOPE = "openid offline_access https://graph.microsoft.com/user.readbasic.all"; @@ -70,26 +71,19 @@ private final boolean useEmailAsUsername; private final String tenant; private final String clientId; - private String providerPrefix; private final boolean linkOffice365Id; + private final String extIdScheme; @Inject AzureActiveDirectoryService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); - providerPrefix = AZURE_PROVIDER_PREFIX; - - // ?: Did we find the client_id with the CONFIG_SUFFIX + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); if (cfg.getString(InitOAuth.CLIENT_ID) == null) { - // -> No, we did not find the client_id in the azure config so we should try the old legacy - // office365 section - cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX_LEGACY); - // We must also use the new provider prefix - providerPrefix = OFFICE365_PROVIDER_PREFIX; + cfg = cfgFactory.create(LEGACY_PROVIDER_NAME); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(LEGACY_PROVIDER_NAME); + } else { + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } - this.linkOffice365Id = cfg.getBoolean(InitOAuth.LINK_TO_EXISTING_OFFICE365_ACCOUNT, false); this.canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; this.useEmailAsUsername = cfg.getBoolean(InitOAuth.USE_EMAIL_AS_USERNAME, false); this.tenant = cfg.getString(InitOAuth.TENANT, DEFAULT_TENANT); @@ -106,6 +100,7 @@ log.debug("OAuth2: scope={}", SCOPE); log.debug("OAuth2: useEmailAsUsername={}", useEmailAsUsername); } + this.linkOffice365Id = cfg.getBoolean(InitOAuth.LINK_TO_EXISTING_OFFICE365_ACCOUNT, false); } @Override @@ -187,7 +182,7 @@ } return new OAuthUserInfo( - providerPrefix + id.getAsString(), + extIdScheme + ":" + id.getAsString(), login, asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/bitbucket/BitbucketOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/bitbucket/BitbucketOAuthService.java index d766e33..6ec4577 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/bitbucket/BitbucketOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/bitbucket/BitbucketOAuthService.java
@@ -26,40 +26,39 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.util.concurrent.ExecutionException; import org.slf4j.Logger; @Singleton +@OAuthServiceProviderConfig(name = BitbucketOAuthService.PROVIDER_NAME) public class BitbucketOAuthService implements OAuthServiceProvider { private static final Logger log = getLogger(BitbucketOAuthService.class); - public static final String CONFIG_SUFFIX = "-bitbucket-oauth"; - private static final String BITBUCKET_PROVIDER_PREFIX = "bitbucket-oauth:"; + public static final String PROVIDER_NAME = "bitbucket"; private static final String PROTECTED_RESOURCE_URL = "https://bitbucket.org/api/1.0/user/"; private final boolean fixLegacyUserId; private final OAuth20Service service; + private final String extIdScheme; @Inject BitbucketOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); - + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; fixLegacyUserId = cfg.getBoolean(InitOAuth.FIX_LEGACY_USER_ID, false); service = @@ -67,6 +66,7 @@ .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET)) .callback(canonicalWebUrl + "oauth") .build(new BitbucketApi()); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -99,7 +99,7 @@ JsonElement displayName = jsonObject.get("display_name"); return new OAuthUserInfo( - BITBUCKET_PROVIDER_PREFIX + username, + extIdScheme + ":" + username, username, null, displayName == null || displayName.isJsonNull() ? null : displayName.getAsString(),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/cas/CasOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/cas/CasOAuthService.java index 1be982f..25f5e90 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/cas/CasOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/cas/CasOAuthService.java
@@ -25,14 +25,12 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -41,6 +39,9 @@ import com.google.inject.ProvisionException; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -49,23 +50,22 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = CasOAuthService.PROVIDER_NAME) public class CasOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(CasOAuthService.class); - public static final String CONFIG_SUFFIX = "-cas-oauth"; - private static final String CAS_PROVIDER_PREFIX = "cas-oauth:"; + public static final String PROVIDER_NAME = "cas"; private static final String PROTECTED_RESOURCE_URL = "%s/oauth2.0/profile"; private static final String USE_JSON_EXTRACTOR = "use-json-extractor"; private final String rootUrl; private final boolean fixLegacyUserId; private final OAuth20Service service; + private final String extIdScheme; @Inject CasOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); rootUrl = cfg.getString(InitOAuth.ROOT_URL); if (!URI.create(rootUrl).isAbsolute()) { throw new ProvisionException("Root URL must be absolute URL"); @@ -78,6 +78,7 @@ .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET)) .callback(canonicalWebUrl + "oauth") .build(new CasApi(rootUrl, useJsonExtractor)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -148,7 +149,7 @@ } return new OAuthUserInfo( - CAS_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), login, email, name,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthService.java index 77cb974..612a822 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthService.java
@@ -25,20 +25,22 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import com.googlesource.gerrit.plugins.oauth.github.GitHubOAuthService; import java.io.IOException; import java.net.URI; @@ -47,22 +49,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton +@OAuthServiceProviderConfig(name = CognitoOAuthService.PROVIDER_NAME) public class CognitoOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(GitHubOAuthService.class); - public static final String CONFIG_SUFFIX = "-cognito-oauth"; - private static final String COGNITO_PROVIDER_PREFIX = "cognito-oauth:"; + public static final String PROVIDER_NAME = "cognito"; private static final String PROTECTED_RESOURCE_URL = "%s/oauth2/userInfo"; private final String rootUrl; private final OAuth20Service service; private final String serviceName; private final boolean linkExistingGerrit; + private final String extIdScheme; @Inject CognitoOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -79,6 +81,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope("openid profile email") .build(new CognitoApi(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -110,7 +113,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - COGNITO_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(username), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/dex/DexOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/dex/DexOAuthService.java index 03c8a07..4f8e7c8 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/dex/DexOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/dex/DexOAuthService.java
@@ -22,14 +22,12 @@ import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; @@ -37,6 +35,9 @@ import com.google.inject.ProvisionException; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -47,22 +48,21 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = DexOAuthService.PROVIDER_NAME) public class DexOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(DexOAuthService.class); + public static final String PROVIDER_NAME = "dex"; - public static final String CONFIG_SUFFIX = "-dex-oauth"; - private static final String DEX_PROVIDER_PREFIX = "dex-oauth:"; private final OAuth20Service service; private final String rootUrl; private final String domain; private final String serviceName; + private final String extIdScheme; @Inject DexOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -78,6 +78,7 @@ .defaultScope("openid profile email offline_access") .callback(canonicalWebUrl + "oauth") .build(new DexApi(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } private String parseJwt(String input) throws UnsupportedEncodingException { @@ -125,7 +126,7 @@ } return new OAuthUserInfo( - DEX_PROVIDER_PREFIX + email /*externalId*/, + extIdScheme + ":" + email /*externalId*/, username /*username*/, email /*email*/, name /*displayName*/,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/facebook/FacebookOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/facebook/FacebookOAuthService.java index dfb56d6..5888369 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/facebook/FacebookOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/facebook/FacebookOAuthService.java
@@ -25,20 +25,21 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletResponse; @@ -46,24 +47,21 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = FacebookOAuthService.PROVIDER_NAME) public class FacebookOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(FacebookOAuthService.class); - public static final String CONFIG_SUFFIX = "-facebook-oauth"; private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me"; - - private static final String FACEBOOK_PROVIDER_PREFIX = "facebook-oauth:"; + public static final String PROVIDER_NAME = "facebook"; private static final String SCOPE = "email"; private static final String FIELDS_QUERY = "fields"; private static final String FIELDS = "email,name"; private final OAuth20Service service; + private final String extIdScheme; @Inject FacebookOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; service = @@ -72,6 +70,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope(SCOPE) .build(new Facebook2Api()); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -108,7 +107,7 @@ JsonElement login = jsonObject.get("email"); return new OAuthUserInfo( - FACEBOOK_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(login), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/github/GitHubOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/github/GitHubOAuthService.java index 2ccf49b..b72a93f 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/github/GitHubOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/github/GitHubOAuthService.java
@@ -25,20 +25,21 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletResponse; @@ -46,10 +47,10 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = GitHubOAuthService.PROVIDER_NAME) public class GitHubOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(GitHubOAuthService.class); - public static final String CONFIG_SUFFIX = "-github-oauth"; - private static final String GITHUB_PROVIDER_PREFIX = "github-oauth:"; + public static final String PROVIDER_NAME = "github"; private static final String GITHUB_API_ENDPOINT_URL = "https://api.github.com/"; private static final String GHE_API_ENDPOINT_URL = "%sapi/v3/"; static final String GITHUB_ROOT_URL = "https://github.com/"; @@ -58,13 +59,12 @@ static final String SCOPE = "user:email"; private final boolean fixLegacyUserId; private final OAuth20Service service; + private final String extIdScheme; @Inject GitHubOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; fixLegacyUserId = cfg.getBoolean(InitOAuth.FIX_LEGACY_USER_ID, false); rootUrl = @@ -77,6 +77,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope(SCOPE) .build(new GitHub2Api(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } private String getApiUrl() { @@ -117,7 +118,7 @@ JsonElement name = jsonObject.get("name"); JsonElement login = jsonObject.get("login"); return new OAuthUserInfo( - GITHUB_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(login), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/gitlab/GitLabOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/gitlab/GitLabOAuthService.java index 6174019..426b06f 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/gitlab/GitLabOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/gitlab/GitLabOAuthService.java
@@ -27,14 +27,12 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; @@ -42,26 +40,28 @@ import com.google.inject.ProvisionException; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; import org.slf4j.Logger; @Singleton +@OAuthServiceProviderConfig(name = GitLabOAuthService.PROVIDER_NAME) public class GitLabOAuthService implements OAuthServiceProvider { private static final Logger log = getLogger(GitLabOAuthService.class); - public static final String CONFIG_SUFFIX = "-gitlab-oauth"; private static final String PROTECTED_RESOURCE_URL = "%s/api/v3/user"; - private static final String GITLAB_PROVIDER_PREFIX = "gitlab-oauth:"; + public static final String PROVIDER_NAME = "gitlab"; private final OAuth20Service service; private final String rootUrl; + private final String extIdScheme; @Inject GitLabOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); if (!URI.create(rootUrl).isAbsolute()) { @@ -72,6 +72,7 @@ .apiSecret(cfg.getString(InitOAuth.CLIENT_SECRET)) .callback(canonicalWebUrl + "oauth") .build(new GitLabApi(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -101,7 +102,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - GITLAB_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(username), asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/google/GoogleOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/google/GoogleOAuthService.java index 01851cb..2daee21 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/google/GoogleOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/google/GoogleOAuthService.java
@@ -27,20 +27,21 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; import com.google.common.base.Strings; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -54,10 +55,10 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = GoogleOAuthService.PROVIDER_NAME) public class GoogleOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(GoogleOAuthService.class); - public static final String CONFIG_SUFFIX = "-google-oauth"; - private static final String GOOGLE_PROVIDER_PREFIX = "google-oauth:"; + public static final String PROVIDER_NAME = "google"; private static final String PROTECTED_RESOURCE_URL = "https://www.googleapis.com/oauth2/v2/userinfo"; private static final String SCOPE = "email profile"; @@ -66,13 +67,12 @@ private final List<String> domains; private final boolean useEmailAsUsername; private final boolean fixLegacyUserId; + private final String extIdScheme; @Inject GoogleOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); this.canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; if (cfg.getBoolean(InitOAuth.LINK_TO_EXISTING_OPENID_ACCOUNT, false)) { log.warn( @@ -94,6 +94,7 @@ log.debug("OAuth2: domains={}", domains); log.debug("OAuth2: useEmailAsUsername={}", useEmailAsUsername); } + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -144,7 +145,7 @@ login = email.getAsString().split("@")[0]; } return new OAuthUserInfo( - GOOGLE_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), login, asString(email), asString(name),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/keycloak/KeycloakOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/keycloak/KeycloakOAuthService.java index 352a1b6..2a06f06 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/keycloak/KeycloakOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/keycloak/KeycloakOAuthService.java
@@ -22,20 +22,22 @@ import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; @@ -45,22 +47,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton +@OAuthServiceProviderConfig(name = KeycloakOAuthService.PROVIDER_NAME) public class KeycloakOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(KeycloakOAuthService.class); + public static final String PROVIDER_NAME = "keycloak"; - public static final String CONFIG_SUFFIX = "-keycloak-oauth"; - private static final String KEYCLOAK_PROVIDER_PREFIX = "keycloak-oauth:"; private final OAuth20Service service; private final String serviceName; private final boolean usePreferredUsername; + private final String extIdScheme; @Inject KeycloakOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; String rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -77,6 +79,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope("openid") .build(new KeycloakApi(rootUrl, realm)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } private String parseJwt(String input) throws UnsupportedEncodingException { @@ -124,7 +127,7 @@ if (usePreferredUsername) { username = usernameAsString; } - String externalId = KEYCLOAK_PROVIDER_PREFIX + usernameAsString; + String externalId = extIdScheme + ":" + usernameAsString; String email = emailElement.getAsString(); String name = nameElement.getAsString();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/lemon/LemonLDAPOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/lemon/LemonLDAPOAuthService.java index cdaa090..ea3fbd8 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/lemon/LemonLDAPOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/lemon/LemonLDAPOAuthService.java
@@ -26,29 +26,30 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; import java.io.IOException; import java.util.concurrent.ExecutionException; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; @Singleton +@OAuthServiceProviderConfig(name = LemonLDAPOAuthService.PROVIDER_NAME) public class LemonLDAPOAuthService implements OAuthServiceProvider { private static final Logger log = getLogger(LemonLDAPOAuthService.class); - public static final String CONFIG_SUFFIX = "-lemonldap-oauth"; + public static final String PROVIDER_NAME = "lemonldap"; private static final String PROTECTED_RESOURCE_URL = "%s/oauth2/userinfo"; private static final String LEMONLDAP_PROVIDER_PREFIX = "llng-oauth:"; private final OAuth20Service service; @@ -56,10 +57,8 @@ @Inject LemonLDAPOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); service =
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/phabricator/PhabricatorOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/phabricator/PhabricatorOAuthService.java index 05cd721..7a67fc7 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/phabricator/PhabricatorOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/phabricator/PhabricatorOAuthService.java
@@ -25,14 +25,12 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; @@ -40,6 +38,9 @@ import com.google.inject.ProvisionException; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -48,20 +49,19 @@ import org.slf4j.LoggerFactory; @Singleton +@OAuthServiceProviderConfig(name = PhabricatorOAuthService.PROVIDER_NAME) public class PhabricatorOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(PhabricatorOAuthService.class); - public static final String CONFIG_SUFFIX = "-phabricator-oauth"; - private static final String PHABRICATOR_PROVIDER_PREFIX = "phabricator-oauth:"; + public static final String PROVIDER_NAME = "phabricator"; private static final String PROTECTED_RESOURCE_URL = "%s/api/user.whoami"; private final String rootUrl; private final OAuth20Service service; + private final String extIdScheme; @Inject PhabricatorOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); if (!URI.create(rootUrl).isAbsolute()) { @@ -75,6 +75,7 @@ if (log.isDebugEnabled()) { log.debug("OAuth2: canonicalWebUrl={}", canonicalWebUrl); } + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -116,11 +117,7 @@ login = username.getAsString(); } return new OAuthUserInfo( - PHABRICATOR_PROVIDER_PREFIX + id.getAsString(), - login, - asString(email), - asString(name), - null); + extIdScheme + ":" + id.getAsString(), login, asString(email), asString(name), null); } } catch (ExecutionException | InterruptedException e) { throw new RuntimeException("Cannot retrieve user info resource", e);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/oauth/tuleap/TuleapOAuthService.java b/src/main/java/com/googlesource/gerrit/plugins/oauth/tuleap/TuleapOAuthService.java index c7423d8..b24aac8 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/oauth/tuleap/TuleapOAuthService.java +++ b/src/main/java/com/googlesource/gerrit/plugins/oauth/tuleap/TuleapOAuthService.java
@@ -25,20 +25,22 @@ import com.github.scribejava.core.model.Verb; import com.github.scribejava.core.oauth.OAuth20Service; import com.google.common.base.CharMatcher; -import com.google.gerrit.extensions.annotations.PluginName; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.extensions.auth.oauth.OAuthVerifier; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderConfig; +import com.googlesource.gerrit.plugins.oauth.OAuthServiceProviderExternalIdScheme; import java.io.IOException; import java.net.URI; import java.util.concurrent.ExecutionException; @@ -46,21 +48,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton +@OAuthServiceProviderConfig(name = TuleapOAuthService.PROVIDER_NAME) public class TuleapOAuthService implements OAuthServiceProvider { private static final Logger log = LoggerFactory.getLogger(TuleapOAuthService.class); - private static final String TULEAP_PROVIDER_PREFIX = "tuleap-oauth:"; - public static final String CONFIG_SUFFIX = "-tuleap-oauth"; + public static final String PROVIDER_NAME = "tuleap"; private static final String PROTECTED_RESOURCE_URL = "%s/oauth2/userinfo"; private final OAuth20Service service; private final String serviceName; private final String rootUrl; + private final String extIdScheme; @Inject TuleapOAuthService( - PluginConfigFactory cfgFactory, - @PluginName String pluginName, - @CanonicalWebUrl Provider<String> urlProvider) { - PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName + CONFIG_SUFFIX); + OAuthPluginConfigFactory cfgFactory, @CanonicalWebUrl Provider<String> urlProvider) { + PluginConfig cfg = cfgFactory.create(PROVIDER_NAME); String canonicalWebUrl = CharMatcher.is('/').trimTrailingFrom(urlProvider.get()) + "/"; rootUrl = cfg.getString(InitOAuth.ROOT_URL); @@ -75,6 +77,7 @@ .callback(canonicalWebUrl + "oauth") .defaultScope("openid profile email") .build(new TuleapApi(rootUrl)); + extIdScheme = OAuthServiceProviderExternalIdScheme.create(PROVIDER_NAME); } @Override @@ -104,7 +107,7 @@ JsonElement email = jsonObject.get("email"); JsonElement name = jsonObject.get("name"); return new OAuthUserInfo( - TULEAP_PROVIDER_PREFIX + id.getAsString(), + extIdScheme + ":" + id.getAsString(), asString(username), asString(email), asString(name),
diff --git a/src/test/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthServiceTest.java b/src/test/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthServiceTest.java index d2b6edf..60ee64b 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthServiceTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/oauth/cognito/CognitoOAuthServiceTest.java
@@ -25,9 +25,9 @@ import com.google.gerrit.extensions.auth.oauth.OAuthToken; import com.google.gerrit.extensions.auth.oauth.OAuthUserInfo; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.inject.Provider; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; import java.lang.reflect.Field; import javax.servlet.http.HttpServletResponse; import org.junit.Before; @@ -40,7 +40,7 @@ public class CognitoOAuthServiceTest { // Mocks for constructor dependencies of CognitoOAuthService - @Mock private PluginConfigFactory mockConfigFactory; + @Mock private OAuthPluginConfigFactory mockConfigFactory; @Mock private PluginConfig mockPluginConfig; @Mock private Provider<String> mockUrlProvider; @@ -48,7 +48,6 @@ @Mock private OAuth20Service mockScribeOAuthService; // Constants for configuration values - private static final String TEST_PLUGIN_NAME = "gerrit-oauth-provider-cognito"; private static final String TEST_CANONICAL_WEB_URL = "http://gerrit.example.com"; private static final String TEST_COGNITO_ROOT_URL = "https://cognito-idp.us-east-1.amazonaws.com/USER_POOL_ID"; @@ -68,9 +67,7 @@ @Before public void setUp() throws Exception { // Mock the PluginConfigFactory to return our mockPluginConfig - when(mockConfigFactory.getFromGerritConfig( - TEST_PLUGIN_NAME + CognitoOAuthService.CONFIG_SUFFIX)) - .thenReturn(mockPluginConfig); + when(mockConfigFactory.create(CognitoOAuthService.PROVIDER_NAME)).thenReturn(mockPluginConfig); // Mock the CanonicalWebUrl provider when(mockUrlProvider.get()).thenReturn(TEST_CANONICAL_WEB_URL); @@ -99,7 +96,7 @@ .thenReturn(linkExistingGerritAccounts); CognitoOAuthService serviceInstance = - new CognitoOAuthService(mockConfigFactory, TEST_PLUGIN_NAME, mockUrlProvider); + new CognitoOAuthService(mockConfigFactory, mockUrlProvider); // Replace the internal OAuth20Service with our mock using reflection. Field serviceField = CognitoOAuthService.class.getDeclaredField("service");
diff --git a/src/test/java/com/googlesource/gerrit/plugins/oauth/github/GithubApiUrlTest.java b/src/test/java/com/googlesource/gerrit/plugins/oauth/github/GithubApiUrlTest.java index 142e27c..73cbce1 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/oauth/github/GithubApiUrlTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/oauth/github/GithubApiUrlTest.java
@@ -21,9 +21,9 @@ import com.google.common.base.Strings; import com.google.gerrit.extensions.auth.oauth.OAuthServiceProvider; import com.google.gerrit.server.config.PluginConfig; -import com.google.gerrit.server.config.PluginConfigFactory; import com.google.inject.Provider; import com.googlesource.gerrit.plugins.oauth.InitOAuth; +import com.googlesource.gerrit.plugins.oauth.OAuthPluginConfigFactory; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import org.eclipse.jgit.lib.Config; @@ -38,23 +38,21 @@ private static final String CANONICAL_URL = "https://localhost"; private static final String TEST_CLIENT_ID = "test_client_id"; - @Mock private PluginConfigFactory pluginConfigFactoryMock; @Mock private Provider<String> urlProviderMock; + @Mock OAuthPluginConfigFactory oauthPluginConfigFactoryMock; private OAuthServiceProvider getGithubOAuthProvider(String rootUrl) { - PluginConfig.Update pluginConfig = - PluginConfig.Update.forTest(PLUGIN_NAME + GitHubOAuthService.CONFIG_SUFFIX, new Config()); + String configSection = PLUGIN_NAME + "-" + GitHubOAuthService.PROVIDER_NAME + "-oauth"; + PluginConfig.Update pluginConfig = PluginConfig.Update.forTest(configSection, new Config()); if (!Strings.isNullOrEmpty(rootUrl)) { pluginConfig.setString(InitOAuth.ROOT_URL, rootUrl); } pluginConfig.setString(InitOAuth.CLIENT_ID, TEST_CLIENT_ID); pluginConfig.setString(InitOAuth.CLIENT_SECRET, "secret"); - when(pluginConfigFactoryMock.getFromGerritConfig( - PLUGIN_NAME + GitHubOAuthService.CONFIG_SUFFIX)) - .thenReturn(pluginConfig.asPluginConfig()); when(urlProviderMock.get()).thenReturn(CANONICAL_URL); - - return new GitHubOAuthService(pluginConfigFactoryMock, PLUGIN_NAME, urlProviderMock); + when(oauthPluginConfigFactoryMock.create(GitHubOAuthService.PROVIDER_NAME)) + .thenReturn(pluginConfig.asPluginConfig()); + return new GitHubOAuthService(oauthPluginConfigFactoryMock, urlProviderMock); } private String getExpectedUrl(String rootUrl) throws Exception {