diff --git a/CHANGELOG.md b/CHANGELOG.md index bf50ff684..d545d830e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to AET will be documented in this file. ## Unreleased **List of changes that are finished but not yet released in any final version.** +- [PR-583](https://github.com/Cognifide/aet/pull/583) Enable login modifier to read login and password from environment variables (fixed [#512](https://github.com/Cognifide/aet/issues/512)). ## Version 3.4.0 diff --git a/core/jobs/pom.xml b/core/jobs/pom.xml index 5600320b1..b383a7b73 100644 --- a/core/jobs/pom.xml +++ b/core/jobs/pom.xml @@ -149,6 +149,10 @@ org.assertj assertj-core + + com.github.stefanbirkner + system-rules + diff --git a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfig.java b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfig.java index 4c37de76a..597894371 100644 --- a/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfig.java +++ b/core/jobs/src/main/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfig.java @@ -18,15 +18,16 @@ import com.cognifide.aet.job.api.ParametersValidator; import com.cognifide.aet.job.api.exceptions.ParametersException; import java.util.Map; +import java.util.Optional; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; class LoginModifierConfig { - private static final String DEFAULT_LOGIN = "admin"; + static final String DEFAULT_LOGIN = "admin"; - private static final String DEFAULT_PASSWORD = "admin"; + static final String DEFAULT_PASSWORD = "admin"; private static final String DEFAULT_LOGIN_INPUT_SELECTOR = "//input[@name='j_username']"; @@ -36,11 +37,11 @@ class LoginModifierConfig { private static final String DEFAULT_LOGIN_TOKEN = "login-token"; - private static final String LOGIN_PARAM = "login"; + static final String LOGIN_PARAM = "login"; - private static final String PASSWORD_PARAM = "password"; + static final String PASSWORD_PARAM = "password"; - private static final String LOGIN_PAGE_PARAM = "login-page"; + static final String LOGIN_PAGE_PARAM = "login-page"; private static final String LOGIN_INPUT_SELECTOR_PARAM = "login-input-selector"; @@ -82,8 +83,8 @@ class LoginModifierConfig { public LoginModifierConfig(Map params) throws ParametersException { this.loginPage = params.get(LOGIN_PAGE_PARAM); - this.login = getParameter(params, LOGIN_PARAM, DEFAULT_LOGIN); - this.password = getParameter(params, PASSWORD_PARAM, DEFAULT_PASSWORD); + this.login = getEnvParameter(params, LOGIN_PARAM, DEFAULT_LOGIN); + this.password = getEnvParameter(params, PASSWORD_PARAM, DEFAULT_PASSWORD); this.loginInputSelector = getParameter(params, LOGIN_INPUT_SELECTOR_PARAM, DEFAULT_LOGIN_INPUT_SELECTOR); this.passwordInputSelector = getParameter(params, PASSWORD_INPUT_SELECTOR_PARAM, @@ -102,6 +103,22 @@ public LoginModifierConfig(Map params) throws ParametersExceptio .checkRange(retrialNumber, 1, Integer.MAX_VALUE, "Retrial number has to be at least 1"); } + private String getEnvParameter(Map params, String key, String defaultValue) { + return Optional.ofNullable(params.get(key)) + .filter(StringUtils::isNotEmpty) + .map(value -> isEnv(value) ? getEnv(value, defaultValue) : value) + .orElse(defaultValue); + } + + private boolean isEnv(String value) { + return value.startsWith("${") && value.endsWith("}") ; + } + + private String getEnv(String value, String defaultValue) { + return Optional.ofNullable(System.getenv(value.substring(2, value.length() - 1))) + .orElse(defaultValue); + } + private String getParameter(Map params, String key, String defaultValue) { return StringUtils.defaultString(params.get(key), defaultValue); } diff --git a/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfigTest.java b/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfigTest.java new file mode 100644 index 000000000..25e21cade --- /dev/null +++ b/core/jobs/src/test/java/com/cognifide/aet/job/common/modifiers/login/LoginModifierConfigTest.java @@ -0,0 +1,143 @@ +/* + * AET + * + * Copyright (C) 2013 Cognifide Limited + * + * 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.cognifide.aet.job.common.modifiers.login; + +import static com.cognifide.aet.job.common.modifiers.login.LoginModifierConfig.DEFAULT_LOGIN; +import static com.cognifide.aet.job.common.modifiers.login.LoginModifierConfig.DEFAULT_PASSWORD; +import static com.cognifide.aet.job.common.modifiers.login.LoginModifierConfig.LOGIN_PAGE_PARAM; +import static com.cognifide.aet.job.common.modifiers.login.LoginModifierConfig.LOGIN_PARAM; +import static com.cognifide.aet.job.common.modifiers.login.LoginModifierConfig.PASSWORD_PARAM; +import static org.junit.Assert.assertEquals; + +import com.cognifide.aet.job.api.exceptions.ParametersException; +import com.googlecode.zohhak.api.TestWith; +import com.googlecode.zohhak.api.runners.ZohhakRunner; +import java.util.HashMap; +import java.util.Map; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; +import org.junit.runner.RunWith; + +@RunWith(ZohhakRunner.class) +public class LoginModifierConfigTest { + + @Rule + public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); + + @Test + public void whenNoPasswordProvided_expectDefaultPasswordInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(DEFAULT_PASSWORD, tested.getPassword()); + } + + @TestWith({ + "s3cret", + "$ecret", + "${ecret", + "$ecret}", + "s3cret}" + }) + public void whenPasswordPassedAsPlainText_expectPasswordInTheConfig(String password) throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(PASSWORD_PARAM, password); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(password, tested.getPassword()); + } + + @Test + public void whenPasswordPassedAsEnv_expectPasswordInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(PASSWORD_PARAM, "${MY_SECRET_PASSWORD}"); + environmentVariables.set("MY_SECRET_PASSWORD", "pass-from-env"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals("pass-from-env", tested.getPassword()); + } + + @Test + public void whenPasswordPassedAsEnvAndEnvNotSet_expectDefaultPasswordInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(PASSWORD_PARAM, "${MY_SECRET_PASSWORD}"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(DEFAULT_PASSWORD, tested.getPassword()); + } + + //----- + + @Test + public void whenNoLoginProvided_expectDefaultLoginInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(DEFAULT_LOGIN, tested.getLogin()); + } + + @TestWith({ + "s3cret", + "$ecret", + "${ecret", + "$ecret}", + "s3cret}" + }) + public void whenLoginPassedAsPlainText_expectLoginInTheConfig(String login) throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(LOGIN_PARAM, login); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(login, tested.getLogin()); + } + + @Test + public void whenLoginPassedAsEnv_expectLoginInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(LOGIN_PARAM, "${MY_SECRET_LOGIN}"); + environmentVariables.set("MY_SECRET_LOGIN", "user-from-env"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals("user-from-env", tested.getLogin()); + } + + @Test + public void whenLoginPassedAsEnvAndEnvNotSet_expectDefaultLoginInTheConfig() throws ParametersException { + Map params = new HashMap<>(); + params.put(LOGIN_PAGE_PARAM, "whatever"); + params.put(DEFAULT_LOGIN, "${MY_SECRET_PASSWORD}"); + + LoginModifierConfig tested = new LoginModifierConfig(params); + + assertEquals(DEFAULT_LOGIN, tested.getLogin()); + } + +} \ No newline at end of file diff --git a/documentation/src/main/wiki/LoginModifier.md b/documentation/src/main/wiki/LoginModifier.md index 36cb4602d..a5c209b6d 100644 --- a/documentation/src/main/wiki/LoginModifier.md +++ b/documentation/src/main/wiki/LoginModifier.md @@ -14,8 +14,8 @@ Module name: **login** | Parameter | Value | Mandatory | Default value | | --------- | ----- | --------- | ------------- | -| `login` | User's login | no | admin | -| `password` | Password | no | admin | +| `login` | User's login, can be passed plaintext or read from environment variable using `"${ENV_VARIABLE_NAME}"`. See the example below. | no | admin | +| `password` | Password, can be passed plaintext or read from environment variable using `"${ENV_VARIABLE_NAME}"`. See the example below. | no | admin | | `login-page` | Full url to login page (starting with `http` or `https`) or login page path that is in the `domain` specified for the suite | yes | | | `login-input-selector` | Xpath expression for login input | no | //input[@name='j_username'] | | `password-input-selector` | Xpath expression for password input | no | //input[@name='j_password'] | @@ -27,6 +27,7 @@ Module name: **login** ##### Example Usage +> Pass `login` and `password` as plain text and `login-page` as full URL: ```xml @@ -55,6 +56,7 @@ Module name: **login** ``` +> Pass `login` and `password` as plain text and `login-page` as URL inside the `domain` specified for the suite: ```xml @@ -81,4 +83,33 @@ Module name: **login** ... +``` + +> Pass `login` and `password` as environment variables: +```xml + + + + + + + ... + + + ... + + + ... + + + ... + + ... + + ``` \ No newline at end of file