From 408850e7bdf9fb60118757b1efe35ce2937983be Mon Sep 17 00:00:00 2001 From: Marko Strukelj Date: Thu, 27 Oct 2016 16:10:13 +0200 Subject: [PATCH] KEYCLOAK-3767 kcreg should show hint for help if required arguments are missing --- .../registration/cli/commands/AttrsCmd.java | 4 +-- .../registration/cli/commands/ConfigCmd.java | 18 +++++++---- .../cli/commands/ConfigCredentialsCmd.java | 13 ++++++-- .../cli/commands/ConfigInitialTokenCmd.java | 11 +++++-- .../commands/ConfigRegistrationTokenCmd.java | 16 +++++++--- .../cli/commands/ConfigTruststoreCmd.java | 16 +++++++--- .../registration/cli/commands/CreateCmd.java | 14 +++++--- .../registration/cli/commands/DeleteCmd.java | 11 +++++-- .../registration/cli/commands/GetCmd.java | 11 +++++-- .../registration/cli/commands/UpdateCmd.java | 15 ++++++--- .../cli/commands/UpdateTokenCmd.java | 9 +++++- .../cli/registration/AbstractCliTest.java | 5 +-- .../cli/registration/KcRegConfigTest.java | 10 ++++-- .../testsuite/cli/registration/KcRegTest.java | 32 ++++++++++--------- .../cli/registration/KcRegTruststoreTest.java | 11 ++++--- .../cli/registration/KcRegUpdateTest.java | 5 +-- 16 files changed, 141 insertions(+), 60 deletions(-) diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java index 958ae27f5c..efa8e25500 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/AttrsCmd.java @@ -61,14 +61,14 @@ public class AttrsCmd extends AbstractGlobalOptionsCmd { if (args != null) { if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } attr = args.get(0); } Class type = regType == EndpointType.DEFAULT ? ClientRepresentation.class : (regType == EndpointType.OIDC ? OIDCClientRepresentation.class : null); if (type == null) { - throw new RuntimeException("Endpoint not supported: " + regType); + throw new IllegalArgumentException("Endpoint not supported: " + regType); } AttributeKey key = attr == null ? new AttributeKey() : new AttributeKey(attr); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java index 06594d7587..82c4a54a47 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCmd.java @@ -23,12 +23,14 @@ import org.jboss.aesh.console.command.CommandException; import org.jboss.aesh.console.command.Command; import org.jboss.aesh.console.command.CommandResult; import org.jboss.aesh.console.command.invocation.CommandInvocation; -import org.keycloak.client.registration.cli.util.OsUtil; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; +import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; + /** * @author Marko Strukelj */ @@ -69,7 +71,7 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { if (printHelp()) { return help ? CommandResult.SUCCESS : CommandResult.FAILURE; } - throw new RuntimeException("Unknown sub-command: " + cmd); + throw new IllegalArgumentException("Unknown sub-command: " + cmd + suggestHelp()); } } } @@ -78,13 +80,17 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { return help ? CommandResult.SUCCESS : CommandResult.FAILURE; } - throw new RuntimeException("Sub-command required by '" + OsUtil.CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'"); + throw new IllegalArgumentException("Sub-command required by '" + CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'"); } finally { commandInvocation.stop(); } } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help config' for more information"; + } + protected String help() { return usage(); } @@ -92,13 +98,13 @@ public class ConfigCmd extends AbstractAuthOptionsCmd implements Command { public static String usage() { StringWriter sb = new StringWriter(); PrintWriter out = new PrintWriter(sb); - out.println("Usage: " + OsUtil.CMD + " config SUB_COMMAND [ARGUMENTS]"); + out.println("Usage: " + CMD + " config SUB_COMMAND [ARGUMENTS]"); out.println(); out.println("Where SUB_COMMAND is one of: 'credentials', 'truststore', 'initial-token', 'registration-token'"); out.println(); out.println(); - out.println("Use '" + OsUtil.CMD + " help config SUB_COMMAND' for more info."); - out.println("Use '" + OsUtil.CMD + " help' for general information and a list of commands."); + out.println("Use '" + CMD + " help config SUB_COMMAND' for more info."); + out.println("Use '" + CMD + " help' for general information and a list of commands."); return sb.toString(); } } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java index fc2fa615c3..d83f2c4c6f 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigCredentialsCmd.java @@ -25,6 +25,7 @@ import static org.keycloak.client.registration.cli.util.ConfigUtil.saveTokens; import static org.keycloak.client.registration.cli.util.IoUtil.printErr; import static org.keycloak.client.registration.cli.util.IoUtil.readSecret; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.OS_ARCH; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; @@ -69,6 +70,8 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm processGlobalOptions(); return process(commandInvocation); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -83,7 +86,7 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm // check server if (server == null) { - throw new RuntimeException("Required option not specified: --server"); + throw new IllegalArgumentException("Required option not specified: --server"); } try { @@ -93,7 +96,7 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm } if (realm == null) - throw new RuntimeException("Required option not specified: --realm"); + throw new IllegalArgumentException("Required option not specified: --realm"); String signedRequestToken = null; boolean clientSet = clientId != null; @@ -122,7 +125,7 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm if (keystore != null) { if (secret != null) { - throw new RuntimeException("Can't use both --keystore and --secret"); + throw new IllegalArgumentException("Can't use both --keystore and --secret"); } if (!new File(keystore).isFile()) { @@ -174,6 +177,10 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd implements Comm return CommandResult.SUCCESS; } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help config credentials' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java index 09a757bf98..0db641ee0e 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigInitialTokenCmd.java @@ -19,6 +19,7 @@ import static org.keycloak.client.registration.cli.util.ConfigUtil.DEFAULT_CONFI import static org.keycloak.client.registration.cli.util.ConfigUtil.saveMergeConfig; import static org.keycloak.client.registration.cli.util.IoUtil.warnfOut; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.OS_ARCH; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; @@ -47,6 +48,8 @@ public class ConfigInitialTokenCmd extends AbstractAuthOptionsCmd implements Com } return process(commandInvocation); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -85,13 +88,13 @@ public class ConfigInitialTokenCmd extends AbstractAuthOptionsCmd implements Com } if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } String token = args.size() == 1 ? args.get(0) : null; if (realm == null) { - throw new RuntimeException("Realm not specified"); + throw new IllegalArgumentException("Realm not specified"); } if (token != null && token.startsWith("-")) { @@ -138,6 +141,10 @@ public class ConfigInitialTokenCmd extends AbstractAuthOptionsCmd implements Com return CommandResult.SUCCESS; } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help config initial-token' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java index ec01ea6d06..9e38503f68 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigRegistrationTokenCmd.java @@ -17,6 +17,7 @@ import java.util.List; import static org.keycloak.client.registration.cli.util.ConfigUtil.DEFAULT_CONFIG_FILE_STRING; import static org.keycloak.client.registration.cli.util.ConfigUtil.saveMergeConfig; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.OS_ARCH; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; @@ -44,6 +45,9 @@ public class ConfigRegistrationTokenCmd extends AbstractAuthOptionsCmd implement } return process(commandInvocation); + + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -77,21 +81,21 @@ public class ConfigRegistrationTokenCmd extends AbstractAuthOptionsCmd implement } if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } String token = args.size() == 1 ? args.get(0) : null; if (server == null) { - throw new RuntimeException("Required option not specified: --server"); + throw new IllegalArgumentException("Required option not specified: --server"); } if (realm == null) { - throw new RuntimeException("Required option not specified: --realm"); + throw new IllegalArgumentException("Required option not specified: --realm"); } if (clientId == null) { - throw new RuntimeException("Required option not specified: --client"); + throw new IllegalArgumentException("Required option not specified: --client"); } checkUnsupportedOptions( @@ -128,6 +132,10 @@ public class ConfigRegistrationTokenCmd extends AbstractAuthOptionsCmd implement return CommandResult.SUCCESS; } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help config registration-token' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java index acc1ca36a7..b8f1f34c25 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/ConfigTruststoreCmd.java @@ -17,6 +17,7 @@ import static org.keycloak.client.registration.cli.util.ConfigUtil.DEFAULT_CONFI import static org.keycloak.client.registration.cli.util.ConfigUtil.saveMergeConfig; import static org.keycloak.client.registration.cli.util.IoUtil.readSecret; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.OS_ARCH; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; @@ -44,6 +45,9 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma } return process(commandInvocation); + + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -77,7 +81,7 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma } if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } String truststore = null; @@ -105,7 +109,7 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma if (!delete) { if (truststore == null) { - throw new RuntimeException("No truststore specified"); + throw new IllegalArgumentException("No truststore specified"); } if (!new File(truststore).isFile()) { @@ -121,10 +125,10 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma } else { if (truststore != null) { - throw new RuntimeException("Option --delete is mutually exclusive with specifying a TRUSTSTORE"); + throw new IllegalArgumentException("Option --delete is mutually exclusive with specifying a TRUSTSTORE"); } if (trustPass != null) { - throw new RuntimeException("Options --trustpass and --delete are mutually exclusive"); + throw new IllegalArgumentException("Options --trustpass and --delete are mutually exclusive"); } store = null; pass = null; @@ -138,6 +142,10 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd implements Comma return CommandResult.SUCCESS; } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help config truststore' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java index 49a0d1bdf2..cdecfff99a 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/CreateCmd.java @@ -56,6 +56,7 @@ import static org.keycloak.client.registration.cli.util.IoUtil.printErr; import static org.keycloak.client.registration.cli.util.IoUtil.readFully; import static org.keycloak.client.registration.cli.util.IoUtil.readSecret; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.OS_ARCH; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; import static org.keycloak.client.registration.cli.util.ParseUtil.mergeAttributes; @@ -114,25 +115,25 @@ public class CreateCmd extends AbstractAuthOptionsCmd implements Command { case "-s": case "--set": { if (!it.hasNext()) { - throw new RuntimeException("Option " + option + " requires a value"); + throw new IllegalArgumentException("Option " + option + " requires a value"); } String[] keyVal = parseKeyVal(it.next()); attrs.add(new AttributeOperation(SET, keyVal[0], keyVal[1])); break; } default: { - throw new RuntimeException("Unsupported option: " + option); + throw new IllegalArgumentException("Unsupported option: " + option); } } } } if (file == null && attrs.size() == 0) { - throw new RuntimeException("No file nor attribute values specified"); + throw new IllegalArgumentException("No file nor attribute values specified"); } if (outputClient && returnClientId) { - throw new RuntimeException("Options -o and -i can't be used together"); + throw new IllegalArgumentException("Options -o and -i are mutually exclusive"); } // if --token is specified read it @@ -211,6 +212,8 @@ public class CreateCmd extends AbstractAuthOptionsCmd implements Command { return CommandResult.SUCCESS; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -235,6 +238,9 @@ public class CreateCmd extends AbstractAuthOptionsCmd implements Command { return noOptions() && regType == null && file == null && (args == null || args.size() == 0); } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help create' for more information"; + } protected String help() { return usage(); diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java index 4c3e0d9604..291023ae89 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/DeleteCmd.java @@ -39,6 +39,7 @@ import static org.keycloak.client.registration.cli.util.HttpUtil.doDelete; import static org.keycloak.client.registration.cli.util.HttpUtil.urlencode; import static org.keycloak.client.registration.cli.util.IoUtil.warnfErr; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; @@ -61,11 +62,11 @@ public class DeleteCmd extends AbstractAuthOptionsCmd { processGlobalOptions(); if (args == null || args.isEmpty()) { - throw new RuntimeException("CLIENT not specified"); + throw new IllegalArgumentException("CLIENT not specified"); } if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } String clientId = args.get(0); @@ -108,6 +109,8 @@ public class DeleteCmd extends AbstractAuthOptionsCmd { }); return CommandResult.SUCCESS; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -118,6 +121,10 @@ public class DeleteCmd extends AbstractAuthOptionsCmd { return noOptions() && (args == null || args.size() == 0); } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help delete' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java index 3cb580f510..c28fd95979 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/GetCmd.java @@ -51,6 +51,7 @@ import static org.keycloak.client.registration.cli.util.IoUtil.warnfErr; import static org.keycloak.client.registration.cli.util.IoUtil.printOut; import static org.keycloak.client.registration.cli.util.IoUtil.readFully; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; /** @@ -79,11 +80,11 @@ public class GetCmd extends AbstractAuthOptionsCmd { processGlobalOptions(); if (args == null || args.isEmpty()) { - throw new RuntimeException("CLIENT not specified"); + throw new IllegalArgumentException("CLIENT not specified"); } if (args.size() > 1) { - throw new RuntimeException("Invalid option: " + args.get(1)); + throw new IllegalArgumentException("Invalid option: " + args.get(1)); } String clientId = args.get(0); @@ -170,6 +171,8 @@ public class GetCmd extends AbstractAuthOptionsCmd { } return CommandResult.SUCCESS; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -180,6 +183,10 @@ public class GetCmd extends AbstractAuthOptionsCmd { return noOptions() && endpoint == null && (args == null || args.size() == 0); } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help get' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java index 8a3697ca09..91928790fc 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateCmd.java @@ -62,6 +62,7 @@ import static org.keycloak.client.registration.cli.util.IoUtil.warnfErr; import static org.keycloak.client.registration.cli.util.IoUtil.readFully; import static org.keycloak.client.registration.cli.util.HttpUtil.APPLICATION_JSON; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; import static org.keycloak.client.registration.cli.util.ParseUtil.mergeAttributes; import static org.keycloak.client.registration.cli.util.ParseUtil.parseFileOrStdin; @@ -112,7 +113,7 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { if (args != null) { Iterator it = args.iterator(); if (!it.hasNext()) { - throw new RuntimeException("CLIENT_ID not specified"); + throw new IllegalArgumentException("CLIENT_ID not specified"); } clientId = it.next(); @@ -127,7 +128,7 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { case "-s": case "--set": { if (!it.hasNext()) { - throw new RuntimeException("Option " + option + " requires a value"); + throw new IllegalArgumentException("Option " + option + " requires a value"); } String[] keyVal = parseKeyVal(it.next()); attrs.add(new AttributeOperation(SET, keyVal[0], keyVal[1])); @@ -139,14 +140,14 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { break; } default: { - throw new RuntimeException("Unsupported option: " + option); + throw new IllegalArgumentException("Unsupported option: " + option); } } } } if (file == null && attrs.size() == 0) { - throw new RuntimeException("No file nor attribute values specified"); + throw new IllegalArgumentException("No file nor attribute values specified"); } // We have several options for update: @@ -318,6 +319,8 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { return CommandResult.SUCCESS; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -338,6 +341,10 @@ public class UpdateCmd extends AbstractAuthOptionsCmd { return noOptions() && regType == null && file == null && (args == null || args.size() == 0); } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help update' for more information"; + } + protected String help() { return usage(); } diff --git a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java index c7332434a5..16295f4ef1 100644 --- a/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java +++ b/integration/client-cli/client-registration-cli/src/main/java/org/keycloak/client/registration/cli/commands/UpdateTokenCmd.java @@ -45,6 +45,7 @@ import static org.keycloak.client.registration.cli.util.HttpUtil.doPost; import static org.keycloak.client.registration.cli.util.IoUtil.printOut; import static org.keycloak.client.registration.cli.util.IoUtil.warnfOut; import static org.keycloak.client.registration.cli.util.OsUtil.CMD; +import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.client.registration.cli.util.OsUtil.PROMPT; /** @@ -67,7 +68,7 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { processGlobalOptions(); if (args == null || args.isEmpty()) { - throw new RuntimeException("CLIENT not specified"); + throw new IllegalArgumentException("CLIENT not specified"); } String clientId = args.get(0); @@ -127,6 +128,8 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { //System.out.println("Token updated for client " + clientId); return CommandResult.SUCCESS; + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(e.getMessage() + suggestHelp(), e); } finally { commandInvocation.stop(); } @@ -137,6 +140,10 @@ public class UpdateTokenCmd extends AbstractAuthOptionsCmd { return noOptions() && (args == null || args.size() == 0); } + protected String suggestHelp() { + return EOL + "Try '" + CMD + " help update-token' for more information"; + } + protected String help() { return usage(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractCliTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractCliTest.java index ceec8b85f8..1098053657 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractCliTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/AbstractCliTest.java @@ -39,6 +39,7 @@ import java.util.Map; import java.util.UUID; import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; +import static org.keycloak.testsuite.cli.KcRegExec.WORK_DIR; import static org.keycloak.testsuite.cli.KcRegExec.execute; /** @@ -351,7 +352,7 @@ public abstract class AbstractCliTest extends AbstractKeycloakTest { FileConfigHandler initCustomConfigFile() { String filename = UUID.randomUUID().toString() + ".config"; - File cfgFile = new File(KcRegExec.WORK_DIR + "/" + filename); + File cfgFile = new File(WORK_DIR + "/" + filename); FileConfigHandler handler = new FileConfigHandler(); handler.setConfigFile(cfgFile.getAbsolutePath()); return handler; @@ -363,7 +364,7 @@ public abstract class AbstractCliTest extends AbstractKeycloakTest { File initTempFile(String extension, String content) throws IOException { String filename = UUID.randomUUID().toString() + extension; - File file = new File(KcRegExec.WORK_DIR + "/" + filename); + File file = new File(WORK_DIR + "/" + filename); if (content != null) { OutputStream os = new FileOutputStream(file); os.write(content.getBytes(Charset.forName("iso_8859_1"))); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java index 473fb1deab..b91296cead 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegConfigTest.java @@ -8,6 +8,7 @@ import org.keycloak.testsuite.util.TempFileResource; import java.io.IOException; +import static org.keycloak.client.registration.cli.util.OsUtil.CMD; import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.testsuite.cli.KcRegExec.execute; @@ -25,18 +26,21 @@ public class KcRegConfigTest extends AbstractCliTest { // without --server KcRegExec exe = execute("config registration-token --config '" + configFile.getName() + "' "); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("error message", "Required option not specified: --server", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config registration-token' for more information", exe.stderrLines().get(1)); // without --realm exe = execute("config registration-token --config '" + configFile.getName() + "' --server http://localhost:8080/auth"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("error message", "Required option not specified: --realm", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config registration-token' for more information", exe.stderrLines().get(1)); // without --client exe = execute("config registration-token --config '" + configFile.getName() + "' --server http://localhost:8080/auth --realm test"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("error message", "Required option not specified: --client", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config registration-token' for more information", exe.stderrLines().get(1)); // specify token on cmdline exe = execute("config registration-token --config '" + configFile.getName() + "' --server http://localhost:8080/auth --realm test --client my_client NEWTOKEN"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java index 7da3a7e062..5647ec881f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTest.java @@ -5,7 +5,6 @@ import org.junit.Test; import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.FileConfigHandler; import org.keycloak.client.registration.cli.config.RealmConfigData; -import org.keycloak.client.registration.cli.util.OsUtil; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.TempFileResource; @@ -48,51 +47,51 @@ public class KcRegTest extends AbstractCliTest { exe = execute("config"); assertExitCodeAndStreamSizes(exe, 1, 0, 1); Assert.assertEquals("error message", - "Sub-command required by '" + OsUtil.CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'", + "Sub-command required by '" + CMD + " config' - one of: 'credentials', 'truststore', 'initial-token', 'registration-token'", exe.stderrLines().get(0)); exe = execute("config credentials"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " config credentials --server SERVER_URL --realm REALM [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " config credentials --server SERVER_URL --realm REALM [ARGUMENTS]", exe.stdoutLines().get(0)); exe = execute("config initial-token"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " config initial-token --server SERVER --realm REALM [--delete | TOKEN] [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " config initial-token --server SERVER --realm REALM [--delete | TOKEN] [ARGUMENTS]", exe.stdoutLines().get(0)); exe = execute("config registration-token"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " config registration-token --server SERVER --realm REALM --client CLIENT [--delete | TOKEN] [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " config registration-token --server SERVER --realm REALM --client CLIENT [--delete | TOKEN] [ARGUMENTS]", exe.stdoutLines().get(0)); exe = execute("config truststore"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " config truststore [TRUSTSTORE | --delete] [--trustpass PASSWOD] [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " config truststore [TRUSTSTORE | --delete] [--trustpass PASSWOD] [ARGUMENTS]", exe.stdoutLines().get(0)); exe = execute("create"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " create [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " create [ARGUMENTS]", exe.stdoutLines().get(0)); //Assert.assertEquals("error message", "No file nor attribute values specified", exe.stderrLines().get(0)); exe = execute("get"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " get CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " get CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); //Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); exe = execute("update"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " update CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " update CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); //Assert.assertEquals("error message", "No file nor attribute values specified", exe.stderrLines().get(0)); exe = execute("delete"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " delete CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " delete CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); //Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); exe = execute("attrs"); @@ -103,7 +102,7 @@ public class KcRegTest extends AbstractCliTest { exe = execute("update-token"); assertExitCodeAndStdErrSize(exe, 1, 0); Assert.assertTrue("help message returned", exe.stdoutLines().size() > 10); - Assert.assertEquals("help message", "Usage: " + OsUtil.CMD + " update-token CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("help message", "Usage: " + CMD + " update-token CLIENT [ARGUMENTS]", exe.stdoutLines().get(0)); //Assert.assertEquals("error message", "CLIENT not specified", exe.stderrLines().get(0)); exe = execute("help"); @@ -150,7 +149,7 @@ public class KcRegTest extends AbstractCliTest { exe = execute("config --help"); assertExitCodeAndStdErrSize(exe, 0, 0); - Assert.assertEquals("stdout first line", "Usage: " + OsUtil.CMD + " config SUB_COMMAND [ARGUMENTS]", exe.stdoutLines().get(0)); + Assert.assertEquals("stdout first line", "Usage: " + CMD + " config SUB_COMMAND [ARGUMENTS]", exe.stdoutLines().get(0)); exe = execute("config credentials --help"); assertExitCodeAndStdErrSize(exe, 0, 0); @@ -208,8 +207,9 @@ public class KcRegTest extends AbstractCliTest { KcRegExec exe = execute("get my_client --nonexistent"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("stderr first line", "Invalid option: --nonexistent", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help get' for more information", exe.stderrLines().get(1)); } @Test @@ -229,8 +229,9 @@ public class KcRegTest extends AbstractCliTest { */ KcRegExec exe = execute("config credentials --realm master --user admin --password admin"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("stderr first line", "Required option not specified: --server", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config credentials' for more information", exe.stderrLines().get(1)); } @Test @@ -240,8 +241,9 @@ public class KcRegTest extends AbstractCliTest { */ KcRegExec exe = execute("config credentials --server " + serverUrl + " --user admin --password admin"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("stderr first line", "Required option not specified: --realm", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config credentials' for more information", exe.stderrLines().get(1)); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java index 9a094f3888..e3f7729264 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegTruststoreTest.java @@ -4,13 +4,14 @@ import org.junit.Assert; import org.junit.Test; import org.keycloak.client.registration.cli.config.ConfigData; import org.keycloak.client.registration.cli.config.FileConfigHandler; -import org.keycloak.client.registration.cli.util.ConfigUtil; import org.keycloak.testsuite.cli.KcRegExec; import org.keycloak.testsuite.util.TempFileResource; import java.io.File; import java.io.IOException; +import static org.keycloak.client.registration.cli.util.ConfigUtil.DEFAULT_CONFIG_FILE_PATH; +import static org.keycloak.client.registration.cli.util.OsUtil.CMD; import static org.keycloak.client.registration.cli.util.OsUtil.EOL; import static org.keycloak.testsuite.cli.KcRegExec.execute; @@ -90,15 +91,17 @@ public class KcRegTruststoreTest extends AbstractCliTest { assertExitCodeAndStreamSizes(exe, 0, 0, 0); exe = execute("config truststore --delete '" + truststore.getAbsolutePath() + "'"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("incompatible", "Option --delete is mutually exclusive with specifying a TRUSTSTORE", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config truststore' for more information", exe.stderrLines().get(1)); exe = execute("config truststore --delete --trustpass secret"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("no truststore error", "Options --trustpass and --delete are mutually exclusive", exe.stderrLines().get(0)); + Assert.assertEquals("try help", "Try '" + CMD + " help config truststore' for more information", exe.stderrLines().get(1)); FileConfigHandler cfghandler = new FileConfigHandler(); - cfghandler.setConfigFile(ConfigUtil.DEFAULT_CONFIG_FILE_PATH); + cfghandler.setConfigFile(DEFAULT_CONFIG_FILE_PATH); ConfigData config = cfghandler.loadConfig(); Assert.assertNull("truststore null", config.getTruststore()); Assert.assertNull("trustpass null", config.getTrustpass()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegUpdateTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegUpdateTest.java index fba1806ff7..79e670793e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegUpdateTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/registration/KcRegUpdateTest.java @@ -12,6 +12,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Arrays; +import static org.keycloak.client.registration.cli.util.OsUtil.CMD; import static org.keycloak.testsuite.cli.KcRegExec.execute; /** @@ -90,9 +91,9 @@ public class KcRegUpdateTest extends AbstractCliTest { // check that using an invalid attribute key is not ignored exe = execute("update my_client --nonexisting --config '" + configFile.getName() + "'"); - assertExitCodeAndStreamSizes(exe, 1, 0, 1); + assertExitCodeAndStreamSizes(exe, 1, 0, 2); Assert.assertEquals("error message", "Unsupported option: --nonexisting", exe.stderrLines().get(0)); - + Assert.assertEquals("try help", "Try '" + CMD + " help update' for more information", exe.stderrLines().get(1)); // try use incompatible endpoint