From 92065179fa4f7afab3f161ba2efac61f2bf60cc0 Mon Sep 17 00:00:00 2001 From: Chris Robison Date: Thu, 15 Aug 2019 08:44:43 -0600 Subject: [PATCH 1/7] Adding per profile override feature --- Readme.MD | 7 ++- .../java/com/okta/tools/OktaAwsConfig.java | 53 +++++++++++++------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/Readme.MD b/Readme.MD index c32e8ac..a75be46 100644 --- a/Readme.MD +++ b/Readme.MD @@ -162,7 +162,12 @@ Here is the list of parameters that can be environment variables or settings in - Your link is located under ```EMBED LINK``` - Replace the example values in ```~/.okta/config.properties``` with your values -Note: environment variables take precedence over the config file. +You can specify configuration overrides for each profile by creating a ```~/.okta/config.{profilename}.properties``` file. The base settings +will be loaded first and the profile-specific settings will be loaded after, allowing you to only override specific settings that need to be different. +For example, if you want the ```prod``` profile to connect to a different Okta org, create a ```~/.okta/config.prod.properties```file and set +```OKTA_ORG``` to something different. + +Note: environment variables take precedence over any config file. ## Troubleshooting diff --git a/src/main/java/com/okta/tools/OktaAwsConfig.java b/src/main/java/com/okta/tools/OktaAwsConfig.java index 532da98..4b25401 100644 --- a/src/main/java/com/okta/tools/OktaAwsConfig.java +++ b/src/main/java/com/okta/tools/OktaAwsConfig.java @@ -15,12 +15,14 @@ */ package com.okta.tools; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Optional; import java.util.Properties; import java.util.logging.Logger; @@ -31,20 +33,23 @@ final class OktaAwsConfig { private static final Logger logger = Logger.getLogger(OktaAwsConfig.class.getName()); private static final String CONFIG_FILENAME = "config.properties"; + private static final String CONFIG_PROFILE_FILENAME_FORMAT = "config.%s.properties"; static OktaAwsCliEnvironment loadEnvironment() { - return loadEnvironment(null); + return loadEnvironment(System.getenv("OKTA_PROFILE")); } static OktaAwsCliEnvironment loadEnvironment(String profile) { Properties properties = new Properties(); - Optional path = getConfigFile(); - if (path.isPresent()) { - try (InputStream config = new FileInputStream(path.get().toFile())) { - logger.finer(() -> "Reading config settings from file: " + path.get().toAbsolutePath().toString()); - properties.load(new InputStreamReader(config)); - } catch (IOException e) { - throw new IllegalStateException(e); + Optional> paths = getConfigFile(profile); + if (paths.isPresent()) { + for (Path path : paths.get()) { + try (InputStream config = new FileInputStream(path.toFile())) { + logger.finer(() -> "Reading config settings from file: " + path.toAbsolutePath().toString()); + properties.load(new InputStreamReader(config)); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } else { try (InputStream config = properties.getClass().getResourceAsStream("/config.properties")) { @@ -108,17 +113,31 @@ private static String getOutput(Process process) throws IOException { } } - private static Optional getConfigFile() { - Path configInWorkingDir = Paths.get(CONFIG_FILENAME); - if (configInWorkingDir.toFile().isFile()) { - return Optional.of(configInWorkingDir); + private static Optional> getConfigFile(String profile) { + ArrayList configFiles = new ArrayList<>(); + configFiles.add(CONFIG_FILENAME); + if (StringUtils.isNotBlank(profile)) { + configFiles.add(String.format(CONFIG_PROFILE_FILENAME_FORMAT, profile)); + } + + ArrayList paths = new ArrayList<>(); + for (String configFile : configFiles) { + Path configInWorkingDir = Paths.get(configFile); + if (configInWorkingDir.toFile().isFile()) { + paths.add(configInWorkingDir); + } + Path userHome = Paths.get(System.getProperty("user.home")); + Path oktaDir = userHome.resolve(".okta"); + Path configInOktaDir = oktaDir.resolve(configFile); + if (configInOktaDir.toFile().isFile()) { + paths.add(configInOktaDir); + } } - Path userHome = Paths.get(System.getProperty("user.home")); - Path oktaDir = userHome.resolve(".okta"); - Path configInOktaDir = oktaDir.resolve(CONFIG_FILENAME); - if (configInOktaDir.toFile().isFile()) { - return Optional.of(configInOktaDir); + + if (!paths.isEmpty()) { + return Optional.of(paths); } + return Optional.empty(); } From 0187368fbecbb3d329cb5f28db7f802e2e89b272 Mon Sep 17 00:00:00 2001 From: John Hammerlund Date: Thu, 15 Aug 2019 10:54:14 -0700 Subject: [PATCH 2/7] Fix Okta Push polling exception A v2.0 code refactor / cleanup broke a few JSON traversals needed to support Okta MFA - Push. This reverts some of the broken logic. Fixes #316 --- .../okta/tools/authentication/OktaMFA.java | 31 ++++++++++++++----- .../com/okta/tools/helpers/HttpHelper.java | 2 ++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/okta/tools/authentication/OktaMFA.java b/src/main/java/com/okta/tools/authentication/OktaMFA.java index b959b2a..946278f 100644 --- a/src/main/java/com/okta/tools/authentication/OktaMFA.java +++ b/src/main/java/com/okta/tools/authentication/OktaMFA.java @@ -289,9 +289,7 @@ private static String verifyAnswer(String answer, JSONObject factor, String stat } private static String handlePushPolling(JSONObject profile, JSONObject jsonObjResponse) throws IOException, InterruptedException { - JSONObject links = jsonObjResponse.getJSONObject(LINKS); - JSONObject pollLink = links.getJSONObject("poll"); - String pollUrl = pollLink.getString("href"); + String pollUrl = getPollURL(jsonObjResponse); JSONObject pollResult = postAndGetJsonResponse(profile, pollUrl); String result = pollResult.getString(FACTOR_RESULT); @@ -299,13 +297,32 @@ private static String handlePushPolling(JSONObject profile, JSONObject jsonObjRe System.err.println("Waiting for you to approve the Okta push notification on your device..."); Thread.sleep(500); pollResult = postAndGetJsonResponse(profile, pollUrl); + String status = pollResult.getString(STATUS); + if ("SUCCESS".equals(status)) { + return pollResult.getString(SESSION_TOKEN); + } result = pollResult.getString(FACTOR_RESULT); } - if ("SUCCESS".equals(result)) { - return pollResult.getString(SESSION_TOKEN); - } else { - return result; + return result; + } + + private static String getPollURL(JSONObject jsonObjResponse) throws RuntimeException { + JSONObject linksObj = jsonObjResponse.getJSONObject(LINKS); + JSONArray linkNames = linksObj.names(); + JSONArray links = linksObj.toJSONArray(linkNames); + JSONObject pollLink = null; + for (int i = 0; i < links.length(); i++) { + JSONObject link = links.getJSONObject(i); + String linkName = link.getString("name"); + if (linkName.equals("poll")) { + pollLink = link; + break; + } + } + if (pollLink == null) { + throw new IllegalStateException("Could not determine URL for MFA polling"); } + return pollLink.getString("href"); } private static JSONObject postAndGetJsonResponse(JSONObject profile, String url) throws IOException { diff --git a/src/main/java/com/okta/tools/helpers/HttpHelper.java b/src/main/java/com/okta/tools/helpers/HttpHelper.java index 2dd1373..817f463 100644 --- a/src/main/java/com/okta/tools/helpers/HttpHelper.java +++ b/src/main/java/com/okta/tools/helpers/HttpHelper.java @@ -15,7 +15,9 @@ */ package com.okta.tools.helpers; +import com.amazonaws.RequestConfig; import org.apache.http.HttpHost; +import org.apache.http.client.config.CookieSpecs; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; From 33f061968e9d2b72eddce6b872ee0b4b7a3a2b27 Mon Sep 17 00:00:00 2001 From: John Hammerlund Date: Thu, 15 Aug 2019 11:00:13 -0700 Subject: [PATCH 3/7] Revert unnecessary change --- src/main/java/com/okta/tools/helpers/HttpHelper.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/okta/tools/helpers/HttpHelper.java b/src/main/java/com/okta/tools/helpers/HttpHelper.java index 817f463..2dd1373 100644 --- a/src/main/java/com/okta/tools/helpers/HttpHelper.java +++ b/src/main/java/com/okta/tools/helpers/HttpHelper.java @@ -15,9 +15,7 @@ */ package com.okta.tools.helpers; -import com.amazonaws.RequestConfig; import org.apache.http.HttpHost; -import org.apache.http.client.config.CookieSpecs; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; From 6f3208191ee541864762b13cf991a40c5b39ece8 Mon Sep 17 00:00:00 2001 From: Jeremy Plichta Date: Wed, 21 Aug 2019 20:58:37 -0600 Subject: [PATCH 4/7] fix problem where web browser auth goes to aws console page and never returns if only one role is available to the user. --- .../com/okta/tools/authentication/BrowserAuthentication.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/okta/tools/authentication/BrowserAuthentication.java b/src/main/java/com/okta/tools/authentication/BrowserAuthentication.java index 1fbe412..fc88b45 100644 --- a/src/main/java/com/okta/tools/authentication/BrowserAuthentication.java +++ b/src/main/java/com/okta/tools/authentication/BrowserAuthentication.java @@ -80,8 +80,8 @@ public void start(final Stage stage) throws IOException { initializeCookies(uri); SubresourceIntegrityStrippingHack.overrideHttpsProtocolHandler(environment); - webEngine.getLoadWorker().stateProperty() - .addListener((ov, oldState, newState) -> { + webEngine.locationProperty() + .addListener((ov, oldLocation, newLocation) -> { if (webEngine.getDocument() != null) { checkForAwsSamlSignon(stage, webEngine); stage.setTitle(webEngine.getLocation()); From 13364f87b620cf9dc514710b61332be18774cc4e Mon Sep 17 00:00:00 2001 From: Jeremy Plichta Date: Wed, 21 Aug 2019 21:20:23 -0600 Subject: [PATCH 5/7] 2.0.4 release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ef90a20..a962ecc 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ com.okta.developer okta-aws-cli - 2.0.4-SNAPSHOT + 2.0.4 jar From 9b5fc268f851d0a1c362407dc227ef3622cd0297 Mon Sep 17 00:00:00 2001 From: Jeremy Plichta Date: Wed, 21 Aug 2019 21:21:41 -0600 Subject: [PATCH 6/7] prepare for next dev version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a962ecc..02ec03c 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ com.okta.developer okta-aws-cli - 2.0.4 + 2.0.5-SNAPSHOT jar From 3d2ee2e7852b78985adfc5a500a33a9a4186ea10 Mon Sep 17 00:00:00 2001 From: Sam Mingo Date: Thu, 29 Aug 2019 21:41:41 -0400 Subject: [PATCH 7/7] Update install.sh Makes $PREFIX used correctly throughout heredocs --- bin/install.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/bin/install.sh b/bin/install.sh index 15864ec..5e53b0a 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -130,37 +130,37 @@ EOF mkdir -p "${PREFIX}/bin" # Create withokta command -cat <<'EOF' >"${PREFIX}/bin/withokta" +cat <"${PREFIX}/bin/withokta" #!/bin/bash -command="$1" -profile=$2 +command="\$1" +profile=\$2 shift; shift; -if [ "$3" == "logout" ] +if [ "\$3" == "logout" ] then command="logout" fi -env OKTA_PROFILE=$profile java \ - -Djava.util.logging.config.file=~/.okta/logging.properties \ - -classpath ~/.okta/okta-aws-cli.jar \ - com.okta.tools.WithOkta $command "$@" +env OKTA_PROFILE=\$profile java \ + -Djava.util.logging.config.file=${PREFIX}/logging.properties \ + -classpath ${PREFIX}/okta-aws-cli.jar \ + com.okta.tools.WithOkta \$command "\$@" EOF chmod +x "${PREFIX}/bin/withokta" # Create okta-credential_process command -cat <<'EOF' >"${PREFIX}/bin/okta-credential_process" +cat <"${PREFIX}/bin/okta-credential_process" #!/bin/bash -roleARN="$1" +roleARN="\$1" shift; -env OKTA_AWS_ROLE_TO_ASSUME="$roleARN" \ - java -classpath ~/.okta/okta-aws-cli.jar com.okta.tools.CredentialProcess +env OKTA_AWS_ROLE_TO_ASSUME="\$roleARN" \ + java -classpath ${PREFIX}/okta-aws-cli.jar com.okta.tools.CredentialProcess EOF chmod +x "${PREFIX}/bin/okta-credential_process" # Create okta-listroles command cat <"${PREFIX}/bin/okta-listroles" #!/bin/bash -java -classpath ~/.okta/okta-aws-cli.jar com.okta.tools.ListRoles +java -classpath ${PREFIX}/okta-aws-cli.jar com.okta.tools.ListRoles EOF chmod +x "${PREFIX}/bin/okta-listroles" @@ -182,7 +182,7 @@ else #OktaAWSCLI OKTA_ORG=acmecorp.okta.com.changeme.local OKTA_AWS_APP_URL=https://acmecorp.oktapreview.com.changeme.local/home/amazon_aws/0oa5zrwfs815KJmVF0h7/137 -OKTA_USERNAME=$env:USERNAME +OKTA_USERNAME=\$env:USERNAME OKTA_BROWSER_AUTH=true EOF fi