diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCmd.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCmd.java index 4479de98479..3c0bb06aaf4 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCmd.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCmd.java @@ -28,12 +28,14 @@ import static org.keycloak.client.admin.cli.KcAdmMain.CMD; * @author Marko Strukelj */ -@Command(name = "config", description = "COMMAND [ARGUMENTS]", subcommands = { +@Command(name = ConfigCmd.NAME, description = "COMMAND [ARGUMENTS]", subcommands = { ConfigCredentialsCmd.class, ConfigTruststoreCmd.class } ) public class ConfigCmd extends AbstractAuthOptionsCmd { + public static final String NAME = "config"; + @Override protected void process() { diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCredentialsCmd.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCredentialsCmd.java index daf57f25d9e..e988a5f63c0 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCredentialsCmd.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCredentialsCmd.java @@ -33,9 +33,11 @@ import static org.keycloak.client.cli.util.IoUtil.printOut; /** * @author Marko Strukelj */ -@Command(name = "credentials", description = "--server SERVER_URL --realm REALM [ARGUMENTS]") +@Command(name = ConfigCredentialsCmd.NAME, description = "--server SERVER_URL --realm REALM [ARGUMENTS]") public class ConfigCredentialsCmd extends BaseConfigCredentialsCmd { + static final String NAME = "credentials"; + public ConfigCredentialsCmd() { super(KcAdmMain.COMMAND_STATE); } @@ -62,4 +64,8 @@ public class ConfigCredentialsCmd extends BaseConfigCredentialsCmd { super.process(); } } + + String getPassword() { + return this.password; + } } diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/KcAdmCmd.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/KcAdmCmd.java index 3e3cdcfc293..a5411cc9959 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/KcAdmCmd.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/KcAdmCmd.java @@ -22,6 +22,7 @@ import org.keycloak.client.cli.common.BaseGlobalOptionsCmd; import java.io.PrintWriter; import java.io.StringWriter; +import picocli.CommandLine; import picocli.CommandLine.Command; import static org.keycloak.client.admin.cli.KcAdmMain.CMD; @@ -51,6 +52,9 @@ subcommands = { }) public class KcAdmCmd extends BaseGlobalOptionsCmd { + @CommandLine.Spec + CommandLine.Model.CommandSpec spec; + @Override protected boolean nothingToDo() { return true; diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/Globals.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/Globals.java index 3afda5763a1..71e2d450f36 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/Globals.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/Globals.java @@ -44,19 +44,20 @@ public class Globals { CryptoIntegration.init(cl); System.setProperty(BaseAuthOptionsCmd.DEFAULT_CONFIG_PATH_STRING_KEY, defaultConfigFile); - CommandLine cli = createCommandLine(rootCommand, command); + CommandLine cli = createCommandLine(rootCommand, command, new PrintWriter(System.err, true)); int exitCode = cli.execute(args); System.exit(exitCode); } - public static CommandLine createCommandLine(BaseGlobalOptionsCmd rootCommand, String command) { + public static CommandLine createCommandLine(BaseGlobalOptionsCmd rootCommand, String command, PrintWriter errorWriter) { CommandSpec spec = CommandSpec.forAnnotatedObject(rootCommand).name(command); CommandLine cmd = new CommandLine(spec); - + cmd.setExpandAtFiles(false); + cmd.setPosixClusteredShortOptionsAllowed(false); cmd.setExecutionExceptionHandler(new ExecutionExceptionHandler()); cmd.setParameterExceptionHandler(new ShortErrorMessageHandler()); - cmd.setErr(new PrintWriter(System.err, true)); + cmd.setErr(errorWriter); return cmd; } diff --git a/integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/KcAdmCliTest.java b/integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/KcAdmCliTest.java new file mode 100644 index 00000000000..39c161c2841 --- /dev/null +++ b/integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/KcAdmCliTest.java @@ -0,0 +1,23 @@ +package org.keycloak.client.admin.cli.commands; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; + +import org.junit.Test; +import org.keycloak.client.cli.common.Globals; + +import picocli.CommandLine; + +public class KcAdmCliTest { + + @Test + public void testAtFileDisabled() { + KcAdmCmd command = new KcAdmCmd(); + CommandLine cli = Globals.createCommandLine(command, "kcadm", new PrintWriter(new ByteArrayOutputStream())); + cli.execute("config", "credentials", "--user", "user", "--password", "@@password", "--server", "server"); + ConfigCredentialsCmd cmd = command.spec.subcommands().get(ConfigCmd.NAME).getSubcommands().get(ConfigCredentialsCmd.NAME).getCommand(); + assertEquals("@@password", cmd.getPassword()); + } +} \ No newline at end of file diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java index 91bb53a8778..13ec225b4a1 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java @@ -629,7 +629,8 @@ public class Picocli { consumer.accept(spec); CommandLine cmd = new CommandLine(spec); - + cmd.setExpandAtFiles(false); + cmd.setPosixClusteredShortOptionsAllowed(false); cmd.setExecutionExceptionHandler(this.errorHandler); cmd.setParameterExceptionHandler(new ShortErrorMessageHandler()); cmd.setHelpFactory(new HelpFactory()); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/ConfigArgsConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/ConfigArgsConfigSource.java index 8832a69eab7..632512a739d 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/ConfigArgsConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/ConfigArgsConfigSource.java @@ -77,7 +77,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource { if(args == null) { return Collections.emptyList(); } - + List result = new ArrayList(); boolean escaped = false; StringBuilder arg = new StringBuilder(); @@ -101,7 +101,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource { } } result.add(arg.toString()); - + return result; } @@ -167,7 +167,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource { PropertyMapper mapper = PropertyMappers.getMapper(key); // the weaknesses here: // - needs to know all of the short name options that accept a value - // - does not know all of the picocli parsing rules. picocli will accept -cffile, and short option grouping - that's not accounted for + // - Even though We've explicitly disabled PosixClusteredShortOptionsAllowed, it may not know all of the picocli parsing rules. if (mapper != null || SHORT_OPTIONS_ACCEPTING_VALUE.contains(key) || arg.startsWith(SPI_OPTION_PREFIX)) { i++; // consume next as a value to the key value = args.get(i);