diff --git a/core/src/main/java/google/registry/tools/RegistryCli.java b/core/src/main/java/google/registry/tools/RegistryCli.java index 61e0ac820..72a2b3819 100644 --- a/core/src/main/java/google/registry/tools/RegistryCli.java +++ b/core/src/main/java/google/registry/tools/RegistryCli.java @@ -43,34 +43,41 @@ final class RegistryCli implements CommandRunner { // The environment parameter is parsed twice: once here, and once with {@link // RegistryToolEnvironment#parseFromArgs} in the {@link RegistryTool#main} function. // - // The flag names must be in sync between the two, and also - this is ugly and we should feel bad. + // The flag names must be in sync between the two, and also - this is ugly, and we should feel + // bad. @Parameter( names = {"-e", "--environment"}, description = "Sets the default environment to run the command.") private RegistryToolEnvironment environment = RegistryToolEnvironment.PRODUCTION; + @Parameter( + names = "--oauth", + description = + "Turn on OAuth-based authentication, the usage of which is to be deprecated. Use" + + " `create_user` to create an Admin user that allows for OIDC-based authentication.") + private boolean oAuth = false; + @Parameter( names = {"-c", "--commands"}, description = "Returns all command names.") private boolean showAllCommands; @Parameter( - names = {"--credential"}, + names = "--credential", description = "Name of a JSON file containing credential information used by the tool. " + "If not set, credentials saved by running `nomulus login' will be used.") private String credentialJson = null; @Parameter( - names = {"--sql_access_info"}, + names = "--sql_access_info", description = "Name of a file containing space-separated SQL access info used when deploying " + "Beam pipelines") private String sqlAccessInfoFile = null; // Do not make this final - compile-time constant inlining may interfere with JCommander. - @ParametersDelegate - private LoggingParameters loggingParams = new LoggingParameters(); + @ParametersDelegate private LoggingParameters loggingParams = new LoggingParameters(); RegistryToolComponent component; @@ -105,8 +112,8 @@ final class RegistryCli implements CommandRunner { jcommander.setProgramName(programName); // Create all command instances. It would be preferrable to do this in the constructor, but - // JCommander mutates the command instances and doesn't reset them so we have to do it for every - // run. + // JCommander mutates the command instances and doesn't reset them, so we have to do it for + // every run. try { for (Map.Entry> entry : commands.entrySet()) { Command command = entry.getValue().getDeclaredConstructor().newInstance(); @@ -161,6 +168,7 @@ final class RegistryCli implements CommandRunner { DaggerRegistryToolComponent.builder() .credentialFilePath(credentialJson) .sqlAccessInfoFile(sqlAccessInfoFile) + .addOAuthHeader(oAuth) .build(); // JCommander stores sub-commands as nested JCommander objects containing a list of user objects @@ -169,7 +177,7 @@ final class RegistryCli implements CommandRunner { Command command = (Command) Iterables.getOnlyElement(jcommander.getCommands().get(parsedCommand).getObjects()); - loggingParams.configureLogging(); // Must be called after parameters are parsed. + loggingParams.configureLogging(); // Must be called after parameters are parsed. try { runCommand(command); diff --git a/core/src/main/java/google/registry/tools/RegistryToolComponent.java b/core/src/main/java/google/registry/tools/RegistryToolComponent.java index e9862a8d2..099c94377 100644 --- a/core/src/main/java/google/registry/tools/RegistryToolComponent.java +++ b/core/src/main/java/google/registry/tools/RegistryToolComponent.java @@ -123,6 +123,7 @@ interface RegistryToolComponent { void inject(GetDomainCommand command); void inject(GetHostCommand command); + void inject(GetKeyringSecretCommand command); void inject(GetSqlCredentialCommand command); @@ -190,6 +191,9 @@ interface RegistryToolComponent { @BindsInstance Builder sqlAccessInfoFile(@Nullable @Config("sqlAccessInfoFile") String sqlAccessInfoFile); + @BindsInstance + Builder addOAuthHeader(@Config("addOauthHeader") boolean addOauthHeader); + RegistryToolComponent build(); } } diff --git a/core/src/main/java/google/registry/tools/RequestFactoryModule.java b/core/src/main/java/google/registry/tools/RequestFactoryModule.java index 6fa0d6eac..5f7118553 100644 --- a/core/src/main/java/google/registry/tools/RequestFactoryModule.java +++ b/core/src/main/java/google/registry/tools/RequestFactoryModule.java @@ -42,7 +42,8 @@ final class RequestFactoryModule { @Provides static HttpRequestFactory provideHttpRequestFactory( @ApplicationDefaultCredential GoogleCredentialsBundle credentialsBundle, - @Config("oauthClientId") String oauthClientId) { + @Config("oauthClientId") String oauthClientId, + @Config("addOauthHeader") boolean addOauthHeader) { if (RegistryConfig.areServersLocal()) { return new NetHttpTransport() .createRequestFactory( @@ -54,8 +55,10 @@ final class RequestFactoryModule { return new NetHttpTransport() .createRequestFactory( request -> { - // Use the standard credential initializer to set the Authorization header - credentialsBundle.getHttpRequestInitializer().initialize(request); + if (addOauthHeader) { + // Use the standard credential initializer to set the Authorization header + credentialsBundle.getHttpRequestInitializer().initialize(request); + } // Set OIDC token as the alternative bearer token. request .getHeaders() diff --git a/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java b/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java index d9fc2bd50..21866b95d 100644 --- a/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java +++ b/core/src/test/java/google/registry/tools/RequestFactoryModuleTest.java @@ -64,7 +64,7 @@ public class RequestFactoryModuleTest { RegistryConfig.CONFIG_SETTINGS.get().gcpProject.isLocal = true; try { HttpRequestFactory factory = - RequestFactoryModule.provideHttpRequestFactory(credentialsBundle, "client-id"); + RequestFactoryModule.provideHttpRequestFactory(credentialsBundle, "client-id", false); HttpRequestInitializer initializer = factory.getInitializer(); assertThat(initializer).isNotNull(); HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost")); @@ -97,14 +97,23 @@ public class RequestFactoryModuleTest { boolean origIsLocal = RegistryConfig.CONFIG_SETTINGS.get().gcpProject.isLocal; RegistryConfig.CONFIG_SETTINGS.get().gcpProject.isLocal = false; try { + // With OAuth header. HttpRequestFactory factory = - RequestFactoryModule.provideHttpRequestFactory(credentialsBundle, "clientId"); + RequestFactoryModule.provideHttpRequestFactory(credentialsBundle, "clientId", true); HttpRequest request = factory.buildGetRequest(new GenericUrl("http://localhost")); assertThat(request.getHeaders().get("Proxy-Authorization")).isEqualTo("Bearer oidc.token"); assertThat(request.getConnectTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); assertThat(request.getReadTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); verify(httpRequestInitializer).initialize(request); verifyNoMoreInteractions(httpRequestInitializer); + // No OAuth header. + factory = + RequestFactoryModule.provideHttpRequestFactory(credentialsBundle, "clientId", false); + request = factory.buildGetRequest(new GenericUrl("http://localhost")); + assertThat(request.getHeaders().get("Proxy-Authorization")).isEqualTo("Bearer oidc.token"); + assertThat(request.getConnectTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); + assertThat(request.getReadTimeout()).isEqualTo(REQUEST_TIMEOUT_MS); + verifyNoMoreInteractions(httpRequestInitializer); } finally { RegistryConfig.CONFIG_SETTINGS.get().gcpProject.isLocal = origIsLocal; }