From db29e4196ee7ffb603f396b8d91807faf113b34f Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 26 Jul 2024 15:44:48 +0200 Subject: [PATCH 01/35] Fix #472: Set develop version to 1.9.0-SNAPSHOT --- pom.xml | 14 +++++++------- powerauth-backend-tests/pom.xml | 2 +- powerauth-fido2-tests/pom.xml | 2 +- powerauth-load-tests/pom.xml | 2 +- powerauth-test-server/pom.xml | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index f19abbe5..f7c05335 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.wultra powerauth-backend-tests-parent - 1.8.0 + 1.9.0-SNAPSHOT pom Parent pom for backend tests @@ -45,12 +45,12 @@ - 1.8.0 - 1.8.0 - 1.8.0 - 1.8.0 - 1.8.0 - 1.10.0 + 1.9.0-SNAPSHOT + 1.9.0-SNAPSHOT + 1.9.0-SNAPSHOT + 1.9.0-SNAPSHOT + 1.9.0-SNAPSHOT + 1.11.0-SNAPSHOT 2.6.0 7.4 diff --git a/powerauth-backend-tests/pom.xml b/powerauth-backend-tests/pom.xml index a78090aa..b1fb3774 100644 --- a/powerauth-backend-tests/pom.xml +++ b/powerauth-backend-tests/pom.xml @@ -8,7 +8,7 @@ com.wultra powerauth-backend-tests-parent - 1.8.0 + 1.9.0-SNAPSHOT com.wultra diff --git a/powerauth-fido2-tests/pom.xml b/powerauth-fido2-tests/pom.xml index 985412e3..29967504 100644 --- a/powerauth-fido2-tests/pom.xml +++ b/powerauth-fido2-tests/pom.xml @@ -11,7 +11,7 @@ com.wultra powerauth-backend-tests-parent - 1.8.0 + 1.9.0-SNAPSHOT diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index 8dc578d3..73bd3d51 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -6,7 +6,7 @@ com.wultra powerauth-backend-tests-parent - 1.8.0 + 1.9.0-SNAPSHOT powerauth-load-tests diff --git a/powerauth-test-server/pom.xml b/powerauth-test-server/pom.xml index 0ca5cac0..06a85cb9 100644 --- a/powerauth-test-server/pom.xml +++ b/powerauth-test-server/pom.xml @@ -23,7 +23,7 @@ com.wultra powerauth-backend-tests-parent - 1.8.0 + 1.9.0-SNAPSHOT powerauth-test-server From 26b324f8283eb477df7a1d28a847af718944f101 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:25:15 +0000 Subject: [PATCH 02/35] Bump org.wiremock:wiremock-standalone from 3.9.0 to 3.9.1 Bumps [org.wiremock:wiremock-standalone](https://github.com/wiremock/wiremock) from 3.9.0 to 3.9.1. - [Release notes](https://github.com/wiremock/wiremock/releases) - [Commits](https://github.com/wiremock/wiremock/compare/3.9.0...3.9.1) --- updated-dependencies: - dependency-name: org.wiremock:wiremock-standalone dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- powerauth-load-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index 73bd3d51..0d2dd7a9 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -75,7 +75,7 @@ org.wiremock wiremock-standalone - 3.9.0 + 3.9.1 test From 3d17fe329fdb635f48196a68e01ab79f71624bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Thu, 8 Aug 2024 09:27:07 +0200 Subject: [PATCH 03/35] Fix #487: Add OTP activation option for powerauth-test-server (#495) --- docs-private/Developer-How-To-Start.md | 7 ++++--- powerauth-test-server/README.md | 4 +++- .../testserver/model/request/CreateActivationRequest.java | 1 + .../app/testserver/service/ActivationService.java | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs-private/Developer-How-To-Start.md b/docs-private/Developer-How-To-Start.md index 6a476e01..2b93dfc5 100644 --- a/docs-private/Developer-How-To-Start.md +++ b/docs-private/Developer-How-To-Start.md @@ -1,13 +1,14 @@ # Developer - How to Start Guide +## PowerAuth Test Server -## Standalone Run +### Standalone Run - Use IntelliJ Idea run configuration at `../.run/TestServerApplication.run.xml` -- Open [http://localhost:8080/actuator/health](http://localhost:8080/actuator/health) and you should get `{"status":"UP"}` +- Open [http://localhost:8081/actuator/health](http://localhost:8081/actuator/health) and you should get `{"status":"UP"}` -## Database +### Database Database changes are driven by Liquibase. diff --git a/powerauth-test-server/README.md b/powerauth-test-server/README.md index 7ae8bccf..2223b847 100644 --- a/powerauth-test-server/README.md +++ b/powerauth-test-server/README.md @@ -81,7 +81,8 @@ curl --request POST \ "applicationId": "1", "activationName": "test-activation", "password": "1234", - "activationCode": "3A33O-3XMFZ-ORDKE-XJOYQ" + "activationCode": "3A33O-3XMFZ-ORDKE-XJOYQ", + "activationOtp": "otp" } }' ``` @@ -94,6 +95,7 @@ The following request parameters are used: | `activationName` | PowerAuth application name | | `password` | PIN code for future signature verifications (knowledge factor) | | `activationCode` | Activation code, created using the previous initialization request | +| `activationOtp` | Activation OTP used for the activation initialization. Required if the OTP validation of the activation is set to `ON_KEY_EXCHANGE`. | The response contains the `activationId` parameter which is the activation identifier: diff --git a/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/model/request/CreateActivationRequest.java b/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/model/request/CreateActivationRequest.java index 0ce754bb..cf73d241 100644 --- a/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/model/request/CreateActivationRequest.java +++ b/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/model/request/CreateActivationRequest.java @@ -34,5 +34,6 @@ public class CreateActivationRequest { private String activationName; private String password; private String activationCode; + private String activationOtp; } diff --git a/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/service/ActivationService.java b/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/service/ActivationService.java index 0f670c16..6a284ca2 100644 --- a/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/service/ActivationService.java +++ b/powerauth-test-server/src/main/java/com/wultra/security/powerauth/app/testserver/service/ActivationService.java @@ -98,6 +98,7 @@ public CreateActivationResponse createActivation(CreateActivationRequest request model.setUriString(config.getEnrollmentServiceUrl()); model.setVersion(config.getVersion()); model.setDeviceInfo("backend-tests"); + model.setAdditionalActivationOtp(request.getActivationOtp()); final ObjectStepLogger stepLogger; try { From f06fe2cd2a0baee67181f89f89cb6335cdad74b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:01:09 +0000 Subject: [PATCH 04/35] Bump com.webauthn4j:webauthn4j-core Bumps [com.webauthn4j:webauthn4j-core](https://github.com/webauthn4j/webauthn4j) from 0.25.0.RELEASE to 0.25.1.RELEASE. - [Release notes](https://github.com/webauthn4j/webauthn4j/releases) - [Changelog](https://github.com/webauthn4j/webauthn4j/blob/master/github-release-notes-generator.yml) - [Commits](https://github.com/webauthn4j/webauthn4j/compare/0.25.0.RELEASE...0.25.1.RELEASE) --- updated-dependencies: - dependency-name: com.webauthn4j:webauthn4j-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f7c05335..4adc5153 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 2.6.0 7.4 - 0.25.0.RELEASE + 0.25.1.RELEASE true From 49b3f0ed6fcfc382396b9ae1c93e7640e7b66be0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 05:27:57 +0000 Subject: [PATCH 05/35] Bump net.logstash.logback:logstash-logback-encoder from 7.4 to 8.0 Bumps [net.logstash.logback:logstash-logback-encoder](https://github.com/logfellow/logstash-logback-encoder) from 7.4 to 8.0. - [Release notes](https://github.com/logfellow/logstash-logback-encoder/releases) - [Commits](https://github.com/logfellow/logstash-logback-encoder/compare/logstash-logback-encoder-7.4...logstash-logback-encoder-8.0) --- updated-dependencies: - dependency-name: net.logstash.logback:logstash-logback-encoder dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4adc5153..d4c230fb 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ 1.11.0-SNAPSHOT 2.6.0 - 7.4 + 8.0 0.25.1.RELEASE true From 04d17f833aa1cfb5c271f2238a6450c742eddb56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:33:47 +0000 Subject: [PATCH 06/35] Bump org.springframework.boot:spring-boot-starter-parent Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.2...v3.3.3) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d4c230fb..099b7c90 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.2 + 3.3.3 From 9d6ef22e713872d5784edc745ed3a3f6c0e2c8a1 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 3 Sep 2024 07:46:37 +0200 Subject: [PATCH 07/35] Fix #502: Unable to compile after adding support for temporary keys --- .../powerauth/test/shared/PowerAuthApiShared.java | 8 ++++---- .../powerauth/test/shared/PowerAuthEncryptionShared.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java index 4d5d5b1c..acf08544 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java @@ -145,7 +145,7 @@ public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthCli final PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); final ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.VAULT_UNLOCK, - new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version)), + new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version), null), new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) ); VaultUnlockRequestPayload requestPayload = new VaultUnlockRequestPayload(); @@ -224,7 +224,7 @@ public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAut requestL2.setDevicePublicKey(devicePublicKeyBase64); ClientEncryptor clientEncryptorL2 = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.ACTIVATION_LAYER_2, - new EncryptorParameters(version, config.getApplicationKey(), null), + new EncryptorParameters(version, config.getApplicationKey(), null, null), new ClientEncryptorSecrets(config.getMasterPublicKey(), config.getApplicationSecret()) ); ByteArrayOutputStream baosL2 = new ByteArrayOutputStream(); @@ -255,7 +255,7 @@ public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAut // Confirm recovery code ClientEncryptor encryptorConfirmRC = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.CONFIRM_RECOVERY_CODE, - new EncryptorParameters(version, config.getApplicationKey(), activationId), + new EncryptorParameters(version, config.getApplicationKey(), activationId, null), new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) ); ConfirmRecoveryRequestPayload confirmRequestPayload = new ConfirmRecoveryRequestPayload(); @@ -307,7 +307,7 @@ private static TokenInfo createToken(PowerAuthClient powerAuthClient, PowerAuthT final PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); final ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.CREATE_TOKEN, - new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version)), + new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version), null), new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) ); final EncryptedRequest encryptedRequest = clientEncryptor.encryptRequest("{}".getBytes(StandardCharsets.UTF_8)); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java index 9ea52589..efdf1d82 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java @@ -476,7 +476,7 @@ public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAut String requestData = "test_data"; ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.APPLICATION_SCOPE_GENERIC, - new EncryptorParameters(version, config.getApplicationKey(), null), + new EncryptorParameters(version, config.getApplicationKey(), null, null), new ClientEncryptorSecrets(config.getMasterPublicKey(), config.getApplicationSecret()) ); EncryptedRequest encryptedRequest = clientEncryptor.encryptRequest(requestData.getBytes(StandardCharsets.UTF_8)); From fd0166c426dff17c466e496503218468629bf834 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 3 Sep 2024 08:17:22 +0200 Subject: [PATCH 08/35] Fix #504: RandomStringGenerator.Builder#build is deprecated --- .../powerauth/test/shared/PowerAuthSignatureShared.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java index 721a9d07..ea9e852c 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java @@ -428,7 +428,7 @@ public static void signatureLargeDataTest(final VerifySignatureStepModel model, new RandomStringGenerator.Builder() .withinRange('0', 'z') .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS) - .build(); + .get(); final String randomString = randomStringGenerator.generate(10000); fw.write(randomString); fw.close(); From 7d3e03503b2d4508825beb40bad50f2b21cac835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Tue, 3 Sep 2024 17:03:27 +0200 Subject: [PATCH 09/35] Fix #499: FIDO2 Test application: Property to Hide Advanced Option (#500) --- powerauth-fido2-tests/README.md | 7 ++++ .../PowerAuthConfigProperties.java | 1 + .../PowerAuthFido2TestsConfigProperties.java | 41 +++++++++++++++++++ .../fido2/controller/HomeController.java | 11 +++++ .../src/main/resources/application.properties | 8 ++++ .../src/main/resources/templates/login.html | 7 ++-- .../src/main/resources/templates/payment.html | 6 +-- .../src/main/webapp/resources/js/login.js | 8 +++- 8 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java diff --git a/powerauth-fido2-tests/README.md b/powerauth-fido2-tests/README.md index b10386a5..258ff24a 100644 --- a/powerauth-fido2-tests/README.md +++ b/powerauth-fido2-tests/README.md @@ -14,11 +14,18 @@ the PowerAuth Server on the [Developer Portal](https://developers.wultra.com/com ## Configuration Properties +### PowerAuth FIDO2 Tests Configuration + +| Property | Default | Note | +|----------------------------------------------------|---------|----------------------------------------------| +| `powerauth.fido2.test.service.hideDeveloperOption` | `false` | Whether to hide advanced settings in the UI. | + ### PowerAuth Service Configuration | Property | Default | Note | |-------------------------------------------|-----------------------------------------------|-------------------------------------------| | `powerauth.service.baseUrl` | `http://localhost:8080/powerauth-java-server` | PowerAuth service REST API base URL. | +| `powerauth.service.applicationId` | | Set default application ID to use. | | `powerauth.service.security.clientToken` | | PowerAuth REST API authentication token. | | `powerauth.service.security.clientSecret` | | PowerAuth REST API authentication secret. | diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthConfigProperties.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthConfigProperties.java index 3e4d5e9a..a26d01e0 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthConfigProperties.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthConfigProperties.java @@ -33,6 +33,7 @@ public class PowerAuthConfigProperties { private String baseUrl; + private String applicationId; private SecurityProperties security; public record SecurityProperties(String clientToken, String clientSecret) {} diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java new file mode 100644 index 00000000..be9b3605 --- /dev/null +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java @@ -0,0 +1,41 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.wultra.security.powerauth.fido2.configuration; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration of the PowerAuth FIDO2 Tests application. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@Configuration +@ConfigurationProperties(prefix = "powerauth.fido2.test.service") +@Data +public class PowerAuthFido2TestsConfigProperties { + + private boolean hideDeveloperOptions = false; + + public boolean shouldHideDeveloperOptions() { + return hideDeveloperOptions; + } + +} diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java index 448cdf55..78851123 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java @@ -19,6 +19,8 @@ package com.wultra.security.powerauth.fido2.controller; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.fido2.configuration.PowerAuthConfigProperties; +import com.wultra.security.powerauth.fido2.configuration.PowerAuthFido2TestsConfigProperties; import com.wultra.security.powerauth.fido2.service.Fido2SharedService; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpSession; @@ -29,6 +31,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import java.util.List; import java.util.Map; /** @@ -48,12 +51,15 @@ public class HomeController { private static final String LOGIN_PAGE = "login"; private static final String PAYMENT_PAGE = "payment"; + private final PowerAuthFido2TestsConfigProperties powerAuthFido2TestsConfigProperties; + private final PowerAuthConfigProperties powerAuthConfigProperties; private final Fido2SharedService sharedService; private final ServletContext context; @ModelAttribute public void addAttributes(Map model) { model.put("servletContextPath", context.getContextPath()); + model.put("hideDeveloperOption", powerAuthFido2TestsConfigProperties.shouldHideDeveloperOptions()); } @GetMapping("/") @@ -66,6 +72,11 @@ public String homePage(Map model, HttpSession session) { @GetMapping("/login") public String loginPage(Map model) throws PowerAuthClientException { + final List applicationList = sharedService.fetchApplicationNameList(); + final String defaultApplicationId = powerAuthConfigProperties.getApplicationId(); + if (StringUtils.hasText(defaultApplicationId) && applicationList.contains(defaultApplicationId)) { + model.put(SESSION_KEY_APPLICATION_ID, powerAuthConfigProperties.getApplicationId()); + } model.put("applications", sharedService.fetchApplicationNameList()); model.put("templates", sharedService.fetchTemplateNameList()); return LOGIN_PAGE; diff --git a/powerauth-fido2-tests/src/main/resources/application.properties b/powerauth-fido2-tests/src/main/resources/application.properties index f53eb82d..9de5a897 100644 --- a/powerauth-fido2-tests/src/main/resources/application.properties +++ b/powerauth-fido2-tests/src/main/resources/application.properties @@ -1,6 +1,7 @@ # PowerAuth service configuration powerauth.service.baseUrl=http://localhost:8080/powerauth-java-server +powerauth.service.applicationId= powerauth.service.security.clientToken= powerauth.service.security.clientSecret= @@ -14,9 +15,16 @@ powerauth.webauthn.allowedOrigins= powerauth.fido2.test.service.applicationName=powerauth-fido2-tests powerauth.fido2.test.service.applicationDisplayName=PowerAuth FIDO2 Test powerauth.fido2.test.service.applicationEnvironment= +powerauth.fido2.test.service.hideDeveloperOptions=false banner.application.name=${powerauth.fido2.test.service.applicationName} banner.application.version=@project.version@ # Disable JS caching spring.web.resources.cache.cachecontrol.no-store=true + +# To correctly handle redirection +server.forward-headers-strategy=framework + +# To avoid having JSESSIONID in URI +server.servlet.session.tracking-modes=cookie diff --git a/powerauth-fido2-tests/src/main/resources/templates/login.html b/powerauth-fido2-tests/src/main/resources/templates/login.html index c56b3d5d..f9063806 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/login.html +++ b/powerauth-fido2-tests/src/main/resources/templates/login.html @@ -30,9 +30,10 @@

PowerAuth FIDO2 Demo

-
+
@@ -57,7 +58,7 @@
- +
-
-
- - - -
+
diff --git a/powerauth-fido2-tests/src/main/webapp/resources/js/login.js b/powerauth-fido2-tests/src/main/webapp/resources/js/login.js index 91a25b1b..b7467e4f 100644 --- a/powerauth-fido2-tests/src/main/webapp/resources/js/login.js +++ b/powerauth-fido2-tests/src/main/webapp/resources/js/login.js @@ -24,7 +24,7 @@ async function handleLoginSubmit() { } else if (CEREMONY === AUTHENTICATION_CEREMONY) { const templateName = $("#operationTemplate").val(); await requestCredential(userId, applicationId, templateName, {}); - window.location.href = SERVLET_CONTEXT_PATH; + window.location.href = SERVLET_CONTEXT_PATH + QUERY_PARAMS } else { console.error("Unknown ceremony " + CEREMONY); } diff --git a/powerauth-fido2-tests/src/main/webapp/resources/js/payment.js b/powerauth-fido2-tests/src/main/webapp/resources/js/payment.js index 9c3f7d0b..171350b1 100644 --- a/powerauth-fido2-tests/src/main/webapp/resources/js/payment.js +++ b/powerauth-fido2-tests/src/main/webapp/resources/js/payment.js @@ -90,7 +90,7 @@ $(function() { // Set action on Logout button click $('#logoutBtn').click(function(){ - window.location.href = SERVLET_CONTEXT_PATH + "/logout"; + window.location.href = SERVLET_CONTEXT_PATH + "/logout" + QUERY_PARAMS; }); // Set action on Add operation parameter button click From b2565ddc7726add204149aabadce673aba4ce2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Fri, 6 Sep 2024 11:16:53 +0200 Subject: [PATCH 12/35] Fix #509: FIDO2 Test application: Username validation (#512) --- powerauth-fido2-tests/README.md | 7 +- .../PowerAuthFido2TestsConfigProperties.java | 1 + .../controller/DefaultExceptionHandler.java | 17 +++++ .../fido2/controller/HomeController.java | 1 + .../request/RegisterCredentialRequest.java | 3 +- .../request/RegistrationOptionsRequest.java | 3 +- .../validation/EmailConditional.java | 43 +++++++++++ .../validation/EmailConditionalValidator.java | 50 +++++++++++++ .../src/main/resources/application.properties | 1 + .../resources/templates/embeddedLogin.html | 2 +- .../resources/templates/embeddedPayment.html | 2 +- .../resources/templates/forms/loginForm.html | 3 +- .../src/main/resources/templates/login.html | 2 +- .../src/main/resources/templates/payment.html | 2 +- .../EmailConditionalValidatorTest.java | 75 +++++++++++++++++++ 15 files changed, 202 insertions(+), 10 deletions(-) create mode 100644 powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditional.java create mode 100644 powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidator.java create mode 100644 powerauth-fido2-tests/src/test/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidatorTest.java diff --git a/powerauth-fido2-tests/README.md b/powerauth-fido2-tests/README.md index afe8694c..08c88187 100644 --- a/powerauth-fido2-tests/README.md +++ b/powerauth-fido2-tests/README.md @@ -16,9 +16,10 @@ the PowerAuth Server on the [Developer Portal](https://developers.wultra.com/com ### PowerAuth FIDO2 Tests Configuration -| Property | Default | Note | -|-----------------------------------------------------|---------|----------------------------------------------| -| `powerauth.fido2.test.service.hideDeveloperOptions` | `false` | Whether to hide advanced settings in the UI. | +| Property | Default | Note | +|-----------------------------------------------------|---------|-----------------------------------------------------------| +| `powerauth.fido2.test.service.hideDeveloperOptions` | `false` | Whether to hide advanced settings in the UI. | +| `powerauth.fido2.test.service.emailAddressRequired` | `false` | Whether to require email address instead of any username. | ### PowerAuth Service Configuration diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java index be9b3605..eed67a0e 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/configuration/PowerAuthFido2TestsConfigProperties.java @@ -33,6 +33,7 @@ public class PowerAuthFido2TestsConfigProperties { private boolean hideDeveloperOptions = false; + private boolean emailAddressRequired = false; public boolean shouldHideDeveloperOptions() { return hideDeveloperOptions; diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/DefaultExceptionHandler.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/DefaultExceptionHandler.java index 24c7f795..ee4b895e 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/DefaultExceptionHandler.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/DefaultExceptionHandler.java @@ -21,12 +21,16 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthError; import io.getlime.core.rest.model.base.response.ObjectResponse; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; +import java.util.stream.Collectors; + /** * Controller to handle exceptions. * @@ -48,4 +52,17 @@ public class DefaultExceptionHandler { return new ObjectResponse<>("ERROR", error); } + @ExceptionHandler(MethodArgumentNotValidException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public @ResponseBody ObjectResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) { + logger.error("Error occurred while processing the request: {}", ex.getMessage()); + logger.debug("Exception details:", ex); + final PowerAuthError error = new PowerAuthError(); + error.setCode("ERROR"); + error.setMessage(ex.getBindingResult().getFieldErrors().stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.joining(" "))); + return new ObjectResponse<>("ERROR", error); + } + } diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java index 984486e7..5b1501eb 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/HomeController.java @@ -63,6 +63,7 @@ public class HomeController { public void addAttributes(Map model) { model.put("servletContextPath", context.getContextPath()); model.put("hideDeveloperOption", powerAuthFido2TestsConfigProperties.shouldHideDeveloperOptions()); + model.put("emailRequired", powerAuthFido2TestsConfigProperties.isEmailAddressRequired()); } @GetMapping diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegisterCredentialRequest.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegisterCredentialRequest.java index 820b18ef..e729d665 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegisterCredentialRequest.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegisterCredentialRequest.java @@ -20,6 +20,7 @@ import com.webauthn4j.data.AuthenticatorAttachment; import com.webauthn4j.data.PublicKeyCredentialType; +import com.wultra.security.powerauth.fido2.controller.validation.EmailConditional; import com.wultra.security.powerauth.fido2.model.entity.AuthenticatorAttestationResponse; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -33,7 +34,7 @@ public record RegisterCredentialRequest ( @NotBlank String applicationId, - @NotBlank + @NotBlank @EmailConditional String userId, boolean userVerificationRequired, diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegistrationOptionsRequest.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegistrationOptionsRequest.java index 12ef4d0b..01aee3a6 100644 --- a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegistrationOptionsRequest.java +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/request/RegistrationOptionsRequest.java @@ -18,6 +18,7 @@ package com.wultra.security.powerauth.fido2.controller.request; +import com.wultra.security.powerauth.fido2.controller.validation.EmailConditional; import jakarta.validation.constraints.NotBlank; /** @@ -26,7 +27,7 @@ * @author Jan Pesek, jan.pesek@wultra.com */ public record RegistrationOptionsRequest( - @NotBlank + @NotBlank @EmailConditional String userId, @NotBlank diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditional.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditional.java new file mode 100644 index 00000000..2939c349 --- /dev/null +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditional.java @@ -0,0 +1,43 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.wultra.security.powerauth.fido2.controller.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Validation annotation to validate email address. Allow null or empty values. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@Constraint(validatedBy = EmailConditionalValidator.class) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface EmailConditional { + String message() default "Invalid email address."; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidator.java b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidator.java new file mode 100644 index 00000000..cb30e8ce --- /dev/null +++ b/powerauth-fido2-tests/src/main/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidator.java @@ -0,0 +1,50 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.wultra.security.powerauth.fido2.controller.validation; + +import com.wultra.security.powerauth.fido2.configuration.PowerAuthFido2TestsConfigProperties; +import jakarta.validation.ConstraintValidatorContext; +import lombok.AllArgsConstructor; +import org.hibernate.validator.internal.constraintvalidators.AbstractEmailValidator; +import org.springframework.util.StringUtils; + +import java.util.regex.Pattern; + +/** + * Validator to validate email address. Allow null or empty values. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@AllArgsConstructor +public class EmailConditionalValidator extends AbstractEmailValidator { + + private static final Pattern GENERIC_EMAIL_PATTERN = Pattern.compile("[^@\\s]+@[^@\\s]+\\.[^@\\s]+"); + + private final PowerAuthFido2TestsConfigProperties powerAuthFido2TestsConfigProperties; + + @Override + public boolean isValid(final CharSequence value, final ConstraintValidatorContext context) { + if (!StringUtils.hasLength(value) || !powerAuthFido2TestsConfigProperties.isEmailAddressRequired()) { + return true; + } + + return super.isValid(value, context) && GENERIC_EMAIL_PATTERN.matcher(value).matches(); + } + +} diff --git a/powerauth-fido2-tests/src/main/resources/application.properties b/powerauth-fido2-tests/src/main/resources/application.properties index ea619b82..0a03da36 100644 --- a/powerauth-fido2-tests/src/main/resources/application.properties +++ b/powerauth-fido2-tests/src/main/resources/application.properties @@ -16,6 +16,7 @@ powerauth.fido2.test.service.applicationName=powerauth-fido2-tests powerauth.fido2.test.service.applicationDisplayName=PowerAuth FIDO2 Test powerauth.fido2.test.service.applicationEnvironment= powerauth.fido2.test.service.hideDeveloperOptions=false +powerauth.fido2.test.service.emailAddressRequired=false banner.application.name=${powerauth.fido2.test.service.applicationName} banner.application.version=@project.version@ diff --git a/powerauth-fido2-tests/src/main/resources/templates/embeddedLogin.html b/powerauth-fido2-tests/src/main/resources/templates/embeddedLogin.html index c6c280e7..39e43943 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/embeddedLogin.html +++ b/powerauth-fido2-tests/src/main/resources/templates/embeddedLogin.html @@ -19,7 +19,7 @@ -
+
diff --git a/powerauth-fido2-tests/src/main/resources/templates/embeddedPayment.html b/powerauth-fido2-tests/src/main/resources/templates/embeddedPayment.html index 77b5d220..da2a64b1 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/embeddedPayment.html +++ b/powerauth-fido2-tests/src/main/resources/templates/embeddedPayment.html @@ -19,7 +19,7 @@ -
+
diff --git a/powerauth-fido2-tests/src/main/resources/templates/forms/loginForm.html b/powerauth-fido2-tests/src/main/resources/templates/forms/loginForm.html index 9751c7da..c95600ed 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/forms/loginForm.html +++ b/powerauth-fido2-tests/src/main/resources/templates/forms/loginForm.html @@ -16,7 +16,8 @@
- + +
diff --git a/powerauth-fido2-tests/src/main/resources/templates/login.html b/powerauth-fido2-tests/src/main/resources/templates/login.html index 775a64a0..5617863c 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/login.html +++ b/powerauth-fido2-tests/src/main/resources/templates/login.html @@ -46,7 +46,7 @@

PowerAuth & FIDO2

-
+
diff --git a/powerauth-fido2-tests/src/main/resources/templates/payment.html b/powerauth-fido2-tests/src/main/resources/templates/payment.html index 9c88dcd8..710aed04 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/payment.html +++ b/powerauth-fido2-tests/src/main/resources/templates/payment.html @@ -46,7 +46,7 @@

PowerAuth & FIDO2

-
+
diff --git a/powerauth-fido2-tests/src/test/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidatorTest.java b/powerauth-fido2-tests/src/test/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidatorTest.java new file mode 100644 index 00000000..a22c70c0 --- /dev/null +++ b/powerauth-fido2-tests/src/test/java/com/wultra/security/powerauth/fido2/controller/validation/EmailConditionalValidatorTest.java @@ -0,0 +1,75 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.wultra.security.powerauth.fido2.controller.validation; + +import com.wultra.security.powerauth.fido2.configuration.PowerAuthFido2TestsConfigProperties; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +/** + * Test of {@link EmailConditionalValidator}. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@ExtendWith(MockitoExtension.class) +class EmailConditionalValidatorTest { + + @Mock(strictness = Mock.Strictness.LENIENT) + private PowerAuthFido2TestsConfigProperties properties; + + @InjectMocks + private EmailConditionalValidator tested; + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = {"a@b.c", "a.b-c_d@my-domain.com"}) + void testValidation_emailRequired_validExamples(final String input) { + when(properties.isEmailAddressRequired()).thenReturn(true); + assertTrue(isValid(input)); + } + + @ParameterizedTest + @ValueSource(strings = {"abcd@abc", " "}) + void testValidation_emailRequired_invalidExamples(final String input) { + when(properties.isEmailAddressRequired()).thenReturn(true); + assertFalse(isValid(input)); + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = {"username", " ", "a@b.c"}) + void testValidation_emailNotRequired(final String input) { + when(properties.isEmailAddressRequired()).thenReturn(false); + assertTrue(isValid(input)); + } + + private boolean isValid(final String parameter) { + return tested.isValid(parameter, null); + } + +} From 71b34e13688aeef7671aa5ccad6af84507ce92d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Fri, 6 Sep 2024 11:17:11 +0200 Subject: [PATCH 13/35] Fix #513: FIDO2 Test application: Edit texts (#514) --- .../src/main/resources/templates/login.html | 15 ++++++--------- .../src/main/resources/templates/payment.html | 15 ++++++--------- .../main/webapp/resources/css/wultra-login.css | 3 ++- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/powerauth-fido2-tests/src/main/resources/templates/login.html b/powerauth-fido2-tests/src/main/resources/templates/login.html index 5617863c..dc2460ae 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/login.html +++ b/powerauth-fido2-tests/src/main/resources/templates/login.html @@ -23,24 +23,21 @@
DEMO
-

PowerAuth & FIDO2

+

PERSONAL IDENTITY DEVICE & FIDO2

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque finibus efficitur orci. Quisque - pharetra ipsum ante. Aliquam ante nisi, ultricies vel faucibus ut, varius at tellus. + Discover Talisman in action with our interactive demo. Experience effortless and secure + authentication for your digital services. See firsthand how to connect and manage multiple accounts + with advanced security features.

- Sed ipsum quam, lobortis non nisl eget, sodales ullamcorper lacus. Sed varius augue auctor, dictum - mauris et, aliquet odio. In tristique dui blandit lectus scelerisque, auctor mattis felis efficitur. - Quisque nec ornare metus, at rutrum massa. Mauris elementum erat non mollis venenatis. + For instructions and more information, visit Demo | Wultra Talisman.

- Donec ultrices nisl eu tellus finibus pellentesque. Nam molestie neque ut ligula ultrices, vel - facilisis lorem rhoncus. Praesent sodales dolor vitae odio vestibulum tempor. In blandit rhoncus dui - sit amet tempor. Maecenas dapibus ante vel velit lobortis, at volutpat turpis venenatis. + You can find the user manual here: Hardware Token Specifications

diff --git a/powerauth-fido2-tests/src/main/resources/templates/payment.html b/powerauth-fido2-tests/src/main/resources/templates/payment.html index 710aed04..d62a3c8d 100644 --- a/powerauth-fido2-tests/src/main/resources/templates/payment.html +++ b/powerauth-fido2-tests/src/main/resources/templates/payment.html @@ -23,24 +23,21 @@
DEMO
-

PowerAuth & FIDO2

+

PERSONAL IDENTITY DEVICE & FIDO2

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque finibus efficitur orci. Quisque - pharetra ipsum ante. Aliquam ante nisi, ultricies vel faucibus ut, varius at tellus. + Discover Talisman in action with our interactive demo. Experience effortless and secure + authentication for your digital services. See firsthand how to connect and manage multiple accounts + with advanced security features.

- Sed ipsum quam, lobortis non nisl eget, sodales ullamcorper lacus. Sed varius augue auctor, dictum - mauris et, aliquet odio. In tristique dui blandit lectus scelerisque, auctor mattis felis efficitur. - Quisque nec ornare metus, at rutrum massa. Mauris elementum erat non mollis venenatis. + For instructions and more information, visit Demo | Wultra Talisman.

- Donec ultrices nisl eu tellus finibus pellentesque. Nam molestie neque ut ligula ultrices, vel - facilisis lorem rhoncus. Praesent sodales dolor vitae odio vestibulum tempor. In blandit rhoncus dui - sit amet tempor. Maecenas dapibus ante vel velit lobortis, at volutpat turpis venenatis. + You can find the user manual here: Hardware Token Specifications

diff --git a/powerauth-fido2-tests/src/main/webapp/resources/css/wultra-login.css b/powerauth-fido2-tests/src/main/webapp/resources/css/wultra-login.css index 31c9fee8..2469f4eb 100644 --- a/powerauth-fido2-tests/src/main/webapp/resources/css/wultra-login.css +++ b/powerauth-fido2-tests/src/main/webapp/resources/css/wultra-login.css @@ -34,6 +34,7 @@ body { .headline { font-size: 48px; font-weight:700; + line-height: 1; } .header { @@ -70,7 +71,7 @@ h2 { .flex-grid .col2 { display: flex; justify-content: center; - align-items: center; + align-items: start; width: 100%; padding-left: 40px; } From aa05121a4453f958919f1f61b12a05b489c155bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:53:03 +0000 Subject: [PATCH 14/35] Bump gatling.version from 3.11.5 to 3.12.0 Bumps `gatling.version` from 3.11.5 to 3.12.0. Updates `io.gatling.highcharts:gatling-charts-highcharts` from 3.11.5 to 3.12.0 - [Commits](https://github.com/gatling/gatling-highcharts/compare/v3.11.5...v3.12.0) Updates `io.gatling:gatling-test-framework` from 3.11.5 to 3.12.0 - [Commits](https://github.com/gatling/gatling/compare/v3.11.5...v3.12.0) --- updated-dependencies: - dependency-name: io.gatling.highcharts:gatling-charts-highcharts dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: io.gatling:gatling-test-framework dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- powerauth-load-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index 0d2dd7a9..b983c761 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -42,7 +42,7 @@ 4.9.6 4.9.2 - 3.11.5 + 3.12.0 From 1c1a8562f3ef12b7a9fa673fbb7418554c9dd9db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:53:33 +0000 Subject: [PATCH 15/35] Bump com.webauthn4j:webauthn4j-core Bumps [com.webauthn4j:webauthn4j-core](https://github.com/webauthn4j/webauthn4j) from 0.25.1.RELEASE to 0.26.0.RELEASE. - [Release notes](https://github.com/webauthn4j/webauthn4j/releases) - [Changelog](https://github.com/webauthn4j/webauthn4j/blob/master/github-release-notes-generator.yml) - [Commits](https://github.com/webauthn4j/webauthn4j/compare/0.25.1.RELEASE...0.26.0.RELEASE) --- updated-dependencies: - dependency-name: com.webauthn4j:webauthn4j-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 099b7c90..ce68875b 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 2.6.0 8.0 - 0.25.1.RELEASE + 0.26.0.RELEASE true From ce8b786a143b2f61ac7377778e47f3d157b157e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 10 Sep 2024 09:44:38 +0200 Subject: [PATCH 16/35] Fix #480: OIDC: Implement end-to-end tests (#497) * Fix #480: OIDC: Implement end-to-end tests --- .github/workflows/maven-integration-test.yml | 4 + powerauth-backend-tests/README.md | 16 + ...OidcActivationConfigurationProperties.java | 40 +++ .../test/v32/PowerAuthOidcActivationTest.java | 277 ++++++++++++++++++ .../src/test/resources/application.properties | 6 + 5 files changed, 343 insertions(+) create mode 100644 powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthOidcActivationConfigurationProperties.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java diff --git a/.github/workflows/maven-integration-test.yml b/.github/workflows/maven-integration-test.yml index 0cfacaf5..151ed054 100644 --- a/.github/workflows/maven-integration-test.yml +++ b/.github/workflows/maven-integration-test.yml @@ -44,6 +44,10 @@ jobs: POWERAUTH_SERVICE_SECURITY_CLIENTTOKEN: ${{ secrets.POWERAUTH_SERVICE_SECURITY_CLIENTTOKEN }} POWERAUTH_SERVICE_SECURITY_CLIENTSECRET: ${{ secrets.POWERAUTH_SERVICE_SECURITY_CLIENTSECRET }} POWERAUTH_TEST_INCLUDECUSTOMTESTS: ${{ inputs.includeCustomTests == '' || inputs.includeCustomTests }} # default includeCustomTests=true even for 'schedule' event + POWERAUTH_TEST_ACTIVATION_OIDC_USERNAME: ${{ secrets.POWERAUTH_TEST_ACTIVATION_OIDC_USERNAME }} + POWERAUTH_TEST_ACTIVATION_OIDC_PASSWORD: ${{ secrets.POWERAUTH_TEST_ACTIVATION_OIDC_PASSWORD }} + POWERAUTH_TEST_ACTIVATION_OIDC_PROVIDERID: ${{ secrets.POWERAUTH_TEST_ACTIVATION_OIDC_PROVIDERID }} + POWERAUTH_TEST_ACTIVATION_OIDC_SUB: ${{ secrets.POWERAUTH_TEST_ACTIVATION_OIDC_SUB }} - name: Publish Test Report uses: mikepenz/action-junit-report@v4 if: always() diff --git a/powerauth-backend-tests/README.md b/powerauth-backend-tests/README.md index b18a4da9..cbafd086 100644 --- a/powerauth-backend-tests/README.md +++ b/powerauth-backend-tests/README.md @@ -105,6 +105,22 @@ powerauth.service.security.clientToken= powerauth.service.security.clientSecret= ``` + +### OIDC Activation + +OpenID Connect activation requires the provider configuration. +If the properties are not filled, the test is ignored. +Also a database entry must exist in the table `pa_application_config` with a config key `oauth2_providers` and appropriate config values. + +```properties +# OIDC activation +powerauth.test.activation.oidc.username= +powerauth.test.activation.oidc.password= +powerauth.test.activation.oidc.providerId= +powerauth.test.activation.oidc.sub= +``` + + ## Running Tests from Console You can simply run the tests using Maven in folder `powerauth-backend-tests`: diff --git a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthOidcActivationConfigurationProperties.java b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthOidcActivationConfigurationProperties.java new file mode 100644 index 00000000..11f45d65 --- /dev/null +++ b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthOidcActivationConfigurationProperties.java @@ -0,0 +1,40 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.configuration; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Properties for OIDC activation. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@ConfigurationProperties(prefix = "powerauth.test.activation.oidc") +@Component +@Getter +@Setter +public class PowerAuthOidcActivationConfigurationProperties { + + private String username; + private String password; + private String providerId; + private String sub; +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java new file mode 100644 index 00000000..c7316658 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java @@ -0,0 +1,277 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v32; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; +import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; +import com.wultra.security.powerauth.configuration.PowerAuthOidcActivationConfigurationProperties; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.v3.CreateActivationStep; +import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer2Response; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcApplicationConfiguration; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcApplicationConfigurationService; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcConfigurationQuery; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; +import java.security.SecureRandom; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test direct activation via OIDC. + *

+ * Mind that {@code powerauth.test.activation.*} properties must be filled, otherwise the test is ignored. + * Also a database entry must exist in the table {@code pa_application_config} with a config key {@code oauth2_providers} and appropriate config values. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@EnableConfigurationProperties +@ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) +@EnabledIf(expression = "#{T(org.springframework.util.StringUtils).hasText('${powerauth.test.activation.oidc.providerId}')}", loadContext = true) +class PowerAuthOidcActivationTest { + + private static final String VERSION = "3.2"; + + private static File dataFile; + + @Autowired + private PowerAuthTestConfiguration config; + + @Autowired + private PowerAuthOidcActivationConfigurationProperties oidcConfigProperties; + + @Autowired + private OidcApplicationConfigurationService oidcApplicationConfigurationService; + + @Autowired + private PowerAuthClient powerAuthClient; + + @LocalServerPort + private int port; + + private CreateActivationStepModel model; + private ObjectStepLogger stepLogger; + private OidcApplicationConfiguration oidcConfig; + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws Exception { + final File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + + model = new CreateActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setUriString("http://localhost:" + port); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + stepLogger = new ObjectStepLogger(System.out); + + oidcConfig = oidcApplicationConfigurationService.fetchOidcApplicationConfiguration(OidcConfigurationQuery.builder() + .applicationKey(config.getApplicationKey()) + .providerId(oidcConfigProperties.getProviderId()) + .build()); + } + + @Test + void testOidcActivation() throws Exception { + final String nonce = generateRandomString(); + + final WebClient webClient = createWebClient(); + final UriComponents authorizeUriComponents = authorize(webClient, nonce); + final String code = login(webClient, authorizeUriComponents); + assertNotNull(code); + + createActivation(nonce, code); + } + + private UriComponents authorize(final WebClient webClient, final String nonce) { + final Map uriVariables = Map.of( + "clientId", oidcConfig.getClientId(), + "redirectUri", oidcConfig.getRedirectUri(), + "state", generateRandomString(), + "nonce", nonce, + "scope", oidcConfig.getScopes() + ); + final String authorizationUrl = oidcConfig.getIssuerUri() + "/authorize?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}&state={state}&nonce={nonce}&response_type=code"; + final WebClient.ResponseSpec responseSpec = webClient.get().uri(authorizationUrl, uriVariables).retrieve(); + return UriComponentsBuilder.fromUri(fetchRedirectUri(responseSpec)).build(); + } + + private String login(final WebClient webClient, final UriComponents authorizeUriComponents) { + final String authorizeState = authorizeUriComponents.getQueryParams().getFirst("state"); + assertNotNull(authorizeState); + + final MultiValueMap requestBody = new LinkedMultiValueMap<>(); + requestBody.add("username", oidcConfigProperties.getUsername()); + requestBody.add("password", oidcConfigProperties.getPassword()); + requestBody.add("state", authorizeState); + + final String loginUrl = oidcConfig.getIssuerUri() + authorizeUriComponents.getPath(); + final WebClient.ResponseSpec responseSpec = webClient + .post() + .uri(loginUrl) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .body(BodyInserters.fromFormData(requestBody)) + .retrieve(); + final URI redirectUri = fetchRedirectUri(responseSpec); + return resumeLogin(webClient, oidcConfig.getIssuerUri() + redirectUri); + } + + private String resumeLogin(final WebClient webClient, final String uri) { + final WebClient.ResponseSpec responseSpec = webClient.get().uri(uri).retrieve(); + final URI redirectUri = fetchRedirectUri(responseSpec); + final UriComponents uriComponents = UriComponentsBuilder.fromUri(redirectUri).build(); + return uriComponents.getQueryParams().getFirst("code"); + } + + private URI fetchRedirectUri(final WebClient.ResponseSpec responseSpec) { + final ResponseEntity bodilessEntity = responseSpec.toBodilessEntity().block(); + assertNotNull(bodilessEntity); + final HttpStatusCode statusCode = bodilessEntity.getStatusCode(); + assertTrue(statusCode.is3xxRedirection(), "Status Code: " + statusCode); + final URI location = bodilessEntity.getHeaders().getLocation(); + assertNotNull(location); + return location; + } + + private static WebClient createWebClient() { + final List cookies = new ArrayList<>(); + + final ExchangeFilterFunction cookieFilter = ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + if (!cookies.isEmpty()) { + clientRequest = ClientRequest.from(clientRequest) + .header(HttpHeaders.COOKIE, String.join("; ", cookies)) + .build(); + } + return Mono.just(clientRequest); + }).andThen(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + cookies.clear(); + cookies.addAll(Objects.requireNonNull(clientResponse.headers().asHttpHeaders().get(HttpHeaders.SET_COOKIE))); + return Mono.just(clientResponse); + })); + + return WebClient.builder() + .filter(cookieFilter) + .build(); + } + + private static String generateRandomString() { + final SecureRandom secureRandom = new SecureRandom(); + final byte[] randomBytes = new byte[32]; + secureRandom.nextBytes(randomBytes); + return Base64.getUrlEncoder().encodeToString(randomBytes); + } + + private void createActivation(final String nonce, final String code) throws Exception { + final Map identityAttributes = Map.of( + "method", "oidc", + "providerId", oidcConfig.getProviderId(), + "code", code, + "nonce", nonce + ); + + model.setIdentityAttributes(identityAttributes); + + new CreateOidcActivationStep().execute(stepLogger, model.toMap()); + assertTrue(stepLogger.getResult().success()); + assertEquals(200, stepLogger.getResponse().statusCode()); + + final ActivationLayer2Response layer2Response = fetchLayer2Response(stepLogger); + final String activationId = layer2Response.getActivationId(); + + assertNotNull(activationId); + assertNotNull(layer2Response.getCtrData()); + assertNotNull(layer2Response.getServerPublicKey()); + + // Verify activation status - activation was automatically committed + final GetActivationStatusResponse statusResponseActive = powerAuthClient.getActivationStatus(activationId); + assertEquals(ActivationStatus.ACTIVE, statusResponseActive.getActivationStatus()); + assertEquals(oidcConfigProperties.getSub(), statusResponseActive.getUserId()); + + powerAuthClient.removeActivation(activationId, "test"); + } + + private static ActivationLayer2Response fetchLayer2Response(final ObjectStepLogger stepLogger) { + return stepLogger.getItems().stream() + .filter(item -> "Decrypted Layer 2 Response".equals(item.name())) + .map(item -> (ActivationLayer2Response) item.object()) + .findAny() + .orElseThrow(() -> AssertionFailureBuilder.assertionFailure().message("Response was not successfully decrypted").build()); + } + + static class CreateOidcActivationStep extends CreateActivationStep{ + @Override + protected ActivationLayer1Request prepareLayer1Request(final StepContext stepContext, final EciesEncryptedRequest encryptedRequestL2) { + final ActivationLayer1Request activationLayer1Request = super.prepareLayer1Request(stepContext, encryptedRequestL2); + activationLayer1Request.setType(ActivationType.DIRECT); + return activationLayer1Request; + } + } +} diff --git a/powerauth-backend-tests/src/test/resources/application.properties b/powerauth-backend-tests/src/test/resources/application.properties index 5ef0319e..b6f3569b 100644 --- a/powerauth-backend-tests/src/test/resources/application.properties +++ b/powerauth-backend-tests/src/test/resources/application.properties @@ -35,5 +35,11 @@ powerauth.test.identity.otp-verification.skip=false # which pass all checks, and there exists a workaround for the iProov verification process in tests. powerauth.test.identity.result-verification.skip=false +# OIDC activation +powerauth.test.activation.oidc.username= +powerauth.test.activation.oidc.password= +powerauth.test.activation.oidc.providerId= +powerauth.test.activation.oidc.sub= + # TODO - remove circular dependencies from test setup spring.main.allow-circular-references=true From 34f21d057ae87bc6b059262468c50984a77631da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 10 Sep 2024 11:16:41 +0200 Subject: [PATCH 17/35] Fix #493: Add test for OIDC configuration endpoint (#494) * Fix #493: Add test for OIDC configuration endpoint --- ...PowerAuthApplicationConfigurationTest.java | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java new file mode 100644 index 00000000..a374064a --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java @@ -0,0 +1,147 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v3x; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.wultra.app.enrollmentserver.api.model.enrollment.request.OidcApplicationConfigurationRequest; +import com.wultra.app.enrollmentserver.api.model.enrollment.response.OidcApplicationConfigurationResponse; +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.core.rest.model.base.response.ObjectResponse; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; +import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.v3.EncryptStep; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.opentest4j.AssertionFailedError; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test for {@code /api/config/oidc}. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthApplicationConfigurationTest { + + private static final String VERSION = "3.2"; + + private static final ObjectMapper objectMapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + + @Autowired + private PowerAuthTestConfiguration config; + + @Autowired + private PowerAuthClient powerAuthClient; + + private EncryptStepModel encryptModel; + + @BeforeEach + void setUp() throws Exception { + encryptModel = new EncryptStepModel(); + encryptModel.setApplicationKey(config.getApplicationKey()); + encryptModel.setApplicationSecret(config.getApplicationSecret()); + encryptModel.setMasterPublicKey(config.getMasterPublicKey()); + encryptModel.setHeaders(new HashMap<>()); + encryptModel.setResultStatusObject(config.getResultStatusObjectV32()); + encryptModel.setVersion(VERSION); + + final Object oidcConfiguration = Map.of( + "providerId", "xyz999", + "clientId", "jabberwocky", + "clientSecret", "top secret", + "scopes", "openid", + "authorizeUri", "https://authorize.example.com", + "redirectUri", "https://redirect.example.com", + "tokenUri", "https://...", + "userInfoUri", "https://..." + ); + + powerAuthClient.createApplicationConfig(config.getApplicationId(), "oauth2_providers", List.of(oidcConfiguration)); + } + + @Test + void testOidc() throws Exception { + final OidcApplicationConfigurationRequest request = new OidcApplicationConfigurationRequest(); + request.setProviderId("xyz999"); + + encryptModel.setUriString(config.getEnrollmentServiceUrl() + "/api/config/oidc"); + encryptModel.setScope("application"); + encryptModel.setData(objectMapper.writeValueAsBytes(request)); + + final ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); + new EncryptStep().execute(stepLogger, encryptModel.toMap()); + assertTrue(stepLogger.getResult().success()); + assertEquals(200, stepLogger.getResponse().statusCode()); + + final EciesEncryptedResponse response = (EciesEncryptedResponse) stepLogger.getResponse().responseObject(); + assertNotNull(response.getEncryptedData()); + assertNotNull(response.getMac()); + + final OidcApplicationConfigurationResponse decryptedData = stepLogger.getItems().stream() + .filter(isStepItemDecryptedResponse()) + .map(StepItem::object) + .map(Object::toString) + .map(it -> safeReadValue(it, new TypeReference>() {})) + .filter(Objects::nonNull) + .map(ObjectResponse::getResponseObject) + .findFirst() + .orElseThrow(() -> new AssertionFailedError("Decrypted data not found")); + + assertEquals("xyz999", decryptedData.getProviderId()); + assertEquals("jabberwocky", decryptedData.getClientId()); + assertEquals("openid", decryptedData.getScopes()); + assertEquals("https://authorize.example.com", decryptedData.getAuthorizeUri()); + assertEquals("https://redirect.example.com", decryptedData.getRedirectUri()); + assertEquals("https://redirect.example.com", decryptedData.getRedirectUri()); + assertFalse(decryptedData.isPkceEnabled()); + } + + private static Predicate isStepItemDecryptedResponse() { + return stepItem -> "Decrypted Response".equals(stepItem.name()); + } + + private static T safeReadValue(final String value, final TypeReference typeReference) { + try { + return objectMapper.readValue(value, typeReference); + } catch (JsonProcessingException e) { + fail("Unable to read json", e); + return null; + } + } + +} From c8b7f6430fde95466683a9c8439e9946c38fc8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 10 Sep 2024 12:34:19 +0200 Subject: [PATCH 18/35] Fix #506: Add test for OIDC PKCE (#507) * Fix #506: Add test for OIDC PKCE --- .../test/v32/PowerAuthOidcActivationTest.java | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java index c7316658..92f23b54 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java @@ -59,6 +59,9 @@ import java.io.FileWriter; import java.io.IOException; import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.*; @@ -148,7 +151,40 @@ void testOidcActivation() throws Exception { final String code = login(webClient, authorizeUriComponents); assertNotNull(code); - createActivation(nonce, code); + final Map identityAttributes = Map.of( + "method", "oidc", + "providerId", oidcConfig.getProviderId(), + "code", code, + "nonce", nonce + ); + createActivation(identityAttributes); + } + + @Test + void testOidcPkceActivation() throws Exception { + final String nonce = generateRandomString(); + final String codeVerifier = generateRandomString(); + final String codeChallenge = convertToCodeChallenge(codeVerifier); + + final WebClient webClient = createWebClient(); + final UriComponents authorizeUriComponents = authorizeWithPkce(webClient, nonce, codeChallenge); + final String code = login(webClient, authorizeUriComponents); + assertNotNull(code); + + final Map identityAttributes = Map.of( + "method", "oidc", + "providerId", oidcConfig.getProviderId(), + "code", code, + "nonce", nonce, + "codeVerifier", codeVerifier + ); + createActivation(identityAttributes); + } + + private static String convertToCodeChallenge(final String codeVerifier) throws NoSuchAlgorithmException { + final MessageDigest digest = MessageDigest.getInstance("SHA-256"); + final byte[] hash = digest.digest(codeVerifier.getBytes(StandardCharsets.US_ASCII)); + return Base64.getUrlEncoder().withoutPadding().encodeToString(hash); } private UriComponents authorize(final WebClient webClient, final String nonce) { @@ -164,6 +200,21 @@ private UriComponents authorize(final WebClient webClient, final String nonce) { return UriComponentsBuilder.fromUri(fetchRedirectUri(responseSpec)).build(); } + private UriComponents authorizeWithPkce(final WebClient webClient, final String nonce, final String codeChallenge) { + final Map uriVariables = Map.of( + "clientId", oidcConfig.getClientId(), + "redirectUri", oidcConfig.getRedirectUri(), + "state", generateRandomString(), + "nonce", nonce, + "scope", oidcConfig.getScopes(), + "code_challenge", codeChallenge, + "code_challenge_method", "S256" + ); + final String authorizationUrl = oidcConfig.getIssuerUri() + "/authorize?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}&state={state}&nonce={nonce}&response_type=code&code_challenge={code_challenge}&code_challenge_method={code_challenge_method}"; + final WebClient.ResponseSpec responseSpec = webClient.get().uri(authorizationUrl, uriVariables).retrieve(); + return UriComponentsBuilder.fromUri(fetchRedirectUri(responseSpec)).build(); + } + private String login(final WebClient webClient, final UriComponents authorizeUriComponents) { final String authorizeState = authorizeUriComponents.getQueryParams().getFirst("state"); assertNotNull(authorizeState); @@ -226,17 +277,10 @@ private static String generateRandomString() { final SecureRandom secureRandom = new SecureRandom(); final byte[] randomBytes = new byte[32]; secureRandom.nextBytes(randomBytes); - return Base64.getUrlEncoder().encodeToString(randomBytes); + return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes); } - private void createActivation(final String nonce, final String code) throws Exception { - final Map identityAttributes = Map.of( - "method", "oidc", - "providerId", oidcConfig.getProviderId(), - "code", code, - "nonce", nonce - ); - + private void createActivation(final Map identityAttributes) throws Exception { model.setIdentityAttributes(identityAttributes); new CreateOidcActivationStep().execute(stepLogger, model.toMap()); From 8fb6c67a78c6ab03761074c1bb82f3f21f273c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Wed, 11 Sep 2024 07:40:15 +0200 Subject: [PATCH 19/35] Fix configuration of PowerAuthApplicationConfigurationTest (#517) * Fix configuration of PowerAuthApplicationConfigurationTest A follow-up to #493 --- ...PowerAuthApplicationConfigurationTest.java | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java index a374064a..e996ed7b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.wultra.app.enrollmentserver.api.model.enrollment.request.OidcApplicationConfigurationRequest; import com.wultra.app.enrollmentserver.api.model.enrollment.response.OidcApplicationConfigurationResponse; -import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthOidcActivationConfigurationProperties; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; @@ -33,16 +33,13 @@ import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.opentest4j.AssertionFailedError; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit.jupiter.EnabledIf; import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.function.Predicate; @@ -53,9 +50,9 @@ * * @author Lubos Racansky, lubos.racansky@wultra.com */ -@ExtendWith(SpringExtension.class) -@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@SpringBootTest(classes = {PowerAuthTestConfiguration.class, PowerAuthOidcActivationConfigurationProperties.class}) @EnableConfigurationProperties +@EnabledIf(expression = "#{T(org.springframework.util.StringUtils).hasText('${powerauth.test.activation.oidc.providerId}')}", loadContext = true) class PowerAuthApplicationConfigurationTest { private static final String VERSION = "3.2"; @@ -63,15 +60,15 @@ class PowerAuthApplicationConfigurationTest { private static final ObjectMapper objectMapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); @Autowired - private PowerAuthTestConfiguration config; + private PowerAuthOidcActivationConfigurationProperties oidcConfigProperties; @Autowired - private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; private EncryptStepModel encryptModel; @BeforeEach - void setUp() throws Exception { + void setUp() { encryptModel = new EncryptStepModel(); encryptModel.setApplicationKey(config.getApplicationKey()); encryptModel.setApplicationSecret(config.getApplicationSecret()); @@ -79,25 +76,12 @@ void setUp() throws Exception { encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObjectV32()); encryptModel.setVersion(VERSION); - - final Object oidcConfiguration = Map.of( - "providerId", "xyz999", - "clientId", "jabberwocky", - "clientSecret", "top secret", - "scopes", "openid", - "authorizeUri", "https://authorize.example.com", - "redirectUri", "https://redirect.example.com", - "tokenUri", "https://...", - "userInfoUri", "https://..." - ); - - powerAuthClient.createApplicationConfig(config.getApplicationId(), "oauth2_providers", List.of(oidcConfiguration)); } @Test void testOidc() throws Exception { final OidcApplicationConfigurationRequest request = new OidcApplicationConfigurationRequest(); - request.setProviderId("xyz999"); + request.setProviderId(oidcConfigProperties.getProviderId()); encryptModel.setUriString(config.getEnrollmentServiceUrl() + "/api/config/oidc"); encryptModel.setScope("application"); @@ -122,12 +106,10 @@ void testOidc() throws Exception { .findFirst() .orElseThrow(() -> new AssertionFailedError("Decrypted data not found")); - assertEquals("xyz999", decryptedData.getProviderId()); - assertEquals("jabberwocky", decryptedData.getClientId()); - assertEquals("openid", decryptedData.getScopes()); - assertEquals("https://authorize.example.com", decryptedData.getAuthorizeUri()); - assertEquals("https://redirect.example.com", decryptedData.getRedirectUri()); - assertEquals("https://redirect.example.com", decryptedData.getRedirectUri()); + assertEquals(oidcConfigProperties.getProviderId(), decryptedData.getProviderId()); + assertNotNull(decryptedData.getClientId()); + assertNotNull(decryptedData.getScopes()); + assertNotNull(decryptedData.getRedirectUri()); assertFalse(decryptedData.isPkceEnabled()); } From 2ae25085eacba6f87ab0bd52ea0463084ef0edc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Wed, 18 Sep 2024 16:13:42 +0800 Subject: [PATCH 20/35] Fix #518: Add commitPhase parameter to tests (#519) --- .../PowerAuthActivationCommitPhaseShared.java | 356 ++++++++++++++++++ .../shared/PowerAuthActivationOtpShared.java | 33 +- .../shared/PowerAuthActivationShared.java | 4 +- .../PowerAuthCustomActivationOtpShared.java | 2 +- .../test/shared/PowerAuthRecoveryShared.java | 10 +- .../test/shared/PowerAuthSignatureShared.java | 4 +- .../PowerAuthActivationCommitPhaseTest.java | 140 +++++++ .../test/v31/PowerAuthActivationOtpTest.java | 8 +- .../PowerAuthIdentityVerificationTest.java | 2 +- .../test/v31/PowerAuthOnboardingTest.java | 2 +- .../PowerAuthActivationCommitPhaseTest.java | 141 +++++++ .../test/v32/PowerAuthActivationOtpTest.java | 8 +- .../PowerAuthIdentityVerificationTest.java | 2 +- .../test/v32/PowerAuthOnboardingTest.java | 2 +- .../scenario/ActivationInitScenario.scala | 2 +- 15 files changed, 664 insertions(+), 52 deletions(-) create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java new file mode 100644 index 00000000..4aad1656 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java @@ -0,0 +1,356 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.shared; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.ActivationOtpValidation; +import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; +import com.wultra.security.powerauth.client.model.enumeration.CommitPhase; +import com.wultra.security.powerauth.client.model.enumeration.RecoveryCodeStatus; +import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.client.model.request.CommitActivationRequest; +import com.wultra.security.powerauth.client.model.request.InitActivationRequest; +import com.wultra.security.powerauth.client.model.response.CommitActivationResponse; +import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; +import com.wultra.security.powerauth.client.model.response.InitActivationResponse; +import com.wultra.security.powerauth.client.model.response.LookupRecoveryCodesResponse; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.v3.GetStatusStep; +import io.getlime.security.powerauth.lib.cmd.steps.v3.PrepareActivationStep; +import org.json.simple.JSONObject; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * PowerAuth activation commit phase shared logic. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class PowerAuthActivationCommitPhaseShared { + + public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, + PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + final InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + initRequest.setActivationOtp(validOtpValue); + initRequest.setCommitPhase(CommitPhase.ON_KEY_EXCHANGE); + final InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + model.setAdditionalActivationOtp(validOtpValue); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertTrue(stepLoggerPrepare.getResult().success()); + assertEquals(200, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + final GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertNotNull(activationStatusResponse); + assertEquals(ActivationStatus.ACTIVE, activationStatusResponse.getActivationStatus()); + + // Verify associated recovery code + final LookupRecoveryCodesResponse recoveryCodes = powerAuthClient.lookupRecoveryCodes(config.getUser(version), initResponse.getActivationId(), config.getApplicationId(), null, null); + assertEquals(1, recoveryCodes.getRecoveryCodes().size()); + assertEquals(RecoveryCodeStatus.ACTIVE, recoveryCodes.getRecoveryCodes().get(0).getStatus()); + + // Remove activation + powerAuthClient.removeActivation(initResponse.getActivationId(), "test"); + } + + public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, + PrepareActivationStepModel model, String validOtpValue, + String invalidOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + initRequest.setActivationOtp(validOtpValue); + initRequest.setCommitPhase(CommitPhase.ON_KEY_EXCHANGE); + InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + for (int iteration = 1; iteration <= 5; iteration++) { + final boolean lastIteration = iteration == 5; + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + model.setAdditionalActivationOtp(invalidOtpValue); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertFalse(stepLoggerPrepare.getResult().success()); + assertEquals(400, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + ActivationStatus expectedActivationStatus = lastIteration ? ActivationStatus.REMOVED : ActivationStatus.CREATED; + GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertNotNull(activationStatusResponse); + assertEquals(expectedActivationStatus, activationStatusResponse.getActivationStatus()); + } + } + + public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, + String validOtpValue, String invalidOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + initRequest.setActivationOtp(validOtpValue); + initRequest.setCommitPhase(CommitPhase.ON_COMMIT); + InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertTrue(stepLoggerPrepare.getResult().success()); + assertEquals(200, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertNotNull(activationStatusResponse); + assertEquals(ActivationStatus.PENDING_COMMIT, activationStatusResponse.getActivationStatus()); + + // Try commit activation with wrong OTP. Last attempt is valid. + for (int iteration = 1; iteration <= 5; iteration++) { + boolean lastIteration = iteration == 5; + final CommitActivationRequest commitRequest = new CommitActivationRequest(); + commitRequest.setActivationId(initResponse.getActivationId()); + commitRequest.setActivationOtp(lastIteration ? validOtpValue : invalidOtpValue); + + boolean isActivated; + try { + final CommitActivationResponse commitResponse = powerAuthClient.commitActivation(commitRequest); + isActivated = commitResponse.isActivated(); + } catch (PowerAuthClientException ex) { + isActivated = false; + } + assertEquals(lastIteration, isActivated); + + // Verify activation status + activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(lastIteration ? ActivationStatus.ACTIVE : ActivationStatus.PENDING_COMMIT, activationStatusResponse.getActivationStatus()); + } + + // Remove activation + powerAuthClient.removeActivation(initResponse.getActivationId(), "test"); + } + + public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, + PrepareActivationStepModel model, String validOtpValue, + String invalidOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + initRequest.setActivationOtp(validOtpValue); + initRequest.setCommitPhase(CommitPhase.ON_COMMIT); + InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertTrue(stepLoggerPrepare.getResult().success()); + assertEquals(200, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertNotNull(activationStatusResponse); + assertEquals(ActivationStatus.PENDING_COMMIT, activationStatusResponse.getActivationStatus()); + + // Try commit activation with wrong OTP. Last attempt is valid. + for (int iteration = 1; iteration <= 5; iteration++) { + boolean lastIteration = iteration == 5; + CommitActivationRequest commitRequest = new CommitActivationRequest(); + commitRequest.setActivationId(initResponse.getActivationId()); + commitRequest.setActivationOtp(invalidOtpValue); + + boolean isActivated; + try { + CommitActivationResponse commitResponse = powerAuthClient.commitActivation(commitRequest); + isActivated = commitResponse.isActivated(); + } catch (PowerAuthClientException ex) { + isActivated = false; + } + assertFalse(isActivated); + + // Verify activation status + ActivationStatus expectedActivationStatus = lastIteration ? ActivationStatus.REMOVED : ActivationStatus.PENDING_COMMIT; + activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(expectedActivationStatus, activationStatusResponse.getActivationStatus()); + } + } + + public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, + PrepareActivationStepModel model, GetStatusStepModel statusModel, + String validOtpValue, String invalidOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertTrue(stepLoggerPrepare.getResult().success()); + assertEquals(200, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(ActivationStatus.PENDING_COMMIT, activationStatusResponse.getActivationStatus()); + + // Update OTP + powerAuthClient.updateActivationOtp(initResponse.getActivationId(), null, validOtpValue); + + // Try commit activation with wrong OTP. Last attempt is valid. + for (int iteration = 1; iteration <= 5; iteration++) { + boolean lastIteration = iteration == 5; + boolean isActivated; + try { + CommitActivationRequest commitRequest = new CommitActivationRequest(); + commitRequest.setActivationId(initResponse.getActivationId()); + commitRequest.setActivationOtp(lastIteration ? validOtpValue : invalidOtpValue); + CommitActivationResponse commitResponse = powerAuthClient.commitActivation(commitRequest); + isActivated = commitResponse.isActivated(); + } catch (PowerAuthClientException ex) { + isActivated = false; + } + assertEquals(lastIteration, isActivated); + + // Verify activation status + ActivationStatus expectedActivationStatus = lastIteration ? ActivationStatus.ACTIVE : ActivationStatus.PENDING_COMMIT; + activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(expectedActivationStatus, activationStatusResponse.getActivationStatus()); + } + + // Try to get activation status via RESTful API + ObjectStepLogger stepLoggerStatus = new ObjectStepLogger(System.out); + statusModel.setResultStatusObject(resultStatusObject); + new GetStatusStep().execute(stepLoggerStatus, statusModel.toMap()); + assertTrue(stepLoggerStatus.getResult().success()); + assertEquals(200, stepLoggerStatus.getResponse().statusCode()); + + // Validate failed and max failed attempts. + final Map statusResponseMap = (Map) stepLoggerStatus.getFirstItem("activation-status-obtained").object(); + ActivationStatusBlobInfo statusBlobInfo = (ActivationStatusBlobInfo) statusResponseMap.get("statusBlob"); + assertEquals(5L, statusBlobInfo.getMaxFailedAttempts()); + assertEquals(0L, statusBlobInfo.getFailedAttempts()); + + // Remove activation + powerAuthClient.removeActivation(initResponse.getActivationId(), "test"); + } + + public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, + PrepareActivationStepModel model, String validOtpValue, + String invalidOtpValue, String version) throws Exception { + + final JSONObject resultStatusObject = new JSONObject(); + + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); + + // Prepare activation + model.setActivationCode(initResponse.getActivationCode()); + model.setResultStatusObject(resultStatusObject); + ObjectStepLogger stepLoggerPrepare = new ObjectStepLogger(System.out); + new PrepareActivationStep().execute(stepLoggerPrepare, model.toMap()); + assertTrue(stepLoggerPrepare.getResult().success()); + assertEquals(200, stepLoggerPrepare.getResponse().statusCode()); + + // Verify activation status + GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(ActivationStatus.PENDING_COMMIT, activationStatusResponse.getActivationStatus()); + + // Update OTP + powerAuthClient.updateActivationOtp(initResponse.getActivationId(), null, validOtpValue); + + // Try commit activation with wrong OTP. Last attempt is valid. + for (int iteration = 1; iteration <= 5; iteration++) { + boolean lastIteration = iteration == 5; + boolean isActivated; + try { + CommitActivationRequest commitRequest = new CommitActivationRequest(); + commitRequest.setActivationId(initResponse.getActivationId()); + commitRequest.setActivationOtp(invalidOtpValue); + CommitActivationResponse commitResponse = powerAuthClient.commitActivation(commitRequest); + isActivated = commitResponse.isActivated(); + } catch (PowerAuthClientException ex) { + isActivated = false; + } + assertFalse(isActivated); + + // Verify activation status + ActivationStatus expectedActivationStatus = lastIteration ? ActivationStatus.REMOVED : ActivationStatus.PENDING_COMMIT; + activationStatusResponse = powerAuthClient.getActivationStatus(initResponse.getActivationId()); + assertEquals(expectedActivationStatus, activationStatusResponse.getActivationStatus()); + } + } + + public static void wrongActivationInitParamTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + assertThrows(PowerAuthClientException.class, () -> { + // Init activation + InitActivationRequest initRequest = new InitActivationRequest(); + initRequest.setApplicationId(config.getApplicationId()); + initRequest.setUserId(config.getUser(version)); + initRequest.setMaxFailureCount(5L); + // Set both activation OTP validation and commit phase + initRequest.setActivationOtpValidation(ActivationOtpValidation.ON_KEY_EXCHANGE); + initRequest.setCommitPhase(CommitPhase.ON_KEY_EXCHANGE); + powerAuthClient.initActivation(initRequest); + }); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java index 4c1338bb..a564475f 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java @@ -51,7 +51,7 @@ public class PowerAuthActivationOtpShared { public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); @@ -89,7 +89,7 @@ public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PrepareActivationStepModel model, String validOtpValue, String invalidOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -122,7 +122,7 @@ public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, String invalidOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -175,7 +175,7 @@ public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, Power PrepareActivationStepModel model, String validOtpValue, String invalidOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -226,7 +226,7 @@ public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, P PrepareActivationStepModel model, GetStatusStepModel statusModel, String validOtpValue, String invalidOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -292,7 +292,7 @@ public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PrepareActivationStepModel model, String validOtpValue, String invalidOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -364,20 +364,7 @@ public static void wrongActivationInitParamTest2(PowerAuthClient powerAuthClient }); } - public static void wrongActivationInitParamTest3(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String validOtpValue, String version) { - assertThrows(PowerAuthClientException.class, () -> { - // Init activation - InitActivationRequest initRequest = new InitActivationRequest(); - initRequest.setApplicationId(config.getApplicationId()); - initRequest.setUserId(config.getUser(version)); - initRequest.setMaxFailureCount(5L); - // Set OTP with no validation specified - initRequest.setActivationOtp(validOtpValue); - powerAuthClient.initActivation(initRequest); - }); - } - - public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest3(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -391,7 +378,7 @@ public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient }); } - public static void wrongActivationInitParamTest5(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -408,7 +395,7 @@ public static void wrongActivationInitParamTest5(PowerAuthClient powerAuthClient public static void missingOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -461,7 +448,7 @@ public static void missingOtpOnCommitTest(PowerAuthClient powerAuthClient, Power public static void missingOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java index 813c1c19..f9da14b2 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java @@ -271,7 +271,7 @@ public static void activationPrepareBadMasterPublicKeyTest(PowerAuthClient power public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -549,7 +549,7 @@ public static void lookupActivationsDateInvalidTest(PowerAuthClient powerAuthCli public static void updateActivationStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java index 95b712b2..96951a92 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java @@ -332,7 +332,7 @@ public static void activationRecoveryOtpInvalidTest(PowerAuthClient powerAuthCli */ private static ActivationRecovery getRecoveryData(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java index 4b2a7111..d5396aee 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java @@ -68,7 +68,7 @@ public class PowerAuthRecoveryShared { private static final String PRIVATE_KEY_RECOVERY_POSTCARD_BASE64 = "ALvtO6YEISVuCKugiltkUKgJaJbHRrdT77+9OhS79Gvm"; public static void activationRecoveryTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); @@ -230,7 +230,7 @@ public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClie final RecoveryCodeStatus expectedRecoveryCodeStatusAfterRemove = revokeRecoveryCode ? RecoveryCodeStatus.REVOKED : RecoveryCodeStatus.ACTIVE; final RecoveryPukStatus expectedRecoveryPukStatusAfterRemove = revokeRecoveryCode ? RecoveryPukStatus.INVALID : RecoveryPukStatus.VALID; - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -311,7 +311,7 @@ public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClie } public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -416,7 +416,7 @@ public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerA } public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); String publicKeyServerBase64 = powerAuthClient.getRecoveryConfig(config.getApplicationId()).getPostcardPublicKey(); final String randomUserId = "TestUser_" + UUID.randomUUID(); CreateRecoveryCodeResponse response = powerAuthClient.createRecoveryCode(config.getApplicationId(), randomUserId, 10L); @@ -609,7 +609,7 @@ public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, f } public static void recoveryPostcardInvalidPukIndexTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, String version) throws Exception { - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); String publicKeyServerBase64 = powerAuthClient.getRecoveryConfig(config.getApplicationId()).getPostcardPublicKey(); final String randomUserId = "TestUser_" + UUID.randomUUID(); CreateRecoveryCodeResponse response = powerAuthClient.createRecoveryCode(config.getApplicationId(), randomUserId, 10L); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java index ea9e852c..e857dd92 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java @@ -258,7 +258,7 @@ public static void signatureMaxFailedAttemptsTest(final PowerAuthClient powerAut File tempStatusFile = File.createTempFile("pa_status", ".json"); tempStatusFile.deleteOnExit(); - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); @@ -332,7 +332,7 @@ public static void signatureLookAheadTest(final PowerAuthClient powerAuthClient, File tempStatusFile = File.createTempFile("pa_status_lookahead", ".json"); tempStatusFile.deleteOnExit(); - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Init activation InitActivationRequest initRequest = new InitActivationRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java new file mode 100644 index 00000000..eea303d7 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java @@ -0,0 +1,140 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v31; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationCommitPhaseShared; +import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests for commit phase. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthActivationCommitPhaseTest { + + private static final String VERSION = "3.1"; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel model; + private GetStatusStepModel statusModel; + private File tempStatusFile; + + private final String validOtpValue = "1234-5678"; + private final String invalidOtpValue = "8765-4321"; + + private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + + // Models shared among tests + model = new PrepareActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setUriString(config.getPowerAuthIntegrationUrl()); + statusModel.setVersion(VERSION); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void validOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + + @Test + void invalidOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void validOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void invalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateValidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateValidOtpOnCommitTest(powerAuthClient, config, model, statusModel, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateInvalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateInvalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void wrongActivationInitParamTest() { + PowerAuthActivationCommitPhaseShared.wrongActivationInitParamTest(powerAuthClient, config, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java index 6b7f765b..3a179749 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java @@ -136,8 +136,7 @@ void wrongActivationInitParamTest2() { @Test void wrongActivationInitParamTest3() { - PowerAuthActivationOtpShared.wrongActivationInitParamTest3(powerAuthClient, config, validOtpValue, VERSION); - + PowerAuthActivationOtpShared.wrongActivationInitParamTest3(powerAuthClient, config, VERSION); } @Test @@ -145,11 +144,6 @@ void wrongActivationInitParamTest4() { PowerAuthActivationOtpShared.wrongActivationInitParamTest4(powerAuthClient, config, VERSION); } - @Test - void wrongActivationInitParamTest5() { - PowerAuthActivationOtpShared.wrongActivationInitParamTest5(powerAuthClient, config, VERSION); - } - @Test void missingOtpOnCommitTest() throws Exception { PowerAuthActivationOtpShared.missingOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java index d18da4b9..c832da99 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java @@ -69,7 +69,7 @@ void setUp() throws IOException { File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); // Create result status object - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); EncryptStepModel encryptModel = new EncryptStepModel(); encryptModel.setApplicationKey(config.getApplicationKey()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java index 1a1a26ff..73693bfc 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java @@ -76,7 +76,7 @@ void setUp() throws IOException { // Create temp status file File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Model shared among tests CreateActivationStepModel activationModel = new CreateActivationStepModel(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java new file mode 100644 index 00000000..e6896a61 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java @@ -0,0 +1,141 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v32; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationCommitPhaseShared; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationOtpShared; +import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests for commit phase. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthActivationCommitPhaseTest { + + private static final String VERSION = "3.2"; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel model; + private GetStatusStepModel statusModel; + private File tempStatusFile; + + private final String validOtpValue = "1234-5678"; + private final String invalidOtpValue = "8765-4321"; + + private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + + // Models shared among tests + model = new PrepareActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setUriString(config.getPowerAuthIntegrationUrl()); + statusModel.setVersion(VERSION); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void validOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + + @Test + void invalidOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void validOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void invalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateValidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateValidOtpOnCommitTest(powerAuthClient, config, model, statusModel, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateInvalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateInvalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void wrongActivationInitParamTest() { + PowerAuthActivationCommitPhaseShared.wrongActivationInitParamTest(powerAuthClient, config, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java index 3acf3373..df54b160 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java @@ -139,8 +139,7 @@ void wrongActivationInitParamTest2() { @Test void wrongActivationInitParamTest3() { - PowerAuthActivationOtpShared.wrongActivationInitParamTest3(powerAuthClient, config, validOtpValue, VERSION); - + PowerAuthActivationOtpShared.wrongActivationInitParamTest3(powerAuthClient, config, VERSION); } @Test @@ -148,11 +147,6 @@ void wrongActivationInitParamTest4() { PowerAuthActivationOtpShared.wrongActivationInitParamTest4(powerAuthClient, config, VERSION); } - @Test - void wrongActivationInitParamTest5() { - PowerAuthActivationOtpShared.wrongActivationInitParamTest5(powerAuthClient, config, VERSION); - } - @Test void missingOtpOnCommitTest() throws Exception { PowerAuthActivationOtpShared.missingOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java index 24b3b6ac..2a9183e9 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java @@ -69,7 +69,7 @@ void setUp() throws IOException { File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); // Create result status object - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); EncryptStepModel encryptModel = new EncryptStepModel(); encryptModel.setApplicationKey(config.getApplicationKey()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java index 319660f8..91261d22 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java @@ -77,7 +77,7 @@ void setUp() throws IOException { // Create temp status file File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); - JSONObject resultStatusObject = new JSONObject(); + final JSONObject resultStatusObject = new JSONObject(); // Model shared among tests CreateActivationStepModel activationModel = new CreateActivationStepModel(); diff --git a/powerauth-load-tests/src/test/scala/com/wultra/security/powerauth/test/scenario/ActivationInitScenario.scala b/powerauth-load-tests/src/test/scala/com/wultra/security/powerauth/test/scenario/ActivationInitScenario.scala index dec96e50..d1c1a771 100644 --- a/powerauth-load-tests/src/test/scala/com/wultra/security/powerauth/test/scenario/ActivationInitScenario.scala +++ b/powerauth-load-tests/src/test/scala/com/wultra/security/powerauth/test/scenario/ActivationInitScenario.scala @@ -42,7 +42,7 @@ object ActivationInitScenario { .body(StringBody(session => { s"""{ "requestObject": { - "activationOtpValidation": "NONE", + "commitPhase": "ON_COMMIT", "applicationId": "${ClientConfig.applicationId}", "userId": "${session("userId").as[String]}" } From 641a5ec58432cb05a91fc9200343db11bc92d730 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:35:51 +0000 Subject: [PATCH 21/35] Bump org.springframework.boot:spring-boot-starter-parent Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.3.3 to 3.3.4. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.3...v3.3.4) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce68875b..68150940 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.3 + 3.3.4 From 768780c15428ff534cbab462c9f4fda00c3e4de5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:35:58 +0000 Subject: [PATCH 22/35] Bump io.gatling:gatling-maven-plugin from 4.9.6 to 4.10.0 Bumps [io.gatling:gatling-maven-plugin](https://github.com/gatling/gatling-maven-plugin) from 4.9.6 to 4.10.0. - [Commits](https://github.com/gatling/gatling-maven-plugin/compare/v4.9.6...v4.10.0) --- updated-dependencies: - dependency-name: io.gatling:gatling-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- powerauth-load-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index b983c761..96358f3c 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -39,7 +39,7 @@ 2.13.13 - 4.9.6 + 4.10.0 4.9.2 3.12.0 From f72dc5190721fe8c3ae6cfa70c6640ef21289b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pe=C5=A1ek?= Date: Fri, 4 Oct 2024 15:05:19 +0200 Subject: [PATCH 23/35] Fix #522: Reflect Changes in Callback Management API (#523) --- .../test/shared/PowerAuthCallbackShared.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java index 38dcded9..1f99f6a9 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java @@ -22,6 +22,7 @@ import com.wultra.security.powerauth.client.model.entity.CallbackUrl; import com.wultra.security.powerauth.client.model.enumeration.CallbackUrlType; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.client.model.request.CreateCallbackUrlRequest; import com.wultra.security.powerauth.client.model.response.GetCallbackUrlListResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; @@ -42,9 +43,16 @@ public class PowerAuthCallbackShared { public static void callbackExecutionTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, Integer port, String version) throws PowerAuthClientException, RestClientException { // Skip test when the tested PA server is not running on localhost assumeTrue(config.getPowerAuthRestUrl().contains("localhost:8080")); - String callbackName = UUID.randomUUID().toString(); - String callbackUrlPost = "http://localhost:" + port + "/callback/post"; - powerAuthClient.createCallbackUrl(config.getApplicationId(), callbackName, CallbackUrlType.ACTIVATION_STATUS_CHANGE, callbackUrlPost, Arrays.asList("activationId", "userId", "activationName", "deviceInfo", "platform", "activationFlags", "activationStatus", "blockedReason", "applicationId"), null); + + final CreateCallbackUrlRequest pasCreateCallbackUrlRequest = new CreateCallbackUrlRequest(); + pasCreateCallbackUrlRequest.setApplicationId(config.getApplicationId()); + pasCreateCallbackUrlRequest.setName(UUID.randomUUID().toString()); + pasCreateCallbackUrlRequest.setType(CallbackUrlType.ACTIVATION_STATUS_CHANGE); + pasCreateCallbackUrlRequest.setCallbackUrl("http://localhost:" + port + "/callback/post"); + pasCreateCallbackUrlRequest.setAttributes(List.of("activationId", "userId", "activationName", "deviceInfo", + "platform", "activationFlags", "activationStatus", "blockedReason", "applicationId")); + powerAuthClient.createCallbackUrl(pasCreateCallbackUrlRequest); + final GetCallbackUrlListResponse callbacks = powerAuthClient.getCallbackUrlList(config.getApplicationId()); // Update activation status powerAuthClient.blockActivation(config.getActivationId(version), "TEST_CALLBACK", config.getUser(version)); @@ -64,7 +72,7 @@ public static void callbackExecutionTest(PowerAuthClient powerAuthClient, PowerA powerAuthClient.unblockActivation(config.getActivationId(version), config.getUser(version)); boolean callbackFound = false; for (CallbackUrl callback: callbacks.getCallbackUrlList()) { - if (callbackName.equals(callback.getName())) { + if (Objects.equals(pasCreateCallbackUrlRequest.getName(), callback.getName())) { callbackFound = true; powerAuthClient.removeCallbackUrl(callback.getId()); } From 0c1fb06e3a3b97242941ab1defe65b5541cdeefc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:45:25 +0000 Subject: [PATCH 24/35] Bump io.getlime.core:rest-client-base from 1.11.0-SNAPSHOT to 1.11.0 Bumps [io.getlime.core:rest-client-base](https://github.com/wultra/lime-java-core) from 1.11.0-SNAPSHOT to 1.11.0. - [Release notes](https://github.com/wultra/lime-java-core/releases) - [Commits](https://github.com/wultra/lime-java-core/commits/1.11.0) --- updated-dependencies: - dependency-name: io.getlime.core:rest-client-base dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 68150940..3a354375 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 1.9.0-SNAPSHOT 1.9.0-SNAPSHOT 1.9.0-SNAPSHOT - 1.11.0-SNAPSHOT + 1.11.0 2.6.0 8.0 From 1a478d1753deda3fac5357dc6816bad7e26a3dfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:45:39 +0000 Subject: [PATCH 25/35] Bump com.webauthn4j:webauthn4j-core Bumps [com.webauthn4j:webauthn4j-core](https://github.com/webauthn4j/webauthn4j) from 0.26.0.RELEASE to 0.27.0.RELEASE. - [Release notes](https://github.com/webauthn4j/webauthn4j/releases) - [Changelog](https://github.com/webauthn4j/webauthn4j/blob/master/github-release-notes-generator.yml) - [Commits](https://github.com/webauthn4j/webauthn4j/compare/0.26.0.RELEASE...0.27.0.RELEASE) --- updated-dependencies: - dependency-name: com.webauthn4j:webauthn4j-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 68150940..b3776a89 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 2.6.0 8.0 - 0.26.0.RELEASE + 0.27.0.RELEASE true From 5880eac49412eb49bb1460996005f535ab5e4bed Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 11 Oct 2024 11:21:41 +0200 Subject: [PATCH 26/35] Fix #528: Set release version to 1.9.0 --- pom.xml | 2 +- powerauth-backend-tests/pom.xml | 2 +- powerauth-fido2-tests/pom.xml | 2 +- powerauth-load-tests/pom.xml | 2 +- powerauth-test-server/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 8fcd51f7..8e4368f0 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ com.wultra powerauth-backend-tests-parent - 1.9.0-SNAPSHOT + 1.9.0 pom Parent pom for backend tests diff --git a/powerauth-backend-tests/pom.xml b/powerauth-backend-tests/pom.xml index b1fb3774..a3e5c098 100644 --- a/powerauth-backend-tests/pom.xml +++ b/powerauth-backend-tests/pom.xml @@ -8,7 +8,7 @@ com.wultra powerauth-backend-tests-parent - 1.9.0-SNAPSHOT + 1.9.0 com.wultra diff --git a/powerauth-fido2-tests/pom.xml b/powerauth-fido2-tests/pom.xml index 29967504..239269d9 100644 --- a/powerauth-fido2-tests/pom.xml +++ b/powerauth-fido2-tests/pom.xml @@ -11,7 +11,7 @@ com.wultra powerauth-backend-tests-parent - 1.9.0-SNAPSHOT + 1.9.0 diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index 96358f3c..88b5e528 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -6,7 +6,7 @@ com.wultra powerauth-backend-tests-parent - 1.9.0-SNAPSHOT + 1.9.0 powerauth-load-tests diff --git a/powerauth-test-server/pom.xml b/powerauth-test-server/pom.xml index 06a85cb9..7ec5b4bf 100644 --- a/powerauth-test-server/pom.xml +++ b/powerauth-test-server/pom.xml @@ -23,7 +23,7 @@ com.wultra powerauth-backend-tests-parent - 1.9.0-SNAPSHOT + 1.9.0 powerauth-test-server From 983df926c68f991d2dd7322efc3d89648d09de2f Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 11 Oct 2024 11:40:54 +0200 Subject: [PATCH 27/35] Fix #533: Update Docker --- powerauth-test-server/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/powerauth-test-server/Dockerfile b/powerauth-test-server/Dockerfile index dca87162..ba77ec85 100644 --- a/powerauth-test-server/Dockerfile +++ b/powerauth-test-server/Dockerfile @@ -1,4 +1,4 @@ -FROM ibm-semeru-runtimes:open-21.0.2_13-jre +FROM ibm-semeru-runtimes:open-21.0.4.1_7-jre LABEL maintainer="roman.strobl@wultra.com" # Prepare environment variables @@ -8,7 +8,7 @@ ENV JAVA_HOME=/opt/java/openjdk \ LB_VERSION=4.23.2 \ TOMCAT_HOME=/usr/local/tomcat \ TOMCAT_MAJOR=10 \ - TOMCAT_VERSION=10.1.19 \ + TOMCAT_VERSION=10.1.31 \ LOGBACK_CONF=/opt/logback/conf \ TZ=UTC @@ -21,7 +21,7 @@ RUN apt-get -y update \ # Install tomcat RUN curl -jkSL -o /tmp/apache-tomcat.tar.gz http://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR}/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz \ - && [ "7264da6196a510b0bba74469d215d61a464331302239256477f78b6bec067f7f4d90f671b96a440061ae0e20d16b1be8ca1dbd547dab9927383366dbc677f590 /tmp/apache-tomcat.tar.gz" = "$(sha512sum /tmp/apache-tomcat.tar.gz)" ] \ + && [ "919eb7b8d81ab6ba1c8634846509c0e9214c89c2645eb283c16701a7863502f65cd00549ec0c24ad4fc29dc64b3398dcca7440308715b7e0e8f06553c59a3449 /tmp/apache-tomcat.tar.gz" = "$(sha512sum /tmp/apache-tomcat.tar.gz)" ] \ && gunzip /tmp/apache-tomcat.tar.gz \ && tar -C /opt -xf /tmp/apache-tomcat.tar \ && ln -s /opt/apache-tomcat-$TOMCAT_VERSION $TOMCAT_HOME From 088530fe70d2df14ebe8abdea7da4b790d5f8586 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 14 Oct 2024 08:26:19 +0200 Subject: [PATCH 28/35] Fix tomcat hash in Dockerfile A follow-up to #533 --- powerauth-test-server/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-test-server/Dockerfile b/powerauth-test-server/Dockerfile index ba77ec85..06cea5c6 100644 --- a/powerauth-test-server/Dockerfile +++ b/powerauth-test-server/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get -y update \ # Install tomcat RUN curl -jkSL -o /tmp/apache-tomcat.tar.gz http://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR}/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz \ - && [ "919eb7b8d81ab6ba1c8634846509c0e9214c89c2645eb283c16701a7863502f65cd00549ec0c24ad4fc29dc64b3398dcca7440308715b7e0e8f06553c59a3449 /tmp/apache-tomcat.tar.gz" = "$(sha512sum /tmp/apache-tomcat.tar.gz)" ] \ + && [ "0e3d423a843e2d9ba4f28a9f0a2f1073d5a1389557dfda041759f8df968bace63cd6948bd76df2727b5133ddb7c33e05dab43cea1d519ca0b6d519461152cce9 /tmp/apache-tomcat.tar.gz" = "$(sha512sum /tmp/apache-tomcat.tar.gz)" ] \ && gunzip /tmp/apache-tomcat.tar.gz \ && tar -C /opt -xf /tmp/apache-tomcat.tar \ && ln -s /opt/apache-tomcat-$TOMCAT_VERSION $TOMCAT_HOME From 2528fb678283f79f022ba618574baeaff2b884e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:18:29 +0000 Subject: [PATCH 29/35] Bump powerauth-crypto.version from 1.9.0-SNAPSHOT to 1.9.0 Bumps `powerauth-crypto.version` from 1.9.0-SNAPSHOT to 1.9.0. Updates `io.getlime.security:powerauth-java-crypto` from 1.9.0-SNAPSHOT to 1.9.0 - [Release notes](https://github.com/wultra/powerauth-crypto/releases) - [Changelog](https://github.com/wultra/powerauth-crypto/blob/develop/docs/Releases.md) - [Commits](https://github.com/wultra/powerauth-crypto/commits/1.9.0) Updates `io.getlime.security:powerauth-java-http` from 1.9.0-SNAPSHOT to 1.9.0 - [Release notes](https://github.com/wultra/powerauth-crypto/releases) - [Changelog](https://github.com/wultra/powerauth-crypto/blob/develop/docs/Releases.md) - [Commits](https://github.com/wultra/powerauth-crypto/commits/1.9.0) --- updated-dependencies: - dependency-name: io.getlime.security:powerauth-java-crypto dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: io.getlime.security:powerauth-java-http dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8fcd51f7..c31d8f59 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 1.9.0-SNAPSHOT 1.9.0-SNAPSHOT - 1.9.0-SNAPSHOT + 1.9.0 1.9.0-SNAPSHOT 1.9.0-SNAPSHOT 1.11.0 From 3764a8fbe74719fefc71c4f66770ae942b14f279 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:19:07 +0000 Subject: [PATCH 30/35] Bump io.gatling:gatling-maven-plugin from 4.10.0 to 4.10.1 Bumps [io.gatling:gatling-maven-plugin](https://github.com/gatling/gatling-maven-plugin) from 4.10.0 to 4.10.1. - [Commits](https://github.com/gatling/gatling-maven-plugin/compare/v4.10.0...v4.10.1) --- updated-dependencies: - dependency-name: io.gatling:gatling-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- powerauth-load-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-load-tests/pom.xml b/powerauth-load-tests/pom.xml index 96358f3c..1f57c342 100644 --- a/powerauth-load-tests/pom.xml +++ b/powerauth-load-tests/pom.xml @@ -39,7 +39,7 @@ 2.13.13 - 4.10.0 + 4.10.1 4.9.2 3.12.0 From 619c13dc3f6ef21d6940ff275b71473a420f25a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Tue, 15 Oct 2024 15:39:14 +0800 Subject: [PATCH 31/35] Fix #524: Add tests for crypto protocol version 3.3 (#535) --- .../PowerAuthTestConfiguration.java | 135 ++------ .../powerauth/model/TemporaryKey.java | 35 ++ .../powerauth/test/PowerAuthTestSetUp.java | 91 +---- .../powerauth/test/PowerAuthTestTearDown.java | 13 +- .../test/PowerAuthConfigurationTest.java | 12 +- .../PowerAuthActivationCommitPhaseShared.java | 15 +- .../PowerAuthActivationFlagsShared.java | 7 +- .../shared/PowerAuthActivationOtpShared.java | 25 +- .../shared/PowerAuthActivationShared.java | 60 ++-- .../test/shared/PowerAuthApiShared.java | 213 ++++++++---- .../test/shared/PowerAuthCallbackShared.java | 10 +- .../PowerAuthCustomActivationOtpShared.java | 10 +- .../PowerAuthCustomActivationShared.java | 38 ++- .../shared/PowerAuthEncryptionShared.java | 33 +- .../test/shared/PowerAuthInfoShared.java | 3 +- .../test/shared/PowerAuthRecoveryShared.java | 21 +- .../test/shared/PowerAuthSignatureShared.java | 29 +- .../test/shared/PowerAuthTokenShared.java | 19 +- .../shared/PowerAuthVaultUnlockShared.java | 40 ++- .../shared/util/ResponseVerificationUtil.java | 41 +++ .../shared/util/TemporaryKeyFetchUtil.java | 196 +++++++++++ .../test/v30/PowerAuthActivationTest.java | 12 +- .../v30/PowerAuthCustomActivationTest.java | 14 +- .../test/v30/PowerAuthEncryptionTest.java | 14 +- .../test/v30/PowerAuthRecoveryTest.java | 10 +- .../test/v30/PowerAuthSignatureTest.java | 12 +- .../test/v30/PowerAuthTokenTest.java | 12 +- .../test/v30/PowerAuthVaultUnlockTest.java | 12 +- .../test/v31/PowerAuthActivationCodeTest.java | 12 +- .../PowerAuthActivationCommitPhaseTest.java | 9 +- .../test/v31/PowerAuthActivationOtpTest.java | 14 +- .../test/v31/PowerAuthActivationTest.java | 10 +- .../v31/PowerAuthCustomActivationOtpTest.java | 16 +- .../v31/PowerAuthCustomActivationTest.java | 12 +- .../test/v31/PowerAuthEncryptionTest.java | 14 +- .../PowerAuthIdentityVerificationTest.java | 10 +- .../test/v31/PowerAuthOnboardingTest.java | 12 +- .../test/v31/PowerAuthRecoveryTest.java | 10 +- .../test/v31/PowerAuthSignatureTest.java | 12 +- .../test/v31/PowerAuthTokenTest.java | 12 +- .../test/v31/PowerAuthVaultUnlockTest.java | 12 +- .../test/v32/PowerAuthActivationCodeTest.java | 12 +- .../PowerAuthActivationCommitPhaseTest.java | 10 +- .../test/v32/PowerAuthActivationOtpTest.java | 17 +- .../test/v32/PowerAuthActivationTest.java | 11 +- .../v32/PowerAuthCustomActivationOtpTest.java | 16 +- .../v32/PowerAuthCustomActivationTest.java | 12 +- .../test/v32/PowerAuthEncryptionTest.java | 14 +- .../PowerAuthIdentityVerificationTest.java | 10 +- .../test/v32/PowerAuthOidcActivationTest.java | 7 +- .../test/v32/PowerAuthOnboardingTest.java | 12 +- .../test/v32/PowerAuthRecoveryTest.java | 10 +- .../test/v32/PowerAuthSignatureTest.java | 12 +- .../test/v32/PowerAuthTokenTest.java | 12 +- .../test/v32/PowerAuthVaultUnlockTest.java | 12 +- .../test/v33/PowerAuthActivationCodeTest.java | 111 ++++++ .../PowerAuthActivationCommitPhaseTest.java | 141 ++++++++ .../test/v33/PowerAuthActivationOtpTest.java | 163 +++++++++ .../test/v33/PowerAuthActivationTest.java | 182 ++++++++++ .../v33/PowerAuthCustomActivationOtpTest.java | 163 +++++++++ .../v33/PowerAuthCustomActivationTest.java | 177 ++++++++++ .../test/v33/PowerAuthEncryptionTest.java | 238 +++++++++++++ .../PowerAuthIdentityVerificationTest.java | 218 ++++++++++++ .../test/v33/PowerAuthOidcActivationTest.java | 322 ++++++++++++++++++ .../test/v33/PowerAuthOnboardingTest.java | 162 +++++++++ .../test/v33/PowerAuthRecoveryTest.java | 104 ++++++ .../test/v33/PowerAuthSignatureTest.java | 232 +++++++++++++ .../test/v33/PowerAuthTokenTest.java | 138 ++++++++ .../test/v33/PowerAuthVaultUnlockTest.java | 146 ++++++++ .../v3x/PowerAuthActivationFlagsTest.java | 5 +- .../powerauth/test/v3x/PowerAuthApiTest.java | 9 +- ...PowerAuthApplicationConfigurationTest.java | 5 +- .../test/v3x/PowerAuthCallbackTest.java | 3 +- .../powerauth/test/v3x/PowerAuthInfoTest.java | 5 +- 74 files changed, 3452 insertions(+), 526 deletions(-) create mode 100644 powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/model/TemporaryKey.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/ResponseVerificationUtil.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/TemporaryKeyFetchUtil.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCommitPhaseTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationOtpTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationOtpTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOidcActivationTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthRecoveryTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthSignatureTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthTokenTest.java create mode 100644 powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthVaultUnlockTest.java diff --git a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthTestConfiguration.java b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthTestConfiguration.java index 59124b45..d2ce073b 100644 --- a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthTestConfiguration.java +++ b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/configuration/PowerAuthTestConfiguration.java @@ -25,6 +25,7 @@ import com.wultra.security.powerauth.test.PowerAuthTestSetUp; import com.wultra.security.powerauth.test.PowerAuthTestTearDown; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; @@ -41,8 +42,7 @@ import java.security.PublicKey; import java.security.Security; import java.time.Duration; -import java.util.Base64; -import java.util.UUID; +import java.util.*; /** * Configuration for the PowerAuth test. @@ -119,23 +119,10 @@ public class PowerAuthTestConfiguration { private final KeyConvertor keyConvertor = new KeyConvertor(); private final ObjectMapper objectMapper = RestClientConfiguration.defaultMapper(); - // Version 3.2 temporary storage - private File statusFileV32; - private final JSONObject resultStatusObjectV32 = new JSONObject(); - private String activationIdV32; - private String userV32; - - // Version 3.1 temporary storage - private File statusFileV31; - private final JSONObject resultStatusObjectV31 = new JSONObject(); - private String activationIdV31; - private String userV31; - - // Version 3.0 temporary storage - private File statusFileV3; - private final JSONObject resultStatusObjectV3 = new JSONObject(); - private String activationIdV3; - private String userV3; + private final Map statusFiles = new HashMap<>(); + private final Map resultStatusObjects = new HashMap<>(); + private final Map activationIds = new HashMap<>(); + private final Map users = new HashMap<>(); private final String password = "1234"; @@ -186,17 +173,18 @@ public void setUp() throws Exception { // Prepare common userId final String userId = UUID.randomUUID().toString(); - // Create status file and user for version 3.2 - statusFileV32 = File.createTempFile("pa_status_v32", ".json"); - userV32 = "TestUserV32_" + userId; - - // Create status file and user for version 3.1 - statusFileV31 = File.createTempFile("pa_status_v31", ".json"); - userV31 = "TestUserV31_" + userId; - - // Create status file and user for version 3.0 - statusFileV3 = File.createTempFile("pa_status_v3", ".json"); - userV3 = "TestUserV3_" + userId; + // Create status files and users + Arrays.stream(PowerAuthVersion.values()).forEach(version -> { + try { + final File statusFile = File.createTempFile("pa_status_" + version, ".json"); + statusFiles.put(version, statusFile); + final String user = "TestUser_" + version + "_" + userId; + users.put(version, user); + resultStatusObjects.put(version, new JSONObject()); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); // Random application name applicationVersionForTests = applicationVersion + "_" + System.currentTimeMillis(); @@ -265,70 +253,20 @@ public KeyConvertor getKeyConvertor() { return keyConvertor; } - public File getStatusFileV32() { - return statusFileV32; - } - - public File getStatusFileV31() { - return statusFileV31; - } - - public File getStatusFileV3() { - return statusFileV3; - } - - public JSONObject getResultStatusObjectV32() { - return resultStatusObjectV32; - } - - public JSONObject getResultStatusObjectV31() { - return resultStatusObjectV31; - } - - public JSONObject getResultStatusObjectV3() { - return resultStatusObjectV3; - } - - public JSONObject getResultStatusObject(String version) { - return switch (version) { - case "3.2" -> resultStatusObjectV32; - case "3.1" -> resultStatusObjectV31; - case "3.0" -> resultStatusObjectV3; - default -> null; - }; - } - - public String getActivationIdV32() { - return activationIdV32; - } - - public void setActivationIdV32(String activationIdV32) { - this.activationIdV32 = activationIdV32; - } - - public String getActivationIdV31() { - return activationIdV31; + public File getStatusFile(PowerAuthVersion version) { + return statusFiles.get(version); } - public void setActivationIdV31(String activationIdV31) { - this.activationIdV31 = activationIdV31; + public JSONObject getResultStatusObject(PowerAuthVersion version) { + return resultStatusObjects.get(version); } - public String getActivationIdV3() { - return activationIdV3; + public void setActivationId(String activationId, PowerAuthVersion version) { + activationIds.put(version, activationId); } - public void setActivationIdV3(String activationIdV3) { - this.activationIdV3 = activationIdV3; - } - - public String getActivationId(String version) { - return switch (version) { - case "3.2" -> activationIdV32; - case "3.1" -> activationIdV31; - case "3.0" -> activationIdV3; - default -> null; - }; + public String getActivationId(PowerAuthVersion version) { + return activationIds.get(version); } public String getPassword() { @@ -339,25 +277,8 @@ public ObjectMapper getObjectMapper() { return objectMapper; } - public String getUserV3() { - return userV3; - } - - public String getUserV31() { - return userV31; - } - - public String getUserV32() { - return userV32; - } - - public String getUser(String version) { - return switch (version) { - case "3.2" -> userV32; - case "3.1" -> userV31; - case "3.0" -> userV3; - default -> null; - }; + public String getUser(PowerAuthVersion version) { + return users.get(version); } public void setApplicationKey(String applicationKey) { diff --git a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/model/TemporaryKey.java b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/model/TemporaryKey.java new file mode 100644 index 00000000..7285d1db --- /dev/null +++ b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/model/TemporaryKey.java @@ -0,0 +1,35 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.model; + +import lombok.Data; + +import java.security.PublicKey; + +/** + * Temporary key model class. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@Data +public class TemporaryKey { + + private String id; + private PublicKey publicKey; + +} diff --git a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestSetUp.java b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestSetUp.java index 91a89236..da805a29 100644 --- a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestSetUp.java +++ b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestSetUp.java @@ -27,6 +27,7 @@ import com.wultra.security.powerauth.client.model.request.UpdateRecoveryConfigRequest; import com.wultra.security.powerauth.client.model.response.*; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.v3.PrepareActivationStep; @@ -62,9 +63,13 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { public void execute() throws Exception { createApplication(); - createActivationV32(); - createActivationV31(); - createActivationV3(); + Arrays.stream(PowerAuthVersion.values()).forEach(version -> { + try { + createActivation(version); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); createOperationTemplates(); } @@ -140,92 +145,26 @@ private void createApplication() throws PowerAuthClientException { } } - private void createActivationV32() throws Exception { - // Init activation - final InitActivationRequest initRequest = new InitActivationRequest(); - initRequest.setApplicationId(config.getApplicationId()); - initRequest.setUserId(config.getUserV32()); - final InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); - - // Prepare activation - PrepareActivationStepModel model = new PrepareActivationStepModel(); - model.setActivationCode(initResponse.getActivationCode()); - model.setActivationName("test v32"); - model.setApplicationKey(config.getApplicationKey()); - model.setApplicationSecret(config.getApplicationSecret()); - model.setMasterPublicKey(config.getMasterPublicKey()); - model.setHeaders(new HashMap<>()); - model.setPassword(config.getPassword()); - model.setStatusFileName(config.getStatusFileV32().getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); - model.setUriString(config.getPowerAuthIntegrationUrl()); - model.setVersion("3.2"); - model.setDeviceInfo("backend-tests"); - - ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); - new PrepareActivationStep().execute(stepLogger, model.toMap()); - assertTrue(stepLogger.getResult().success()); - - // Commit activation - CommitActivationResponse commitResponse = powerAuthClient.commitActivation(initResponse.getActivationId(), "test"); - assertEquals(initResponse.getActivationId(), commitResponse.getActivationId()); - - config.setActivationIdV32(initResponse.getActivationId()); - } - - private void createActivationV31() throws Exception { - // Init activation - final InitActivationRequest initRequest = new InitActivationRequest(); - initRequest.setApplicationId(config.getApplicationId()); - initRequest.setUserId(config.getUserV31()); - final InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); - - // Prepare activation - PrepareActivationStepModel model = new PrepareActivationStepModel(); - model.setActivationCode(initResponse.getActivationCode()); - model.setActivationName("test v31"); - model.setApplicationKey(config.getApplicationKey()); - model.setApplicationSecret(config.getApplicationSecret()); - model.setMasterPublicKey(config.getMasterPublicKey()); - model.setHeaders(new HashMap<>()); - model.setPassword(config.getPassword()); - model.setStatusFileName(config.getStatusFileV31().getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV31()); - model.setUriString(config.getPowerAuthIntegrationUrl()); - model.setVersion("3.1"); - model.setDeviceInfo("backend-tests"); - - ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); - new PrepareActivationStep().execute(stepLogger, model.toMap()); - assertTrue(stepLogger.getResult().success()); - - // Commit activation - CommitActivationResponse commitResponse = powerAuthClient.commitActivation(initResponse.getActivationId(), "test"); - assertEquals(initResponse.getActivationId(), commitResponse.getActivationId()); - - config.setActivationIdV31(initResponse.getActivationId()); - } - - private void createActivationV3() throws Exception { + private void createActivation(PowerAuthVersion version) throws Exception { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); - initRequest.setUserId(config.getUserV3()); + initRequest.setUserId(config.getUser(version)); InitActivationResponse initResponse = powerAuthClient.initActivation(initRequest); // Prepare activation PrepareActivationStepModel model = new PrepareActivationStepModel(); model.setActivationCode(initResponse.getActivationCode()); - model.setActivationName("test v3"); + model.setActivationName("test v" + version); model.setApplicationKey(config.getApplicationKey()); model.setApplicationSecret(config.getApplicationSecret()); model.setMasterPublicKey(config.getMasterPublicKey()); model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); - model.setStatusFileName(config.getStatusFileV3().getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV3()); + model.setStatusFileName(config.getStatusFile(version).getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(version)); model.setUriString(config.getPowerAuthIntegrationUrl()); - model.setVersion("3.0"); + model.setVersion(version); model.setDeviceInfo("backend-tests"); ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); @@ -236,7 +175,7 @@ private void createActivationV3() throws Exception { CommitActivationResponse commitResponse = powerAuthClient.commitActivation(initResponse.getActivationId(), "test"); assertEquals(initResponse.getActivationId(), commitResponse.getActivationId()); - config.setActivationIdV3(initResponse.getActivationId()); + config.setActivationId(initResponse.getActivationId(), version); } } diff --git a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestTearDown.java b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestTearDown.java index 906e5d94..834e5eea 100644 --- a/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestTearDown.java +++ b/powerauth-backend-tests/src/main/java/com/wultra/security/powerauth/test/PowerAuthTestTearDown.java @@ -21,8 +21,11 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.client.model.request.OperationTemplateDeleteRequest; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.springframework.beans.factory.annotation.Autowired; +import java.util.Arrays; + import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -46,8 +49,14 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { } public void execute() throws PowerAuthClientException { - powerAuthClient.removeActivation(config.getActivationIdV3(), "test"); - assertTrue(config.getStatusFileV3().delete()); + Arrays.stream(PowerAuthVersion.values()).forEach(version -> { + try { + powerAuthClient.removeActivation(config.getActivationId(version), "test"); + assertTrue(config.getStatusFile(version).delete()); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); removeOperationTemplates(); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/PowerAuthConfigurationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/PowerAuthConfigurationTest.java index 5a373649..886a47f2 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/PowerAuthConfigurationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/PowerAuthConfigurationTest.java @@ -18,6 +18,7 @@ package com.wultra.security.powerauth.test; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -49,13 +50,18 @@ public void applicationSetUpTest() { assertNotEquals("", config.getApplicationKey()); assertNotNull(config.getApplicationSecret()); assertNotEquals("", config.getApplicationSecret()); - assertNotNull(config.getActivationIdV3()); + for (PowerAuthVersion version: PowerAuthVersion.values()) { + assertNotNull(config.getActivationId(version)); + } } @Test public void activationSetUpTest() { - assertNotNull(config.getStatusFileV3()); - assertNotNull(config.getResultStatusObjectV3()); + for (PowerAuthVersion version: PowerAuthVersion.values()) { + assertNotNull(config.getStatusFile(version)); + assertNotNull(config.getResultStatusObject(version)); + assertNotNull(config.getUser(version)); + } } } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java index 4aad1656..877dfb9c 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationCommitPhaseShared.java @@ -31,6 +31,7 @@ import com.wultra.security.powerauth.client.model.response.LookupRecoveryCodesResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; @@ -50,7 +51,7 @@ public class PowerAuthActivationCommitPhaseShared { public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { + PrepareActivationStepModel model, String validOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -88,7 +89,7 @@ public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, P public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -121,7 +122,7 @@ public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, } public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, - String validOtpValue, String invalidOtpValue, String version) throws Exception { + String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -174,7 +175,7 @@ public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAu public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -225,7 +226,7 @@ public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, Power public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, GetStatusStepModel statusModel, - String validOtpValue, String invalidOtpValue, String version) throws Exception { + String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -291,7 +292,7 @@ public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, P public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -339,7 +340,7 @@ public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, } } - public static void wrongActivationInitParamTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationFlagsShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationFlagsShared.java index fa8f0769..94a7948a 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationFlagsShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationFlagsShared.java @@ -22,6 +22,7 @@ import com.wultra.security.powerauth.client.model.request.LookupActivationsRequest; import com.wultra.security.powerauth.client.model.response.*; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; @@ -42,7 +43,7 @@ */ public class PowerAuthActivationFlagsShared { - public static void activationFlagCrudTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String version) throws Exception { + public static void activationFlagCrudTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -84,7 +85,7 @@ public static void activationFlagCrudTest(PowerAuthClient powerAuthClient, Power assertEquals(Arrays.asList("FLAG3", "FLAG4"), listResponse4.getActivationFlags()); } - public static void activationFlagLookupTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String version) throws Exception { + public static void activationFlagLookupTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -134,7 +135,7 @@ public static void activationFlagLookupTest(PowerAuthClient powerAuthClient, Pow assertTrue(response5.getActivations().isEmpty()); } - public static void activationProviderFlagTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, int port, String version) throws Exception { + public static void activationProviderFlagTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, int port, PowerAuthVersion version) throws Exception { // Create custom activation with test provider CreateActivationStepModel model = new CreateActivationStepModel(); model.setActivationName("test v" + version); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java index a564475f..8322d4a0 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationOtpShared.java @@ -30,6 +30,7 @@ import com.wultra.security.powerauth.client.model.response.LookupRecoveryCodesResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; @@ -49,7 +50,7 @@ public class PowerAuthActivationOtpShared { public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { + PrepareActivationStepModel model, String validOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -87,7 +88,7 @@ public static void validOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, P public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -120,7 +121,7 @@ public static void invalidOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, } public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, - String validOtpValue, String invalidOtpValue, String version) throws Exception { + String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -173,7 +174,7 @@ public static void validOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAu public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -224,7 +225,7 @@ public static void invalidOtpOnCommitTest(PowerAuthClient powerAuthClient, Power public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, GetStatusStepModel statusModel, - String validOtpValue, String invalidOtpValue, String version) throws Exception { + String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -290,7 +291,7 @@ public static void updateValidOtpOnCommitTest(PowerAuthClient powerAuthClient, P public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PrepareActivationStepModel model, String validOtpValue, - String invalidOtpValue, String version) throws Exception { + String invalidOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -338,7 +339,7 @@ public static void updateInvalidOtpOnCommitTest(PowerAuthClient powerAuthClient, } } - public static void wrongActivationInitParamTest1(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest1(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -351,7 +352,7 @@ public static void wrongActivationInitParamTest1(PowerAuthClient powerAuthClient }); } - public static void wrongActivationInitParamTest2(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest2(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -364,7 +365,7 @@ public static void wrongActivationInitParamTest2(PowerAuthClient powerAuthClient }); } - public static void wrongActivationInitParamTest3(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest3(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -378,7 +379,7 @@ public static void wrongActivationInitParamTest3(PowerAuthClient powerAuthClient }); } - public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) { + public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) { assertThrows(PowerAuthClientException.class, () -> { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); @@ -393,7 +394,7 @@ public static void wrongActivationInitParamTest4(PowerAuthClient powerAuthClient } public static void missingOtpOnCommitTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { + PrepareActivationStepModel model, String validOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -446,7 +447,7 @@ public static void missingOtpOnCommitTest(PowerAuthClient powerAuthClient, Power } public static void missingOtpOnKeysExchangeTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String validOtpValue, String version) throws Exception { + PrepareActivationStepModel model, String validOtpValue, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java index f9da14b2..694e4ac5 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthActivationShared.java @@ -27,11 +27,13 @@ import com.wultra.security.powerauth.client.model.request.LookupActivationsRequest; import com.wultra.security.powerauth.client.model.response.*; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.util.ResponseVerificationUtil; import io.getlime.core.rest.model.base.response.ErrorResponse; import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; @@ -43,7 +45,6 @@ import io.getlime.security.powerauth.rest.api.model.response.ActivationStatusResponse; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import org.json.simple.JSONObject; -import org.junit.jupiter.api.Test; import javax.crypto.SecretKey; import java.security.KeyPair; @@ -64,7 +65,7 @@ public class PowerAuthActivationShared { private static final PowerAuthClientActivation CLIENT_ACTIVATION = new PowerAuthClientActivation(); public static void activationPrepareTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation final InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -142,7 +143,7 @@ public static void activationNonExistentTest(PowerAuthClient powerAuthClient) th } public static void activationPrepareUnsupportedApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Unsupport application version powerAuthClient.unsupportApplicationVersion(config.getApplicationId(), config.getApplicationVersionId()); @@ -176,8 +177,7 @@ public static void activationPrepareUnsupportedApplicationTest(PowerAuthClient p ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLoggerPrepare.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); // Support application version powerAuthClient.supportApplicationVersion(config.getApplicationId(), config.getApplicationVersionId()); @@ -192,7 +192,7 @@ public static void activationPrepareUnsupportedApplicationTest(PowerAuthClient p } public static void activationPrepareExpirationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation should not fail, because application version is not known (applicationKey is not sent in InitActivationRequest) InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -236,7 +236,7 @@ public static void activationPrepareWithoutInitTest(PowerAuthTestConfiguration c } public static void activationPrepareBadMasterPublicKeyTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -270,7 +270,7 @@ public static void activationPrepareBadMasterPublicKeyTest(PowerAuthClient power } public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); // Init activation @@ -304,13 +304,13 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu assertTrue(stepLoggerStatus.getResult().success()); assertEquals(200, stepLoggerStatus.getResponse().statusCode()); ActivationStatusRequest request = (ActivationStatusRequest) stepLoggerStatus.getRequest().requestObject(); - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { assertNotNull(request.getChallenge()); } ObjectResponse responseObject = (ObjectResponse) stepLoggerStatus.getResponse().responseObject(); ActivationStatusResponse response = responseObject.getResponseObject(); assertEquals(initResponse.getActivationId(), response.getActivationId()); - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { assertNotNull(response.getNonce()); } @@ -323,7 +323,7 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu ActivationStatusBlobInfo statusBlob; byte[] challengeData = null; byte[] nonceData = null; - if ("3.0".equals(version)) { + if (version == PowerAuthVersion.V3_0) { statusBlob = CLIENT_ACTIVATION.getStatusFromEncryptedBlob(cStatusBlob, null, null, transportMasterKey); } else { challengeData = Base64.getDecoder().decode(request.getChallenge()); @@ -356,7 +356,7 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu assertEquals(initResponse.getActivationId(), response.getActivationId()); // Verify activation status blob - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { challengeData = Base64.getDecoder().decode(request.getChallenge()); nonceData = Base64.getDecoder().decode(response.getNonce()); } @@ -381,7 +381,7 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu assertEquals(initResponse.getActivationId(), response.getActivationId()); // Verify activation status blob - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { challengeData = Base64.getDecoder().decode(request.getChallenge()); nonceData = Base64.getDecoder().decode(response.getNonce()); } @@ -404,7 +404,7 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu assertEquals(initResponse.getActivationId(), response.getActivationId()); // Verify activation status blob - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { challengeData = Base64.getDecoder().decode(request.getChallenge()); nonceData = Base64.getDecoder().decode(response.getNonce()); } @@ -415,7 +415,7 @@ public static void activationStatusTest(PowerAuthClient powerAuthClient, PowerAu } public static void activationInvalidApplicationKeyTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation should not fail, because application version is not known (applicationKey is not sent in InitActivationRequest) InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -441,12 +441,11 @@ public static void activationInvalidApplicationKeyTest(PowerAuthClient powerAuth ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLoggerPrepare.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); } public static void activationInvalidApplicationSecretTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { // Init activation should not fail, because application version is not known (applicationKey is not sent in InitActivationRequest) InitActivationRequest initRequest = new InitActivationRequest(); initRequest.setApplicationId(config.getApplicationId()); @@ -472,11 +471,10 @@ public static void activationInvalidApplicationSecretTest(PowerAuthClient powerA ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLoggerPrepare.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); } - public static void lookupActivationsTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { InitActivationResponse response = powerAuthClient.initActivation(config.getUser(version), config.getApplicationId()); GetActivationStatusResponse statusResponse = powerAuthClient.getActivationStatus(response.getActivationId()); final Date timestampCreated = statusResponse.getTimestampCreated(); @@ -493,7 +491,7 @@ public static void lookupActivationsNonExistentUserTest(PowerAuthClient powerAut assertEquals(0, response.getActivations().size()); } - public static void lookupActivationsApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { LookupActivationsRequest lookupActivationsRequest = new LookupActivationsRequest(); lookupActivationsRequest.getUserIds().add(config.getUser(version)); lookupActivationsRequest.getApplicationIds().add(config.getApplicationId()); @@ -501,7 +499,7 @@ public static void lookupActivationsApplicationTest(PowerAuthClient powerAuthCli assertTrue(response.getActivations().size() >= 1); } - public static void lookupActivationsNonExistentApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsNonExistentApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { final LookupActivationsRequest lookupActivationsRequest = new LookupActivationsRequest(); lookupActivationsRequest.getUserIds().add(config.getUser(version)); lookupActivationsRequest.getApplicationIds().add("10000000"); @@ -509,7 +507,7 @@ public static void lookupActivationsNonExistentApplicationTest(PowerAuthClient p assertEquals(0, response.getActivations().size()); } - public static void lookupActivationsStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { LookupActivationsRequest lookupActivationsRequest = new LookupActivationsRequest(); lookupActivationsRequest.getUserIds().add(config.getUser(version)); lookupActivationsRequest.setActivationStatus(ActivationStatus.ACTIVE); @@ -517,7 +515,7 @@ public static void lookupActivationsStatusTest(PowerAuthClient powerAuthClient, assertTrue(response.getActivations().size() >= 1); } - public static void lookupActivationsInvalidStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsInvalidStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { // // This test may fail in case that our battery of tests leaves some activation in the blocked state. // Try to re-run the test alone, or fix the new test case that collides with this one. @@ -529,7 +527,7 @@ public static void lookupActivationsInvalidStatusTest(PowerAuthClient powerAuthC assertEquals(0, response.getActivations().size()); } - public static void lookupActivationsDateValidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsDateValidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { LookupActivationsRequest lookupActivationsRequest = new LookupActivationsRequest(); lookupActivationsRequest.getUserIds().add(config.getUser(version)); final Date timestampLastUsedAfter = Date.from(Instant.now().minus(Duration.ofMinutes(1))); @@ -538,7 +536,7 @@ public static void lookupActivationsDateValidTest(PowerAuthClient powerAuthClien assertTrue(response.getActivations().size() >= 1); } - public static void lookupActivationsDateInvalidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws Exception { + public static void lookupActivationsDateInvalidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { LookupActivationsRequest lookupActivationsRequest = new LookupActivationsRequest(); lookupActivationsRequest.getUserIds().add(config.getUser(version)); final Date timestampLastUsedAfter = Date.from(Instant.now().plus(Duration.ofMinutes(1))); @@ -548,7 +546,7 @@ public static void lookupActivationsDateInvalidTest(PowerAuthClient powerAuthCli } public static void updateActivationStatusTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, - PrepareActivationStepModel model, String version) throws Exception { + PrepareActivationStepModel model, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); // Init activation @@ -582,13 +580,13 @@ public static void updateActivationStatusTest(PowerAuthClient powerAuthClient, P assertTrue(stepLoggerStatus.getResult().success()); assertEquals(200, stepLoggerStatus.getResponse().statusCode()); final ActivationStatusRequest request = (ActivationStatusRequest) stepLoggerStatus.getRequest().requestObject(); - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { assertNotNull(request.getChallenge()); } final ObjectResponse responseObject = (ObjectResponse) stepLoggerStatus.getResponse().responseObject(); ActivationStatusResponse response = responseObject.getResponseObject(); assertEquals(initResponse.getActivationId(), response.getActivationId()); - if (!"3.0".equals(version)) { + if (version != PowerAuthVersion.V3_0) { assertNotNull(response.getNonce()); } @@ -601,7 +599,7 @@ public static void updateActivationStatusTest(PowerAuthClient powerAuthClient, P byte[] nonceData = null; byte[] cStatusBlob = Base64.getDecoder().decode(response.getEncryptedStatusBlob()); ActivationStatusBlobInfo statusBlob; - if ("3.0".equals(version)) { + if (version == PowerAuthVersion.V3_0) { statusBlob = CLIENT_ACTIVATION.getStatusFromEncryptedBlob(cStatusBlob, null, null, transportMasterKey); } else { challengeData = Base64.getDecoder().decode(request.getChallenge()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java index acf08544..9e953d9a 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthApiShared.java @@ -23,8 +23,11 @@ import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; import com.wultra.security.powerauth.client.model.enumeration.SignatureType; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.client.model.request.*; import com.wultra.security.powerauth.client.model.response.*; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.model.TemporaryKey; +import com.wultra.security.powerauth.test.shared.util.TemporaryKeyFetchUtil; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; import io.getlime.security.powerauth.crypto.client.keyfactory.PowerAuthClientKeyFactory; import io.getlime.security.powerauth.crypto.client.signature.PowerAuthClientSignature; @@ -33,11 +36,7 @@ import io.getlime.security.powerauth.crypto.lib.config.SignatureConfiguration; import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.exception.EncryptorException; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedResponse; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.*; import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; @@ -46,11 +45,9 @@ import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.crypto.lib.util.SignatureUtils; import io.getlime.security.powerauth.http.PowerAuthHttpBody; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.BaseStepModel; -import io.getlime.security.powerauth.lib.cmd.util.CounterUtil; -import io.getlime.security.powerauth.lib.cmd.util.EncryptedStorageUtil; -import io.getlime.security.powerauth.lib.cmd.util.JsonUtil; -import io.getlime.security.powerauth.lib.cmd.util.RestClientConfiguration; +import io.getlime.security.powerauth.lib.cmd.util.*; import io.getlime.security.powerauth.rest.api.model.entity.TokenResponsePayload; import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer2Request; import io.getlime.security.powerauth.rest.api.model.request.ConfirmRecoveryRequestPayload; @@ -63,13 +60,11 @@ import javax.crypto.SecretKey; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; import java.util.Base64; import java.util.Calendar; import java.util.GregorianCalendar; @@ -97,7 +92,7 @@ public class PowerAuthApiShared { private static final int TIME_SYNCHRONIZATION_WINDOW_SECONDS = 60; - public static void verifySignatureTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws GenericCryptoException, CryptoProviderException, InvalidKeyException, PowerAuthClientException { + public static void verifySignatureTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws GenericCryptoException, CryptoProviderException, InvalidKeyException, PowerAuthClientException { Calendar before = new GregorianCalendar(); before.add(Calendar.SECOND, -TIME_SYNCHRONIZATION_WINDOW_SECONDS); byte[] nonceBytes = KEY_GENERATOR.generateRandomBytes(16); @@ -112,7 +107,7 @@ public static void verifySignatureTest(PowerAuthClient powerAuthClient, PowerAut SecretKey signaturePossessionKey = KEY_CONVERTOR.convertBytesToSharedSecretKey(signaturePossessionKeyBytes); String signatureValue = CLIENT_SIGNATURE.signatureForData(normalizedDataWithSecret.getBytes(StandardCharsets.UTF_8), KEY_FACTORY.keysForSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, signaturePossessionKey, signatureKnowledgeKey, null), ctrData, SignatureConfiguration.base64()); - VerifySignatureResponse signatureResponse = powerAuthClient.verifySignature(config.getActivationId(version), config.getApplicationKey(), normalizedData, signatureValue, SignatureType.POSSESSION_KNOWLEDGE, version, null); + VerifySignatureResponse signatureResponse = powerAuthClient.verifySignature(config.getActivationId(version), config.getApplicationKey(), normalizedData, signatureValue, SignatureType.POSSESSION_KNOWLEDGE, version.value(), null); assertTrue(signatureResponse.isSignatureValid()); BaseStepModel model = new BaseStepModel(); model.setResultStatusObject(config.getResultStatusObject(version)); @@ -126,7 +121,7 @@ public static void verifySignatureTest(PowerAuthClient powerAuthClient, PowerAut assertEquals(config.getActivationId(version), item.getActivationId()); assertEquals(normalizedDataWithSecret, new String(Base64.getDecoder().decode(item.getDataBase64()))); assertEquals(SignatureType.POSSESSION_KNOWLEDGE, item.getSignatureType()); - assertEquals(version, item.getSignatureVersion()); + assertEquals(version.value(), item.getSignatureVersion()); assertEquals(ActivationStatus.ACTIVE, item.getActivationStatus()); assertEquals(config.getApplicationId(), item.getApplicationId()); assertEquals(config.getUser(version), item.getUserId()); @@ -137,16 +132,17 @@ public static void verifySignatureTest(PowerAuthClient powerAuthClient, PowerAut assertTrue(signatureFound); } - public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws GenericCryptoException, CryptoProviderException, InvalidKeySpecException, EncryptorException, IOException, InvalidKeyException, PowerAuthClientException { + public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { byte[] transportMasterKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "transportMasterKey")); byte[] serverPublicKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "serverPublicKey")); byte[] encryptedDevicePrivateKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "encryptedDevicePrivateKey")); byte[] nonceBytes = KEY_GENERATOR.generateRandomBytes(16); final PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); + final TemporaryKey temporaryKey = TemporaryKeyFetchUtil.fetchTemporaryKey(version, EncryptorScope.ACTIVATION_SCOPE, config); final ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.VAULT_UNLOCK, - new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version), null), - new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) + new EncryptorParameters(version.value(), config.getApplicationKey(), config.getActivationId(version), temporaryKey != null ? temporaryKey.getId() : null), + new ClientEncryptorSecrets(temporaryKey != null ? temporaryKey.getPublicKey() : serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) ); VaultUnlockRequestPayload requestPayload = new VaultUnlockRequestPayload(); requestPayload.setReason("TEST"); @@ -158,6 +154,7 @@ public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthCli eciesRequest.setMac(encryptedRequest.getMac()); eciesRequest.setNonce(encryptedRequest.getNonce()); eciesRequest.setTimestamp(encryptedRequest.getTimestamp()); + eciesRequest.setTemporaryKeyId(temporaryKey != null ? temporaryKey.getId() : null); final byte[] requestBytes = OBJECT_MAPPER.writeValueAsBytes(eciesRequest); String normalizedData = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/signature/validate", nonceBytes, requestBytes); String normalizedDataWithSecret = normalizedData + "&" + config.getApplicationSecret(); @@ -169,8 +166,20 @@ public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthCli SecretKey signaturePossessionKey = KEY_CONVERTOR.convertBytesToSharedSecretKey(signaturePossessionKeyBytes); String signatureValue = CLIENT_SIGNATURE.signatureForData(normalizedDataWithSecret.getBytes(StandardCharsets.UTF_8), KEY_FACTORY.keysForSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, signaturePossessionKey, signatureKnowledgeKey, null), ctrData, SignatureConfiguration.base64()); - VaultUnlockResponse unlockResponse = powerAuthClient.unlockVault(config.getActivationId(version), config.getApplicationKey(), signatureValue, SignatureType.POSSESSION_KNOWLEDGE, version, normalizedData, - eciesRequest.getEphemeralPublicKey(), eciesRequest.getEncryptedData(), eciesRequest.getMac(), eciesRequest.getNonce(), eciesRequest.getTimestamp()); + final VaultUnlockRequest unlockRequest = new VaultUnlockRequest(); + unlockRequest.setActivationId(config.getActivationId(version)); + unlockRequest.setApplicationKey(config.getApplicationKey()); + unlockRequest.setSignature(signatureValue); + unlockRequest.setSignatureType(SignatureType.POSSESSION_KNOWLEDGE); + unlockRequest.setSignatureVersion(version.value()); + unlockRequest.setSignedData(normalizedData); + unlockRequest.setEphemeralPublicKey(eciesRequest.getEphemeralPublicKey()); + unlockRequest.setEncryptedData(encryptedRequest.getEncryptedData()); + unlockRequest.setMac(eciesRequest.getMac()); + unlockRequest.setNonce(eciesRequest.getNonce()); + unlockRequest.setTimestamp(eciesRequest.getTimestamp()); + unlockRequest.setTemporaryKeyId(eciesRequest.getTemporaryKeyId()); + VaultUnlockResponse unlockResponse = powerAuthClient.unlockVault(unlockRequest); assertTrue(unlockResponse.isSignatureValid()); byte[] decryptedData = clientEncryptor.decryptResponse(new EncryptedResponse( unlockResponse.getEncryptedData(), @@ -197,13 +206,13 @@ public static void unlockVaultAndECDSASignatureTest(PowerAuthClient powerAuthCli // createApplication and createApplication version tests are skipped to avoid creating too many applications - public static void createValidateAndRemoveTokenTestActiveActivation(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws InvalidKeySpecException, CryptoProviderException, GenericCryptoException, IOException, EncryptorException, PowerAuthClientException { + public static void createValidateAndRemoveTokenTestActiveActivation(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { final TokenInfo tokenInfo = createToken(powerAuthClient, config, version); // Check successful token validation and activation status final ValidateTokenResponse validateResponse = powerAuthClient.validateToken(tokenInfo.getTokenId(), Base64.getEncoder().encodeToString(tokenInfo.getTokenNonce()), - version, + version.value(), Long.parseLong(new String(tokenInfo.getTokenTimestamp())), Base64.getEncoder().encodeToString(tokenInfo.getTokenDigest())); assertTrue(validateResponse.isTokenValid()); @@ -214,7 +223,7 @@ public static void createValidateAndRemoveTokenTestActiveActivation(PowerAuthCli assertTrue(removeResponse.isRemoved()); } - public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws CryptoProviderException, GenericCryptoException, IOException, EncryptorException, InvalidKeyException, InvalidKeySpecException, PowerAuthClientException { + public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { String activationName = "test_create_recovery"; KeyPair deviceKeyPair = CLIENT_ACTIVATION.generateDeviceKeyPair(); byte[] devicePublicKeyBytes = KEY_CONVERTOR.convertPublicKeyToBytes(deviceKeyPair.getPublic()); @@ -222,17 +231,26 @@ public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAut ActivationLayer2Request requestL2 = new ActivationLayer2Request(); requestL2.setActivationName(activationName); requestL2.setDevicePublicKey(devicePublicKeyBase64); + final TemporaryKey temporaryKey = TemporaryKeyFetchUtil.fetchTemporaryKey(version, EncryptorScope.APPLICATION_SCOPE, config); ClientEncryptor clientEncryptorL2 = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.ACTIVATION_LAYER_2, - new EncryptorParameters(version, config.getApplicationKey(), null, null), - new ClientEncryptorSecrets(config.getMasterPublicKey(), config.getApplicationSecret()) + new EncryptorParameters(version.value(), config.getApplicationKey(), null, temporaryKey != null ? temporaryKey.getId() : null), + new ClientEncryptorSecrets(temporaryKey != null ? temporaryKey.getPublicKey() : config.getMasterPublicKey(), config.getApplicationSecret()) ); ByteArrayOutputStream baosL2 = new ByteArrayOutputStream(); OBJECT_MAPPER.writeValue(baosL2, requestL2); EncryptedRequest encryptedRequestL2 = clientEncryptorL2.encryptRequest(baosL2.toByteArray()); - CreateActivationResponse createResponse = powerAuthClient.createActivation(config.getUser(version), null, - null, config.getApplicationKey(), encryptedRequestL2.getEphemeralPublicKey(), - encryptedRequestL2.getEncryptedData(), encryptedRequestL2.getMac(), encryptedRequestL2.getNonce(), version, encryptedRequestL2.getTimestamp()); + final CreateActivationRequest activationRequest = new CreateActivationRequest(); + activationRequest.setUserId(config.getUser(version)); + activationRequest.setApplicationKey(config.getApplicationKey()); + activationRequest.setEphemeralPublicKey(encryptedRequestL2.getEphemeralPublicKey()); + activationRequest.setEncryptedData(encryptedRequestL2.getEncryptedData()); + activationRequest.setMac(encryptedRequestL2.getMac()); + activationRequest.setNonce(encryptedRequestL2.getNonce()); + activationRequest.setTimestamp(encryptedRequestL2.getTimestamp()); + activationRequest.setTemporaryKeyId(encryptedRequestL2.getTemporaryKeyId()); + activationRequest.setProtocolVersion(version.value()); + CreateActivationResponse createResponse = powerAuthClient.createActivation(activationRequest); String activationId = createResponse.getActivationId(); assertNotNull(activationId); byte[] responseRaw = clientEncryptorL2.decryptResponse(new EncryptedResponse( @@ -253,66 +271,111 @@ public static void recoveryCodeConfirmAndActivationTest(PowerAuthClient powerAut SecretKey transportMasterKey = KEY_FACTORY.generateServerTransportKey(masterSecretKey); byte[] transportMasterKeyBytes = KEY_CONVERTOR.convertSharedSecretKeyToBytes(transportMasterKey); // Confirm recovery code - ClientEncryptor encryptorConfirmRC = ENCRYPTOR_FACTORY.getClientEncryptor( - EncryptorId.CONFIRM_RECOVERY_CODE, - new EncryptorParameters(version, config.getApplicationKey(), activationId, null), - new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) - ); - ConfirmRecoveryRequestPayload confirmRequestPayload = new ConfirmRecoveryRequestPayload(); - confirmRequestPayload.setRecoveryCode(recoveryCode); + final String activationIdOrig = config.getActivationId(version); + final String transportMasterKeyOrig = (String) config.getResultStatusObject(version).get("transportMasterKey"); + final String serverPublicKeyOrig = (String) config.getResultStatusObject(version).get("serverPublicKey"); + try { + config.setActivationId(activationId, version); + config.getResultStatusObject(version).put("transportMasterKey", Base64.getEncoder().encodeToString(transportMasterKeyBytes)); + config.getResultStatusObject(version).put("serverPublicKey", responseL2.getServerPublicKey()); + final TemporaryKey temporaryKey2 = TemporaryKeyFetchUtil.fetchTemporaryKey(version, EncryptorScope.ACTIVATION_SCOPE, config); + System.out.println(temporaryKey2); + System.out.println(temporaryKey2.getId()); + System.out.println(new EncryptorParameters(version.value(), config.getApplicationKey(), activationId, temporaryKey2 != null ? temporaryKey2.getId() : null)); + ClientEncryptor encryptorConfirmRC = ENCRYPTOR_FACTORY.getClientEncryptor( + EncryptorId.CONFIRM_RECOVERY_CODE, + new EncryptorParameters(version.value(), config.getApplicationKey(), activationId, temporaryKey2 != null ? temporaryKey2.getId() : null), + new ClientEncryptorSecrets(temporaryKey2 != null ? temporaryKey2.getPublicKey() : serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) + ); + ConfirmRecoveryRequestPayload confirmRequestPayload = new ConfirmRecoveryRequestPayload(); + confirmRequestPayload.setRecoveryCode(recoveryCode); - EncryptedRequest encryptedRequestConfirm = encryptorConfirmRC.encryptRequest(OBJECT_MAPPER.writeValueAsBytes(confirmRequestPayload)); - ConfirmRecoveryCodeResponse confirmResponse = powerAuthClient.confirmRecoveryCode(activationId, config.getApplicationKey(), encryptedRequestConfirm.getEphemeralPublicKey(), - encryptedRequestConfirm.getEncryptedData(), encryptedRequestConfirm.getMac(), encryptedRequestConfirm.getNonce(), version, encryptedRequestConfirm.getTimestamp()); - byte[] confirmResponseRaw = encryptorConfirmRC.decryptResponse(new EncryptedResponse( - confirmResponse.getEncryptedData(), - confirmResponse.getMac(), - confirmResponse.getNonce(), - confirmResponse.getTimestamp() - )); - final ConfirmRecoveryResponsePayload confirmResponsePayload = RestClientConfiguration.defaultMapper().readValue(confirmResponseRaw, ConfirmRecoveryResponsePayload.class); - assertTrue(confirmResponsePayload.isAlreadyConfirmed()); - // Create recovery activation - KeyPair deviceKeyPairR = CLIENT_ACTIVATION.generateDeviceKeyPair(); - byte[] devicePublicKeyBytesR = KEY_CONVERTOR.convertPublicKeyToBytes(deviceKeyPairR.getPublic()); - String devicePublicKeyBase64R = Base64.getEncoder().encodeToString(devicePublicKeyBytesR); - ActivationLayer2Request requestL2R = new ActivationLayer2Request(); - requestL2R.setActivationName(activationName + "_2"); - requestL2R.setDevicePublicKey(devicePublicKeyBase64R); - // Note: we reuse clientEncryptorL2 - ByteArrayOutputStream baosL2R = new ByteArrayOutputStream(); - OBJECT_MAPPER.writeValue(baosL2R, requestL2R); - clientEncryptorL2.encryptRequest(baosL2R.toByteArray()); - EncryptedRequest encryptedRequestL2R = clientEncryptorL2.encryptRequest(baosL2R.toByteArray()); - RecoveryCodeActivationResponse createResponseR = powerAuthClient.createActivationUsingRecoveryCode(recoveryCode, recoveryPuk, - config.getApplicationKey(), null, encryptedRequestL2R.getEphemeralPublicKey(), - encryptedRequestL2R.getEncryptedData(), encryptedRequestL2R.getMac(), encryptedRequestL2R.getNonce(), version, encryptedRequestL2R.getTimestamp()); - String activationIdNew = createResponseR.getActivationId(); - GetActivationStatusResponse statusResponseR1 = powerAuthClient.getActivationStatus(activationIdNew); - assertEquals(ActivationStatus.PENDING_COMMIT, statusResponseR1.getActivationStatus()); - CommitActivationResponse commitResponseR = powerAuthClient.commitActivation(activationIdNew, config.getUser(version)); - assertTrue(commitResponseR.isActivated()); - GetActivationStatusResponse statusResponseR2 = powerAuthClient.getActivationStatus(activationIdNew); - assertEquals(ActivationStatus.ACTIVE, statusResponseR2.getActivationStatus()); - GetActivationStatusResponse statusResponseR3 = powerAuthClient.getActivationStatus(activationId); - assertEquals(ActivationStatus.REMOVED, statusResponseR3.getActivationStatus()); + EncryptedRequest encryptedRequestConfirm = encryptorConfirmRC.encryptRequest(OBJECT_MAPPER.writeValueAsBytes(confirmRequestPayload)); + final ConfirmRecoveryCodeRequest confirmRequest = new ConfirmRecoveryCodeRequest(); + confirmRequest.setActivationId(activationId); + confirmRequest.setApplicationKey(config.getApplicationKey()); + confirmRequest.setEphemeralPublicKey(encryptedRequestConfirm.getEphemeralPublicKey()); + confirmRequest.setEncryptedData(encryptedRequestConfirm.getEncryptedData()); + confirmRequest.setMac(encryptedRequestConfirm.getMac()); + confirmRequest.setNonce(encryptedRequestConfirm.getNonce()); + confirmRequest.setTimestamp(encryptedRequestConfirm.getTimestamp()); + confirmRequest.setTemporaryKeyId(encryptedRequestConfirm.getTemporaryKeyId()); + confirmRequest.setProtocolVersion(version.value()); + ConfirmRecoveryCodeResponse confirmResponse = powerAuthClient.confirmRecoveryCode(confirmRequest); + byte[] confirmResponseRaw = encryptorConfirmRC.decryptResponse(new EncryptedResponse( + confirmResponse.getEncryptedData(), + confirmResponse.getMac(), + confirmResponse.getNonce(), + confirmResponse.getTimestamp() + )); + final ConfirmRecoveryResponsePayload confirmResponsePayload = RestClientConfiguration.defaultMapper().readValue(confirmResponseRaw, ConfirmRecoveryResponsePayload.class); + assertTrue(confirmResponsePayload.isAlreadyConfirmed()); + // Create recovery activation + KeyPair deviceKeyPairR = CLIENT_ACTIVATION.generateDeviceKeyPair(); + byte[] devicePublicKeyBytesR = KEY_CONVERTOR.convertPublicKeyToBytes(deviceKeyPairR.getPublic()); + String devicePublicKeyBase64R = Base64.getEncoder().encodeToString(devicePublicKeyBytesR); + ActivationLayer2Request requestL2R = new ActivationLayer2Request(); + requestL2R.setActivationName(activationName + "_2"); + requestL2R.setDevicePublicKey(devicePublicKeyBase64R); + // Note: we reuse clientEncryptorL2 + ByteArrayOutputStream baosL2R = new ByteArrayOutputStream(); + OBJECT_MAPPER.writeValue(baosL2R, requestL2R); + clientEncryptorL2.encryptRequest(baosL2R.toByteArray()); + EncryptedRequest encryptedRequestL2R = clientEncryptorL2.encryptRequest(baosL2R.toByteArray()); + final RecoveryCodeActivationRequest activationRequestRecovery = new RecoveryCodeActivationRequest(); + activationRequestRecovery.setRecoveryCode(recoveryCode); + activationRequestRecovery.setPuk(recoveryPuk); + activationRequestRecovery.setApplicationKey(config.getApplicationKey()); + activationRequestRecovery.setEphemeralPublicKey(encryptedRequestL2R.getEphemeralPublicKey()); + activationRequestRecovery.setEncryptedData(encryptedRequestL2R.getEncryptedData()); + activationRequestRecovery.setMac(encryptedRequestL2R.getMac()); + activationRequestRecovery.setNonce(encryptedRequestL2R.getNonce()); + activationRequestRecovery.setTimestamp(encryptedRequestL2R.getTimestamp()); + activationRequestRecovery.setTemporaryKeyId(encryptedRequestL2R.getTemporaryKeyId()); + activationRequestRecovery.setProtocolVersion(version.value()); + RecoveryCodeActivationResponse createResponseR = powerAuthClient.createActivationUsingRecoveryCode(activationRequestRecovery); + String activationIdNew = createResponseR.getActivationId(); + GetActivationStatusResponse statusResponseR1 = powerAuthClient.getActivationStatus(activationIdNew); + assertEquals(ActivationStatus.PENDING_COMMIT, statusResponseR1.getActivationStatus()); + CommitActivationResponse commitResponseR = powerAuthClient.commitActivation(activationIdNew, config.getUser(version)); + assertTrue(commitResponseR.isActivated()); + GetActivationStatusResponse statusResponseR2 = powerAuthClient.getActivationStatus(activationIdNew); + assertEquals(ActivationStatus.ACTIVE, statusResponseR2.getActivationStatus()); + GetActivationStatusResponse statusResponseR3 = powerAuthClient.getActivationStatus(activationId); + assertEquals(ActivationStatus.REMOVED, statusResponseR3.getActivationStatus()); + } finally { + config.setActivationId(activationIdOrig, version); + config.getResultStatusObject(version).put("transportMasterKey", transportMasterKeyOrig); + config.getResultStatusObject(version).put("serverPublicKey", serverPublicKeyOrig); + } } // Activation flags are tested using PowerAuthActivationFlagsTest // Application roles are tested using PowerAuthApplicationRolesTest - private static TokenInfo createToken(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, String version) throws InvalidKeySpecException, CryptoProviderException, GenericCryptoException, IOException, EncryptorException, PowerAuthClientException { + private static TokenInfo createToken(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { byte[] transportMasterKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "transportMasterKey")); byte[] serverPublicKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "serverPublicKey")); final PublicKey serverPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); + final TemporaryKey temporaryKey = TemporaryKeyFetchUtil.fetchTemporaryKey(version, EncryptorScope.ACTIVATION_SCOPE, config); final ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.CREATE_TOKEN, - new EncryptorParameters(version, config.getApplicationKey(), config.getActivationId(version), null), - new ClientEncryptorSecrets(serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) + new EncryptorParameters(version.value(), config.getApplicationKey(), config.getActivationId(version), temporaryKey != null ? temporaryKey.getId() : null), + new ClientEncryptorSecrets(temporaryKey != null ? temporaryKey.getPublicKey() :serverPublicKey, config.getApplicationSecret(), transportMasterKeyBytes) ); final EncryptedRequest encryptedRequest = clientEncryptor.encryptRequest("{}".getBytes(StandardCharsets.UTF_8)); - final CreateTokenResponse tokenResponse = powerAuthClient.createToken(config.getActivationId(version), config.getApplicationKey(), encryptedRequest.getEphemeralPublicKey(), encryptedRequest.getEncryptedData(), - encryptedRequest.getMac(), encryptedRequest.getNonce(), version, encryptedRequest.getTimestamp(), SignatureType.POSSESSION_KNOWLEDGE); + final CreateTokenRequest tokenRequest = new CreateTokenRequest(); + tokenRequest.setActivationId(config.getActivationId(version)); + tokenRequest.setApplicationKey(config.getApplicationKey()); + tokenRequest.setEphemeralPublicKey(encryptedRequest.getEphemeralPublicKey()); + tokenRequest.setEncryptedData(encryptedRequest.getEncryptedData()); + tokenRequest.setMac(encryptedRequest.getMac()); + tokenRequest.setNonce(encryptedRequest.getNonce()); + tokenRequest.setProtocolVersion(version.value()); + tokenRequest.setTimestamp(encryptedRequest.getTimestamp()); + tokenRequest.setTemporaryKeyId(encryptedRequest.getTemporaryKeyId()); + tokenRequest.setSignatureType(SignatureType.POSSESSION_KNOWLEDGE); + final CreateTokenResponse tokenResponse = powerAuthClient.createToken(tokenRequest); final byte[] decryptedData = clientEncryptor.decryptResponse(new EncryptedResponse( tokenResponse.getEncryptedData(), @@ -334,7 +397,7 @@ private static TokenInfo createToken(PowerAuthClient powerAuthClient, PowerAuthT tokenInfo.setTokenDigest(CLIENT_TOKEN_GENERATOR.computeTokenDigest( tokenInfo.getTokenNonce(), tokenInfo.getTokenTimestamp(), - version, + version.value(), Base64.getDecoder().decode(response.getTokenSecret()))); return tokenInfo; } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java index 1f99f6a9..4fbd3bab 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCallbackShared.java @@ -25,12 +25,13 @@ import com.wultra.security.powerauth.client.model.request.CreateCallbackUrlRequest; import com.wultra.security.powerauth.client.model.response.GetCallbackUrlListResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; import org.springframework.core.ParameterizedTypeReference; import java.util.*; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; /** @@ -40,7 +41,7 @@ */ public class PowerAuthCallbackShared { - public static void callbackExecutionTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, Integer port, String version) throws PowerAuthClientException, RestClientException { + public static void callbackExecutionTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, Integer port, PowerAuthVersion version) throws PowerAuthClientException, RestClientException { // Skip test when the tested PA server is not running on localhost assumeTrue(config.getPowerAuthRestUrl().contains("localhost:8080")); @@ -69,6 +70,11 @@ public static void callbackExecutionTest(PowerAuthClient powerAuthClient, PowerA request.put("blockedReason", "TEST_CALLBACK"); request.put("applicationId", config.getApplicationId()); RestClientFactory.getRestClient().post(callbackUrlVerify, request, new ParameterizedTypeReference() {}); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } powerAuthClient.unblockActivation(config.getActivationId(version), config.getUser(version)); boolean callbackFound = false; for (CallbackUrl callback: callbacks.getCallbackUrlList()) { diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java index 96951a92..e04fdd45 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationOtpShared.java @@ -28,6 +28,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.provider.CustomActivationProviderForTests; import io.getlime.security.powerauth.crypto.lib.model.ActivationStatusBlobInfo; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; @@ -194,7 +195,7 @@ public static void customActivationOtpInvalidTest(PowerAuthClient powerAuthClien public static void activationRecoveryOtpValidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, ActivationRecoveryStepModel recoveryModel, GetStatusStepModel statusModel, - String validOtpValue, String invalidOtpValue, String version) throws Exception { + String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { ActivationRecovery activationRecovery = getRecoveryData(powerAuthClient, config, tempStatusFile, version); @@ -266,8 +267,7 @@ public static void activationRecoveryOtpValidTest(PowerAuthClient powerAuthClien } public static void activationRecoveryOtpInvalidTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, - ActivationRecoveryStepModel recoveryModel, String validOtpValue, String invalidOtpValue, - String version) throws Exception { + ActivationRecoveryStepModel recoveryModel, String validOtpValue, String invalidOtpValue, PowerAuthVersion version) throws Exception { ActivationRecovery activationRecovery = getRecoveryData(powerAuthClient, config, tempStatusFile, version); @@ -330,7 +330,7 @@ public static void activationRecoveryOtpInvalidTest(PowerAuthClient powerAuthCli * @return Object containing recovery code and recovery puk. * @throws Exception In case of failure. */ - private static ActivationRecovery getRecoveryData(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, String version) throws Exception { + private static ActivationRecovery getRecoveryData(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, File tempStatusFile, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); @@ -343,7 +343,7 @@ private static ActivationRecovery getRecoveryData(PowerAuthClient powerAuthClien // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_v" + version); + prepareModel.setActivationName("test_recovery" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationShared.java index ed28dbfa..e50d30d5 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthCustomActivationShared.java @@ -25,9 +25,11 @@ import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; import com.wultra.security.powerauth.client.model.response.GetApplicationDetailResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.util.ResponseVerificationUtil; import io.getlime.core.rest.model.base.response.ErrorResponse; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.VerifySignatureStep; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; @@ -47,6 +49,11 @@ import static org.junit.jupiter.api.Assertions.*; +/** + * Custom activation test shared logic. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ public class PowerAuthCustomActivationShared { public static void customActivationValidTest(PowerAuthClient powerAuthClient, CreateActivationStepModel model, ObjectStepLogger stepLogger) throws Exception { @@ -230,14 +237,18 @@ public static void customActivationBadMasterPublicKeyTest(PowerAuthTestConfigura // Create activation new CreateActivationStep().execute(stepLogger, model.toMap()); assertFalse(stepLogger.getResult().success()); - assertEquals(400, stepLogger.getResponse().statusCode()); - - // Verify error response - ObjectMapper objectMapper = config.getObjectMapper(); - final ErrorResponse errorResponse = objectMapper.readValue(stepLogger.getResponse().responseObject().toString(), ErrorResponse.class); - assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + if (model.getVersion().useTemporaryKeys()) { + // JWT signature error, cannot obtain server response + assertNull(stepLogger.getResponse()); + } else { + assertEquals(400, stepLogger.getResponse().statusCode()); + // Verify error response + ObjectMapper objectMapper = config.getObjectMapper(); + final ErrorResponse errorResponse = objectMapper.readValue(stepLogger.getResponse().responseObject().toString(), ErrorResponse.class); + assertEquals("ERROR", errorResponse.getStatus()); + assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); + assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + } // Revert master public key change model.setMasterPublicKey(originalKey); @@ -268,8 +279,7 @@ public static void customActivationUnsupportedApplicationTest(PowerAuthClient po ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLogger.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); // Support application version powerAuthClient.supportApplicationVersion(config.getApplicationId(), config.getApplicationVersionId()); @@ -299,8 +309,7 @@ public static void customActivationInvalidApplicationKeyTest(PowerAuthTestConfig ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLogger.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); model.setApplicationKey(config.getApplicationKey()); } @@ -321,8 +330,7 @@ public static void customActivationInvalidApplicationSecretTest(PowerAuthTestCon ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLogger.getResponse().responseObject().toString(), ErrorResponse.class); assertEquals("ERROR", errorResponse.getStatus()); - assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); - assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + ResponseVerificationUtil.verifyErrorResponse(model, errorResponse); model.setApplicationSecret(config.getApplicationSecret()); } @@ -360,7 +368,7 @@ public static void customActivationDoubleCommitTest(PowerAuthClient powerAuthCli public static void customActivationSignatureMaxFailedTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, CreateActivationStepModel model, ObjectStepLogger stepLogger, - File dataFile, File tempStatusFile, Integer port, String version) throws Exception { + File dataFile, File tempStatusFile, Integer port, PowerAuthVersion version) throws Exception { Map identityAttributes = new HashMap<>(); identityAttributes.put("test_id", "TEST_10_SIGNATURES_MAX_FAILED"); identityAttributes.put("username", "TestUser1"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java index efdf1d82..ece8bbdd 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java @@ -33,6 +33,7 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.HashBasedCounter; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; @@ -132,7 +133,7 @@ public static void encryptEmptyDataTest(PowerAuthTestConfiguration config, Encry assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void encryptBlockedActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, EncryptStepModel encryptModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void encryptBlockedActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, EncryptStepModel encryptModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { encryptModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/activation"); encryptModel.setScope("activation"); @@ -167,7 +168,7 @@ public static void encryptBlockedActivationTest(PowerAuthClient powerAuthClient, assertTrue(responseSuccessfullyDecrypted); } - public static void signAndEncryptTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void signAndEncryptTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed"); @@ -221,12 +222,12 @@ public static void signAndEncryptEmptyDataTest(PowerAuthTestConfiguration config assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void signAndEncryptLargeDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void signAndEncryptLargeDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed"); SecureRandom secureRandom = new SecureRandom(); - File dataFileLarge = File.createTempFile("data_large_v" + version.replace(".", ""), ".dat"); + File dataFileLarge = File.createTempFile("data_large_" + version, ".dat"); dataFileLarge.deleteOnExit(); FileWriter fw = new FileWriter(dataFileLarge); fw.write("{\"data\": \""); @@ -245,11 +246,11 @@ public static void signAndEncryptLargeDataTest(PowerAuthTestConfiguration config assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void signAndEncryptStringDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void signAndEncryptStringDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed/string"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed/string"); - File dataFile = File.createTempFile("data_string_v" + version.replace(".", ""), ".dat"); + File dataFile = File.createTempFile("data_string" + version, ".dat"); dataFile.deleteOnExit(); BufferedWriter out = Files.newBufferedWriter(dataFile.toPath(), StandardCharsets.UTF_8); @@ -269,11 +270,11 @@ public static void signAndEncryptStringDataTest(PowerAuthTestConfiguration confi assertEquals("\"Server successfully decrypted data and verified signature, request data: " + requestData + ", user ID: " + config.getUser(version) + "\"", result); } - public static void signAndEncryptRawDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void signAndEncryptRawDataTest(PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed/raw"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed/raw"); - File dataFile = File.createTempFile("data_raw_v" + version.replace(".", ""), ".dat"); + File dataFile = File.createTempFile("data_raw_" + version, ".dat"); dataFile.deleteOnExit(); BufferedWriter out = Files.newBufferedWriter(dataFile.toPath(), StandardCharsets.UTF_8); @@ -329,7 +330,7 @@ public static void signAndEncryptInvalidResourceIdTest(PowerAuthTestConfiguratio assertEquals(401, stepLogger.getResponse().statusCode()); } - public static void signAndEncryptBlockedActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void signAndEncryptBlockedActivationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed"); @@ -362,7 +363,7 @@ public static void signAndEncryptBlockedActivationTest(PowerAuthClient powerAuth assertTrue(responseSuccessfullyDecrypted); } - public static void signAndEncryptUnsupportedApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, String version) throws Exception { + public static void signAndEncryptUnsupportedApplicationTest(PowerAuthClient powerAuthClient, PowerAuthTestConfiguration config, VerifySignatureStepModel signatureModel, PowerAuthVersion version) throws Exception { signatureModel.setResourceId("/exchange/v3/signed"); signatureModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/signed"); @@ -472,16 +473,16 @@ public static void signAndEncryptThreeFactorTest(PowerAuthTestConfiguration conf assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, String version) throws EncryptorException, PowerAuthClientException { + public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, PowerAuthVersion version) throws EncryptorException, PowerAuthClientException { String requestData = "test_data"; ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.APPLICATION_SCOPE_GENERIC, - new EncryptorParameters(version, config.getApplicationKey(), null, null), + new EncryptorParameters(version.value(), config.getApplicationKey(), null, null), new ClientEncryptorSecrets(config.getMasterPublicKey(), config.getApplicationSecret()) ); EncryptedRequest encryptedRequest = clientEncryptor.encryptRequest(requestData.getBytes(StandardCharsets.UTF_8)); final GetEciesDecryptorRequest eciesDecryptorRequest = new GetEciesDecryptorRequest(); - eciesDecryptorRequest.setProtocolVersion(version); + eciesDecryptorRequest.setProtocolVersion(version.value()); eciesDecryptorRequest.setActivationId(null); eciesDecryptorRequest.setApplicationKey(config.getApplicationKey()); eciesDecryptorRequest.setEphemeralPublicKey(encryptedRequest.getEphemeralPublicKey()); @@ -497,7 +498,7 @@ public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAut assertEquals("ERR0024", ex.getPowerAuthError().get().getCode()); } - public static void encryptedResponseTest(final PowerAuthTestConfiguration config, EncryptStepModel encryptModel, ObjectStepLogger stepLogger, String version) throws Exception { + public static void encryptedResponseTest(final PowerAuthTestConfiguration config, EncryptStepModel encryptModel, ObjectStepLogger stepLogger, PowerAuthVersion version) throws Exception { encryptModel.setUriString(config.getEnrollmentServiceUrl() + "/exchange/v3/activation"); encryptModel.setScope("activation"); @@ -508,11 +509,11 @@ public static void encryptedResponseTest(final PowerAuthTestConfiguration config assertNotNull(responseObject.getEncryptedData()); assertNotNull(responseObject.getMac()); switch (version) { - case "3.0", "3.1" -> { + case V3_0, V3_1 -> { assertNull(responseObject.getNonce()); assertNull(responseObject.getTimestamp()); } - case "3.2" -> { + case V3_2, V3_3 -> { assertNotNull(responseObject.getNonce()); assertNotNull(responseObject.getTimestamp()); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthInfoShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthInfoShared.java index d11f3fe1..39a51ad4 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthInfoShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthInfoShared.java @@ -26,6 +26,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.ObjectResponse; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; @@ -53,7 +54,7 @@ public class PowerAuthInfoShared { // Tolerate 60 seconds time difference between client and server in tests private static final long SERVER_CLIENT_TIME_DIFF_TOLERANCE_MILLIS = 60000; - public static void testUserInfo(final PowerAuthTestConfiguration config, final EncryptStepModel encryptModel, final String version) throws Exception { + public static void testUserInfo(final PowerAuthTestConfiguration config, final EncryptStepModel encryptModel, final PowerAuthVersion version) throws Exception { encryptModel.setUriString(config.getEnrollmentServiceUrl() + "/pa/v3/user/info"); encryptModel.setScope("activation"); encryptModel.setData(objectMapper.writeValueAsBytes(new UserInfoRequest())); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java index d5396aee..85bffafa 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthRecoveryShared.java @@ -33,6 +33,7 @@ import io.getlime.security.powerauth.crypto.lib.model.RecoveryInfo; import io.getlime.security.powerauth.crypto.lib.model.RecoverySeed; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; @@ -67,7 +68,7 @@ public class PowerAuthRecoveryShared { private static final String PRIVATE_KEY_RECOVERY_POSTCARD_BASE64 = "ALvtO6YEISVuCKugiltkUKgJaJbHRrdT77+9OhS79Gvm"; - public static void activationRecoveryTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { + public static void activationRecoveryTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); // Init activation @@ -78,7 +79,7 @@ public static void activationRecoveryTest(final PowerAuthClient powerAuthClient, // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_v" + version); + prepareModel.setActivationName("test_recovery" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); @@ -223,7 +224,7 @@ public static void activationRecoveryTest(final PowerAuthClient powerAuthClient, } - public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { + public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final PowerAuthVersion version) throws Exception { for (int loop = 1; loop <= 2; loop++) { // We'll perform two iterations and revoke Recovery Code on activationRemove() in the second one. final boolean revokeRecoveryCode = loop == 2; @@ -240,7 +241,7 @@ public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClie // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_v" + version); + prepareModel.setActivationName("test_recovery" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); @@ -310,7 +311,7 @@ public static void removeActivationAndRevokeRecoveryCodeTest(final PowerAuthClie } } - public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { + public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); // Init activation @@ -321,7 +322,7 @@ public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerA // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_invalid_puk_v" + version); + prepareModel.setActivationName("test_recovery_invalid_puk" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); @@ -415,7 +416,7 @@ public static void activationRecoveryInvalidPukTest(final PowerAuthClient powerA assertEquals(RecoveryPukStatus.INVALID, rcStatusResponse2.getRecoveryCodes().get(0).getPuks().get(0).getStatus()); } - public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final String version) throws Exception { + public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, final PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); String publicKeyServerBase64 = powerAuthClient.getRecoveryConfig(config.getApplicationId()).getPostcardPublicKey(); final String randomUserId = "TestUser_" + UUID.randomUUID(); @@ -456,7 +457,7 @@ public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, f // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_postcard_v" + version); + prepareModel.setActivationName("test_recovery_postcard" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); @@ -608,7 +609,7 @@ public static void recoveryPostcardTest(final PowerAuthClient powerAuthClient, f assertEquals(RecoveryPukStatus.VALID, response2.getRecoveryCodes().get(0).getPuks().get(0).getStatus()); } - public static void recoveryPostcardInvalidPukIndexTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, String version) throws Exception { + public static void recoveryPostcardInvalidPukIndexTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final File tempStatusFile, PowerAuthVersion version) throws Exception { final JSONObject resultStatusObject = new JSONObject(); String publicKeyServerBase64 = powerAuthClient.getRecoveryConfig(config.getApplicationId()).getPostcardPublicKey(); final String randomUserId = "TestUser_" + UUID.randomUUID(); @@ -640,7 +641,7 @@ public static void recoveryPostcardInvalidPukIndexTest(final PowerAuthClient pow // Prepare activation, assume recovery is enabled on server PrepareActivationStepModel prepareModel = new PrepareActivationStepModel(); - prepareModel.setActivationName("test_recovery_postcard_v" + version); + prepareModel.setActivationName("test_recovery_postcard" + version); prepareModel.setApplicationKey(config.getApplicationKey()); prepareModel.setApplicationSecret(config.getApplicationSecret()); prepareModel.setMasterPublicKey(config.getMasterPublicKey()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java index e857dd92..e9930449 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthSignatureShared.java @@ -34,6 +34,7 @@ import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.crypto.lib.util.SignatureUtils; import io.getlime.security.powerauth.http.PowerAuthHttpBody; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.VerifySignatureStep; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; @@ -133,7 +134,7 @@ public static void signatureCounterLookAheadTest(final PowerAuthTestConfiguratio } - public static void signatureBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final String version) throws Exception { + public static void signatureBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final PowerAuthVersion version) throws Exception { powerAuthClient.blockActivation(config.getActivationId(version), "test", "test"); ObjectStepLogger stepLogger1 = new ObjectStepLogger(System.out); @@ -178,8 +179,8 @@ public static void signatureThreeFactorTest(final VerifySignatureStepModel model assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void signatureEmptyDataTest(final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - File dataFile = File.createTempFile("data_empty_v" + version, ".json"); + public static void signatureEmptyDataTest(final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + File dataFile = File.createTempFile("data_empty" + version, ".json"); dataFile.deleteOnExit(); FileWriter fw = new FileWriter(dataFile); fw.close(); @@ -253,7 +254,7 @@ public static void signatureUnsupportedApplicationTest(final PowerAuthClient pow assertEquals("OK", responseOK.getStatus()); } - public static void signatureMaxFailedAttemptsTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final String version) throws Exception { + public static void signatureMaxFailedAttemptsTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final PowerAuthVersion version) throws Exception { // Create temp status file File tempStatusFile = File.createTempFile("pa_status", ".json"); tempStatusFile.deleteOnExit(); @@ -327,7 +328,7 @@ public static void signatureMaxFailedAttemptsTest(final PowerAuthClient powerAut powerAuthClient.removeActivation(initResponse.getActivationId(), "test"); } - public static void signatureLookAheadTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final String version) throws Exception { + public static void signatureLookAheadTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final PowerAuthVersion version) throws Exception { // Create temp status file File tempStatusFile = File.createTempFile("pa_status_lookahead", ".json"); tempStatusFile.deleteOnExit(); @@ -420,8 +421,8 @@ public static void signatureCounterIncrementTest(final VerifySignatureStepModel } } - public static void signatureLargeDataTest(final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - final File dataFileLarge = File.createTempFile("data_large_v" + version, ".dat"); + public static void signatureLargeDataTest(final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + final File dataFileLarge = File.createTempFile("data_large" + version, ".dat"); dataFileLarge.deleteOnExit(); final FileWriter fw = new FileWriter(dataFileLarge); final RandomStringGenerator randomStringGenerator = @@ -443,7 +444,7 @@ public static void signatureLargeDataTest(final VerifySignatureStepModel model, assertEquals("OK", responseOK.getStatus()); } - public static void signatureOfflinePersonalizedValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void signatureOfflinePersonalizedValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { final CreatePersonalizedOfflineSignaturePayloadResponse offlineResponse = powerAuthClient.createPersonalizedOfflineSignaturePayload( config.getActivationId(version), offlineData); String nonce = offlineResponse.getNonce(); @@ -504,7 +505,7 @@ public static void signatureOfflinePersonalizedValidTest(final PowerAuthClient p CounterUtil.incrementCounter(model); } - public static void signatureOfflinePersonalizedInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void signatureOfflinePersonalizedInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { CreatePersonalizedOfflineSignaturePayloadResponse offlineResponse = powerAuthClient.createPersonalizedOfflineSignaturePayload( config.getActivationId(version), offlineData); @@ -568,7 +569,7 @@ public static void signatureOfflinePersonalizedInvalidTest(final PowerAuthClient assertEquals(config.getApplicationId(), signatureResponse.getApplicationId()); } - public static void signatureOfflineNonPersonalizedValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void signatureOfflineNonPersonalizedValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { CreateNonPersonalizedOfflineSignaturePayloadResponse offlineResponse = powerAuthClient.createNonPersonalizedOfflineSignaturePayload( config.getApplicationId(), offlineData); String nonce = offlineResponse.getNonce(); @@ -627,7 +628,7 @@ public static void signatureOfflineNonPersonalizedValidTest(final PowerAuthClien CounterUtil.incrementCounter(model); } - public static void signatureOfflineNonPersonalizedInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void signatureOfflineNonPersonalizedInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { CreateNonPersonalizedOfflineSignaturePayloadResponse offlineResponse = powerAuthClient.createNonPersonalizedOfflineSignaturePayload( config.getApplicationId(), offlineData); String nonce = offlineResponse.getNonce(); @@ -729,11 +730,11 @@ public static void signatureInvalidResourceIdTest(final PowerAuthTestConfigurati model.setResourceId("/pa/signature/validate"); } - public static void testSignatureOfflinePersonalizedProximityCheckValid(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void testSignatureOfflinePersonalizedProximityCheckValid(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { testSignatureOfflinePersonalizedProximityCheck(powerAuthClient, config, model, stepLogger, version, true); } - public static void testSignatureOfflinePersonalizedProximityCheckInvalid(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { + public static void testSignatureOfflinePersonalizedProximityCheckInvalid(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { testSignatureOfflinePersonalizedProximityCheck(powerAuthClient, config, model, stepLogger, version, false); } @@ -743,7 +744,7 @@ private static void checkSignatureError(ErrorResponse errorResponse) { assertTrue("Signature validation failed".equals(errorResponse.getResponseObject().getMessage()) || "POWER_AUTH_SIGNATURE_INVALID".equals(errorResponse.getResponseObject().getMessage())); } - private static void testSignatureOfflinePersonalizedProximityCheck(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final String version, final boolean expectedResult) throws Exception { + private static void testSignatureOfflinePersonalizedProximityCheck(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VerifySignatureStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version, final boolean expectedResult) throws Exception { final String seed = "LtxE0f0RWNx3hy7ISjUPWA=="; final CreatePersonalizedOfflineSignaturePayloadRequest request = new CreatePersonalizedOfflineSignaturePayloadRequest(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthTokenShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthTokenShared.java index d73a514c..98d69132 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthTokenShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthTokenShared.java @@ -22,6 +22,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.core.rest.model.base.response.ErrorResponse; import io.getlime.security.powerauth.crypto.lib.generator.HashBasedCounter; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.VerifyTokenStep; @@ -46,7 +47,7 @@ */ public class PowerAuthTokenShared { - public static void tokenCreateAndVerifyTest(final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final File dataFile, final String version) throws Exception { + public static void tokenCreateAndVerifyTest(final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final File dataFile, final PowerAuthVersion version) throws Exception { ObjectStepLogger stepLogger1 = new ObjectStepLogger(); new CreateTokenStep().execute(stepLogger1, model.toMap()); assertTrue(stepLogger1.getResult().success()); @@ -98,7 +99,7 @@ public static void tokenCreateInvalidPasswordTest(final PowerAuthTestConfigurati checkSignatureError(errorResponse); } - public static void tokenVerifyInvalidTokenTest(final PowerAuthTestConfiguration config, final File dataFile, final String version) throws Exception { + public static void tokenVerifyInvalidTokenTest(final PowerAuthTestConfiguration config, final File dataFile, final PowerAuthVersion version) throws Exception { VerifyTokenStepModel modelVerify = new VerifyTokenStepModel(); modelVerify.setTokenId("test"); modelVerify.setTokenSecret("test"); @@ -120,7 +121,7 @@ public static void tokenVerifyInvalidTokenTest(final PowerAuthTestConfiguration checkSignatureError(errorResponse); } - public static void tokenVerifyRemovedTokenTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final File dataFile, final String version) throws Exception { + public static void tokenVerifyRemovedTokenTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final File dataFile, final PowerAuthVersion version) throws Exception { ObjectStepLogger stepLogger1 = new ObjectStepLogger(); new CreateTokenStep().execute(stepLogger1, model.toMap()); assertTrue(stepLogger1.getResult().success()); @@ -163,7 +164,7 @@ public static void tokenVerifyRemovedTokenTest(final PowerAuthClient powerAuthCl checkSignatureError(errorResponse); } - public static void tokenCreateBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final String version) throws Exception { + public static void tokenCreateBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final CreateTokenStepModel model, final PowerAuthVersion version) throws Exception { powerAuthClient.blockActivation(config.getActivationId(version), "test", "test"); ObjectStepLogger stepLogger1 = new ObjectStepLogger(System.out); @@ -190,7 +191,11 @@ public static void tokenUnsupportedApplicationTest(final PowerAuthClient powerAu ObjectStepLogger stepLogger1 = new ObjectStepLogger(System.out); new CreateTokenStep().execute(stepLogger1, model.toMap()); assertFalse(stepLogger1.getResult().success()); - assertEquals(401, stepLogger1.getResponse().statusCode()); + if (model.getVersion().useTemporaryKeys()) { + assertEquals(400, stepLogger1.getResponse().statusCode()); + } else { + assertEquals(401, stepLogger1.getResponse().statusCode()); + } ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLogger1.getResponse().responseObject().toString(), ErrorResponse.class); @@ -221,8 +226,8 @@ public static void tokenCounterIncrementTest(final CreateTokenStepModel model, f } private static void checkSignatureError(final ErrorResponse errorResponse) { - // Errors differ when Web Flow is used because of its Exception handler - assertTrue("POWERAUTH_AUTH_FAIL".equals(errorResponse.getResponseObject().getCode()) || "ERR_AUTHENTICATION".equals(errorResponse.getResponseObject().getCode())); + // Errors differ when Web Flow is used because of its Exception handler, for protocol version 3.3 temporary key error is present + assertTrue("POWERAUTH_AUTH_FAIL".equals(errorResponse.getResponseObject().getCode()) || "ERR_AUTHENTICATION".equals(errorResponse.getResponseObject().getCode()) || "ERR_TEMPORARY_KEY".equals(errorResponse.getResponseObject().getCode())); } private static String getTokenUri(final PowerAuthTestConfiguration config) { diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthVaultUnlockShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthVaultUnlockShared.java index 6d589585..fcfa2c71 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthVaultUnlockShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthVaultUnlockShared.java @@ -25,6 +25,7 @@ import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.HashBasedCounter; import io.getlime.security.powerauth.crypto.lib.util.SignatureUtils; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import io.getlime.security.powerauth.lib.cmd.steps.v3.VaultUnlockStep; @@ -108,7 +109,7 @@ public static void vaultUnlockThreeFactorTest(final VaultUnlockStepModel model, assertEquals(400, stepLogger.getResponse().statusCode()); } - public static void vaultUnlockBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final String version) throws Exception { + public static void vaultUnlockBlockedActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final PowerAuthVersion version) throws Exception { powerAuthClient.blockActivation(config.getActivationId(version), "test", "test"); ObjectStepLogger stepLogger1 = new ObjectStepLogger(System.out); @@ -135,7 +136,11 @@ public static void vaultUnlockUnsupportedApplicationTest(final PowerAuthClient p ObjectStepLogger stepLogger1 = new ObjectStepLogger(System.out); new VaultUnlockStep().execute(stepLogger1, model.toMap()); assertFalse(stepLogger1.getResult().success()); - assertEquals(401, stepLogger1.getResponse().statusCode()); + if (model.getVersion().useTemporaryKeys()) { + assertEquals(400, stepLogger1.getResponse().statusCode()); + } else { + assertEquals(401, stepLogger1.getResponse().statusCode()); + } ObjectMapper objectMapper = config.getObjectMapper(); final ErrorResponse errorResponse = objectMapper.readValue(stepLogger1.getResponse().responseObject().toString(), ErrorResponse.class); @@ -179,8 +184,8 @@ public static void vaultUnlockTooLongReasonTest(final PowerAuthTestConfiguration assertEquals("POWER_AUTH_SECURE_VAULT_INVALID", errorResponse.getResponseObject().getMessage()); } - public static void vaultUnlockAndECDSASignatureValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - final byte[] dataBytes = ("test_data_v" + version).getBytes(StandardCharsets.UTF_8); + public static void vaultUnlockAndECDSASignatureValidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + final byte[] dataBytes = ("test_data" + version).getBytes(StandardCharsets.UTF_8); final String data = Base64.getEncoder().encodeToString(dataBytes); final PrivateKey devicePrivateKey = obtainDevicePrivateKeyUsingVaultUnlock(stepLogger, model, config); @@ -191,20 +196,20 @@ public static void vaultUnlockAndECDSASignatureValidTest(final PowerAuthClient p assertTrue(verifyResponse.isSignatureValid()); } - public static void vaultUnlockAndECDSASignatureInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - final byte[] dataBytes = ("test_data_v" + version).getBytes(StandardCharsets.UTF_8); + public static void vaultUnlockAndECDSASignatureInvalidTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + final byte[] dataBytes = ("test_data" + version).getBytes(StandardCharsets.UTF_8); final String data = Base64.getEncoder().encodeToString(dataBytes); final PrivateKey devicePrivateKey = obtainDevicePrivateKeyUsingVaultUnlock(stepLogger, model, config); final byte[] signature = SIGNATURE_UTILS.computeECDSASignature("test_data_crippled".getBytes(StandardCharsets.UTF_8), devicePrivateKey); - final VerifyECDSASignatureResponse verifyResponse = powerAuthClient.verifyECDSASignature(config.getActivationIdV32(), data, Base64.getEncoder().encodeToString(signature)); + final VerifyECDSASignatureResponse verifyResponse = powerAuthClient.verifyECDSASignature(config.getActivationId(version), data, Base64.getEncoder().encodeToString(signature)); assertFalse(verifyResponse.isSignatureValid()); } - public static void vaultUnlockAndECDSASignatureInvalidActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - final byte[] dataBytes = ("test_data_v" + version).getBytes(StandardCharsets.UTF_8); + public static void vaultUnlockAndECDSASignatureInvalidActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + final byte[] dataBytes = ("test_data" + version).getBytes(StandardCharsets.UTF_8); final String data = Base64.getEncoder().encodeToString(dataBytes); final PrivateKey devicePrivateKey = obtainDevicePrivateKeyUsingVaultUnlock(stepLogger, model, config); @@ -212,9 +217,10 @@ public static void vaultUnlockAndECDSASignatureInvalidActivationTest(final Power final byte[] signature = SIGNATURE_UTILS.computeECDSASignature(dataBytes, devicePrivateKey); final String activationIdInvalid = switch (version) { - case "3.0" -> config.getActivationIdV31(); - case "3.1" -> config.getActivationIdV32(); - case "3.2" -> config.getActivationIdV3(); + case V3_0 -> config.getActivationId(PowerAuthVersion.V3_3); + case V3_1 -> config.getActivationId(PowerAuthVersion.V3_2); + case V3_2 -> config.getActivationId(PowerAuthVersion.V3_1); + case V3_3 -> config.getActivationId(PowerAuthVersion.V3_0); default -> null; }; @@ -222,8 +228,8 @@ public static void vaultUnlockAndECDSASignatureInvalidActivationTest(final Power assertFalse(verifyResponse.isSignatureValid()); } - public static void vaultUnlockAndECDSASignatureNonExistentActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final String version) throws Exception { - final byte[] dataBytes = ("test_data_v" + version).getBytes(StandardCharsets.UTF_8); + public static void vaultUnlockAndECDSASignatureNonExistentActivationTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, final VaultUnlockStepModel model, final ObjectStepLogger stepLogger, final PowerAuthVersion version) throws Exception { + final byte[] dataBytes = ("test_data" + version).getBytes(StandardCharsets.UTF_8); final String data = Base64.getEncoder().encodeToString(dataBytes); final PrivateKey devicePrivateKey = obtainDevicePrivateKeyUsingVaultUnlock(stepLogger, model, config); @@ -253,8 +259,8 @@ private static PrivateKey obtainDevicePrivateKeyUsingVaultUnlock(final ObjectSte } private static void checkSignatureError(ErrorResponse errorResponse) { - // Errors differ when Web Flow is used because of its Exception handler - assertTrue("POWERAUTH_AUTH_FAIL".equals(errorResponse.getResponseObject().getCode()) || "ERR_AUTHENTICATION".equals(errorResponse.getResponseObject().getCode())); - assertTrue("Signature validation failed".equals(errorResponse.getResponseObject().getMessage()) || "POWER_AUTH_SIGNATURE_INVALID".equals(errorResponse.getResponseObject().getMessage())); + // Errors differ when Web Flow is used because of its Exception handler, for protocol version 3.3 temporary key error is present + assertTrue("POWERAUTH_AUTH_FAIL".equals(errorResponse.getResponseObject().getCode()) || "ERR_AUTHENTICATION".equals(errorResponse.getResponseObject().getCode()) || "ERR_TEMPORARY_KEY".equals(errorResponse.getResponseObject().getCode())); + assertTrue("Signature validation failed".equals(errorResponse.getResponseObject().getMessage()) || "POWER_AUTH_SIGNATURE_INVALID".equals(errorResponse.getResponseObject().getMessage()) || "POWER_AUTH_TEMPORARY_KEY_FAILURE".equals(errorResponse.getResponseObject().getMessage())); } } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/ResponseVerificationUtil.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/ResponseVerificationUtil.java new file mode 100644 index 00000000..9be406f6 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/ResponseVerificationUtil.java @@ -0,0 +1,41 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.shared.util; + +import io.getlime.core.rest.model.base.response.ErrorResponse; +import io.getlime.security.powerauth.lib.cmd.steps.model.BaseStepModel; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Utilities for verifying server responses dependent on protocol versions. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class ResponseVerificationUtil { + + public static void verifyErrorResponse(BaseStepModel model, ErrorResponse errorResponse) { + if (model.getVersion().useTemporaryKeys()) { + assertEquals("ERR_TEMPORARY_KEY", errorResponse.getResponseObject().getCode()); + assertEquals("POWER_AUTH_TEMPORARY_KEY_FAILURE", errorResponse.getResponseObject().getMessage()); + } else { + assertEquals("ERR_ACTIVATION", errorResponse.getResponseObject().getCode()); + assertEquals("POWER_AUTH_ACTIVATION_INVALID", errorResponse.getResponseObject().getMessage()); + } + } +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/TemporaryKeyFetchUtil.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/TemporaryKeyFetchUtil.java new file mode 100644 index 00000000..3843ae41 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/util/TemporaryKeyFetchUtil.java @@ -0,0 +1,196 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.shared.util; + +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import com.wultra.core.rest.client.base.RestClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.model.TemporaryKey; +import io.getlime.core.rest.model.base.request.ObjectRequest; +import io.getlime.core.rest.model.base.response.ObjectResponse; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; +import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.util.HMACHashUtilities; +import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; +import io.getlime.security.powerauth.crypto.lib.util.SignatureUtils; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.util.JsonUtil; +import io.getlime.security.powerauth.lib.cmd.util.MapUtil; +import io.getlime.security.powerauth.lib.cmd.util.RestClientFactory; +import io.getlime.security.powerauth.rest.api.model.request.TemporaryKeyRequest; +import io.getlime.security.powerauth.rest.api.model.response.TemporaryKeyResponse; +import org.bouncycastle.asn1.ASN1EncodableVector; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.DLSequence; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.crypto.SecretKey; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.PublicKey; +import java.security.interfaces.ECPublicKey; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.*; + +/** + * Utilities for fetching temporary keys from the server. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class TemporaryKeyFetchUtil { + + private TemporaryKeyFetchUtil() { + } + + private static final KeyGenerator KEY_GENERATOR = new KeyGenerator(); + private static final KeyConvertor KEY_CONVERTOR = new KeyConvertor(); + private static final SignatureUtils SIGNATURE_UTILS = new SignatureUtils(); + + /** + * Fetch temporary key for encryption from the server. + * @param version Protocol version. + * @param scope Encryption scope. + * @param config Test configuration. + * @throws Exception Thrown in case temporary key fetch fails. + */ + public static TemporaryKey fetchTemporaryKey(PowerAuthVersion version, EncryptorScope scope, PowerAuthTestConfiguration config) throws Exception { + if (version.useTemporaryKeys()) { + return fetchTemporaryKeyImpl(version, scope, config); + } + return null; + } + + private static TemporaryKey fetchTemporaryKeyImpl(PowerAuthVersion version, EncryptorScope scope, PowerAuthTestConfiguration config) throws Exception { + final String baseUri = config.getEnrollmentServiceUrl(); + final Map headers = prepareHeaders(); + final String uri = baseUri + "/pa/v3/keystore/create"; + final byte[] challengeBytes = KEY_GENERATOR.generateRandomBytes(18); + final String challenge = Base64.getEncoder().encodeToString(challengeBytes); + final String requestData = createJwtRequest(version, scope, challenge, config); + final TemporaryKeyRequest jwtData = new TemporaryKeyRequest(); + jwtData.setJwt(requestData); + final ObjectRequest request = new ObjectRequest<>(jwtData); + final RestClient restClient = RestClientFactory.getRestClient(); + final ObjectResponse response = Objects.requireNonNull(restClient).postObject(uri, request, null, MapUtil.toMultiValueMap(headers), TemporaryKeyResponse.class); + return handleTemporaryKeyResponse(version, response, scope, config); + } + + private static Map prepareHeaders() { + Map headers = new HashMap<>(); + headers.put(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + return headers; + } + + private static String createJwtRequest(PowerAuthVersion version, EncryptorScope scope, String challenge, PowerAuthTestConfiguration config) throws Exception { + final String applicationKey = config.getApplicationKey(); + final String activationId = scope == EncryptorScope.ACTIVATION_SCOPE ? config.getActivationId(version) : null; + final Instant now = Instant.now(); + final JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder() + .claim("applicationKey", applicationKey) + .claim("activationId", activationId) + .claim("challenge", challenge) + .issueTime(Date.from(now)) + .expirationTime(Date.from(now.plus(5, ChronoUnit.MINUTES))) + .build(); + final byte[] secretKey = getSecretKey(version, scope, config); + return signJwt(jwtClaims, secretKey); + } + + private static byte[] getSecretKey(PowerAuthVersion version, EncryptorScope scope, PowerAuthTestConfiguration config) throws Exception { + final String appSecret = config.getApplicationSecret(); + if (scope == EncryptorScope.APPLICATION_SCOPE) { + return Base64.getDecoder().decode(appSecret); + } else if (scope == EncryptorScope.ACTIVATION_SCOPE) { + final byte[] transportMasterKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "transportMasterKey")); + final SecretKey transportMasterKey = KEY_CONVERTOR.convertBytesToSharedSecretKey(transportMasterKeyBytes); + final byte[] appSecretBytes = Base64.getDecoder().decode(appSecret); + final SecretKey secretKeyBytes = KEY_GENERATOR.deriveSecretKeyHmac(transportMasterKey, appSecretBytes); + return KEY_CONVERTOR.convertSharedSecretKeyToBytes(secretKeyBytes); + } + return null; + } + + private static String signJwt(JWTClaimsSet jwtClaims, byte[] secretKey) throws Exception { + final JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256); + final byte[] payloadBytes = jwtClaims.toPayload().toBytes(); + final Base64URL encodedHeader = jwsHeader.toBase64URL(); + final Base64URL encodedPayload = Base64URL.encode(payloadBytes); + final String signingInput = encodedHeader + "." + encodedPayload; + final byte[] hash = new HMACHashUtilities().hash(secretKey, signingInput.getBytes(StandardCharsets.UTF_8)); + final Base64URL signature = Base64URL.encode(hash); + return encodedHeader + "." + encodedPayload + "." + signature; + } + + private static TemporaryKey handleTemporaryKeyResponse(PowerAuthVersion version, ObjectResponse response, EncryptorScope scope, PowerAuthTestConfiguration config) throws Exception { + final String jwtResponse = response.getResponseObject().getJwt(); + final SignedJWT decodedJWT = SignedJWT.parse(jwtResponse); + final ECPublicKey publicKey = switch (scope) { + case ACTIVATION_SCOPE -> { + byte[] serverPublicKeyBytes = Base64.getDecoder().decode(JsonUtil.stringValue(config.getResultStatusObject(version), "serverPublicKey")); + yield (ECPublicKey) KEY_CONVERTOR.convertBytesToPublicKey(serverPublicKeyBytes); + } + case APPLICATION_SCOPE -> (ECPublicKey) config.getMasterPublicKey(); + }; + + if (!validateJwtSignature(decodedJWT, publicKey)) { + return null; + } + final TemporaryKey temporaryKey = new TemporaryKey(); + temporaryKey.setId((String) decodedJWT.getJWTClaimsSet().getClaim("sub")); + final String temporaryPublicKeyBase64 = (String) decodedJWT.getJWTClaimsSet().getClaim("publicKey"); + final byte[] temporaryPublicKeyBytes = Base64.getDecoder().decode(temporaryPublicKeyBase64); + final PublicKey temporaryPublicKey = KEY_CONVERTOR.convertBytesToPublicKey(temporaryPublicKeyBytes); + temporaryKey.setPublicKey(temporaryPublicKey); + return temporaryKey; + } + + private static boolean validateJwtSignature(SignedJWT jwt, PublicKey publicKey) throws Exception { + final Base64URL[] jwtParts = jwt.getParsedParts(); + final Base64URL encodedHeader = jwtParts[0]; + final Base64URL encodedPayload = jwtParts[1]; + final Base64URL encodedSignature = jwtParts[2]; + final String signingInput = encodedHeader + "." + encodedPayload; + final byte[] signatureBytes = convertRawSignatureToDER(encodedSignature.decode()); + return SIGNATURE_UTILS.validateECDSASignature(signingInput.getBytes(StandardCharsets.UTF_8), signatureBytes, publicKey); + } + + private static byte[] convertRawSignatureToDER(byte[] rawSignature) throws Exception { + if (rawSignature.length % 2 != 0) { + throw new IllegalArgumentException("Invalid ECDSA signature format"); + } + int len = rawSignature.length / 2; + byte[] rBytes = new byte[len]; + byte[] sBytes = new byte[len]; + System.arraycopy(rawSignature, 0, rBytes, 0, len); + System.arraycopy(rawSignature, len, sBytes, 0, len); + BigInteger r = new BigInteger(1, rBytes); + BigInteger s = new BigInteger(1, sBytes); + ASN1EncodableVector v = new ASN1EncodableVector(); + v.add(new ASN1Integer(r)); + v.add(new ASN1Integer(s)); + return new DLSequence(v).getEncoded(); + } + +} \ No newline at end of file diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthActivationTest.java index df6906ef..3fbdca7a 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthActivationTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.json.simple.JSONObject; import org.junit.jupiter.api.AfterEach; @@ -38,12 +39,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthActivationTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -63,11 +69,11 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new PrepareActivationStepModel(); - model.setActivationName("test v" + VERSION); + model.setActivationName("test " + VERSION); model.setApplicationKey(config.getApplicationKey()); model.setApplicationSecret(config.getApplicationSecret()); model.setMasterPublicKey(config.getMasterPublicKey()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthCustomActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthCustomActivationTest.java index a86d8d9e..a5876b81 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthCustomActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthCustomActivationTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import org.junit.jupiter.api.*; @@ -38,13 +39,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth custom activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableConfigurationProperties @ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) class PowerAuthCustomActivationTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -82,18 +88,18 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new CreateActivationStepModel(); - model.setActivationName("test v" + VERSION); + model.setActivationName("test " + VERSION); model.setApplicationKey(config.getApplicationKey()); model.setApplicationSecret(config.getApplicationSecret()); model.setMasterPublicKey(config.getMasterPublicKey()); model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV3()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString("http://localhost:" + port); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java index 28722be0..0ed86dd9 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthEncryptionShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -44,13 +45,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth encryption tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthEncryptionTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthTestConfiguration config; private static File dataFile; @@ -90,7 +96,7 @@ void setUp() throws IOException { encryptModel.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV3()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -100,9 +106,9 @@ void setUp() throws IOException { signatureModel.setHeaders(new HashMap<>()); signatureModel.setHttpMethod("POST"); signatureModel.setPassword(config.getPassword()); - signatureModel.setResultStatusObject(config.getResultStatusObjectV3()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - signatureModel.setStatusFileName(config.getStatusFileV3().getAbsolutePath()); + signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); signatureModel.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthRecoveryTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthRecoveryTest.java index 9cf39ff7..1a95f09e 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthRecoveryTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthRecoveryTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthRecoveryShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -34,12 +35,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation recovery tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthRecoveryTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -58,7 +64,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_recovery_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_recovery_" + VERSION, ".json"); } @AfterEach diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthSignatureTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthSignatureTest.java index c67299a6..bec5667b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthSignatureTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthSignatureTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthSignatureShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import org.junit.jupiter.api.AfterAll; @@ -42,12 +43,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth signature tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties public class PowerAuthSignatureTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthTestConfiguration config; private static File dataFile; @@ -89,9 +95,9 @@ void setUp() throws IOException { model.setHttpMethod("POST"); model.setPassword(config.getPassword()); model.setResourceId("/pa/signature/validate"); - model.setResultStatusObject(config.getResultStatusObjectV3()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - model.setStatusFileName(config.getStatusFileV3().getAbsolutePath()); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthTokenTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthTokenTest.java index 1bd45be0..a6a1d256 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthTokenTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthTokenTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthTokenShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; import org.junit.jupiter.api.AfterAll; @@ -40,12 +41,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth token tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthTokenTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -85,8 +91,8 @@ void setUp() { model.setHeaders(new HashMap<>()); model.setMasterPublicKey(config.getMasterPublicKey()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV3()); - model.setStatusFileName(config.getStatusFileV3().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthVaultUnlockTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthVaultUnlockTest.java index 6c52e30d..b130e5ea 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthVaultUnlockTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthVaultUnlockTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthVaultUnlockShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import org.junit.jupiter.api.BeforeEach; @@ -33,12 +34,17 @@ import java.util.HashMap; +/** + * PowerAuth vault unlock tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthVaultUnlockTest { - private static final String VERSION = "3.0"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_0; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -62,8 +68,8 @@ void setUp() { model.setApplicationSecret(config.getApplicationSecret()); model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV3()); - model.setStatusFileName(config.getStatusFileV3().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setReason("TEST_" + VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCodeTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCodeTest.java index 7df801a5..26bcff86 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCodeTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCodeTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationCodeShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -40,12 +41,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation with activation code tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties public class PowerAuthActivationCodeTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthTestConfiguration config; private PrepareActivationStepModel activationModel; @@ -61,7 +67,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests activationModel = new PrepareActivationStepModel(); @@ -85,7 +91,7 @@ void setUp() throws IOException { signatureModel.setHttpMethod("POST"); signatureModel.setHeaders(new HashMap<>()); signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - signatureModel.setResultStatusObject(config.getResultStatusObjectV31()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); signatureModel.setVersion(VERSION); signatureModel.setDryRun(false); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java index eea303d7..2dca26d1 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationCommitPhaseTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationCommitPhaseShared; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.junit.jupiter.api.AfterEach; @@ -48,7 +49,7 @@ @EnableConfigurationProperties class PowerAuthActivationCommitPhaseTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -74,7 +75,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests model = new PrepareActivationStepModel(); @@ -85,14 +86,14 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java index 3a179749..bef5e560 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationOtpTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationOtpShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.junit.jupiter.api.AfterEach; @@ -37,12 +38,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthActivationOtpTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -66,7 +72,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests model = new PrepareActivationStepModel(); @@ -77,14 +83,14 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV31()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV31()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationTest.java index b6433240..5dd88a8b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthActivationTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.json.simple.JSONObject; import org.junit.jupiter.api.AfterEach; @@ -38,12 +39,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthActivationTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -63,7 +69,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new PrepareActivationStepModel(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationOtpTest.java index f6d18452..d30297ac 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationOtpTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationOtpShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; @@ -40,13 +41,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth custom activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableConfigurationProperties @ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) class PowerAuthCustomActivationOtpTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -90,7 +96,7 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws IOException { // Create temp status files - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests createModel = new CreateActivationStepModel(); @@ -101,7 +107,7 @@ void setUp() throws IOException { createModel.setHeaders(new HashMap<>()); createModel.setPassword(config.getPassword()); createModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - createModel.setResultStatusObject(config.getResultStatusObjectV31()); + createModel.setResultStatusObject(config.getResultStatusObject(VERSION)); createModel.setUriString("http://localhost:" + port); createModel.setVersion(VERSION); createModel.setDeviceInfo("backend-tests"); @@ -114,14 +120,14 @@ void setUp() throws IOException { recoveryModel.setHeaders(new HashMap<>()); recoveryModel.setPassword(config.getPassword()); recoveryModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - recoveryModel.setResultStatusObject(config.getResultStatusObjectV31()); + recoveryModel.setResultStatusObject(config.getResultStatusObject(VERSION)); recoveryModel.setUriString("http://localhost:" + port); recoveryModel.setVersion(VERSION); recoveryModel.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV31()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationTest.java index d8401c46..3eb80920 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthCustomActivationTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import org.junit.jupiter.api.*; @@ -38,13 +39,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth custom activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableConfigurationProperties @ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) class PowerAuthCustomActivationTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -82,7 +88,7 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new CreateActivationStepModel(); @@ -93,7 +99,7 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV31()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString("http://localhost:" + port); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java index d04b7828..4143beff 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthEncryptionShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -44,13 +45,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth encryption tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthEncryptionTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthTestConfiguration config; private static File dataFile; @@ -90,7 +96,7 @@ void setUp() throws IOException { encryptModel.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV31()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -100,9 +106,9 @@ void setUp() throws IOException { signatureModel.setHeaders(new HashMap<>()); signatureModel.setHttpMethod("POST"); signatureModel.setPassword(config.getPassword()); - signatureModel.setResultStatusObject(config.getResultStatusObjectV31()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - signatureModel.setStatusFileName(config.getStatusFileV31().getAbsolutePath()); + signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); signatureModel.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java index c832da99..cbfd320d 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthIdentityVerificationTest.java @@ -23,6 +23,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthIdentityVerificationShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.*; import org.json.simple.JSONObject; @@ -39,13 +40,18 @@ import java.io.IOException; import java.util.HashMap; +/** + * PowerAuth identity verification tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthIdentityVerificationTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -66,7 +72,7 @@ public void setPowerAuthClient(PowerAuthClient powerAuthClient) { @BeforeEach void setUp() throws IOException { // Create temp status file - File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Create result status object final JSONObject resultStatusObject = new JSONObject(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java index 73693bfc..2c3547f1 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthOnboardingTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthOnboardingShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; @@ -39,13 +40,18 @@ import java.io.IOException; import java.util.HashMap; +/** + * PowerAuth onboarding tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthOnboardingTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -70,12 +76,12 @@ void setUp() throws IOException { encryptModel.setApplicationSecret(config.getApplicationSecret()); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV31()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); encryptModel.setScope("application"); // Create temp status file - File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); final JSONObject resultStatusObject = new JSONObject(); // Model shared among tests diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthRecoveryTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthRecoveryTest.java index 0a9bc513..180a4035 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthRecoveryTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthRecoveryTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthRecoveryShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -34,12 +35,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation recovery tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthRecoveryTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -58,7 +64,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_recovery_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_recovery_" + VERSION, ".json"); } @AfterEach diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthSignatureTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthSignatureTest.java index a555e2aa..5054eee3 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthSignatureTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthSignatureTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthSignatureShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import org.junit.jupiter.api.AfterAll; @@ -42,12 +43,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth signature tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthSignatureTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthTestConfiguration config; private static File dataFile; @@ -89,9 +95,9 @@ void setUp() throws IOException { model.setHttpMethod("POST"); model.setPassword(config.getPassword()); model.setResourceId("/pa/signature/validate"); - model.setResultStatusObject(config.getResultStatusObjectV31()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - model.setStatusFileName(config.getStatusFileV31().getAbsolutePath()); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthTokenTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthTokenTest.java index 1d766c65..3a39958b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthTokenTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthTokenTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthTokenShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; import org.junit.jupiter.api.AfterAll; @@ -40,12 +41,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth token tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthTokenTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -85,8 +91,8 @@ void setUp() { model.setHeaders(new HashMap<>()); model.setMasterPublicKey(config.getMasterPublicKey()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV31()); - model.setStatusFileName(config.getStatusFileV31().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthVaultUnlockTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthVaultUnlockTest.java index b608b3e8..1619f31b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthVaultUnlockTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthVaultUnlockTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthVaultUnlockShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import org.junit.jupiter.api.BeforeEach; @@ -33,12 +34,17 @@ import java.util.HashMap; +/** + * PowerAuth vault unlock tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthVaultUnlockTest { - private static final String VERSION = "3.1"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_1; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -62,8 +68,8 @@ void setUp() { model.setApplicationSecret(config.getApplicationSecret()); model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV31()); - model.setStatusFileName(config.getStatusFileV31().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setReason("TEST_" + VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCodeTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCodeTest.java index 043a849a..c04cce0b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCodeTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCodeTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationCodeShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -40,12 +41,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation with activation code tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties public class PowerAuthActivationCodeTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthTestConfiguration config; private PrepareActivationStepModel activationModel; @@ -61,7 +67,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests activationModel = new PrepareActivationStepModel(); @@ -85,7 +91,7 @@ void setUp() throws IOException { signatureModel.setHttpMethod("POST"); signatureModel.setHeaders(new HashMap<>()); signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - signatureModel.setResultStatusObject(config.getResultStatusObjectV32()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); signatureModel.setVersion(VERSION); signatureModel.setDryRun(false); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java index e6896a61..1970d79e 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationCommitPhaseTest.java @@ -20,8 +20,8 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationCommitPhaseShared; -import com.wultra.security.powerauth.test.shared.PowerAuthActivationOtpShared; import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.junit.jupiter.api.AfterEach; @@ -49,7 +49,7 @@ @EnableConfigurationProperties class PowerAuthActivationCommitPhaseTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -75,7 +75,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests model = new PrepareActivationStepModel(); @@ -86,14 +86,14 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java index df54b160..4d618f74 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationOtpTest.java @@ -20,7 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationOtpShared; -import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.junit.jupiter.api.AfterEach; @@ -38,12 +38,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthActivationOtpTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -54,8 +59,6 @@ class PowerAuthActivationOtpTest { private final String validOtpValue = "1234-5678"; private final String invalidOtpValue = "8765-4321"; - private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); - @Autowired public void setPowerAuthClient(PowerAuthClient powerAuthClient) { this.powerAuthClient = powerAuthClient; @@ -69,7 +72,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests model = new PrepareActivationStepModel(); @@ -80,14 +83,14 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationTest.java index c9e4b483..b2961e77 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthActivationTest.java @@ -21,7 +21,7 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationShared; -import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.json.simple.JSONObject; import org.junit.jupiter.api.AfterEach; @@ -39,12 +39,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthActivationTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -64,7 +69,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new PrepareActivationStepModel(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationOtpTest.java index 2dda6e21..29a18459 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationOtpTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationOtpTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationOtpShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; @@ -40,13 +41,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth custom activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableConfigurationProperties @ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) class PowerAuthCustomActivationOtpTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -90,7 +96,7 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws IOException { // Create temp status files - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Models shared among tests createModel = new CreateActivationStepModel(); @@ -101,7 +107,7 @@ void setUp() throws IOException { createModel.setHeaders(new HashMap<>()); createModel.setPassword(config.getPassword()); createModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - createModel.setResultStatusObject(config.getResultStatusObjectV32()); + createModel.setResultStatusObject(config.getResultStatusObject(VERSION)); createModel.setUriString("http://localhost:" + port); createModel.setVersion(VERSION); createModel.setDeviceInfo("backend-tests"); @@ -114,14 +120,14 @@ void setUp() throws IOException { recoveryModel.setHeaders(new HashMap<>()); recoveryModel.setPassword(config.getPassword()); recoveryModel.setStatusFileName(tempStatusFile.getAbsolutePath()); - recoveryModel.setResultStatusObject(config.getResultStatusObjectV32()); + recoveryModel.setResultStatusObject(config.getResultStatusObject(VERSION)); recoveryModel.setUriString("http://localhost:" + port); recoveryModel.setVersion(VERSION); recoveryModel.setDeviceInfo("backend-tests"); statusModel = new GetStatusStepModel(); statusModel.setHeaders(new HashMap<>()); - statusModel.setResultStatusObject(config.getResultStatusObjectV32()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); statusModel.setUriString(config.getPowerAuthIntegrationUrl()); statusModel.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationTest.java index 2871c82d..39272397 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthCustomActivationTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import org.junit.jupiter.api.*; @@ -38,13 +39,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth custom activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @EnableConfigurationProperties @ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) class PowerAuthCustomActivationTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -82,7 +88,7 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new CreateActivationStepModel(); @@ -93,7 +99,7 @@ void setUp() throws IOException { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString("http://localhost:" + port); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java index 9603919d..13f68306 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthEncryptionShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; @@ -44,13 +45,18 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth encryption tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthEncryptionTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthTestConfiguration config; private static File dataFile; @@ -90,7 +96,7 @@ void setUp() throws IOException { encryptModel.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV32()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -100,9 +106,9 @@ void setUp() throws IOException { signatureModel.setHeaders(new HashMap<>()); signatureModel.setHttpMethod("POST"); signatureModel.setPassword(config.getPassword()); - signatureModel.setResultStatusObject(config.getResultStatusObjectV32()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - signatureModel.setStatusFileName(config.getStatusFileV32().getAbsolutePath()); + signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); signatureModel.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java index 2a9183e9..e27f2d72 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthIdentityVerificationTest.java @@ -23,6 +23,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthIdentityVerificationShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.*; import org.json.simple.JSONObject; @@ -39,13 +40,18 @@ import java.io.IOException; import java.util.HashMap; +/** + * PowerAuth identity verification tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthIdentityVerificationTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -66,7 +72,7 @@ public void setPowerAuthClient(PowerAuthClient powerAuthClient) { @BeforeEach void setUp() throws IOException { // Create temp status file - File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Create result status object final JSONObject resultStatusObject = new JSONObject(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java index 92f23b54..e25ff8c5 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOidcActivationTest.java @@ -22,6 +22,7 @@ import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; import com.wultra.security.powerauth.configuration.PowerAuthOidcActivationConfigurationProperties; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; @@ -81,7 +82,7 @@ @EnabledIf(expression = "#{T(org.springframework.util.StringUtils).hasText('${powerauth.test.activation.oidc.providerId}')}", loadContext = true) class PowerAuthOidcActivationTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private static File dataFile; @@ -119,7 +120,7 @@ static void tearDownAfterClass() { @BeforeEach void setUp() throws Exception { - final File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + final File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); model = new CreateActivationStepModel(); model.setActivationName("test v" + VERSION); @@ -129,7 +130,7 @@ void setUp() throws Exception { model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); model.setStatusFileName(tempStatusFile.getAbsolutePath()); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setUriString("http://localhost:" + port); model.setVersion(VERSION); model.setDeviceInfo("backend-tests"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java index 91261d22..4d183f7d 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthOnboardingTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthOnboardingShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; @@ -39,13 +40,18 @@ import java.io.IOException; import java.util.HashMap; +/** + * PowerAuth onboarding tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthOnboardingTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -71,12 +77,12 @@ void setUp() throws IOException { encryptModel.setApplicationSecret(config.getApplicationSecret()); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV31()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); encryptModel.setScope("application"); // Create temp status file - File tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); final JSONObject resultStatusObject = new JSONObject(); // Model shared among tests diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthRecoveryTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthRecoveryTest.java index f61b7a55..3b55af9b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthRecoveryTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthRecoveryTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthRecoveryShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -34,12 +35,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth activation recovery tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthRecoveryTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -58,7 +64,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_recovery_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_recovery_" + VERSION, ".json"); } @AfterEach diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthSignatureTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthSignatureTest.java index 3ae0f522..4caad7fe 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthSignatureTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthSignatureTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthSignatureShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; import org.junit.jupiter.api.AfterAll; @@ -42,12 +43,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth signature tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthSignatureTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthTestConfiguration config; private static File dataFile; @@ -89,9 +95,9 @@ void setUp() throws IOException { model.setHttpMethod("POST"); model.setPassword(config.getPassword()); model.setResourceId("/pa/signature/validate"); - model.setResultStatusObject(config.getResultStatusObjectV32()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); - model.setStatusFileName(config.getStatusFileV32().getAbsolutePath()); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthTokenTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthTokenTest.java index 37dd0be5..bfa2307a 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthTokenTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthTokenTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthTokenShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; import org.junit.jupiter.api.AfterAll; @@ -40,12 +41,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +/** + * PowerAuth token tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthTokenTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -85,8 +91,8 @@ void setUp() { model.setHeaders(new HashMap<>()); model.setMasterPublicKey(config.getMasterPublicKey()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV32()); - model.setStatusFileName(config.getStatusFileV32().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setVersion(VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthVaultUnlockTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthVaultUnlockTest.java index b9901aac..a27fe20f 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthVaultUnlockTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthVaultUnlockTest.java @@ -21,6 +21,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthVaultUnlockShared; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; import org.junit.jupiter.api.BeforeEach; @@ -33,12 +34,17 @@ import java.util.HashMap; +/** + * PowerAuth vault unlock tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ @ExtendWith(SpringExtension.class) @SpringBootTest(classes = PowerAuthTestConfiguration.class) @EnableConfigurationProperties class PowerAuthVaultUnlockTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_2; private PowerAuthTestConfiguration config; private PowerAuthClient powerAuthClient; @@ -62,8 +68,8 @@ void setUp() { model.setApplicationSecret(config.getApplicationSecret()); model.setHeaders(new HashMap<>()); model.setPassword(config.getPassword()); - model.setResultStatusObject(config.getResultStatusObjectV32()); - model.setStatusFileName(config.getStatusFileV32().getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); model.setUriString(config.getPowerAuthIntegrationUrl()); model.setReason("TEST_" + VERSION); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java new file mode 100644 index 00000000..5d9eda25 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java @@ -0,0 +1,111 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2018 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationCodeShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; +import org.json.simple.JSONObject; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth activation with activation code tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +public class PowerAuthActivationCodeTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel activationModel; + private VerifySignatureStepModel signatureModel; + private File tempStatusFile; + private ObjectStepLogger stepLogger; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Model shared among tests + activationModel = new PrepareActivationStepModel(); + activationModel.setActivationName("test v" + VERSION); + activationModel.setApplicationKey(config.getApplicationKey()); + activationModel.setApplicationSecret(config.getApplicationSecret()); + activationModel.setMasterPublicKey(config.getMasterPublicKey()); + activationModel.setHeaders(new HashMap<>()); + activationModel.setPassword(config.getPassword()); + activationModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + activationModel.setResultStatusObject(new JSONObject()); + activationModel.setUriString(config.getPowerAuthIntegrationUrl()); + activationModel.setVersion(VERSION); + activationModel.setDeviceInfo("backend-tests"); + + signatureModel = new VerifySignatureStepModel(); + signatureModel.setApplicationKey(config.getApplicationKey()); + signatureModel.setApplicationSecret(config.getApplicationSecret()); + signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_BIOMETRY); + signatureModel.setPassword(config.getPassword()); + signatureModel.setHttpMethod("POST"); + signatureModel.setHeaders(new HashMap<>()); + signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + signatureModel.setVersion(VERSION); + signatureModel.setDryRun(false); + + stepLogger = new ObjectStepLogger(System.out); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) + void activationUsingActivationCodeTest() throws Exception { + PowerAuthActivationCodeShared.activationUsingActivationCodeTest(config, activationModel, signatureModel, stepLogger); + } +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCommitPhaseTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCommitPhaseTest.java new file mode 100644 index 00000000..4da64345 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCommitPhaseTest.java @@ -0,0 +1,141 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationCommitPhaseShared; +import io.getlime.security.powerauth.crypto.client.activation.PowerAuthClientActivation; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests for commit phase. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthActivationCommitPhaseTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel model; + private GetStatusStepModel statusModel; + private File tempStatusFile; + + private final String validOtpValue = "1234-5678"; + private final String invalidOtpValue = "8765-4321"; + + private static final PowerAuthClientActivation activation = new PowerAuthClientActivation(); + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Models shared among tests + model = new PrepareActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + statusModel.setUriString(config.getPowerAuthIntegrationUrl()); + statusModel.setVersion(VERSION); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void validOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + + @Test + void invalidOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void validOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.validOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void invalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.invalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateValidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateValidOtpOnCommitTest(powerAuthClient, config, model, statusModel, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateInvalidOtpOnCommitTest() throws Exception { + PowerAuthActivationCommitPhaseShared.updateInvalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void wrongActivationInitParamTest() { + PowerAuthActivationCommitPhaseShared.wrongActivationInitParamTest(powerAuthClient, config, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationOtpTest.java new file mode 100644 index 00000000..ebb05849 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationOtpTest.java @@ -0,0 +1,163 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2020 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationOtpShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthActivationOtpTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel model; + private GetStatusStepModel statusModel; + private File tempStatusFile; + + private final String validOtpValue = "1234-5678"; + private final String invalidOtpValue = "8765-4321"; + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Models shared among tests + model = new PrepareActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + statusModel.setUriString(config.getPowerAuthIntegrationUrl()); + statusModel.setVersion(VERSION); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void validOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationOtpShared.validOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + + @Test + void invalidOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationOtpShared.invalidOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void validOtpOnCommitTest() throws Exception { + PowerAuthActivationOtpShared.validOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void invalidOtpOnCommitTest() throws Exception { + PowerAuthActivationOtpShared.invalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateValidOtpOnCommitTest() throws Exception { + PowerAuthActivationOtpShared.updateValidOtpOnCommitTest(powerAuthClient, config, model, statusModel, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void updateInvalidOtpOnCommitTest() throws Exception { + PowerAuthActivationOtpShared.updateInvalidOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void wrongActivationInitParamTest1() { + PowerAuthActivationOtpShared.wrongActivationInitParamTest1(powerAuthClient, config, VERSION); + } + + @Test + void wrongActivationInitParamTest2() { + PowerAuthActivationOtpShared.wrongActivationInitParamTest2(powerAuthClient, config, VERSION); + } + + @Test + void wrongActivationInitParamTest3() { + PowerAuthActivationOtpShared.wrongActivationInitParamTest3(powerAuthClient, config, VERSION); + } + + @Test + void wrongActivationInitParamTest4() { + PowerAuthActivationOtpShared.wrongActivationInitParamTest4(powerAuthClient, config, VERSION); + } + + @Test + void missingOtpOnCommitTest() throws Exception { + PowerAuthActivationOtpShared.missingOtpOnCommitTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + + @Test + void missingOtpOnKeysExchangeTest() throws Exception { + PowerAuthActivationOtpShared.missingOtpOnKeysExchangeTest(powerAuthClient, config, model, validOtpValue, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationTest.java new file mode 100644 index 00000000..fce351f9 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationTest.java @@ -0,0 +1,182 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2018 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; +import org.json.simple.JSONObject; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthActivationTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PrepareActivationStepModel model; + private File tempStatusFile; + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Model shared among tests + model = new PrepareActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(new JSONObject()); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void activationPrepareTest() throws Exception { + PowerAuthActivationShared.activationPrepareTest(powerAuthClient, config, model, VERSION); + } + + @Test + void activationNonExistentTest() throws PowerAuthClientException { + PowerAuthActivationShared.activationNonExistentTest(powerAuthClient); + } + + @Test + void activationPrepareUnsupportedApplicationTest() throws Exception { + PowerAuthActivationShared.activationPrepareUnsupportedApplicationTest(powerAuthClient, config, model, VERSION); + } + + @Test + void activationPrepareExpirationTest() throws Exception { + PowerAuthActivationShared.activationPrepareExpirationTest(powerAuthClient, config, model, VERSION); + } + + @Test + void activationPrepareWithoutInitTest() throws Exception { + PowerAuthActivationShared.activationPrepareWithoutInitTest(config, model); + } + + // Test activationPrepareBadMasterPublicKeyTest is skipped, because master public key is not used + // in protocol version 3.3 for encryption due to use of temporary keys. + + @Test + void activationStatusTest() throws Exception { + PowerAuthActivationShared.activationStatusTest(powerAuthClient, config, model, VERSION); + } + + @Test + void activationInvalidApplicationKeyTest() throws Exception { + PowerAuthActivationShared.activationInvalidApplicationKeyTest(powerAuthClient, config, model, VERSION); + } + + @Test + void activationInvalidApplicationSecretTest() throws Exception { + PowerAuthActivationShared.activationInvalidApplicationSecretTest(powerAuthClient, config, model, VERSION); + } + + @Test + void lookupActivationsTest() throws Exception { + PowerAuthActivationShared.lookupActivationsTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsNonExistentUserTest() throws Exception { + PowerAuthActivationShared.lookupActivationsNonExistentUserTest(powerAuthClient); + } + + @Test + void lookupActivationsApplicationTest() throws Exception { + PowerAuthActivationShared.lookupActivationsApplicationTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsNonExistentApplicationTest() throws Exception { + PowerAuthActivationShared.lookupActivationsNonExistentApplicationTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsStatusTest() throws Exception { + PowerAuthActivationShared.lookupActivationsStatusTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsInvalidStatusTest() throws Exception { + PowerAuthActivationShared.lookupActivationsInvalidStatusTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsDateValidTest() throws Exception { + PowerAuthActivationShared.lookupActivationsDateValidTest(powerAuthClient, config, VERSION); + } + + @Test + void lookupActivationsDateInvalidTest() throws Exception { + PowerAuthActivationShared.lookupActivationsDateInvalidTest(powerAuthClient, config, VERSION); + } + + @Test + void updateActivationStatusTest() throws Exception { + PowerAuthActivationShared.updateActivationStatusTest(powerAuthClient, config, model, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationOtpTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationOtpTest.java new file mode 100644 index 00000000..6733f751 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationOtpTest.java @@ -0,0 +1,163 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2018 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationOtpShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.ActivationRecoveryStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth custom activation OTP tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@EnableConfigurationProperties +@ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) +class PowerAuthCustomActivationOtpTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private CreateActivationStepModel createModel; + private ActivationRecoveryStepModel recoveryModel; + private GetStatusStepModel statusModel; + + private static File dataFile; + private File tempStatusFile; + private ObjectStepLogger stepLogger; + + private final String validOtpValue = "1234-5678"; + private final String invalidOtpValue = "8765-4321"; + + @LocalServerPort + private int port; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status files + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Models shared among tests + createModel = new CreateActivationStepModel(); + createModel.setActivationName("test v" + VERSION); + createModel.setApplicationKey(config.getApplicationKey()); + createModel.setApplicationSecret(config.getApplicationSecret()); + createModel.setMasterPublicKey(config.getMasterPublicKey()); + createModel.setHeaders(new HashMap<>()); + createModel.setPassword(config.getPassword()); + createModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + createModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + createModel.setUriString("http://localhost:" + port); + createModel.setVersion(VERSION); + createModel.setDeviceInfo("backend-tests"); + + recoveryModel = new ActivationRecoveryStepModel(); + recoveryModel.setActivationName("test v" + VERSION); + recoveryModel.setApplicationKey(config.getApplicationKey()); + recoveryModel.setApplicationSecret(config.getApplicationSecret()); + recoveryModel.setMasterPublicKey(config.getMasterPublicKey()); + recoveryModel.setHeaders(new HashMap<>()); + recoveryModel.setPassword(config.getPassword()); + recoveryModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + recoveryModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + recoveryModel.setUriString("http://localhost:" + port); + recoveryModel.setVersion(VERSION); + recoveryModel.setDeviceInfo("backend-tests"); + + statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + statusModel.setUriString(config.getPowerAuthIntegrationUrl()); + statusModel.setVersion(VERSION); + + // Prepare step logger + stepLogger = new ObjectStepLogger(System.out); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void customActivationOtpValidTest() throws Exception { + PowerAuthCustomActivationOtpShared.customActivationOtpValidTest(powerAuthClient, createModel, statusModel, stepLogger, validOtpValue, invalidOtpValue); + } + + @Test + void customActivationOtpInvalidTest() throws Exception { + PowerAuthCustomActivationOtpShared.customActivationOtpInvalidTest(powerAuthClient, createModel, stepLogger, validOtpValue, invalidOtpValue); + } + + @Test + void activationRecoveryOtpValidTest() throws Exception { + PowerAuthCustomActivationOtpShared.activationRecoveryOtpValidTest(powerAuthClient, config, tempStatusFile, recoveryModel, statusModel, validOtpValue, invalidOtpValue, VERSION); + } + + @Test + void activationRecoveryOtpInvalidTest() throws Exception { + PowerAuthCustomActivationOtpShared.activationRecoveryOtpInvalidTest(powerAuthClient, config, tempStatusFile, recoveryModel, validOtpValue, invalidOtpValue, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationTest.java new file mode 100644 index 00000000..698f5424 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthCustomActivationTest.java @@ -0,0 +1,177 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2018 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthCustomActivationShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth custom activation tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@EnableConfigurationProperties +@ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) +class PowerAuthCustomActivationTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private CreateActivationStepModel model; + private static File dataFile; + private File tempStatusFile; + private ObjectStepLogger stepLogger; + + @LocalServerPort + private int port; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Model shared among tests + model = new CreateActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setUriString("http://localhost:" + port); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + // Prepare step logger + stepLogger = new ObjectStepLogger(System.out); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void customActivationValidTest() throws Exception { + PowerAuthCustomActivationShared.customActivationValidTest(powerAuthClient, model, stepLogger); + } + + @Test + void customActivationValid2Test() throws Exception { + PowerAuthCustomActivationShared.customActivationValid2Test(powerAuthClient, model, stepLogger); + } + + @Test + void customActivationValid3Test() throws Exception { + PowerAuthCustomActivationShared.customActivationValid3Test(powerAuthClient, model, stepLogger); + } + + @Test + void customActivationMissingUsernameTest() throws Exception { + PowerAuthCustomActivationShared.customActivationMissingUsernameTest(config, model, stepLogger); + + } + + @Test + void customActivationEmptyUsernameTest() throws Exception { + PowerAuthCustomActivationShared.customActivationEmptyUsernameTest(config, model, stepLogger); + } + + @Test + void customActivationUsernameTooLongTest() throws Exception { + PowerAuthCustomActivationShared.customActivationUsernameTooLongTest(config, model, stepLogger); + } + + @Test + void customActivationBadMasterPublicKeyTest() throws Exception { + PowerAuthCustomActivationShared.customActivationBadMasterPublicKeyTest(config, model, stepLogger); + } + + @Test + void customActivationUnsupportedApplicationTest() throws Exception { + PowerAuthCustomActivationShared.customActivationUnsupportedApplicationTest(powerAuthClient, config, model, stepLogger); + } + + @Test + void customActivationInvalidApplicationKeyTest() throws Exception { + PowerAuthCustomActivationShared.customActivationInvalidApplicationKeyTest(config, model, stepLogger); + } + + @Test + void customActivationInvalidApplicationSecretTest() throws Exception { + PowerAuthCustomActivationShared.customActivationInvalidApplicationSecretTest(config, model, stepLogger); + } + + @Test + void customActivationDoubleCommitTest() throws Exception { + PowerAuthCustomActivationShared.customActivationDoubleCommitTest(powerAuthClient, model, stepLogger); + } + + @Test + void customActivationSignatureMaxFailedTest() throws Exception { + PowerAuthCustomActivationShared.customActivationSignatureMaxFailedTest(powerAuthClient, config, model, stepLogger, dataFile, tempStatusFile, port, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java new file mode 100644 index 00000000..71f10d80 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java @@ -0,0 +1,238 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2018 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthEncryptionShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth encryption tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +@EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) +class PowerAuthEncryptionTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthTestConfiguration config; + private static File dataFile; + private EncryptStepModel encryptModel; + private VerifySignatureStepModel signatureModel; + private ObjectStepLogger stepLogger; + private PowerAuthClient powerAuthClient; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("{\"data\": \"hello\"}"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws IOException { + encryptModel = new EncryptStepModel(); + encryptModel.setApplicationKey(config.getApplicationKey()); + encryptModel.setApplicationSecret(config.getApplicationSecret()); + encryptModel.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); + encryptModel.setMasterPublicKey(config.getMasterPublicKey()); + encryptModel.setHeaders(new HashMap<>()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setVersion(VERSION); + + signatureModel = new VerifySignatureStepModel(); + signatureModel.setApplicationKey(config.getApplicationKey()); + signatureModel.setApplicationSecret(config.getApplicationSecret()); + signatureModel.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); + signatureModel.setHeaders(new HashMap<>()); + signatureModel.setHttpMethod("POST"); + signatureModel.setPassword(config.getPassword()); + signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); + signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); + signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + signatureModel.setVersion(VERSION); + + stepLogger = new ObjectStepLogger(System.out); + } + + @Test + void encryptInActivationScopeTest() throws Exception { + PowerAuthEncryptionShared.encryptInActivationScopeTest(config, encryptModel, stepLogger); + } + + @Test + void encryptInApplicationScopeTest() throws Exception { + PowerAuthEncryptionShared.encryptInApplicationScopeTest(config, encryptModel, stepLogger); + } + + @Test + void encryptInInvalidScope1Test() throws Exception { + PowerAuthEncryptionShared.encryptInInvalidScope1Test(config, encryptModel, stepLogger); + } + + @Test + void encryptInInvalidScope2Test() throws Exception { + PowerAuthEncryptionShared.encryptInInvalidScope2Test(config, encryptModel, stepLogger); + } + + @Test + void encryptEmptyDataTest() throws Exception { + PowerAuthEncryptionShared.encryptEmptyDataTest(config, encryptModel, stepLogger); + } + + @Test + void encryptBlockedActivationTest() throws Exception { + PowerAuthEncryptionShared.encryptBlockedActivationTest(powerAuthClient, config, encryptModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptTest(config, signatureModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptWeakSignatureTypeTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptWeakSignatureTypeTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptInvalidPasswordTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptInvalidPasswordTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptEmptyDataTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptEmptyDataTest(config, signatureModel, encryptModel, stepLogger); + } + + @Test + void signAndEncryptLargeDataTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptLargeDataTest(config, signatureModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptStringDataTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptStringDataTest(config, signatureModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptRawDataTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptRawDataTest(config, signatureModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptGenerifiedDataTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptGenerifiedDataTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptInvalidResourceIdTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptInvalidResourceIdTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptBlockedActivationTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptBlockedActivationTest(powerAuthClient, config, signatureModel, stepLogger, VERSION); + } + + @Test + void signAndEncryptUnsupportedApplicationTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptUnsupportedApplicationTest(powerAuthClient, config, signatureModel, VERSION); + } + + @Test + void signAndEncryptCounterIncrementTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptCounterIncrementTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptLookAheadTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptLookAheadTest(config, signatureModel); + } + + @Test + void signAndEncryptSingleFactorTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptSingleFactorTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptBiometryTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptBiometryTest(config, signatureModel, stepLogger); + } + + @Test + void signAndEncryptThreeFactorTest() throws Exception { + PowerAuthEncryptionShared.signAndEncryptThreeFactorTest(config, signatureModel, stepLogger); + } + + @Test + void replayAttackEciesDecryptorTest() throws Exception { + PowerAuthEncryptionShared.replayAttackEciesDecryptorTest(powerAuthClient, config, VERSION); + } + + @Test + void encryptedResponseTest() throws Exception { + PowerAuthEncryptionShared.encryptedResponseTest(config, encryptModel, stepLogger, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java new file mode 100644 index 00000000..6681b6c4 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java @@ -0,0 +1,218 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2021 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthIdentityVerificationShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.*; +import org.json.simple.JSONObject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +/** + * PowerAuth identity verification tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +@EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) +class PowerAuthIdentityVerificationTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PowerAuthIdentityVerificationShared.TestContext ctx; + + private final ObjectMapper objectMapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + // Create result status object + final JSONObject resultStatusObject = new JSONObject(); + + EncryptStepModel encryptModel = new EncryptStepModel(); + encryptModel.setApplicationKey(config.getApplicationKey()); + encryptModel.setApplicationSecret(config.getApplicationSecret()); + encryptModel.setMasterPublicKey(config.getMasterPublicKey()); + encryptModel.setHeaders(new HashMap<>()); + encryptModel.setResultStatusObject(resultStatusObject); + encryptModel.setVersion(VERSION); + + VerifySignatureStepModel signatureModel = new VerifySignatureStepModel(); + signatureModel.setApplicationKey(config.getApplicationKey()); + signatureModel.setApplicationSecret(config.getApplicationSecret()); + signatureModel.setHeaders(new HashMap<>()); + signatureModel.setHttpMethod("POST"); + signatureModel.setPassword(config.getPassword()); + signatureModel.setResultStatusObject(resultStatusObject); + signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION); + signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + signatureModel.setVersion(VERSION); + + TokenAndEncryptStepModel tokenAndEncryptModel = new TokenAndEncryptStepModel(); + tokenAndEncryptModel.setApplicationKey(config.getApplicationKey()); + tokenAndEncryptModel.setApplicationSecret(config.getApplicationSecret()); + tokenAndEncryptModel.setHeaders(new HashMap<>()); + tokenAndEncryptModel.setHttpMethod("POST"); + tokenAndEncryptModel.setResultStatusObject(resultStatusObject); + tokenAndEncryptModel.setVersion(VERSION); + + VerifyTokenStepModel tokenModel = new VerifyTokenStepModel(); + tokenModel.setHeaders(new HashMap<>()); + tokenModel.setResultStatusObject(resultStatusObject); + tokenModel.setHttpMethod("POST"); + tokenModel.setVersion(VERSION); + + // Model shared among tests + CreateActivationStepModel activationModel = new CreateActivationStepModel(); + activationModel.setActivationName("test v3.1 document verification"); + activationModel.setApplicationKey(config.getApplicationKey()); + activationModel.setApplicationSecret(config.getApplicationSecret()); + activationModel.setMasterPublicKey(config.getMasterPublicKey()); + activationModel.setHeaders(new HashMap<>()); + activationModel.setPassword(config.getPassword()); + activationModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + activationModel.setResultStatusObject(resultStatusObject); + activationModel.setUriString(config.getEnrollmentServiceUrl()); + activationModel.setVersion(VERSION); + activationModel.setDeviceInfo("backend-tests"); + + CreateTokenStepModel createTokenModel = new CreateTokenStepModel(); + createTokenModel.setApplicationKey(config.getApplicationKey()); + createTokenModel.setApplicationSecret(config.getApplicationSecret()); + createTokenModel.setHeaders(new HashMap<>()); + createTokenModel.setMasterPublicKey(config.getMasterPublicKey()); + createTokenModel.setPassword(config.getPassword()); + createTokenModel.setResultStatusObject(resultStatusObject); + createTokenModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + createTokenModel.setUriString(config.getEnrollmentServiceUrl()); + createTokenModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION); + createTokenModel.setVersion(VERSION); + + ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); + ctx = new PowerAuthIdentityVerificationShared.TestContext(powerAuthClient, config, activationModel, encryptModel, signatureModel, createTokenModel, tokenAndEncryptModel, tokenModel, objectMapper, stepLogger); + } + + @Test + void testSuccessfulIdentityVerification() throws Exception { + PowerAuthIdentityVerificationShared.testSuccessfulIdentityVerification(ctx); + } + + @Test + void testScaFailedPresenceCheck() throws Exception { + PowerAuthIdentityVerificationShared.testScaFailedPresenceCheck(ctx); + } + + @Test + void testScaFailedOtpCheck() throws Exception { + PowerAuthIdentityVerificationShared.testScaFailedOtpCheck(ctx); + } + + @Test + void testSuccessfulIdentityVerificationWithRestarts() throws Exception { + PowerAuthIdentityVerificationShared.testSuccessfulIdentityVerificationWithRestarts(ctx); + } + + @Test + void testSuccessfulIdentityVerificationMultipleDocSubmits() throws Exception { + PowerAuthIdentityVerificationShared.testSuccessfulIdentityVerificationMultipleDocSubmits(ctx); + } + + @Test + void testDocSubmitDifferentDocumentType() throws Exception { + PowerAuthIdentityVerificationShared.testDocSubmitDifferentDocumentType(ctx); + } + + @Test + void testDocSubmitDifferentCardSide() throws Exception { + PowerAuthIdentityVerificationShared.testDocSubmitDifferentCardSide(ctx); + } + + @Test + void testDocSubmitMaxAttemptsLimit() throws Exception { + PowerAuthIdentityVerificationShared.testDocSubmitMaxAttemptsLimit(ctx); + } + + @Test + void testIdentityVerificationNotDocumentPhotos() throws Exception { + PowerAuthIdentityVerificationShared.testIdentityVerificationNotDocumentPhotos(ctx); + } + + @Test + void testIdentityVerificationCleanup() throws Exception { + PowerAuthIdentityVerificationShared.testIdentityVerificationCleanup(ctx); + } + + @Test + void testIdentityVerificationMaxAttemptLimit() throws Exception { + PowerAuthIdentityVerificationShared.testIdentityVerificationMaxAttemptLimit(ctx); + } + + @Test + void largeUploadTest() throws Exception { + PowerAuthIdentityVerificationShared.largeUploadTest(ctx); + } + + @Test + void initDocumentVerificationSdkTest() throws Exception { + PowerAuthIdentityVerificationShared.initDocumentVerificationSdkTest(ctx); + } + + @Test + void testFailedScaOtpMaxFailedAttemptsIdentityRestart() throws Exception { + PowerAuthIdentityVerificationShared.testFailedScaOtpMaxFailedAttemptsIdentityRestart(ctx); + } + + @Test + void testErrorScoreLimit() throws Exception { + PowerAuthIdentityVerificationShared.testErrorScoreLimit(ctx); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOidcActivationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOidcActivationTest.java new file mode 100644 index 00000000..6fa49bb7 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOidcActivationTest.java @@ -0,0 +1,322 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2024 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; +import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; +import com.wultra.security.powerauth.configuration.PowerAuthOidcActivationConfigurationProperties; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.context.StepContext; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.v3.CreateActivationStep; +import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer2Response; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcApplicationConfiguration; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcApplicationConfigurationService; +import io.getlime.security.powerauth.rest.api.spring.service.oidc.OidcConfigurationQuery; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test direct activation via OIDC. + *

+ * Mind that {@code powerauth.test.activation.*} properties must be filled, otherwise the test is ignored. + * Also a database entry must exist in the table {@code pa_application_config} with a config key {@code oauth2_providers} and appropriate config values. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@EnableConfigurationProperties +@ComponentScan(basePackages = {"com.wultra.security.powerauth", "io.getlime.security.powerauth"}) +@EnabledIf(expression = "#{T(org.springframework.util.StringUtils).hasText('${powerauth.test.activation.oidc.providerId}')}", loadContext = true) +class PowerAuthOidcActivationTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private static File dataFile; + + @Autowired + private PowerAuthTestConfiguration config; + + @Autowired + private PowerAuthOidcActivationConfigurationProperties oidcConfigProperties; + + @Autowired + private OidcApplicationConfigurationService oidcApplicationConfigurationService; + + @Autowired + private PowerAuthClient powerAuthClient; + + @LocalServerPort + private int port; + + private CreateActivationStepModel model; + private ObjectStepLogger stepLogger; + private OidcApplicationConfiguration oidcConfig; + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws Exception { + final File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + + model = new CreateActivationStepModel(); + model.setActivationName("test v" + VERSION); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setStatusFileName(tempStatusFile.getAbsolutePath()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setUriString("http://localhost:" + port); + model.setVersion(VERSION); + model.setDeviceInfo("backend-tests"); + + stepLogger = new ObjectStepLogger(System.out); + + oidcConfig = oidcApplicationConfigurationService.fetchOidcApplicationConfiguration(OidcConfigurationQuery.builder() + .applicationKey(config.getApplicationKey()) + .providerId(oidcConfigProperties.getProviderId()) + .build()); + } + + @Test + void testOidcActivation() throws Exception { + final String nonce = generateRandomString(); + + final WebClient webClient = createWebClient(); + final UriComponents authorizeUriComponents = authorize(webClient, nonce); + final String code = login(webClient, authorizeUriComponents); + assertNotNull(code); + + final Map identityAttributes = Map.of( + "method", "oidc", + "providerId", oidcConfig.getProviderId(), + "code", code, + "nonce", nonce + ); + createActivation(identityAttributes); + } + + @Test + void testOidcPkceActivation() throws Exception { + final String nonce = generateRandomString(); + final String codeVerifier = generateRandomString(); + final String codeChallenge = convertToCodeChallenge(codeVerifier); + + final WebClient webClient = createWebClient(); + final UriComponents authorizeUriComponents = authorizeWithPkce(webClient, nonce, codeChallenge); + final String code = login(webClient, authorizeUriComponents); + assertNotNull(code); + + final Map identityAttributes = Map.of( + "method", "oidc", + "providerId", oidcConfig.getProviderId(), + "code", code, + "nonce", nonce, + "codeVerifier", codeVerifier + ); + createActivation(identityAttributes); + } + + private static String convertToCodeChallenge(final String codeVerifier) throws NoSuchAlgorithmException { + final MessageDigest digest = MessageDigest.getInstance("SHA-256"); + final byte[] hash = digest.digest(codeVerifier.getBytes(StandardCharsets.US_ASCII)); + return Base64.getUrlEncoder().withoutPadding().encodeToString(hash); + } + + private UriComponents authorize(final WebClient webClient, final String nonce) { + final Map uriVariables = Map.of( + "clientId", oidcConfig.getClientId(), + "redirectUri", oidcConfig.getRedirectUri(), + "state", generateRandomString(), + "nonce", nonce, + "scope", oidcConfig.getScopes() + ); + final String authorizationUrl = oidcConfig.getIssuerUri() + "/authorize?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}&state={state}&nonce={nonce}&response_type=code"; + final WebClient.ResponseSpec responseSpec = webClient.get().uri(authorizationUrl, uriVariables).retrieve(); + return UriComponentsBuilder.fromUri(fetchRedirectUri(responseSpec)).build(); + } + + private UriComponents authorizeWithPkce(final WebClient webClient, final String nonce, final String codeChallenge) { + final Map uriVariables = Map.of( + "clientId", oidcConfig.getClientId(), + "redirectUri", oidcConfig.getRedirectUri(), + "state", generateRandomString(), + "nonce", nonce, + "scope", oidcConfig.getScopes(), + "code_challenge", codeChallenge, + "code_challenge_method", "S256" + ); + final String authorizationUrl = oidcConfig.getIssuerUri() + "/authorize?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}&state={state}&nonce={nonce}&response_type=code&code_challenge={code_challenge}&code_challenge_method={code_challenge_method}"; + final WebClient.ResponseSpec responseSpec = webClient.get().uri(authorizationUrl, uriVariables).retrieve(); + return UriComponentsBuilder.fromUri(fetchRedirectUri(responseSpec)).build(); + } + + private String login(final WebClient webClient, final UriComponents authorizeUriComponents) { + final String authorizeState = authorizeUriComponents.getQueryParams().getFirst("state"); + assertNotNull(authorizeState); + + final MultiValueMap requestBody = new LinkedMultiValueMap<>(); + requestBody.add("username", oidcConfigProperties.getUsername()); + requestBody.add("password", oidcConfigProperties.getPassword()); + requestBody.add("state", authorizeState); + + final String loginUrl = oidcConfig.getIssuerUri() + authorizeUriComponents.getPath(); + final WebClient.ResponseSpec responseSpec = webClient + .post() + .uri(loginUrl) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .body(BodyInserters.fromFormData(requestBody)) + .retrieve(); + final URI redirectUri = fetchRedirectUri(responseSpec); + return resumeLogin(webClient, oidcConfig.getIssuerUri() + redirectUri); + } + + private String resumeLogin(final WebClient webClient, final String uri) { + final WebClient.ResponseSpec responseSpec = webClient.get().uri(uri).retrieve(); + final URI redirectUri = fetchRedirectUri(responseSpec); + final UriComponents uriComponents = UriComponentsBuilder.fromUri(redirectUri).build(); + return uriComponents.getQueryParams().getFirst("code"); + } + + private URI fetchRedirectUri(final WebClient.ResponseSpec responseSpec) { + final ResponseEntity bodilessEntity = responseSpec.toBodilessEntity().block(); + assertNotNull(bodilessEntity); + final HttpStatusCode statusCode = bodilessEntity.getStatusCode(); + assertTrue(statusCode.is3xxRedirection(), "Status Code: " + statusCode); + final URI location = bodilessEntity.getHeaders().getLocation(); + assertNotNull(location); + return location; + } + + private static WebClient createWebClient() { + final List cookies = new ArrayList<>(); + + final ExchangeFilterFunction cookieFilter = ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + if (!cookies.isEmpty()) { + clientRequest = ClientRequest.from(clientRequest) + .header(HttpHeaders.COOKIE, String.join("; ", cookies)) + .build(); + } + return Mono.just(clientRequest); + }).andThen(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + cookies.clear(); + cookies.addAll(Objects.requireNonNull(clientResponse.headers().asHttpHeaders().get(HttpHeaders.SET_COOKIE))); + return Mono.just(clientResponse); + })); + + return WebClient.builder() + .filter(cookieFilter) + .build(); + } + + private static String generateRandomString() { + final SecureRandom secureRandom = new SecureRandom(); + final byte[] randomBytes = new byte[32]; + secureRandom.nextBytes(randomBytes); + return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes); + } + + private void createActivation(final Map identityAttributes) throws Exception { + model.setIdentityAttributes(identityAttributes); + + new CreateOidcActivationStep().execute(stepLogger, model.toMap()); + assertTrue(stepLogger.getResult().success()); + assertEquals(200, stepLogger.getResponse().statusCode()); + + final ActivationLayer2Response layer2Response = fetchLayer2Response(stepLogger); + final String activationId = layer2Response.getActivationId(); + + assertNotNull(activationId); + assertNotNull(layer2Response.getCtrData()); + assertNotNull(layer2Response.getServerPublicKey()); + + // Verify activation status - activation was automatically committed + final GetActivationStatusResponse statusResponseActive = powerAuthClient.getActivationStatus(activationId); + assertEquals(ActivationStatus.ACTIVE, statusResponseActive.getActivationStatus()); + assertEquals(oidcConfigProperties.getSub(), statusResponseActive.getUserId()); + + powerAuthClient.removeActivation(activationId, "test"); + } + + private static ActivationLayer2Response fetchLayer2Response(final ObjectStepLogger stepLogger) { + return stepLogger.getItems().stream() + .filter(item -> "Decrypted Layer 2 Response".equals(item.name())) + .map(item -> (ActivationLayer2Response) item.object()) + .findAny() + .orElseThrow(() -> AssertionFailureBuilder.assertionFailure().message("Response was not successfully decrypted").build()); + } + + static class CreateOidcActivationStep extends CreateActivationStep{ + @Override + protected ActivationLayer1Request prepareLayer1Request(final StepContext stepContext, final EciesEncryptedRequest encryptedRequestL2) { + final ActivationLayer1Request activationLayer1Request = super.prepareLayer1Request(stepContext, encryptedRequestL2); + activationLayer1Request.setType(ActivationType.DIRECT); + return activationLayer1Request; + } + } +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java new file mode 100644 index 00000000..6d5cdbe0 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java @@ -0,0 +1,162 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2021 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthOnboardingShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateActivationStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; +import io.getlime.security.powerauth.lib.cmd.steps.model.GetStatusStepModel; +import org.json.simple.JSONObject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + +/** + * PowerAuth onboarding tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +@EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) +class PowerAuthOnboardingTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private PowerAuthOnboardingShared.TestContext ctx; + + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeEach + void setUp() throws IOException { + EncryptStepModel encryptModel = new EncryptStepModel(); + encryptModel.setApplicationKey(config.getApplicationKey()); + encryptModel.setApplicationSecret(config.getApplicationSecret()); + encryptModel.setMasterPublicKey(config.getMasterPublicKey()); + encryptModel.setHeaders(new HashMap<>()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setVersion(VERSION); + encryptModel.setScope("application"); + + // Create temp status file + File tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); + final JSONObject resultStatusObject = new JSONObject(); + + // Model shared among tests + CreateActivationStepModel activationModel = new CreateActivationStepModel(); + activationModel.setActivationName("test v" + VERSION + " onboarding"); + activationModel.setApplicationKey(config.getApplicationKey()); + activationModel.setApplicationSecret(config.getApplicationSecret()); + activationModel.setMasterPublicKey(config.getMasterPublicKey()); + activationModel.setHeaders(new HashMap<>()); + activationModel.setPassword(config.getPassword()); + activationModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + activationModel.setResultStatusObject(resultStatusObject); + activationModel.setUriString(config.getEnrollmentServiceUrl()); + activationModel.setVersion(VERSION); + activationModel.setDeviceInfo("backend-tests"); + + GetStatusStepModel statusModel = new GetStatusStepModel(); + statusModel.setHeaders(new HashMap<>()); + statusModel.setResultStatusObject(resultStatusObject); + statusModel.setUriString(config.getEnrollmentServiceUrl()); + statusModel.setVersion(VERSION); + + ObjectStepLogger stepLogger = new ObjectStepLogger(System.out); + ctx = new PowerAuthOnboardingShared.TestContext(powerAuthClient, config, activationModel, statusModel, encryptModel, objectMapper, stepLogger); + } + + @Test + void testSuccessfulOnboarding() throws Exception { + PowerAuthOnboardingShared.testSuccessfulOnboarding(ctx); + } + + @Test + void testInvalidOtp() throws Exception { + PowerAuthOnboardingShared.testInvalidOtp(ctx); + } + + @Test + void testOtpForNonExistingUser() throws Exception { + PowerAuthOnboardingShared.testOtpForNonExistingUser(ctx); + } + + @Test + void testInvalidProcessId() { + PowerAuthOnboardingShared.testInvalidProcessId(ctx); + } + + @Test + void testOnboardingCleanup() throws Exception { + PowerAuthOnboardingShared.testOnboardingCleanup(ctx); + } + + @Test + void testResendPeriod() throws Exception { + PowerAuthOnboardingShared.testResendPeriod(ctx); + } + + @Test + void testMaxProcesses() throws Exception { + PowerAuthOnboardingShared.testMaxProcesses(ctx); + } + + @Test + void testOtpMaxFailedAttemptsReached() throws Exception { + PowerAuthOnboardingShared.testOtpMaxFailedAttemptsReached(ctx); + } + + @Test + void testMaxAttemptsNotReached() throws Exception { + PowerAuthOnboardingShared.testMaxAttemptsNotReached(ctx); + } + + @Test + void testResumeProcesses() throws Exception { + PowerAuthOnboardingShared.testResumeProcesses(ctx); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthRecoveryTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthRecoveryTest.java new file mode 100644 index 00000000..9b9cfc4e --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthRecoveryTest.java @@ -0,0 +1,104 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2019 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthRecoveryShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth activation recovery tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthRecoveryTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthClient powerAuthClient; + private PowerAuthTestConfiguration config; + private File tempStatusFile; + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @BeforeEach + void setUp() throws IOException { + // Create temp status file + tempStatusFile = File.createTempFile("pa_status_recovery_" + VERSION, ".json"); + } + + @AfterEach + void tearDown() { + assertTrue(tempStatusFile.delete()); + } + + @Test + void activationRecoveryTest() throws Exception { + PowerAuthRecoveryShared.activationRecoveryTest(powerAuthClient, config, tempStatusFile, VERSION); + } + + @Test + void removeActivationAndRevokeRecoveryCodeTest() throws Exception { + PowerAuthRecoveryShared.removeActivationAndRevokeRecoveryCodeTest(powerAuthClient, config, tempStatusFile, VERSION); + } + + @Test + void activationRecoveryInvalidPukTest() throws Exception { + PowerAuthRecoveryShared.activationRecoveryInvalidPukTest(powerAuthClient, config, tempStatusFile, VERSION); + } + + @Test + void recoveryPostcardTest() throws Exception { + PowerAuthRecoveryShared.recoveryPostcardTest(powerAuthClient, config, tempStatusFile, VERSION); + } + + @Test + void recoveryPostcardInvalidPukIndexTest() throws Exception { + PowerAuthRecoveryShared.recoveryPostcardInvalidPukIndexTest(powerAuthClient, config, tempStatusFile, VERSION); + } + + // TODO - revoke test + + // TODO - negative tests for postcards + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthSignatureTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthSignatureTest.java new file mode 100644 index 00000000..5979d70d --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthSignatureTest.java @@ -0,0 +1,232 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2019 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthSignatureShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.VerifySignatureStepModel; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth signature tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthSignatureTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthTestConfiguration config; + private static File dataFile; + private VerifySignatureStepModel model; + private ObjectStepLogger stepLogger; + + private PowerAuthClient powerAuthClient; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() throws IOException { + model = new VerifySignatureStepModel(); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setData(Files.readAllBytes(Paths.get(dataFile.getAbsolutePath()))); + model.setHeaders(new HashMap<>()); + model.setHttpMethod("POST"); + model.setPassword(config.getPassword()); + model.setResourceId("/pa/signature/validate"); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); + model.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + model.setVersion(VERSION); + + stepLogger = new ObjectStepLogger(System.out); + } + + @Test + void signatureValidTest() throws Exception { + PowerAuthSignatureShared.signatureValidTest(model, stepLogger); + } + + @Test + void signatureInvalidPasswordTest() throws Exception { + PowerAuthSignatureShared.signatureInvalidPasswordTest(config, model, stepLogger); + } + + @Test + void signatureIncorrectPasswordFormatTest() throws Exception { + PowerAuthSignatureShared.signatureIncorrectPasswordFormatTest(config, model, stepLogger); + } + + @Test + void signatureCounterLookAheadTest() throws Exception { + PowerAuthSignatureShared.signatureCounterLookAheadTest(config, model); + } + + @Test + void signatureBlockedActivationTest() throws Exception { + PowerAuthSignatureShared.signatureBlockedActivationTest(powerAuthClient, config, model, VERSION); + } + + @Test + void signatureSingleFactorTest() throws Exception { + PowerAuthSignatureShared.signatureSingleFactorTest(model, stepLogger); + } + + @Test + void signatureBiometryTest() throws Exception { + PowerAuthSignatureShared.signatureBiometryTest(model, stepLogger); + } + + @Test + void signatureThreeFactorTest() throws Exception { + PowerAuthSignatureShared.signatureThreeFactorTest(model, stepLogger); + } + + @Test + void signatureEmptyDataTest() throws Exception { + PowerAuthSignatureShared.signatureEmptyDataTest(model, stepLogger, VERSION); + } + + @Test + void signatureValidGetTest() throws Exception { + PowerAuthSignatureShared.signatureValidGetTest(config, model, stepLogger); + } + + @Test + void signatureValidGetNoParamTest() throws Exception { + PowerAuthSignatureShared.signatureValidGetNoParamTest(config, model, stepLogger); + } + + @Test + void signatureGetInvalidPasswordTest() throws Exception { + PowerAuthSignatureShared.signatureGetInvalidPasswordTest(config, model, stepLogger); + } + + @Test + void signatureUnsupportedApplicationTest() throws Exception { + PowerAuthSignatureShared.signatureUnsupportedApplicationTest(powerAuthClient, config, model); + } + + @Test + void signatureMaxFailedAttemptsTest() throws Exception { + PowerAuthSignatureShared.signatureMaxFailedAttemptsTest(powerAuthClient, config, model, VERSION); + } + + @Test + void signatureLookAheadTest() throws Exception { + PowerAuthSignatureShared.signatureLookAheadTest(powerAuthClient, config, model, VERSION); + } + + @Test + void signatureCounterIncrementTest() throws Exception { + PowerAuthSignatureShared.signatureCounterIncrementTest(model, stepLogger); + } + + @Test + void signatureLargeDataTest() throws Exception { + PowerAuthSignatureShared.signatureLargeDataTest(model, stepLogger, VERSION); + } + + @Test + void signatureOfflinePersonalizedValidTest() throws Exception { + PowerAuthSignatureShared.signatureOfflinePersonalizedValidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void signatureOfflinePersonalizedInvalidTest() throws Exception { + PowerAuthSignatureShared.signatureOfflinePersonalizedInvalidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void signatureOfflineNonPersonalizedValidTest() throws Exception { + PowerAuthSignatureShared.signatureOfflineNonPersonalizedValidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void signatureOfflineNonPersonalizedInvalidTest() throws Exception { + PowerAuthSignatureShared.signatureOfflineNonPersonalizedInvalidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void signatureSwappedKeyTest() throws Exception { + PowerAuthSignatureShared.signatureSwappedKeyTest(config, model, stepLogger); + } + + @Test + void signatureInvalidResourceIdTest() throws Exception { + PowerAuthSignatureShared.signatureInvalidResourceIdTest(config, model, stepLogger); + } + + @Test + void testSignatureOfflinePersonalizedProximityCheckValid() throws Exception { + PowerAuthSignatureShared.testSignatureOfflinePersonalizedProximityCheckValid(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void testSignatureOfflinePersonalizedProximityCheckInvalid() throws Exception { + PowerAuthSignatureShared.testSignatureOfflinePersonalizedProximityCheckInvalid(powerAuthClient, config, model, stepLogger, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthTokenTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthTokenTest.java new file mode 100644 index 00000000..2a5a89c6 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthTokenTest.java @@ -0,0 +1,138 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2019 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthTokenShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.CreateTokenStepModel; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * PowerAuth token tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthTokenTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthTestConfiguration config; + private PowerAuthClient powerAuthClient; + private CreateTokenStepModel model; + private ObjectStepLogger stepLogger; + + private static File dataFile; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeAll + static void setUpBeforeClass() throws IOException { + dataFile = File.createTempFile("data", ".json"); + FileWriter fw = new FileWriter(dataFile); + fw.write("All your base are belong to us!"); + fw.close(); + } + + @AfterAll + static void tearDownAfterClass() { + assertTrue(dataFile.delete()); + } + + @BeforeEach + void setUp() { + model = new CreateTokenStepModel(); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setHeaders(new HashMap<>()); + model.setMasterPublicKey(config.getMasterPublicKey()); + model.setPassword(config.getPassword()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); + model.setVersion(VERSION); + + stepLogger = new ObjectStepLogger(System.out); + } + + @Test + void tokenCreateAndVerifyTest() throws Exception { + PowerAuthTokenShared.tokenCreateAndVerifyTest(config, model, dataFile, VERSION); + } + + @Test + void tokenCreateInvalidPasswordTest() throws Exception { + PowerAuthTokenShared.tokenCreateInvalidPasswordTest(config, model, stepLogger); + } + + @Test + void tokenVerifyInvalidTokenTest() throws Exception { + PowerAuthTokenShared.tokenVerifyInvalidTokenTest(config, dataFile, VERSION); + } + + @Test + void tokenVerifyRemovedTokenTest() throws Exception { + PowerAuthTokenShared.tokenVerifyRemovedTokenTest(powerAuthClient, config, model, dataFile, VERSION); + } + + @Test + void tokenCreateBlockedActivationTest() throws Exception { + PowerAuthTokenShared.tokenCreateBlockedActivationTest(powerAuthClient, config, model, VERSION); + } + + @Test + void tokenUnsupportedApplicationTest() throws Exception { + PowerAuthTokenShared.tokenUnsupportedApplicationTest(powerAuthClient, config, model); + } + + @Test + void tokenCounterIncrementTest() throws Exception { + PowerAuthTokenShared.tokenCounterIncrementTest(model, stepLogger); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthVaultUnlockTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthVaultUnlockTest.java new file mode 100644 index 00000000..958c7c98 --- /dev/null +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthVaultUnlockTest.java @@ -0,0 +1,146 @@ +/* + * PowerAuth test and related software components + * Copyright (C) 2019 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.wultra.security.powerauth.test.v33; + +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.test.shared.PowerAuthVaultUnlockShared; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; +import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; +import io.getlime.security.powerauth.lib.cmd.steps.model.VaultUnlockStepModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.HashMap; + +/** + * PowerAuth vault unlock tests. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PowerAuthTestConfiguration.class) +@EnableConfigurationProperties +class PowerAuthVaultUnlockTest { + + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; + + private PowerAuthTestConfiguration config; + private PowerAuthClient powerAuthClient; + private VaultUnlockStepModel model; + private ObjectStepLogger stepLogger; + + @Autowired + public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { + this.config = config; + } + + @Autowired + public void setPowerAuthClient(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } + + @BeforeEach + void setUp() { + model = new VaultUnlockStepModel(); + model.setApplicationKey(config.getApplicationKey()); + model.setApplicationSecret(config.getApplicationSecret()); + model.setHeaders(new HashMap<>()); + model.setPassword(config.getPassword()); + model.setResultStatusObject(config.getResultStatusObject(VERSION)); + model.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); + model.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); + model.setUriString(config.getPowerAuthIntegrationUrl()); + model.setReason("TEST_" + VERSION); + model.setVersion(VERSION); + + stepLogger = new ObjectStepLogger(System.out); + } + + @Test + void vaultUnlockTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockTest(model, stepLogger); + } + + @Test + void vaultUnlockInvalidPasswordTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockInvalidPasswordTest(config, model, stepLogger); + } + + @Test + void vaultUnlockSingleFactorTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockSingleFactorTest(config, model, stepLogger); + } + + @Test + void vaultUnlockBiometryFactorTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockBiometryFactorTest(model, stepLogger); + } + + @Test + void vaultUnlockThreeFactorTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockThreeFactorTest(model, stepLogger); + } + + @Test + void vaultUnlockBlockedActivationTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockBlockedActivationTest(powerAuthClient, config, model, VERSION); + } + + @Test + void vaultUnlockUnsupportedApplicationTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockUnsupportedApplicationTest(powerAuthClient, config, model); + } + + @Test + void vaultUnlockCounterIncrementTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockCounterIncrementTest(model, stepLogger); + } + + @Test + void vaultUnlockTooLongReasonTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockTooLongReasonTest(config, model, stepLogger); + } + + @Test + void vaultUnlockAndECDSASignatureValidTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockAndECDSASignatureValidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void vaultUnlockAndECDSASignatureInvalidTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockAndECDSASignatureInvalidTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void vaultUnlockAndECDSASignatureInvalidActivationTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockAndECDSASignatureInvalidActivationTest(powerAuthClient, config, model, stepLogger, VERSION); + } + + @Test + void vaultUnlockAndECDSASignatureNonExistentActivationTest() throws Exception { + PowerAuthVaultUnlockShared.vaultUnlockAndECDSASignatureNonExistentActivationTest(powerAuthClient, config, model, stepLogger, VERSION); + } + +} diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthActivationFlagsTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthActivationFlagsTest.java index 872d971d..9d0b47f5 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthActivationFlagsTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthActivationFlagsTest.java @@ -20,6 +20,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthActivationFlagsShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.PrepareActivationStepModel; import org.json.simple.JSONObject; import org.junit.jupiter.api.AfterEach; @@ -51,7 +52,7 @@ public class PowerAuthActivationFlagsTest { // Test only in the latestPowerAuth protocol version - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -74,7 +75,7 @@ public void setPowerAuthTestConfiguration(PowerAuthTestConfiguration config) { @BeforeEach void setUp() throws IOException { // Create temp status file - tempStatusFile = File.createTempFile("pa_status_v" + VERSION.replace(".", ""), ".json"); + tempStatusFile = File.createTempFile("pa_status_" + VERSION, ".json"); // Model shared among tests model = new PrepareActivationStepModel(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApiTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApiTest.java index 5e718731..d836c66b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApiTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApiTest.java @@ -24,6 +24,7 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.exception.EncryptorException; import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; import io.getlime.security.powerauth.crypto.lib.model.exception.GenericCryptoException; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +46,7 @@ @EnableConfigurationProperties class PowerAuthApiTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; @@ -66,20 +67,20 @@ void verifySignatureTest() throws GenericCryptoException, CryptoProviderExceptio } @Test - void unlockVaultAndECDSASignatureTest() throws GenericCryptoException, CryptoProviderException, InvalidKeySpecException, EncryptorException, IOException, InvalidKeyException, PowerAuthClientException { + void unlockVaultAndECDSASignatureTest() throws Exception { PowerAuthApiShared.unlockVaultAndECDSASignatureTest(powerAuthClient, config, VERSION); } // createApplication and createApplication version tests are skipped to avoid creating too many applications @Test - void createValidateAndRemoveTokenTestActiveActivation() throws InvalidKeySpecException, CryptoProviderException, GenericCryptoException, IOException, EncryptorException, PowerAuthClientException { + void createValidateAndRemoveTokenTestActiveActivation() throws Exception { PowerAuthApiShared.createValidateAndRemoveTokenTestActiveActivation(powerAuthClient, config, VERSION); } @Test - void recoveryCodeConfirmAndActivationTest() throws CryptoProviderException, GenericCryptoException, IOException, EncryptorException, InvalidKeyException, InvalidKeySpecException, PowerAuthClientException { + void recoveryCodeConfirmAndActivationTest() throws Exception { PowerAuthApiShared.recoveryCodeConfirmAndActivationTest(powerAuthClient, config, VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java index e996ed7b..6a226fc7 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java @@ -26,6 +26,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthOidcActivationConfigurationProperties; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import io.getlime.core.rest.model.base.response.ObjectResponse; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.logging.ObjectStepLogger; import io.getlime.security.powerauth.lib.cmd.logging.model.StepItem; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; @@ -55,7 +56,7 @@ @EnabledIf(expression = "#{T(org.springframework.util.StringUtils).hasText('${powerauth.test.activation.oidc.providerId}')}", loadContext = true) class PowerAuthApplicationConfigurationTest { - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; private static final ObjectMapper objectMapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); @@ -74,7 +75,7 @@ void setUp() { encryptModel.setApplicationSecret(config.getApplicationSecret()); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV32()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); } diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthCallbackTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthCallbackTest.java index 444f12cb..cb8cf066 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthCallbackTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthCallbackTest.java @@ -24,6 +24,7 @@ import com.wultra.security.powerauth.client.model.response.GetCallbackUrlListResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthCallbackShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -46,7 +47,7 @@ class PowerAuthCallbackTest { // Test only in the latestPowerAuth protocol version - private static final String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; private PowerAuthClient powerAuthClient; private PowerAuthTestConfiguration config; diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java index f8f90c1a..037b96f0 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java @@ -19,6 +19,7 @@ import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; import com.wultra.security.powerauth.test.shared.PowerAuthInfoShared; +import io.getlime.security.powerauth.lib.cmd.consts.PowerAuthVersion; import io.getlime.security.powerauth.lib.cmd.steps.model.EncryptStepModel; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -42,7 +43,7 @@ @EnabledIf(expression = "${powerauth.test.includeCustomTests}", loadContext = true) class PowerAuthInfoTest { - private final static String VERSION = "3.2"; + private static final PowerAuthVersion VERSION = PowerAuthVersion.V3_3; @Autowired private PowerAuthTestConfiguration config; @@ -56,7 +57,7 @@ void setUp() { encryptModel.setApplicationSecret(config.getApplicationSecret()); encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); - encryptModel.setResultStatusObject(config.getResultStatusObjectV32()); + encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); encryptModel.setVersion(VERSION); } From eca3ebdca176a0648bbf0793fe91ca24542128a1 Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Tue, 15 Oct 2024 15:41:47 +0800 Subject: [PATCH 32/35] Fix #539: Change PowerAuth protocol version to 3.3 in test server --- powerauth-test-server/src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-test-server/src/main/resources/application.properties b/powerauth-test-server/src/main/resources/application.properties index d6f61efb..9cf980fc 100644 --- a/powerauth-test-server/src/main/resources/application.properties +++ b/powerauth-test-server/src/main/resources/application.properties @@ -2,7 +2,7 @@ powerauth.enrollment.service.url=http://localhost:8080/enrollment-server # PowerAuth protocol version -powerauth.version=3.1 +powerauth.version=3.3 # Store result status in memory resultstatus.persistenceType=memory From b77da7c867ab1f88bc15f299ea7057f02c1c614f Mon Sep 17 00:00:00 2001 From: Roman Strobl Date: Mon, 21 Oct 2024 15:15:10 +0800 Subject: [PATCH 33/35] Fix #541: Configure Base URI string for encryption tests --- .../test/shared/PowerAuthEncryptionShared.java | 10 +++++++--- .../powerauth/test/v30/PowerAuthEncryptionTest.java | 2 ++ .../powerauth/test/v31/PowerAuthEncryptionTest.java | 2 ++ .../powerauth/test/v32/PowerAuthEncryptionTest.java | 2 ++ .../test/v33/PowerAuthActivationCodeTest.java | 1 + .../powerauth/test/v33/PowerAuthEncryptionTest.java | 2 ++ .../test/v33/PowerAuthIdentityVerificationTest.java | 3 +++ .../powerauth/test/v33/PowerAuthOnboardingTest.java | 1 + .../security/powerauth/test/v3x/PowerAuthInfoTest.java | 1 + 9 files changed, 21 insertions(+), 3 deletions(-) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java index ece8bbdd..99c4925f 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/shared/PowerAuthEncryptionShared.java @@ -23,13 +23,15 @@ import com.wultra.security.powerauth.client.model.request.GetEciesDecryptorRequest; import com.wultra.security.powerauth.client.model.response.GetEciesDecryptorResponse; import com.wultra.security.powerauth.configuration.PowerAuthTestConfiguration; +import com.wultra.security.powerauth.model.TemporaryKey; +import com.wultra.security.powerauth.test.shared.util.TemporaryKeyFetchUtil; import io.getlime.core.rest.model.base.response.ErrorResponse; import io.getlime.security.powerauth.crypto.lib.encryptor.ClientEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.exception.EncryptorException; import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ClientEncryptorSecrets; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.crypto.lib.generator.HashBasedCounter; @@ -473,11 +475,12 @@ public static void signAndEncryptThreeFactorTest(PowerAuthTestConfiguration conf assertEquals(200, stepLogger.getResponse().statusCode()); } - public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, PowerAuthVersion version) throws EncryptorException, PowerAuthClientException { + public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAuthClient, final PowerAuthTestConfiguration config, PowerAuthVersion version) throws Exception { + final TemporaryKey temporaryKey = TemporaryKeyFetchUtil.fetchTemporaryKey(version, EncryptorScope.APPLICATION_SCOPE, config); String requestData = "test_data"; ClientEncryptor clientEncryptor = ENCRYPTOR_FACTORY.getClientEncryptor( EncryptorId.APPLICATION_SCOPE_GENERIC, - new EncryptorParameters(version.value(), config.getApplicationKey(), null, null), + new EncryptorParameters(version.value(), config.getApplicationKey(), null, temporaryKey != null ? temporaryKey.getId() : null), new ClientEncryptorSecrets(config.getMasterPublicKey(), config.getApplicationSecret()) ); EncryptedRequest encryptedRequest = clientEncryptor.encryptRequest(requestData.getBytes(StandardCharsets.UTF_8)); @@ -488,6 +491,7 @@ public static void replayAttackEciesDecryptorTest(final PowerAuthClient powerAut eciesDecryptorRequest.setEphemeralPublicKey(encryptedRequest.getEphemeralPublicKey()); eciesDecryptorRequest.setNonce(encryptedRequest.getNonce()); eciesDecryptorRequest.setTimestamp(encryptedRequest.getTimestamp()); + eciesDecryptorRequest.setTemporaryKeyId(temporaryKey != null ? temporaryKey.getId() : null); GetEciesDecryptorResponse decryptorResponse = powerAuthClient.getEciesDecryptor(eciesDecryptorRequest); assertNotNull(decryptorResponse.getSecretKey()); assertNotNull(decryptorResponse.getSharedInfo2()); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java index 0ed86dd9..b8bc882c 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v30/PowerAuthEncryptionTest.java @@ -97,6 +97,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -110,6 +111,7 @@ void setUp() throws IOException { signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); stepLogger = new ObjectStepLogger(System.out); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java index 4143beff..76e30658 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v31/PowerAuthEncryptionTest.java @@ -97,6 +97,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -110,6 +111,7 @@ void setUp() throws IOException { signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); stepLogger = new ObjectStepLogger(System.out); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java index 13f68306..369e7399 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v32/PowerAuthEncryptionTest.java @@ -97,6 +97,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -110,6 +111,7 @@ void setUp() throws IOException { signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); stepLogger = new ObjectStepLogger(System.out); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java index 5d9eda25..fec293d5 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthActivationCodeTest.java @@ -92,6 +92,7 @@ void setUp() throws IOException { signatureModel.setHeaders(new HashMap<>()); signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); signatureModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); signatureModel.setDryRun(false); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java index 71f10d80..d5879a6b 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthEncryptionTest.java @@ -97,6 +97,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); signatureModel = new VerifySignatureStepModel(); @@ -110,6 +111,7 @@ void setUp() throws IOException { signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE); signatureModel.setStatusFileName(config.getStatusFile(VERSION).getAbsolutePath()); signatureModel.setUriString(config.getPowerAuthIntegrationUrl() + "/pa/v3/signature/validate"); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); stepLogger = new ObjectStepLogger(System.out); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java index 6681b6c4..89a27505 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthIdentityVerificationTest.java @@ -83,6 +83,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(resultStatusObject); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); VerifySignatureStepModel signatureModel = new VerifySignatureStepModel(); @@ -94,6 +95,7 @@ void setUp() throws IOException { signatureModel.setResultStatusObject(resultStatusObject); signatureModel.setSignatureType(PowerAuthSignatureTypes.POSSESSION); signatureModel.setStatusFileName(tempStatusFile.getAbsolutePath()); + signatureModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); signatureModel.setVersion(VERSION); TokenAndEncryptStepModel tokenAndEncryptModel = new TokenAndEncryptStepModel(); @@ -102,6 +104,7 @@ void setUp() throws IOException { tokenAndEncryptModel.setHeaders(new HashMap<>()); tokenAndEncryptModel.setHttpMethod("POST"); tokenAndEncryptModel.setResultStatusObject(resultStatusObject); + tokenAndEncryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); tokenAndEncryptModel.setVersion(VERSION); VerifyTokenStepModel tokenModel = new VerifyTokenStepModel(); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java index 6d5cdbe0..219e83e6 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v33/PowerAuthOnboardingTest.java @@ -78,6 +78,7 @@ void setUp() throws IOException { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); encryptModel.setScope("application"); diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java index 037b96f0..dc244382 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthInfoTest.java @@ -58,6 +58,7 @@ void setUp() { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); } From 50b266188b573c464868464813d54d14b1d37a83 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 21 Oct 2024 10:25:11 +0200 Subject: [PATCH 34/35] Configure Base URI string for encryption tests A follow-up to #541 --- .../test/v3x/PowerAuthApplicationConfigurationTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java index 6a226fc7..21ae51f4 100644 --- a/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java +++ b/powerauth-backend-tests/src/test/java/com/wultra/security/powerauth/test/v3x/PowerAuthApplicationConfigurationTest.java @@ -76,6 +76,7 @@ void setUp() { encryptModel.setMasterPublicKey(config.getMasterPublicKey()); encryptModel.setHeaders(new HashMap<>()); encryptModel.setResultStatusObject(config.getResultStatusObject(VERSION)); + encryptModel.setBaseUriString(config.getPowerAuthIntegrationUrl()); encryptModel.setVersion(VERSION); } From 13633bfbccb10ce89536a6cdd064de54547c44d6 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 11 Oct 2024 11:17:57 +0200 Subject: [PATCH 35/35] Fix #530: Update Wultra dependencies --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index c31d8f59..2ecaf66f 100644 --- a/pom.xml +++ b/pom.xml @@ -45,11 +45,11 @@ - 1.9.0-SNAPSHOT - 1.9.0-SNAPSHOT + 1.9.0 + 1.9.0 1.9.0 - 1.9.0-SNAPSHOT - 1.9.0-SNAPSHOT + 1.9.0 + 1.9.0 1.11.0 2.6.0