Merge pull request #4747 from mstruk/KEYCLOAK-5741

KEYCLOAK-5741 [Admin CLI] Fix instructions in build-in help
This commit is contained in:
Bill Burke 2017-11-28 08:57:29 -05:00 committed by GitHub
commit 0a8995efc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 59 additions and 27 deletions

View file

@ -47,7 +47,7 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
@Option(name = "config", description = "Path to the config file (~/.keycloak/kcadm.config by default)") @Option(name = "config", description = "Path to the config file (~/.keycloak/kcadm.config by default)")
String config; String config;
@Option(name = "no-config", description = "No configuration file should be used, no authentication info should be saved", hasValue = false) @Option(name = "no-config", description = "Don't use config file - no authentication info is loaded or saved", hasValue = false)
boolean noconfig; boolean noconfig;
@Option(name = "server", description = "Server endpoint url (e.g. 'http://localhost:8080/auth')") @Option(name = "server", description = "Server endpoint url (e.g. 'http://localhost:8080/auth')")
@ -259,9 +259,12 @@ public abstract class AbstractAuthOptionsCmd extends AbstractGlobalOptionsCmd {
String value = options[++i]; String value = options[++i];
if (value != null) { if (value != null) {
throw new RuntimeException("Unsupported option: " + name); throw new IllegalArgumentException("Unsupported option: " + name);
} }
} }
} }
protected static String booleanOptionForCheck(boolean value) {
return value ? "true" : null;
}
} }

View file

@ -338,11 +338,12 @@ public class AddRolesCmd extends AbstractAuthOptionsCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" --uusername User's 'username'. If more than one user exists with the same username"); out.println(" --uusername User's 'username'. If more than one user exists with the same username");

View file

@ -83,6 +83,8 @@ public class ConfigCredentialsCmd extends AbstractAuthOptionsCmd {
return help ? CommandResult.SUCCESS : CommandResult.FAILURE; return help ? CommandResult.SUCCESS : CommandResult.FAILURE;
} }
checkUnsupportedOptions("--no-config", booleanOptionForCheck(noconfig));
processGlobalOptions(); processGlobalOptions();
return process(commandInvocation); return process(commandInvocation);

View file

@ -111,7 +111,8 @@ public class ConfigTruststoreCmd extends AbstractAuthOptionsCmd {
"--truststore", trustStore, "--truststore", trustStore,
"--keystore", keystore, "--keystore", keystore,
"--keypass", keyPass, "--keypass", keyPass,
"--alias", alias); "--alias", alias,
"--no-config", booleanOptionForCheck(noconfig));
// now update the config // now update the config
processGlobalOptions(); processGlobalOptions();

View file

@ -91,19 +91,20 @@ public class CreateCmd extends AbstractRequestCmd {
out.println(); out.println();
out.println("Command to create new resources on the server."); out.println("Command to create new resources on the server.");
out.println(); out.println();
out.println("Use `" + CMD + " config credentials` to establish an authenticated sessions, or use CREDENTIALS OPTIONS"); out.println("Use `" + CMD + " config credentials` to establish an authenticated sessions, or use --no-config with ");
out.println("to perform one time authentication."); out.println("CREDENTIALS OPTIONS to perform one time authentication.");
out.println(); out.println();
out.println("Arguments:"); out.println("Arguments:");
out.println(); out.println();
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values are:"); out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values are:");

View file

@ -66,11 +66,12 @@ public class DeleteCmd extends CreateCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values start with:"); out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values start with:");

View file

@ -98,11 +98,12 @@ public class GetCmd extends AbstractRequestCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values are:"); out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values are:");
@ -116,7 +117,6 @@ public class GetCmd extends AbstractRequestCmd {
out.println(" which some endpoints recognize"); out.println(" which some endpoints recognize");
out.println(); out.println();
out.println(" -H, --print-headers Print response headers"); out.println(" -H, --print-headers Print response headers");
out.println(" -o, --output After delete output any response to standard output");
out.println(" -F, --fields FILTER A filter pattern to specify which fields of a JSON response to output"); out.println(" -F, --fields FILTER A filter pattern to specify which fields of a JSON response to output");
out.println(" -c, --compressed Don't pretty print the output"); out.println(" -c, --compressed Don't pretty print the output");
out.println(" --format FORMAT Set output format to comma-separated-values by using 'csv'. Default format is 'json'"); out.println(" --format FORMAT Set output format to comma-separated-values by using 'csv'. Default format is 'json'");

View file

@ -342,11 +342,12 @@ public class GetRolesCmd extends GetCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" --uusername User's 'username'. If more than one user exists with the same username"); out.println(" --uusername User's 'username'. If more than one user exists with the same username");

View file

@ -167,7 +167,7 @@ public class NewObjectCmd extends AbstractGlobalOptionsCmd {
out.println(); out.println();
out.println("Command to compose JSON objects from attributes, and merge changes into existing JSON documents."); out.println("Command to compose JSON objects from attributes, and merge changes into existing JSON documents.");
out.println(); out.println();
out.println("This is a local command that does not perform any server requests. It's functionality is fully "); out.println("This is a local command that does not perform any server requests. Its functionality is fully ");
out.println("integrated into 'create', 'update' and 'delete' commands. It's supposed to be a helper tool only."); out.println("integrated into 'create', 'update' and 'delete' commands. It's supposed to be a helper tool only.");
out.println(); out.println();
out.println("Arguments:"); out.println("Arguments:");

View file

@ -338,11 +338,12 @@ public class RemoveRolesCmd extends AbstractAuthOptionsCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" --uusername User's 'username'. If more than one user exists with the same username"); out.println(" --uusername User's 'username'. If more than one user exists with the same username");

View file

@ -150,11 +150,12 @@ public class SetPasswordCmd extends AbstractAuthOptionsCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" --username USERNAME Identify target user by 'username'"); out.println(" --username USERNAME Identify target user by 'username'");

View file

@ -107,11 +107,12 @@ public class UpdateCmd extends AbstractRequestCmd {
out.println(" Global options:"); out.println(" Global options:");
out.println(" -x Print full stack trace when exiting with error"); out.println(" -x Print full stack trace when exiting with error");
out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)"); out.println(" --config Path to the config file (" + DEFAULT_CONFIG_FILE_STRING + " by default)");
out.println(" --no-config Don't use config file - no authentication info is loaded or saved");
out.println(" --truststore PATH Path to a truststore containing trusted certificates"); out.println(" --truststore PATH Path to a truststore containing trusted certificates");
out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)"); out.println(" --trustpass PASSWORD Truststore password (prompted for if not specified and --truststore is used)");
out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish"); out.println(" CREDENTIALS OPTIONS Same set of options as accepted by '" + CMD + " config credentials' in order to establish");
out.println(" an authenticated sessions. This allows on-the-fly transient authentication that does"); out.println(" an authenticated sessions. In combination with --no-config option this allows transient");
out.println(" not touch a config file."); out.println(" (on-the-fly) authentication to be performed which leaves no tokens in config file.");
out.println(); out.println();
out.println(" Command specific options:"); out.println(" Command specific options:");
out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values start with:"); out.println(" ENDPOINT_URI URI used to compose a target resource url. Commonly used values start with:");

View file

@ -258,6 +258,18 @@ public class KcAdmTest extends AbstractAdmCliTest {
Assert.assertEquals("try help", "Try '" + CMD + " help config credentials' for more information", exe.stderrLines().get(1)); Assert.assertEquals("try help", "Try '" + CMD + " help config credentials' for more information", exe.stderrLines().get(1));
} }
@Test
public void testCredentialsWithNoConfig() {
/*
* Test with --no-config specified which is not supported
*/
KcAdmExec exe = KcAdmExec.execute("config credentials --no-config --server " + serverUrl + " --realm master --user admin --password admin");
assertExitCodeAndStreamSizes(exe, 1, 0, 2);
Assert.assertEquals("stderr first line", "Unsupported option: --no-config", exe.stderrLines().get(0));
Assert.assertEquals("try help", "Try '" + CMD + " help config credentials' for more information", exe.stderrLines().get(1));
}
@Test @Test
public void testUserLoginWithDefaultConfig() { public void testUserLoginWithDefaultConfig() {
/* /*

View file

@ -4,6 +4,7 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.keycloak.client.admin.cli.config.ConfigData; import org.keycloak.client.admin.cli.config.ConfigData;
import org.keycloak.client.admin.cli.config.FileConfigHandler; import org.keycloak.client.admin.cli.config.FileConfigHandler;
import org.keycloak.client.admin.cli.util.OsUtil;
import org.keycloak.testsuite.cli.KcAdmExec; import org.keycloak.testsuite.cli.KcAdmExec;
import org.keycloak.testsuite.util.TempFileResource; import org.keycloak.testsuite.util.TempFileResource;
@ -23,21 +24,27 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
@Test @Test
public void testTruststore() throws IOException { public void testTruststore() throws IOException {
File truststore = new File("src/test/resources/keystore/keycloak.truststore");
KcAdmExec exe = execute("config truststore --no-config '" + truststore.getAbsolutePath() + "'");
assertExitCodeAndStreamSizes(exe, 1, 0, 2);
Assert.assertEquals("stderr first line", "Unsupported option: --no-config", exe.stderrLines().get(0));
Assert.assertEquals("try help", "Try '" + OsUtil.CMD + " help config truststore' for more information", exe.stderrLines().get(1));
// only run this test if ssl protected keycloak server is available // only run this test if ssl protected keycloak server is available
if (!isAuthServerSSL()) { if (!isAuthServerSSL()) {
System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'"); System.out.println("TEST SKIPPED - This test requires HTTPS. Run with '-Pauth-server-wildfly -Dauth.server.ssl.required=true'");
return; return;
} }
File truststore = new File("src/test/resources/keystore/keycloak.truststore");
FileConfigHandler handler = initCustomConfigFile(); FileConfigHandler handler = initCustomConfigFile();
try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) { try (TempFileResource configFile = new TempFileResource(handler.getConfigFile())) {
if (runIntermittentlyFailingTests()) { if (runIntermittentlyFailingTests()) {
// configure truststore // configure truststore
KcAdmExec exe = execute("config truststore --config '" + configFile.getName() + "' '" + truststore.getAbsolutePath() + "'"); exe = execute("config truststore --config '" + configFile.getName() + "' '" + truststore.getAbsolutePath() + "'");
assertExitCodeAndStreamSizes(exe, 0, 0, 0); assertExitCodeAndStreamSizes(exe, 0, 0, 0);
@ -80,7 +87,7 @@ public class KcAdmTruststoreTest extends AbstractAdmCliTest {
} }
// configure truststore with password // configure truststore with password
KcAdmExec exe = execute("config truststore --trustpass secret '" + truststore.getAbsolutePath() + "'"); exe = execute("config truststore --trustpass secret '" + truststore.getAbsolutePath() + "'");
assertExitCodeAndStreamSizes(exe, 0, 0, 0); assertExitCodeAndStreamSizes(exe, 0, 0, 0);
// perform authentication against server - asks for password, then for truststore password // perform authentication against server - asks for password, then for truststore password