Integration tests for twofactor
This commit is contained in:
committed by
Michael Vorburger ⛑️
parent
a58debcb2e
commit
5dbde0f2ed
@@ -0,0 +1,42 @@
|
||||
name: Fineract Gradle build - twofactor
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# We need 18.04 for this - the 20.04 image contains MySQL 8.0, and the GitHub Action to install 5.7 is not permitted in the Apache repo.
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
TZ: Asia/Kolkata
|
||||
steps:
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'zulu'
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
|
||||
- name: Start up MySQL 5.7
|
||||
run: |
|
||||
sudo /etc/init.d/mysql start
|
||||
echo "USE mysql;\nALTER USER 'root'@'localhost' IDENTIFIED BY 'mysql';\n" | mysql -u root -proot
|
||||
- name: Initialise databases
|
||||
run: |
|
||||
./gradlew --no-daemon -q createDB -PdbName=fineract_tenants
|
||||
./gradlew --no-daemon -q createDB -PdbName=fineract_default
|
||||
- name: Install additional software
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install ghostscript -y
|
||||
- name: Build & Test
|
||||
run: ./gradlew --no-daemon -q --console=plain licenseMain licenseTest check build test --fail-fast doc -x :integration-tests:test -Ptwofactor=enabled
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Fineract Gradle build
|
||||
name: Fineract Gradle build - basicauth
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
@@ -39,4 +39,4 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install ghostscript -y
|
||||
- name: Build & Test
|
||||
run: ./gradlew --no-daemon -q --console=plain licenseMain licenseTest check build test --fail-fast doc
|
||||
run: ./gradlew --no-daemon -q --console=plain licenseMain licenseTest check build test --fail-fast doc -x :twofactor-tests:test
|
||||
|
||||
@@ -28,6 +28,7 @@ buildscript {
|
||||
'fineract-api',
|
||||
'fineract-provider',
|
||||
'integration-tests',
|
||||
'twofactor-tests',
|
||||
'fineract-client'
|
||||
].contains(it.name)
|
||||
}
|
||||
@@ -144,6 +145,7 @@ allprojects {
|
||||
dependency 'org.webjars.npm:swagger-ui-dist:4.0.1'
|
||||
dependency 'org.webjars:webjars-locator-core:0.48'
|
||||
dependency 'org.springframework.boot:spring-boot-starter-mail:2.6.0'
|
||||
dependency 'com.icegreen:greenmail-junit5:1.6.5'
|
||||
|
||||
// fineract client dependencies
|
||||
dependency "com.squareup.retrofit2:retrofit:$retrofitVersion"
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ public class ExternalServicesPropertiesReadPlatformServiceImpl implements Extern
|
||||
|
||||
if (ExternalServicesConstants.SMTP_USERNAME.equalsIgnoreCase(name)) {
|
||||
username = value;
|
||||
} else if (ExternalServicesConstants.SMTP_PORT.equalsIgnoreCase(port)) {
|
||||
} else if (ExternalServicesConstants.SMTP_PORT.equalsIgnoreCase(name)) {
|
||||
port = value;
|
||||
} else if (ExternalServicesConstants.SMTP_PASSWORD.equalsIgnoreCase(name)) {
|
||||
password = value;
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -69,7 +70,7 @@ public final class DateUtils {
|
||||
|
||||
public static LocalDateTime getLocalDateTimeOfTenant() {
|
||||
final ZoneId zone = getDateTimeZoneOfTenant();
|
||||
LocalDateTime today = LocalDateTime.now(zone);
|
||||
LocalDateTime today = LocalDateTime.now(zone).truncatedTo(ChronoUnit.SECONDS);
|
||||
return today;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -128,6 +128,6 @@ public class TFAccessToken extends AbstractPersistableCustom {
|
||||
}
|
||||
|
||||
private boolean isDateInThePast(LocalDateTime dateTime) {
|
||||
return dateTime.isBefore(DateUtils.getLocalDateTimeOfTenant());
|
||||
return (dateTime.isBefore(DateUtils.getLocalDateTimeOfTenant()) || dateTime.isEqual(DateUtils.getLocalDateTimeOfTenant()));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -53,9 +53,9 @@ insert into c_external_service_properties (`name`, `value`, `external_service_id
|
||||
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('password', 'support80', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('host', 'smtp.gmail.com', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('host', 'localhost', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('port', '587', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('port', '3025', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
|
||||
insert into c_external_service_properties (`name`, `value`, `external_service_id`) values('useTLS', 'true', (select id from c_external_service where name = 'SMTP_Email_Account'));
|
||||
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
rootProject.name='fineract'
|
||||
include ':fineract-provider'
|
||||
include ':integration-tests'
|
||||
include ':twofactor-tests'
|
||||
include ':fineract-client'
|
||||
include ':fineract-doc'
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
description = 'Fineract Integration Tests'
|
||||
|
||||
apply plugin: 'com.bmuschko.cargo'
|
||||
|
||||
// Configuration for the Gradle Cargo plugin
|
||||
// https://github.com/bmuschko/gradle-cargo-plugin
|
||||
configurations {
|
||||
tomcat
|
||||
}
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
cargo {
|
||||
containerId "tomcat9x"
|
||||
|
||||
// looks like Cargo doesn't detect the WAR file automatically in the multi-module setup
|
||||
deployable {
|
||||
file = file("$rootDir/fineract-provider/build/libs/fineract-provider.war")
|
||||
context = 'fineract-provider'
|
||||
}
|
||||
|
||||
local {
|
||||
installer {
|
||||
installConfiguration = configurations.tomcat
|
||||
downloadDir = file("$buildDir/download")
|
||||
extractDir = file("$buildDir/tomcat")
|
||||
}
|
||||
startStopTimeout = 240000
|
||||
containerProperties {
|
||||
property 'cargo.start.jvmargs', '-Dspring.profiles.active=twofactor,basicauth'
|
||||
property 'cargo.tomcat.connector.keystoreFile', file("$rootDir/fineract-provider/src/main/resources/keystore.jks")
|
||||
property 'cargo.tomcat.connector.keystorePass', 'openmf'
|
||||
property 'cargo.tomcat.httpSecure', true
|
||||
property 'cargo.tomcat.connector.sslProtocol', 'TLS'
|
||||
property 'cargo.tomcat.connector.clientAuth', false
|
||||
property 'cargo.protocol', 'https'
|
||||
property 'cargo.servlet.port', 8443
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cargoRunLocal.dependsOn ':fineract-provider:war'
|
||||
cargoStartLocal.dependsOn ':fineract-provider:war'
|
||||
cargoStartLocal.mustRunAfter 'testClasses'
|
||||
|
||||
test {
|
||||
dependsOn cargoStartLocal
|
||||
finalizedBy cargoStopLocal
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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.
|
||||
*/
|
||||
dependencies {
|
||||
// testCompile dependencies are ONLY used in src/test, not src/main.
|
||||
// Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly!
|
||||
//
|
||||
tomcat 'org.apache.tomcat:tomcat:9.0.54@zip'
|
||||
testImplementation( files("$rootDir/fineract-provider/build/classes/java/main/"),
|
||||
project(path: ':fineract-provider', configuration: 'runtimeElements'),
|
||||
'org.junit.jupiter:junit-jupiter-api',
|
||||
'com.icegreen:greenmail-junit5'
|
||||
)
|
||||
testImplementation ('io.rest-assured:rest-assured') {
|
||||
exclude group: 'commons-logging'
|
||||
exclude group: 'org.apache.sling'
|
||||
exclude group: 'com.sun.xml.bind'
|
||||
}
|
||||
testRuntimeOnly(
|
||||
'org.junit.jupiter:junit-jupiter-engine'
|
||||
)
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.fineract.twofactortests;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import com.icegreen.greenmail.configuration.GreenMailConfiguration;
|
||||
import com.icegreen.greenmail.junit5.GreenMailExtension;
|
||||
import com.icegreen.greenmail.util.ServerSetupTest;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.builder.RequestSpecBuilder;
|
||||
import io.restassured.builder.ResponseSpecBuilder;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.path.json.JsonPath;
|
||||
import io.restassured.response.Response;
|
||||
import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.mail.MessagingException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
public class TwoFactorAuthenticationTest {
|
||||
|
||||
private ResponseSpecification responseSpec;
|
||||
private ResponseSpecification responseSpec403;
|
||||
private ResponseSpecification responseSpec401;
|
||||
private RequestSpecification requestSpecWithoutBasic;
|
||||
private RequestSpecification requestSpec;
|
||||
private String basicAuthenticationKey;
|
||||
|
||||
public static final String TENANT_PARAM_NAME = "tenantIdentifier";
|
||||
public static final String DEFAULT_TENANT = "default";
|
||||
public static final String TENANT_IDENTIFIER = TENANT_PARAM_NAME + '=' + DEFAULT_TENANT;
|
||||
private static final String LOGIN_URL = "/fineract-provider/api/v1/authentication?" + TENANT_IDENTIFIER;
|
||||
private static final String HEALTH_URL = "/fineract-provider/actuator/health";
|
||||
|
||||
@RegisterExtension
|
||||
static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP)
|
||||
.withConfiguration(GreenMailConfiguration.aConfig().withUser("support@cloudmicrofinance.com", "support81"))
|
||||
.withPerMethodLifecycle(true);
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws InterruptedException {
|
||||
initializeRestAssured();
|
||||
|
||||
this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
|
||||
// Login with basic authentication
|
||||
awaitSpringBootActuatorHealthyUp();
|
||||
String json = RestAssured.given().contentType(ContentType.JSON).body("{\"username\":\"mifos\", \"password\":\"password\"}").expect()
|
||||
.log().ifError().when().post(LOGIN_URL).asString();
|
||||
assertFalse(StringUtils.isBlank(json));
|
||||
|
||||
this.basicAuthenticationKey = JsonPath.with(json).get("base64EncodedAuthenticationKey");
|
||||
assertFalse(StringUtils.isBlank(this.basicAuthenticationKey));
|
||||
|
||||
this.requestSpec.header("Authorization", "Basic " + basicAuthenticationKey);
|
||||
|
||||
this.requestSpecWithoutBasic = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
|
||||
this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
|
||||
this.responseSpec403 = new ResponseSpecBuilder().expectStatusCode(403).build();
|
||||
this.responseSpec401 = new ResponseSpecBuilder().expectStatusCode(401).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActuatorAccess() {
|
||||
performServerGet(requestSpecWithoutBasic, responseSpec, "/fineract-provider/actuator/info", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiDocsAccess() {
|
||||
performServerGet(requestSpecWithoutBasic, responseSpec, "/fineract-provider/api-docs/apiLive.htm", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessWithoutTwofactor() {
|
||||
performServerGet(requestSpec, responseSpec403, "/fineract-provider/api/v1/offices/1?" + TENANT_IDENTIFIER, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckTwofactorEnabled() {
|
||||
String json = RestAssured.given().contentType(ContentType.JSON).body("{\"username\":\"mifos\", \"password\":\"password\"}").expect()
|
||||
.log().ifError().when().post("/fineract-provider/api/v1/authentication?" + TENANT_IDENTIFIER).asString();
|
||||
assertFalse(StringUtils.isBlank(json));
|
||||
Boolean key = JsonPath.with(json).get("isTwoFactorAuthenticationRequired");
|
||||
assertEquals(key, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTwofactorMethods() {
|
||||
String json = RestAssured.given().spec(requestSpec).expect().log().ifError().when()
|
||||
.get("/fineract-provider/api/v1/twofactor?" + TENANT_IDENTIFIER).asString();
|
||||
assertFalse(StringUtils.isBlank(json));
|
||||
List<HashMap<String, Object>> twoFactorMethods = JsonPath.with(json).getList("$");
|
||||
assertEquals("email", twoFactorMethods.get(0).get("name"));
|
||||
assertEquals("demomfi@mifos.org", twoFactorMethods.get(0).get("target"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwofactorLogin() throws IOException, MessagingException {
|
||||
assertEquals(greenMail.getReceivedMessages().length, 0);
|
||||
performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor?deliveryMethod=email&extendedToken=false&" + TENANT_IDENTIFIER, "", "");
|
||||
assertEquals(greenMail.getReceivedMessages().length, 1);
|
||||
|
||||
Pattern p = Pattern.compile("token is (.+).");
|
||||
Matcher m = p.matcher((CharSequence) greenMail.getReceivedMessages()[0].getContent());
|
||||
|
||||
String token = null;
|
||||
|
||||
while (m.find()) {
|
||||
token = m.group(1);
|
||||
}
|
||||
|
||||
assertNotNull(token);
|
||||
String tfaToken = performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor/validate?token=" + token + "&" + TENANT_IDENTIFIER, "", "token");
|
||||
assertNotNull(tfaToken);
|
||||
|
||||
RequestSpecification requestSpecWithTFA = new RequestSpecBuilder() //
|
||||
.setContentType(ContentType.JSON) //
|
||||
.addHeader("Fineract-Platform-TFA-Token", tfaToken) //
|
||||
.addHeader("Authorization", "Basic " + basicAuthenticationKey) //
|
||||
.build();
|
||||
|
||||
performServerGet(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/offices/1?" + TENANT_IDENTIFIER, "");
|
||||
|
||||
performServerPost(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/invalidate?" + TENANT_IDENTIFIER,
|
||||
"{ \"token\": \"" + tfaToken + "\" }", "");
|
||||
|
||||
performServerGet(requestSpecWithTFA, responseSpec401, "/fineract-provider/api/v1/offices/1?" + TENANT_IDENTIFIER, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTfaConfigSettings() throws IOException, MessagingException {
|
||||
assertEquals(greenMail.getReceivedMessages().length, 0);
|
||||
performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor?deliveryMethod=email&extendedToken=false&" + TENANT_IDENTIFIER, "", "");
|
||||
assertEquals(greenMail.getReceivedMessages().length, 1);
|
||||
|
||||
Pattern p = Pattern.compile("token is (.+).");
|
||||
Matcher m = p.matcher((CharSequence) greenMail.getReceivedMessages()[0].getContent());
|
||||
|
||||
String token = null;
|
||||
|
||||
while (m.find()) {
|
||||
token = m.group(1);
|
||||
}
|
||||
|
||||
assertNotNull(token);
|
||||
String tfaToken = performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor/validate?token=" + token + "&" + TENANT_IDENTIFIER, "", "token");
|
||||
assertNotNull(tfaToken);
|
||||
|
||||
RequestSpecification requestSpecWithTFA = new RequestSpecBuilder() //
|
||||
.setContentType(ContentType.JSON) //
|
||||
.addHeader("Fineract-Platform-TFA-Token", tfaToken) //
|
||||
.addHeader("Authorization", "Basic " + basicAuthenticationKey) //
|
||||
.build();
|
||||
|
||||
// Get the configuration and check one of the values (OTP token length)
|
||||
LinkedHashMap<String, Object> json = performServerGet(requestSpecWithTFA, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor/configure?" + TENANT_IDENTIFIER, "");
|
||||
assertEquals(json.get("otp-token-length"), token.length());
|
||||
|
||||
// Update OTP token length
|
||||
performServerPut(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/configure?" + TENANT_IDENTIFIER,
|
||||
"{\"otp-token-length\": 10 }", "");
|
||||
|
||||
// Invalidate token for re-login
|
||||
performServerPost(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/invalidate?" + TENANT_IDENTIFIER,
|
||||
"{ \"token\": \"" + tfaToken + "\" }", "");
|
||||
|
||||
// Login again
|
||||
performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor?deliveryMethod=email&extendedToken=false&" + TENANT_IDENTIFIER, "", "");
|
||||
assertEquals(greenMail.getReceivedMessages().length, 2);
|
||||
|
||||
Matcher m2 = p.matcher((CharSequence) greenMail.getReceivedMessages()[1].getContent());
|
||||
|
||||
String token2 = null;
|
||||
|
||||
while (m2.find()) {
|
||||
token2 = m2.group(1);
|
||||
}
|
||||
|
||||
assertNotNull(token2);
|
||||
|
||||
// Check that the configuration has worked and length is now 10
|
||||
assertEquals(10, token2.length());
|
||||
|
||||
tfaToken = performServerPost(requestSpec, responseSpec,
|
||||
"/fineract-provider/api/v1/twofactor/validate?token=" + token2 + "&" + TENANT_IDENTIFIER, "", "token");
|
||||
assertNotNull(tfaToken);
|
||||
|
||||
requestSpecWithTFA = new RequestSpecBuilder() //
|
||||
.setContentType(ContentType.JSON) //
|
||||
.addHeader("Fineract-Platform-TFA-Token", tfaToken) //
|
||||
.addHeader("Authorization", "Basic " + basicAuthenticationKey) //
|
||||
.build();
|
||||
|
||||
// Get the configuration and check one of the values (OTP token length)
|
||||
json = performServerGet(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/configure?" + TENANT_IDENTIFIER, "");
|
||||
assertEquals(json.get("otp-token-length"), token2.length());
|
||||
|
||||
// Update OTP token length back to original value
|
||||
performServerPut(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/configure?" + TENANT_IDENTIFIER,
|
||||
"{\"otp-token-length\": " + token.length() + "}", "");
|
||||
|
||||
// Check that configuration has been reset
|
||||
json = performServerGet(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/configure?" + TENANT_IDENTIFIER, "");
|
||||
assertEquals(json.get("otp-token-length"), token.length());
|
||||
|
||||
// Invalidate token for re-login
|
||||
performServerPost(requestSpecWithTFA, responseSpec, "/fineract-provider/api/v1/twofactor/invalidate?" + TENANT_IDENTIFIER,
|
||||
"{ \"token\": \"" + tfaToken + "\" }", "");
|
||||
}
|
||||
|
||||
private static void initializeRestAssured() {
|
||||
RestAssured.baseURI = "https://localhost";
|
||||
RestAssured.port = 8443;
|
||||
RestAssured.keyStore("src/main/resources/keystore.jks", "openmf");
|
||||
RestAssured.useRelaxedHTTPSValidation();
|
||||
}
|
||||
|
||||
private static void awaitSpringBootActuatorHealthyUp() throws InterruptedException {
|
||||
int attempt = 0;
|
||||
final int max_attempts = 10;
|
||||
Response response = null;
|
||||
|
||||
do {
|
||||
try {
|
||||
response = RestAssured.get(HEALTH_URL);
|
||||
|
||||
if (response.statusCode() == 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
Thread.sleep(3000);
|
||||
} catch (Exception e) {
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
} while (attempt < max_attempts);
|
||||
|
||||
fail(HEALTH_URL + " returned " + response.prettyPrint());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T performServerGet(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String getURL, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asString();
|
||||
if (jsonAttributeToGetBack == null) {
|
||||
return (T) json;
|
||||
}
|
||||
return (T) JsonPath.from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
|
||||
.andReturn().asString();
|
||||
if (jsonAttributeToGetBack == null) {
|
||||
return (T) json;
|
||||
}
|
||||
return (T) JsonPath.from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T performServerPut(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final String putURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
|
||||
final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().put(putURL)
|
||||
.andReturn().asString();
|
||||
return (T) JsonPath.from(json).get(jsonAttributeToGetBack);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user