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 a89a4f32ee..daf57f25d9 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 @@ -19,8 +19,16 @@ package org.keycloak.client.admin.cli.commands; import org.keycloak.client.admin.cli.KcAdmMain; import org.keycloak.client.cli.common.BaseConfigCredentialsCmd; +import org.keycloak.client.cli.config.ConfigData; +import picocli.CommandLine; import picocli.CommandLine.Command; +import static java.lang.System.currentTimeMillis; +import static org.keycloak.client.cli.util.AuthUtil.AUTH_BUFFER_TIME; +import static org.keycloak.client.cli.util.ConfigUtil.credentialsAvailable; +import static org.keycloak.client.cli.util.ConfigUtil.loadConfig; +import static org.keycloak.client.cli.util.IoUtil.printOut; + /** * @author Marko Strukelj @@ -32,4 +40,26 @@ public class ConfigCredentialsCmd extends BaseConfigCredentialsCmd { super(KcAdmMain.COMMAND_STATE); } + @CommandLine.Option(names = "--status", description = "Validity of the connection with server") + boolean status; + + @Override + protected boolean nothingToDo() { + return super.nothingToDo() && !status; + } + + @Override + public void process() { + if (status) { + ConfigData config = loadConfig(); + long now = currentTimeMillis(); + if (credentialsAvailable(config) && now + AUTH_BUFFER_TIME < config.sessionRealmConfigData().getExpiresAt()) { + printOut("Logged in (server: " + config.getServerUrl() + ", realm: " + config.getRealm() + ", expired: false, timeToExpiry: " + (config.sessionRealmConfigData().getExpiresAt() - now) / 1000 + "s from now)"); + } else { + printOut("You are not logged in"); + } + } else { + super.process(); + } + } } diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/BaseConfigCredentialsCmd.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/BaseConfigCredentialsCmd.java index 63d9b14367..6cf9fba900 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/BaseConfigCredentialsCmd.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/BaseConfigCredentialsCmd.java @@ -138,7 +138,7 @@ public class BaseConfigCredentialsCmd extends BaseAuthOptionsCmd { if (keyPass == null) { keyPass = System.getenv("KC_CLI_KEY_PASSWORD"); } - + if (storePass == null) { storePass = readPasswordFromConsole("keystore password"); if (keyPass == null) { @@ -192,6 +192,7 @@ public class BaseConfigCredentialsCmd extends BaseAuthOptionsCmd { out.println(" " + getCommand() + " config credentials --server SERVER_URL --realm REALM --user USER [--password PASSWORD] [ARGUMENTS]"); out.println(" " + getCommand() + " config credentials --server SERVER_URL --realm REALM --client CLIENT_ID [--secret SECRET] [ARGUMENTS]"); out.println(" " + getCommand() + " config credentials --server SERVER_URL --realm REALM --client CLIENT_ID [--keystore KEYSTORE] [ARGUMENTS]"); + out.println(" " + getCommand() + " config credentials --status"); out.println(); out.println("Command to establish an authenticated client session with the server. There are many authentication"); out.println("options available, and it depends on server side client authentication configuration how client can or should authenticate."); @@ -201,6 +202,8 @@ public class BaseConfigCredentialsCmd extends BaseAuthOptionsCmd { out.println("If confidential client authentication is also configured, you may have to specify a client id, and client credentials in addition to"); out.println("user credentials. Client credentials are either a client secret, or a keystore information to use Signed JWT mechanism."); out.println("If only client credentials are provided, and no user credentials, then the service account is used for login."); + out.println("If validity of the authentication needs to be checked use the --status option. This would only check the status of the existing config and does not update the config."); + out.println("Other arguments which are passed along with status are ignored"); out.println(); out.println("Arguments:"); out.println(); @@ -222,6 +225,7 @@ public class BaseConfigCredentialsCmd extends BaseAuthOptionsCmd { out.println(" --keypass PASSWORD Key password (prompted for if not specified, --keystore is used without --storepass, and KC_CLI_KEY_PASSWORD"); out.println(" otherwise defaults to keystore password)"); out.println(" --alias ALIAS Alias of the key inside a keystore (defaults to the value of ClientId)"); + out.println(" --status Checks the validity of the existing connection (Note: It does not update the config)"); out.println(); out.println(); out.println("Examples:"); diff --git a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/AuthUtil.java b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/AuthUtil.java index f5a777aeb9..937149cfc0 100644 --- a/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/AuthUtil.java +++ b/integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/util/AuthUtil.java @@ -45,6 +45,8 @@ import static org.keycloak.client.cli.util.HttpUtil.urlencode; */ public class AuthUtil { + public static final int AUTH_BUFFER_TIME = 5000; + public static String ensureToken(ConfigData config, String cmd) { if (config.getExternalToken() != null) { return config.getExternalToken(); @@ -58,15 +60,15 @@ public class AuthUtil { // check expires of access_token against time // if it's less than 5s to expiry, renew it - if (realmConfig.getExpiresAt() - now < 5000) { + if (realmConfig.getExpiresAt() - now < AUTH_BUFFER_TIME) { // check refresh_token against expiry time // if it's less than 5s to expiry, fail with credentials expired - if (realmConfig.getRefreshExpiresAt() != null && realmConfig.getRefreshExpiresAt() - now < 5000) { + if (realmConfig.getRefreshExpiresAt() != null && realmConfig.getRefreshExpiresAt() - now < AUTH_BUFFER_TIME) { throw new RuntimeException("Session has expired. Login again with '" + cmd + " config credentials'"); } - if (realmConfig.getSigExpiresAt() != null && realmConfig.getSigExpiresAt() - now < 5000) { + if (realmConfig.getSigExpiresAt() != null && realmConfig.getSigExpiresAt() - now < AUTH_BUFFER_TIME) { throw new RuntimeException("Session has expired. Login again with '" + cmd + " config credentials'"); }