input = [
+ "test-first",
+ "test-last",
+ "test-email@example.com",
+ "test co",
+ "123456",
+ "654321"
+ ]
+
+ def result = new CommandRunner(mockWebServer.url("/").toString()).runCommandWithInput(input, "register")
+ assertThat result, resultMatches(0, allOf(containsString("An email has been sent to you with a verification code."), containsString("Verification code")), emptyString())
RecordedRequest request = mockWebServer.takeRequest()
assertThat request.getRequestLine(), equalTo("POST /create HTTP/1.1")
diff --git a/integration-tests/src/test/groovy/com/okta/cli/test/RestoreEnvironmentVariables.java b/integration-tests/src/test/groovy/com/okta/cli/test/RestoreEnvironmentVariables.java
new file mode 100644
index 00000000..368e4c48
--- /dev/null
+++ b/integration-tests/src/test/groovy/com/okta/cli/test/RestoreEnvironmentVariables.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017 Okta
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.okta.cli.test;
+
+import org.testng.IInvokedMethod;
+import org.testng.IInvokedMethodListener;
+import org.testng.ITestResult;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TestNG Listener that will restore environment variables after test methods.
+ * All changes to environment variables are reverted after the test.
+ *
+ * public class EnvironmentVariablesTest {
+ * @Test
+ * public void test() {
+ * setEnvironmentVariable("name", "value");
+ * assertEquals("value", System.getenv("name"));
+ * }
+ * }
+ *
+ * Warning: This rule uses reflection for modifying internals of the
+ * environment variables map. It fails if your {@code SecurityManager} forbids
+ * such modifications.
+ *
+ * Based on: https://github.com/stefanbirkner/system-rules/blob/master/src/main/java/org/junit/contrib/java/lang/system/EnvironmentVariables.java
+ */
+public class RestoreEnvironmentVariables implements IInvokedMethodListener {
+
+ private Map originalVariables;
+
+ @Override
+ public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
+ saveValues();
+ }
+
+ @Override
+ public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
+ restoreOriginalVariables();
+ }
+
+ public void saveValues() {
+ originalVariables = new HashMap<>(System.getenv());
+ }
+
+ public void restoreOriginalVariables() {
+ restoreVariables(getEditableMapOfVariables());
+ Map theCaseInsensitiveEnvironment
+ = getTheCaseInsensitiveEnvironment();
+ if (theCaseInsensitiveEnvironment != null)
+ restoreVariables(theCaseInsensitiveEnvironment);
+ }
+
+ void restoreVariables(Map variables) {
+ variables.clear();
+ variables.putAll(originalVariables);
+ }
+
+ /**
+ * Set the value of an environment variable. You can delete an environment
+ * variable by setting it to {@code null}.
+ *
+ * @param name the environment variable's name.
+ * @param value the environment variable's new value.
+ */
+ public static void setEnvironmentVariable(String name, String value) {
+ set(getEditableMapOfVariables(), name, value);
+ set(getTheCaseInsensitiveEnvironment(), name, value);
+ }
+
+ /**
+ * Clears all environment variables.
+ */
+ public static void clearEnvironmentVariables() {
+ getEditableMapOfVariables().clear();
+ }
+
+ private static void set(Map variables, String name, String value) {
+ if (variables != null) //theCaseInsensitiveEnvironment may be null
+ if (value == null)
+ variables.remove(name);
+ else
+ variables.put(name, value);
+ }
+
+ private static Map getEditableMapOfVariables() {
+ Class> classOfMap = System.getenv().getClass();
+ try {
+ return getFieldValue(classOfMap, System.getenv(), "m");
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("System Rules cannot access the field"
+ + " 'm' of the map System.getenv().", e);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException("System Rules expects System.getenv() to"
+ + " have a field 'm' but it has not.", e);
+ }
+ }
+
+ /*
+ * The names of environment variables are case-insensitive in Windows.
+ * Therefore it stores the variables in a TreeMap named
+ * theCaseInsensitiveEnvironment.
+ */
+ private static Map getTheCaseInsensitiveEnvironment() {
+ try {
+ Class> processEnvironment = Class.forName("java.lang.ProcessEnvironment");
+ return getFieldValue(
+ processEnvironment, null, "theCaseInsensitiveEnvironment");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("System Rules expects the existence of"
+ + " the class java.lang.ProcessEnvironment but it does not"
+ + " exist.", e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("System Rules cannot access the static"
+ + " field 'theCaseInsensitiveEnvironment' of the class"
+ + " java.lang.ProcessEnvironment.", e);
+ } catch (NoSuchFieldException e) {
+ //this field is only available for Windows
+ return null;
+ }
+ }
+
+ private static Map getFieldValue(Class> klass,
+ Object object, String name)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field field = klass.getDeclaredField(name);
+ field.setAccessible(true);
+ return (Map) field.get(object);
+ }
+}
diff --git a/integration-tests/src/test/groovy/com/okta/cli/test/RestoreSystemProperties.java b/integration-tests/src/test/groovy/com/okta/cli/test/RestoreSystemProperties.java
new file mode 100644
index 00000000..3777a661
--- /dev/null
+++ b/integration-tests/src/test/groovy/com/okta/cli/test/RestoreSystemProperties.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 Okta
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.okta.cli.test;
+
+import org.testng.IInvokedMethod;
+import org.testng.IInvokedMethodListener;
+import org.testng.ITestResult;
+
+import java.util.Properties;
+
+/**
+ * TestNG Listener that will restore System properties after test methods.
+ *
+ * Based on: https://github.com/stefanbirkner/system-rules/blob/master/src/main/java/org/junit/contrib/java/lang/system/RestoreSystemProperties.java
+ */
+public class RestoreSystemProperties implements IInvokedMethodListener {
+
+ private Properties originalProperties;
+
+ @Override
+ public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
+ saveValues();
+ }
+
+ public void saveValues() {
+ originalProperties = System.getProperties();
+ System.setProperties(copyOf(originalProperties));
+ }
+
+ @Override
+ public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
+ restoreOriginalVariables();
+ }
+
+ public void restoreOriginalVariables() {
+ System.setProperties(originalProperties);
+ }
+
+ private Properties copyOf(Properties source) {
+ Properties copy = new Properties();
+ copy.putAll(source);
+ return copy;
+ }
+}
diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml
index 3b8bca03..d3d2f457 100755
--- a/maven-plugin/pom.xml
+++ b/maven-plugin/pom.xml
@@ -21,7 +21,7 @@
com.okta.cli
okta-cli-tools
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
com.okta
diff --git a/maven-plugin/src/main/java/com/okta/maven/orgcreation/RegisterMojo.java b/maven-plugin/src/main/java/com/okta/maven/orgcreation/RegisterMojo.java
index 3f5181ee..c2e1daeb 100644
--- a/maven-plugin/src/main/java/com/okta/maven/orgcreation/RegisterMojo.java
+++ b/maven-plugin/src/main/java/com/okta/maven/orgcreation/RegisterMojo.java
@@ -15,6 +15,7 @@
*/
package com.okta.maven.orgcreation;
+import com.okta.cli.common.model.OrganizationResponse;
import com.okta.maven.orgcreation.service.DefaultMavenRegistrationService;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -76,7 +77,8 @@ public class RegisterMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
- new DefaultMavenRegistrationService(prompter, oktaPropsFile, demo, interactiveMode)
- .register(firstName, lastName, email, company);
+ DefaultMavenRegistrationService registrationService = new DefaultMavenRegistrationService(prompter, oktaPropsFile, demo, interactiveMode);
+ OrganizationResponse response = registrationService.register(firstName, lastName, email, company);
+ registrationService.verify(response.getId(), null);
}
}
diff --git a/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/DefaultMavenRegistrationService.java b/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/DefaultMavenRegistrationService.java
index efada62e..7ac3b955 100644
--- a/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/DefaultMavenRegistrationService.java
+++ b/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/DefaultMavenRegistrationService.java
@@ -16,9 +16,13 @@
package com.okta.maven.orgcreation.service;
import com.okta.cli.common.model.OrganizationRequest;
+import com.okta.cli.common.model.OrganizationResponse;
+import com.okta.cli.common.model.RegistrationQuestions;
import com.okta.cli.common.service.ClientConfigurationException;
import com.okta.cli.common.service.DefaultSetupService;
import com.okta.cli.common.service.SetupService;
+import lombok.Data;
+import lombok.experimental.Accessors;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.components.interactivity.Prompter;
@@ -26,6 +30,7 @@
import java.io.IOException;
import static com.okta.maven.orgcreation.support.PromptUtil.promptIfNull;
+import static com.okta.maven.orgcreation.support.PromptUtil.promptYesNo;
public class DefaultMavenRegistrationService implements MavenRegistrationService {
@@ -42,13 +47,30 @@ public DefaultMavenRegistrationService(Prompter prompter, File oktaPropsFile, bo
}
@Override
- public void register(String firstName, String lastName, String email, String company) throws MojoExecutionException {
+ public OrganizationResponse register(String firstName, String lastName, String email, String company) throws MojoExecutionException {
try {
SetupService setupService = new DefaultSetupService(null);
- setupService.createOktaOrg(() -> organizationRequest(firstName, lastName, email, company),
- oktaPropsFile,
- demo,
- interactive);
+ RegistrationQuestions registrationQuestions = new MavenPromptingRegistrationQuestions()
+ .setFirstName(firstName)
+ .setLastName(lastName)
+ .setEmail(email)
+ .setCompany(company);
+ return setupService.createOktaOrg(registrationQuestions,
+ oktaPropsFile,
+ demo,
+ interactive);
+ } catch (IOException | ClientConfigurationException e) {
+ throw new MojoExecutionException("Failed to register account: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void verify(String identifier, String code) throws MojoExecutionException {
+ try {
+ SetupService setupService = new DefaultSetupService(null);
+ RegistrationQuestions registrationQuestions = new MavenPromptingRegistrationQuestions()
+ .setCode(code);
+ setupService.verifyOktaOrg(identifier, registrationQuestions, oktaPropsFile);
} catch (IOException | ClientConfigurationException e) {
throw new MojoExecutionException("Failed to register account: " + e.getMessage(), e);
}
@@ -61,4 +83,41 @@ private OrganizationRequest organizationRequest(String firstName, String lastNam
.setEmail(promptIfNull(prompter, interactive, email, "email", "Email address"))
.setOrganization(promptIfNull(prompter, interactive, company, "company", "Company"));
}
+
+ private String codePrompt(String code) {
+ return promptIfNull(prompter, interactive, code, "code", "Verification Code");
+ }
+
+ private boolean overwritePrompt(Boolean overwrite) {
+ return promptYesNo(prompter, interactive, overwrite, "overwriteConfig", "Overwrite configuration file?");
+ }
+
+ @Data
+ @Accessors(chain = true)
+ private class MavenPromptingRegistrationQuestions implements RegistrationQuestions {
+
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String company;
+
+ private String code;
+
+ private Boolean overwriteConfig;
+
+ @Override
+ public boolean isOverwriteConfig() {
+ return overwritePrompt(overwriteConfig);
+ }
+
+ @Override
+ public OrganizationRequest getOrganizationRequest() {
+ return organizationRequest(firstName, lastName, email, company);
+ }
+
+ @Override
+ public String getVerificationCode() {
+ return codePrompt(code);
+ }
+ }
}
diff --git a/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/MavenRegistrationService.java b/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/MavenRegistrationService.java
index 670b2493..31f691c6 100644
--- a/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/MavenRegistrationService.java
+++ b/maven-plugin/src/main/java/com/okta/maven/orgcreation/service/MavenRegistrationService.java
@@ -15,9 +15,12 @@
*/
package com.okta.maven.orgcreation.service;
+import com.okta.cli.common.model.OrganizationResponse;
import org.apache.maven.plugin.MojoExecutionException;
public interface MavenRegistrationService {
- void register(String firstName, String lastName, String email, String company) throws MojoExecutionException;
+ OrganizationResponse register(String firstName, String lastName, String email, String company) throws MojoExecutionException;
+
+ void verify(String identifier, String code) throws MojoExecutionException;
}
diff --git a/maven-plugin/src/main/java/com/okta/maven/orgcreation/support/PromptUtil.java b/maven-plugin/src/main/java/com/okta/maven/orgcreation/support/PromptUtil.java
index 0ee29700..58899c14 100644
--- a/maven-plugin/src/main/java/com/okta/maven/orgcreation/support/PromptUtil.java
+++ b/maven-plugin/src/main/java/com/okta/maven/orgcreation/support/PromptUtil.java
@@ -19,6 +19,9 @@
import org.codehaus.plexus.components.interactivity.PrompterException;
import org.codehaus.plexus.util.StringUtils;
+import java.util.ArrayList;
+import java.util.List;
+
public final class PromptUtil {
private PromptUtil() {}
@@ -43,4 +46,27 @@ public static String promptIfNull(Prompter prompter, boolean interactive, String
}
return value;
}
+
+ public static boolean promptYesNo(Prompter prompter, boolean interactive, Boolean currentValue, String keyName, String promptText) {
+
+ Boolean value = currentValue;
+
+ if (value == null) {
+ if (interactive) {
+ try {
+ List options = new ArrayList<>();
+ options.add("Yes");
+ options.add("No");
+ value = options.get(0).equals(prompter.prompt(promptText, options, options.get(0)));
+ }
+ catch (PrompterException e) {
+ throw new RuntimeException( e.getMessage(), e );
+ }
+ } else {
+ throw new IllegalArgumentException( "You must specify the '" + keyName + "' property either on the command line " +
+ "-D" + keyName + "=... or run in interactive mode" );
+ }
+ }
+ return value;
+ }
}
diff --git a/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/RegisterMojoTest.groovy b/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/RegisterMojoTest.groovy
index 1d125b8e..d6d91cd1 100644
--- a/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/RegisterMojoTest.groovy
+++ b/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/RegisterMojoTest.groovy
@@ -15,6 +15,7 @@
*/
package com.okta.maven.orgcreation
+import com.okta.cli.common.model.OrganizationResponse
import com.okta.maven.orgcreation.service.DefaultMavenRegistrationService
import org.codehaus.plexus.components.interactivity.Prompter
import org.powermock.api.mockito.PowerMockito
@@ -26,6 +27,7 @@ import org.testng.annotations.Test
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.verify
+import static org.mockito.Mockito.when
@PrepareForTest(RegisterMojo)
class RegisterMojoTest {
@@ -47,8 +49,13 @@ class RegisterMojoTest {
def lastName = "Coder"
def email = "joe.coder@example.com"
def company = "Example Co."
+ def orgResponse = new OrganizationResponse()
+ .setEmail(email)
+ .setOrgUrl("https://org.example.com")
+ .setId("test-id")
PowerMockito.whenNew(DefaultMavenRegistrationService).withArguments(prompter, oktaPropsFile, demo, interactive).thenReturn(mavenRegistrationService)
+ when(mavenRegistrationService.register(firstName, lastName, email, company)).thenReturn(orgResponse)
RegisterMojo mojo = new RegisterMojo()
mojo.firstName = firstName
@@ -62,5 +69,6 @@ class RegisterMojoTest {
mojo.execute()
verify(mavenRegistrationService).register(firstName, lastName, email, company)
+ verify(mavenRegistrationService).verify("test-id", null)
}
}
\ No newline at end of file
diff --git a/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/service/DefaultMavenRegistrationServiceTest.groovy b/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/service/DefaultMavenRegistrationServiceTest.groovy
index 88fb80bb..0d64cf22 100644
--- a/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/service/DefaultMavenRegistrationServiceTest.groovy
+++ b/maven-plugin/src/test/groovy/com/okta/maven/orgcreation/service/DefaultMavenRegistrationServiceTest.groovy
@@ -27,11 +27,13 @@ import org.testng.annotations.Test
import static com.okta.maven.orgcreation.TestUtil.expectException
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.equalTo
import static org.mockito.ArgumentMatchers.any
import static org.mockito.ArgumentMatchers.eq
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.spy
import static org.mockito.Mockito.verify
+import static org.mockito.Mockito.when
@PrepareForTest(DefaultMavenRegistrationService)
class DefaultMavenRegistrationServiceTest {
@@ -54,6 +56,20 @@ class DefaultMavenRegistrationServiceTest {
verify(setupService).createOktaOrg(any(), eq(propsFile), eq(false), eq(false))
}
+ @Test
+ void verifyCode() {
+ Prompter prompter = mock(Prompter)
+ File propsFile = mock(File)
+ DefaultSetupService setupService = mock(DefaultSetupService)
+ PowerMockito.whenNew(DefaultSetupService).withArguments(null).thenReturn(setupService)
+
+ def registrationService = spy new DefaultMavenRegistrationService(prompter, propsFile, false, false)
+ registrationService.verify("test-id", null)
+
+ verify(setupService).verifyOktaOrg(eq("test-id"), any(), eq(propsFile))
+ }
+
+
@Test
void promptNeededNonInteractive() {
Prompter prompter = mock(Prompter)
@@ -72,4 +88,22 @@ class DefaultMavenRegistrationServiceTest {
exception = expectException IllegalArgumentException, { registrationService.organizationRequest("first-name", "last-name", "email@example.com", null) }
assertThat exception.message, containsString("-Dcompany")
}
+
+ @Test
+ void promptForCode() {
+ Prompter prompter = mock(Prompter)
+ File propsFile = mock(File)
+
+ when(prompter.prompt(any(String))).thenReturn("totp-code-string")
+
+ assertThat new DefaultMavenRegistrationService(prompter, propsFile, false, true).codePrompt(null), equalTo("totp-code-string")
+ }
+
+ @Test
+ void promptForCode_nonInteractive() {
+ Prompter prompter = mock(Prompter)
+ File propsFile = mock(File)
+
+ expectException IllegalArgumentException, { new DefaultMavenRegistrationService(prompter, propsFile, false, false).codePrompt(null) }
+ }
}
diff --git a/pom.xml b/pom.xml
index 00fbf737..248a67f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
com.okta.cli
okta-cli-tools
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
pom
Okta CLI Tools
@@ -75,25 +75,25 @@
com.okta.cli
okta-cli-common
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
com.okta.cli
okta-cli
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
com.okta.cli
okta-cli-its
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
com.okta
okta-maven-plugin
- 0.3.2-SNAPSHOT
+ 0.4.0-SNAPSHOT
diff --git a/src/findbugs/findbugs-exclude.xml b/src/findbugs/findbugs-exclude.xml
index 53ae3c83..51e69910 100644
--- a/src/findbugs/findbugs-exclude.xml
+++ b/src/findbugs/findbugs-exclude.xml
@@ -31,6 +31,11 @@
+
+
+
+
+