From 77db35ab91e8745aa6fc975d30fb4a78f06b6491 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 9 Dec 2022 16:23:23 +0100 Subject: [PATCH 01/64] Fix #345: Update to Spring Boot 2.7.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f715c576..ac9c5cb4 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.2.1 3.3.2 4.0.1 - 2.6.14 + 2.7.6 1.10.0 1.70 1.6.0-SNAPSHOT From 99b5216c46cb3dc69793840bcb4ef06c72ed4417 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 19 Dec 2022 12:18:39 +0100 Subject: [PATCH 02/64] Fix #352: Set develop version to 1.5.0-SNAPSHOT --- pom.xml | 4 +++- powerauth-restful-model/pom.xml | 2 +- powerauth-restful-security-spring-annotation/pom.xml | 2 +- powerauth-restful-security-spring/pom.xml | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d8d0aa6b..69fe099f 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.4.0 + ${revision} pom 2017 @@ -74,6 +74,8 @@ + 1.5.0-SNAPSHOT + UTF-8 1.8 1.8 diff --git a/powerauth-restful-model/pom.xml b/powerauth-restful-model/pom.xml index 353620ce..df0900fe 100644 --- a/powerauth-restful-model/pom.xml +++ b/powerauth-restful-model/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.4.0 + ${revision} diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 91d185a4..2192f6a1 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.4.0 + ${revision} diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index a4965be6..f597cd1f 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.4.0 + ${revision} From 49ed0053c3fea193ca6be15d27a548a0598a9a44 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 3 Jan 2023 11:43:35 +0100 Subject: [PATCH 03/64] Stop using revision property for project version Follow up to issue #352 --- pom.xml | 4 +--- powerauth-restful-model/pom.xml | 2 +- powerauth-restful-security-spring-annotation/pom.xml | 2 +- powerauth-restful-security-spring/pom.xml | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 8c5f9579..f220c9ab 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ io.getlime.security powerauth-restful-integration-parent - ${revision} + 1.5.0-SNAPSHOT pom 2017 @@ -74,8 +74,6 @@ - 1.5.0-SNAPSHOT - UTF-8 1.8 1.8 diff --git a/powerauth-restful-model/pom.xml b/powerauth-restful-model/pom.xml index df0900fe..36e747f9 100644 --- a/powerauth-restful-model/pom.xml +++ b/powerauth-restful-model/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - ${revision} + 1.5.0-SNAPSHOT diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 2192f6a1..a1ae3b61 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - ${revision} + 1.5.0-SNAPSHOT diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index f597cd1f..0212cb6c 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - ${revision} + 1.5.0-SNAPSHOT From be9e32838cd72c7e384f1dc9b913ae2b02a33799 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 26 Jan 2023 08:25:31 +0100 Subject: [PATCH 04/64] Add dependabot configuration --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..81dcf707 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" From eb6ce6f272c1cad549de9788e0837a0dc31ea25c Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 26 Jan 2023 08:37:22 +0100 Subject: [PATCH 05/64] Remove travis configuration --- .travis.yml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index cfa25b4b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: java -jdk: - - openjdk11 -branches: - only: - - master - - coverity_scan -env: - global: - - secure: "fS5NtYWaRbacaor5Nc8W+/5mFdyirXRVmkTZ0RO6zgmtZCBKnXfOFKCLXMZ2oHCTkyicJASPdPBxfKkxMVMUR+Dr0HjqicAY1/tERS8JYYMgreDP2Na6OvAmKNB1kulBPC2z5kJihaKL69gbqbLJi2qv/Juv/LDQJgOqEVmEdhMHuQ6X9HG51DGAQBDDTVS3j5diVaYW31pa4b7FNgU58pClnSfdaeUYMdKQjQHdSOgvMCP49TnDKBc4ZmtVmrrusM4yPpbLQeNJK0m79kVY1kN8camHKyDn85CsV1S4qMj6ylHgQ90UaATq/yH97gkrV0Vm/XbQEAYN/RpkEsW/Gm5bvPY5CtlXG2lUkbzPYgutxtVUKrRqd4MDc6B/Yxs/ADrmNtKCu2rnTbxlKKpe/wtfxRecP4+QmPx3bbgeHEUt8aDqZvSwNtgaUeY3jTb/vYwkm13VNq8jE7HvOX2Aaq1awbz0xC9aeEihc4xfmMOFaS5pK9ANDqND9EWHamICEonlYU7gNSYgKXfTgPJvUaZDMVrhlACl1c62sucvZaE7bn17mF/5OOj6RHYllM5WjbCmBgLO5sUbWaBJwWLnYSU/MKtoISPToTEsW1wWAYXeQvjY80nAML4dgb4lTqqYy96T3/QrGSXwZ4scVInjxtdpf4bHkElqPA/KLEzEqZ0=" - -before_install: - - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- - -addons: - coverity_scan: - project: - name: "wultra/powerauth-restful-integration" - description: "Build submitted via Travis CI" - notification_email: roman.strobl@wultra.com - build_command_prepend: "mvn clean" - build_command: "mvn -DskipTests=true compile" - branch_pattern: coverity_scan \ No newline at end of file From 973713eee429750b66c2b338d990387c5c80bd68 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 22 Dec 2022 07:54:43 +0100 Subject: [PATCH 06/64] Fix #359: Update Wultra dependencies to snapshot --- pom.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index f220c9ab..711e8c02 100644 --- a/pom.xml +++ b/pom.xml @@ -82,14 +82,13 @@ 3.4.1 3.2.1 3.3.2 - 4.0.1 2.7.6 1.10.0 1.72 - 1.6.0 - 1.4.0 - 1.4.0 - 1.4.0 + 1.7.0-SNAPSHOT + 1.5.0-SNAPSHOT + 1.5.0-SNAPSHOT + 1.5.0-SNAPSHOT From 57fd2bc75737f4ace5effdbed9b2980471a9bc5e Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 26 Jan 2023 08:54:48 +0100 Subject: [PATCH 07/64] Update CodeQL to v2 --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++------------ 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dee72c9e..35b7856d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -18,50 +18,59 @@ on: # The branches below must be a subset of the branches above branches: [ develop ] schedule: - - cron: '27 4 * * 2' + - cron: '0 2 * * 4' jobs: analyze: name: Analyze runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write strategy: fail-fast: false matrix: language: [ 'java' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v3 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - #- run: | - # make bootstrap - # make release + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From 7532af7a9eca718f3b96d4b97276fc5ef76f0ed3 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 19:24:59 +0200 Subject: [PATCH 08/64] Fix #362: Add new /user/info endpoint --- .../api/model/request/v3/UserInfoRequest.java | 28 ++++++ .../response/v3/ActivationLayer1Response.java | 17 ++++ .../exception/PowerAuthUserInfoException.java | 74 ++++++++++++++++ .../api/spring/provider/UserInfoProvider.java | 48 ++++++++++ .../controller/v3/UserInfoController.java | 87 +++++++++++++++++++ .../exception/PowerAuthExceptionHandler.java | 12 +++ .../spring/service/v3/ActivationService.java | 60 +++++++++---- .../spring/service/v3/UserInfoService.java | 78 +++++++++++++++++ 8 files changed, 385 insertions(+), 19 deletions(-) create mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java create mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java create mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java new file mode 100644 index 00000000..bda06622 --- /dev/null +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java @@ -0,0 +1,28 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.model.request.v3; + +/** + * Request object for user info endpoint. + * + * @author Petr Dvorak, petr@wultra.com + */ +public class UserInfoRequest { +} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java index a39707d6..e9d3c6e9 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java @@ -31,6 +31,7 @@ public class ActivationLayer1Response { private EciesEncryptedResponse activationData; private Map customAttributes; + private Map userInfo; /** * Get encrypted activation data. @@ -63,4 +64,20 @@ public Map getCustomAttributes() { public void setCustomAttributes(Map customAttributes) { this.customAttributes = customAttributes; } + + /** + * Get user info as a map of claims. + * @return User info. + */ + public Map getUserInfo() { + return userInfo; + } + + /** + * Set user info via a map of claims. + * @param userInfo User info. + */ + public void setUserInfo(Map userInfo) { + this.userInfo = userInfo; + } } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java new file mode 100644 index 00000000..4b04dd39 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java @@ -0,0 +1,74 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.exception; + +/** + * Exception for endpoints related to the user info endpoint. + * + * @author Petr Dvorak, petr@wultra.com + */ +public class PowerAuthUserInfoException extends Exception { + + + private static final long serialVersionUID = 5046389522294059168L; + + private static final String DEFAULT_CODE = "ERR_USER_INFO"; + private static final String DEFAULT_ERROR = "POWER_AUTH_USER_INFO_ERROR"; + + /** + * Default constructor. + */ + public PowerAuthUserInfoException() { + super(DEFAULT_ERROR); + } + + /** + * Constructor with a custom error message. + * @param message Error message. + */ + public PowerAuthUserInfoException(String message) { + super(message); + } + + /** + * Constructor with a cause. + * @param cause Error cause. + */ + public PowerAuthUserInfoException(Throwable cause) { + super(cause); + } + + /** + * Get default error code, used for example in the REST response. + * @return Default error code. + */ + public String getDefaultCode() { + return DEFAULT_CODE; + } + + /** + * Get default error message, used for example in the REST response. + * @return Default error message. + */ + public String getDefaultError() { + return DEFAULT_ERROR; + } + +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java new file mode 100644 index 00000000..73c71533 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -0,0 +1,48 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.provider; + +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; + +import java.util.Map; + +/** + * Interface for bean that provides information about a given user. + * + * @author Petr Dvorak, petr@wultra.com + */ +public interface UserInfoProvider { + + /** + * Fetch claims (as used, for example, in JWT) for a given user ID. The map may, but does not have to include claims + * "sub", "jti", and "iat". If these claims are set, they will override values which were automatically inferred from the + * authentication object provided by PowerAuth stack. This may be helpful, for example, to anonymize the user ID + * contained in the "sub" claim. + * + * @param userId User ID. + * @param activationId Activation ID. + * @param applicationId Application ID. + * @return Map of claims obtained for a given user ID. + */ + default Map fetchUserClaimsForUserId(String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { + return null; + } + +} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java new file mode 100644 index 00000000..aedc4a5a --- /dev/null +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java @@ -0,0 +1,87 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.controller.v3; + +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import io.getlime.security.powerauth.rest.api.model.request.v3.UserInfoRequest; +import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; +import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; +import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthToken; +import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; +import io.getlime.security.powerauth.rest.api.spring.service.v3.UserInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +/** + * Controller that provides a user information. + *

PowerAuth protocol versions: + *

    + *
  • 3.0
  • + *
  • 3.1
  • + *
+ * + * @author Petr Dvorak, petr@wultra.com + */ +@RestController +@RequestMapping("/pa/v3/user") +public class UserInfoController { + + private final UserInfoService userInfoService; + + /** + * Default constructor. + * @param userInfoService User info service. + */ + @Autowired + public UserInfoController(UserInfoService userInfoService) { + this.userInfoService = userInfoService; + } + + /** + * Fetch user info. + * + * @param request Request with user info service. + * @param authentication PowerAuth Authentication. + * @return Encrypted user info claims. + * @throws PowerAuthUserInfoException In case there is an error while fetching claims. + */ + @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) + @PowerAuthToken(signatureType = { + PowerAuthSignatureTypes.POSSESSION, + PowerAuthSignatureTypes.POSSESSION_BIOMETRY, + PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE + }) + @PostMapping("info") + public Map claims(@EncryptedRequestBody UserInfoRequest request, PowerAuthApiAuthentication authentication) throws PowerAuthUserInfoException { + return userInfoService.fetchUserClaimsByUserId( + authentication.getUserId(), + authentication.getActivationContext().getActivationId(), + authentication.getApplicationId() + ); + } + +} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java index c1a0967d..505cc721 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java @@ -120,4 +120,16 @@ public class PowerAuthExceptionHandler { return new ErrorResponse(ex.getDefaultCode(), ex.getDefaultError()); } + /** + * Handle {@link PowerAuthUserInfoException} exceptions. + * @param ex Exception instance. + * @return Error response. + */ + @ExceptionHandler(value = PowerAuthUserInfoException.class) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public @ResponseBody ErrorResponse handlePowerAuthUserInfoException(PowerAuthUserInfoException ex) { + logger.warn(ex.getMessage(), ex); + return new ErrorResponse(ex.getDefaultCode(), ex.getDefaultError()); + } + } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index 1c50bc0d..9aebdfed 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -40,6 +40,7 @@ import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationRemoveResponse; import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationStatusResponse; import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,6 +73,7 @@ public class ActivationService { private PowerAuthApplicationConfiguration applicationConfiguration; private CustomActivationProvider activationProvider; + private UserInfoProvider userInfoProvider; /** @@ -105,6 +107,15 @@ public void setPowerAuthActivationProvider(CustomActivationProvider activationPr this.activationProvider = activationProvider; } + /** + * Set user info provider via setter injection. + * @param userInfoProvider User info provider. + */ + @Autowired(required = false) + public void setUserInfoProvider(UserInfoProvider userInfoProvider) { + this.userInfoProvider = userInfoProvider; + } + /** * Create activation. * @@ -174,6 +185,12 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); + // Process user info + Map userInfo = null; + if (userInfoProvider != null) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + } + Map processedCustomAttributes = customAttributes; // In case a custom activation provider is enabled, process custom attributes and save any flags if (activationProvider != null) { @@ -216,7 +233,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare and return encrypted response - return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes); + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } // Custom activation @@ -279,6 +296,12 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); + // Process user info + Map userInfo = null; + if (userInfoProvider != null) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + } + // Process custom attributes using a custom logic final Map processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, response.getActivationId(), userId, response.getApplicationId(), ActivationType.CUSTOM, context); @@ -311,15 +334,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare encrypted activation data - final EciesEncryptedResponse encryptedActivationData = new EciesEncryptedResponse(response.getEncryptedData(), response.getMac()); - - // Prepare the created activation response data - final ActivationLayer1Response responseL1 = new ActivationLayer1Response(); - responseL1.setCustomAttributes(processedCustomAttributes); - responseL1.setActivationData(encryptedActivationData); - - // Return response - return responseL1; + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } // Activation using recovery code @@ -368,20 +383,26 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request recoveryRequest.setEncryptedData(encryptedData); recoveryRequest.setMac(mac); recoveryRequest.setNonce(nonce); - final RecoveryCodeActivationResponse recoveryResponse = powerAuthClient.createActivationUsingRecoveryCode( + final RecoveryCodeActivationResponse response = powerAuthClient.createActivationUsingRecoveryCode( recoveryRequest, httpCustomizationService.getQueryParams(), httpCustomizationService.getHttpHeaders() ); + // Process user info + Map userInfo = null; + if (userInfoProvider != null) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + } + Map processedCustomAttributes = customAttributes; // In case a custom activation provider is enabled, process custom attributes and save any flags if (activationProvider != null) { - processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, recoveryResponse.getActivationId(), recoveryResponse.getUserId(), recoveryResponse.getApplicationId(), ActivationType.RECOVERY, context); - final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, recoveryResponse.getActivationId(), recoveryResponse.getUserId(), recoveryResponse.getApplicationId(), ActivationType.RECOVERY, context); + processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); + final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); if (activationFlags != null && !activationFlags.isEmpty()) { final AddActivationFlagsRequest flagsRequest = new AddActivationFlagsRequest(); - flagsRequest.setActivationId(recoveryResponse.getActivationId()); + flagsRequest.setActivationId(response.getActivationId()); flagsRequest.getActivationFlags().addAll(activationFlags); powerAuthClient.addActivationFlags( flagsRequest, @@ -392,9 +413,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Automatically commit activation by default, the optional activation provider can override automatic commit - if (activationProvider == null || activationProvider.shouldAutoCommitActivation(identity, customAttributes, recoveryResponse.getActivationId(), recoveryResponse.getUserId(), recoveryResponse.getApplicationId(), ActivationType.RECOVERY, context)) { + if (activationProvider == null || activationProvider.shouldAutoCommitActivation(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context)) { final CommitActivationRequest commitRequest = new CommitActivationRequest(); - commitRequest.setActivationId(recoveryResponse.getActivationId()); + commitRequest.setActivationId(response.getActivationId()); commitRequest.setExternalUserId(null); final CommitActivationResponse commitResponse = powerAuthClient.commitActivation( commitRequest, @@ -402,12 +423,12 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); if (activationProvider != null && commitResponse.isActivated()) { - activationProvider.activationWasCommitted(identity, customAttributes, recoveryResponse.getActivationId(), recoveryResponse.getUserId(), recoveryResponse.getApplicationId(), ActivationType.RECOVERY, context); + activationProvider.activationWasCommitted(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); } } // Prepare and return encrypted response - return prepareEncryptedResponse(recoveryResponse.getEncryptedData(), recoveryResponse.getMac(), processedCustomAttributes); + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } default: @@ -529,7 +550,7 @@ public ActivationRemoveResponse removeActivation(PowerAuthApiAuthentication apiA * @param processedCustomAttributes Custom attributes to be returned. * @return Encrypted response object. */ - private ActivationLayer1Response prepareEncryptedResponse(String encryptedData, String mac, Map processedCustomAttributes) { + private ActivationLayer1Response prepareEncryptedResponse(String encryptedData, String mac, Map processedCustomAttributes, Map userInfo) { // Prepare encrypted response object for layer 2 final EciesEncryptedResponse encryptedResponseL2 = new EciesEncryptedResponse(); encryptedResponseL2.setEncryptedData(encryptedData); @@ -537,6 +558,7 @@ private ActivationLayer1Response prepareEncryptedResponse(String encryptedData, // The response is encrypted once more before sent to client using ResponseBodyAdvice final ActivationLayer1Response responseL1 = new ActivationLayer1Response(); + responseL1.setUserInfo(userInfo); responseL1.setCustomAttributes(processedCustomAttributes); responseL1.setActivationData(encryptedResponseL2); return responseL1; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java new file mode 100644 index 00000000..f6bcdccb --- /dev/null +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -0,0 +1,78 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.service.v3; + +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; +import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Service for obtaining user info as claims map. + * + * @author Petr Dvorak, petr@wultra.com + */ +@Service +public class UserInfoService { + + private UserInfoProvider userInfoProvider; + + /** + * Setter with optional user info provider bean. + * @param userInfoProvider User info provider. + */ + @Autowired(required = false) + public void setActivationProvider(UserInfoProvider userInfoProvider) { + this.userInfoProvider = userInfoProvider; + } + + /** + * Fetch user info as a map of claims. + * + * @param userId User ID. + * @param activationId Activation ID. + * @param applicationId Application ID. + * @return Map of claims. + * @throws PowerAuthUserInfoException In case there is an error while fetching claims. + */ + public Map fetchUserClaimsByUserId(String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { + final Map map = new LinkedHashMap<>(); + map.put("sub", userId); + map.put("jti", UUID.randomUUID().toString()); + map.put("iat", Instant.now().getEpochSecond()); + + if (userInfoProvider != null) { + final Map claims = userInfoProvider.fetchUserClaimsForUserId(userId, activationId, applicationId); + if (claims != null) { + for (String key : claims.keySet()) { + map.put(key, claims.get(key)); + } + } + } + + return map; + } + +} From d6e5460f2502c7a9216267410db08b0d85c89d9c Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 20:49:11 +0200 Subject: [PATCH 09/64] Add information about the stage where user info is requested --- .../rest/api/model/entity/UserInfoStage.java | 50 ++++++++++++++++ .../api/spring/provider/UserInfoProvider.java | 19 +++++- .../spring/service/v3/ActivationService.java | 60 ++++++++++++------- .../spring/service/v3/UserInfoService.java | 3 +- 4 files changed, 109 insertions(+), 23 deletions(-) create mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/entity/UserInfoStage.java diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/entity/UserInfoStage.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/entity/UserInfoStage.java new file mode 100644 index 00000000..aaf5072a --- /dev/null +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/entity/UserInfoStage.java @@ -0,0 +1,50 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.model.entity; + +/** + * Information about where the user info is requested from, i.e., during the activation, or via a separate user info + * endpoint. + * + * @author Petr Dvorak, petr@wultra.com + */ +public enum UserInfoStage { + + /** + * The user info was requested from the activation process carried out via activation code. + */ + ACTIVATION_PROCESS_ACTIVATION_CODE, + + /** + * The user info was requested from the activation process carried out via custom attributes. + */ + ACTIVATION_PROCESS_CUSTOM, + + /** + * The user info was requested from the activation process carried out via recovery codes. + */ + ACTIVATION_PROCESS_RECOVERY, + + /** + * The user info was requested from the user info endpoint. + */ + USER_INFO_ENDPOINT + +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index 73c71533..75ad6f3b 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.provider; +import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import java.util.Map; @@ -30,18 +31,34 @@ */ public interface UserInfoProvider { + /** + * Determine if the user info should be returned during the activation flow. By default, the user info is only + * available via a specialized /pa/v3/user/info endpoint. By enabling this option, the user info claims + * will be also returned in the activation response body (inside the outer-encrypted layer). + * @param stage Information about where the user info is requested from. + * @param userId User ID. + * @param activationId Activation ID. + * @param applicationId Application ID. + * @return True if the user info should be returned during the activation, false otherwise (user info is only + * returned in the separate user info endpoint). + */ + default boolean returnUserInfoDuringActivation(UserInfoStage stage, String userId, String activationId, String applicationId) { + return false; + } + /** * Fetch claims (as used, for example, in JWT) for a given user ID. The map may, but does not have to include claims * "sub", "jti", and "iat". If these claims are set, they will override values which were automatically inferred from the * authentication object provided by PowerAuth stack. This may be helpful, for example, to anonymize the user ID * contained in the "sub" claim. * + * @param stage Information about where the user info is requested from. * @param userId User ID. * @param activationId Activation ID. * @param applicationId Application ID. * @return Map of claims obtained for a given user ID. */ - default Map fetchUserClaimsForUserId(String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { + default Map fetchUserClaimsForUserId(UserInfoStage stage, String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { return null; } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index 9aebdfed..101a9080 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -23,6 +23,7 @@ import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.client.model.error.PowerAuthErrorRecovery; import com.wultra.security.powerauth.client.v3.*; +import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.application.PowerAuthApplicationConfiguration; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.converter.v3.ActivationContextConverter; @@ -185,20 +186,26 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); + final String userId = response.getUserId(); + final String activationId = response.getActivationId(); + final String applicationId = response.getApplicationId(); + // Process user info Map userInfo = null; if (userInfoProvider != null) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId); + } } Map processedCustomAttributes = customAttributes; // In case a custom activation provider is enabled, process custom attributes and save any flags if (activationProvider != null) { - processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.CODE, context); - List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.CODE, context); + processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, activationId, userId, applicationId, ActivationType.CODE, context); + List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, activationId, userId, applicationId, ActivationType.CODE, context); if (activationFlags != null && !activationFlags.isEmpty()) { final AddActivationFlagsRequest flagsRequest = new AddActivationFlagsRequest(); - flagsRequest.setActivationId(response.getActivationId()); + flagsRequest.setActivationId(activationId); flagsRequest.getActivationFlags().addAll(activationFlags); powerAuthClient.addActivationFlags( flagsRequest, @@ -214,9 +221,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request notifyActivationCommit = true; } else { // Otherwise check if activation should be committed instantly and if yes, perform commit. - if (activationProvider != null && activationProvider.shouldAutoCommitActivation(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.CODE, context)) { + if (activationProvider != null && activationProvider.shouldAutoCommitActivation(identity, customAttributes, activationId, userId, applicationId, ActivationType.CODE, context)) { final CommitActivationRequest commitRequest = new CommitActivationRequest(); - commitRequest.setActivationId(response.getActivationId()); + commitRequest.setActivationId(activationId); commitRequest.setExternalUserId(null); final CommitActivationResponse commitResponse = powerAuthClient.commitActivation( commitRequest, @@ -229,7 +236,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Notify activation provider about an activation commit. if (activationProvider != null && notifyActivationCommit) { - activationProvider.activationWasCommitted(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.CODE, context); + activationProvider.activationWasCommitted(identity, customAttributes, activationId, userId, applicationId, ActivationType.CODE, context); } // Prepare and return encrypted response @@ -296,20 +303,25 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); + final String activationId = response.getActivationId(); + final String applicationId = response.getApplicationId(); + // Process user info Map userInfo = null; if (userInfoProvider != null) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId); + } } // Process custom attributes using a custom logic - final Map processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, response.getActivationId(), userId, response.getApplicationId(), ActivationType.CUSTOM, context); + final Map processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, activationId, userId, applicationId, ActivationType.CUSTOM, context); // Save activation flags in case the provider specified any flags - final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, response.getActivationId(), userId, response.getApplicationId(), ActivationType.CUSTOM, context); + final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, activationId, userId, applicationId, ActivationType.CUSTOM, context); if (activationFlags != null && !activationFlags.isEmpty()) { final AddActivationFlagsRequest flagsRequest = new AddActivationFlagsRequest(); - flagsRequest.setActivationId(response.getActivationId()); + flagsRequest.setActivationId(activationId); flagsRequest.getActivationFlags().addAll(activationFlags); powerAuthClient.addActivationFlags( flagsRequest, @@ -319,9 +331,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Check if activation should be committed instantly and if yes, perform commit - if (activationProvider.shouldAutoCommitActivation(identity, customAttributes, response.getActivationId(), userId, response.getApplicationId(), ActivationType.CUSTOM, context)) { + if (activationProvider.shouldAutoCommitActivation(identity, customAttributes, activationId, userId, applicationId, ActivationType.CUSTOM, context)) { final CommitActivationRequest commitRequest = new CommitActivationRequest(); - commitRequest.setActivationId(response.getActivationId()); + commitRequest.setActivationId(activationId); commitRequest.setExternalUserId(null); final CommitActivationResponse commitResponse = powerAuthClient.commitActivation( commitRequest, @@ -329,7 +341,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); if (commitResponse.isActivated()) { - activationProvider.activationWasCommitted(identity, customAttributes, response.getActivationId(), userId, response.getApplicationId(), ActivationType.CUSTOM, context); + activationProvider.activationWasCommitted(identity, customAttributes, activationId, userId, applicationId, ActivationType.CUSTOM, context); } } @@ -389,20 +401,26 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); + final String userId = response.getUserId(); + final String activationId = response.getActivationId(); + final String applicationId = response.getApplicationId(); + // Process user info Map userInfo = null; if (userInfoProvider != null) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(response.getUserId(), response.getActivationId(), response.getApplicationId()); + if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId); + } } Map processedCustomAttributes = customAttributes; // In case a custom activation provider is enabled, process custom attributes and save any flags if (activationProvider != null) { - processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); - final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); + processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, activationId, userId, applicationId, ActivationType.RECOVERY, context); + final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, activationId, userId, applicationId, ActivationType.RECOVERY, context); if (activationFlags != null && !activationFlags.isEmpty()) { final AddActivationFlagsRequest flagsRequest = new AddActivationFlagsRequest(); - flagsRequest.setActivationId(response.getActivationId()); + flagsRequest.setActivationId(activationId); flagsRequest.getActivationFlags().addAll(activationFlags); powerAuthClient.addActivationFlags( flagsRequest, @@ -413,9 +431,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Automatically commit activation by default, the optional activation provider can override automatic commit - if (activationProvider == null || activationProvider.shouldAutoCommitActivation(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context)) { + if (activationProvider == null || activationProvider.shouldAutoCommitActivation(identity, customAttributes, activationId, userId, applicationId, ActivationType.RECOVERY, context)) { final CommitActivationRequest commitRequest = new CommitActivationRequest(); - commitRequest.setActivationId(response.getActivationId()); + commitRequest.setActivationId(activationId); commitRequest.setExternalUserId(null); final CommitActivationResponse commitResponse = powerAuthClient.commitActivation( commitRequest, @@ -423,7 +441,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request httpCustomizationService.getHttpHeaders() ); if (activationProvider != null && commitResponse.isActivated()) { - activationProvider.activationWasCommitted(identity, customAttributes, response.getActivationId(), response.getUserId(), response.getApplicationId(), ActivationType.RECOVERY, context); + activationProvider.activationWasCommitted(identity, customAttributes, activationId, userId, applicationId, ActivationType.RECOVERY, context); } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index f6bcdccb..b5e206b6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.service.v3; +import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -64,7 +65,7 @@ public Map fetchUserClaimsByUserId(String userId, String activat map.put("iat", Instant.now().getEpochSecond()); if (userInfoProvider != null) { - final Map claims = userInfoProvider.fetchUserClaimsForUserId(userId, activationId, applicationId); + final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); if (claims != null) { for (String key : claims.keySet()) { map.put(key, claims.get(key)); From e07e7707825443bd78bb9aa611342ce98ee8e6e1 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 20:54:14 +0200 Subject: [PATCH 10/64] Fix imports --- .../rest/api/spring/controller/v3/UserInfoController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java index aedc4a5a..a7150c92 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java @@ -29,7 +29,6 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.service.v3.UserInfoService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; From 108931628ef976be994a231080b935531cdb9581 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 20:56:28 +0200 Subject: [PATCH 11/64] Improve logic of the user info avaialbility by stages --- .../rest/api/spring/provider/UserInfoProvider.java | 10 +++++----- .../rest/api/spring/service/v3/ActivationService.java | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index 75ad6f3b..db7ffb60 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -32,9 +32,9 @@ public interface UserInfoProvider { /** - * Determine if the user info should be returned during the activation flow. By default, the user info is only - * available via a specialized /pa/v3/user/info endpoint. By enabling this option, the user info claims - * will be also returned in the activation response body (inside the outer-encrypted layer). + * Determine if the user info should be returned during the provided stage. By default, the user info is only + * available via a specialized /pa/v3/user/info endpoint. By overriding this method, the user info claims + * might be also returned in the activation response body (inside the outer-encrypted layer). * @param stage Information about where the user info is requested from. * @param userId User ID. * @param activationId Activation ID. @@ -42,8 +42,8 @@ public interface UserInfoProvider { * @return True if the user info should be returned during the activation, false otherwise (user info is only * returned in the separate user info endpoint). */ - default boolean returnUserInfoDuringActivation(UserInfoStage stage, String userId, String activationId, String applicationId) { - return false; + default boolean returnUserInfoDuringStage(UserInfoStage stage, String userId, String activationId, String applicationId) { + return stage == UserInfoStage.USER_INFO_ENDPOINT; } /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index 101a9080..c94ca46f 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -193,7 +193,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId)) { + if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId); } } @@ -309,7 +309,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId)) { + if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId); } } @@ -408,7 +408,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringActivation(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId)) { + if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId); } } From 5734198ed301ac33f68e8eb4529a7282ff37a58f Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 21:03:05 +0200 Subject: [PATCH 12/64] Respect developer's wishes when returning claims at the user info endpoint --- .../rest/api/spring/service/v3/UserInfoService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index b5e206b6..d9b07a76 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -65,10 +65,12 @@ public Map fetchUserClaimsByUserId(String userId, String activat map.put("iat", Instant.now().getEpochSecond()); if (userInfoProvider != null) { - final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); - if (claims != null) { - for (String key : claims.keySet()) { - map.put(key, claims.get(key)); + if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId)) { + final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); + if (claims != null) { + for (String key : claims.keySet()) { + map.put(key, claims.get(key)); + } } } } From 2caa0fc879128fae6574fbbcf178644f5ce2b26b Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Thu, 26 Jan 2023 21:55:12 +0200 Subject: [PATCH 13/64] Only use ECIES encryption --- .../controller/v3/UserInfoController.java | 19 ++---- .../spring/service/v3/UserInfoService.java | 58 ++++++++++++++----- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java index a7150c92..b5540cc8 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java @@ -20,12 +20,10 @@ package io.getlime.security.powerauth.rest.api.spring.controller.v3; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.rest.api.model.request.v3.UserInfoRequest; import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; -import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthToken; -import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; +import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.service.v3.UserInfoService; import org.springframework.beans.factory.annotation.Autowired; @@ -64,22 +62,15 @@ public UserInfoController(UserInfoService userInfoService) { * Fetch user info. * * @param request Request with user info service. - * @param authentication PowerAuth Authentication. + * @param eciesContext PowerAuth ECIES encryption context. * @return Encrypted user info claims. * @throws PowerAuthUserInfoException In case there is an error while fetching claims. */ @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) - @PowerAuthToken(signatureType = { - PowerAuthSignatureTypes.POSSESSION, - PowerAuthSignatureTypes.POSSESSION_BIOMETRY, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE - }) @PostMapping("info") - public Map claims(@EncryptedRequestBody UserInfoRequest request, PowerAuthApiAuthentication authentication) throws PowerAuthUserInfoException { - return userInfoService.fetchUserClaimsByUserId( - authentication.getUserId(), - authentication.getActivationContext().getActivationId(), - authentication.getApplicationId() + public Map claims(@EncryptedRequestBody UserInfoRequest request, EciesEncryptionContext eciesContext) throws PowerAuthUserInfoException { + return userInfoService.fetchUserClaimsByActivationId( + eciesContext.getActivationId() ); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index d9b07a76..031af2b6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -19,9 +19,15 @@ */ package io.getlime.security.powerauth.rest.api.spring.service.v3; +import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; +import com.wultra.security.powerauth.client.v3.ActivationStatus; +import com.wultra.security.powerauth.client.v3.GetActivationStatusResponse; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -38,7 +44,15 @@ @Service public class UserInfoService { + private static final Logger logger = LoggerFactory.getLogger(UserInfoService.class); + private UserInfoProvider userInfoProvider; + private final PowerAuthClient powerAuthClient; + + @Autowired + public UserInfoService(PowerAuthClient powerAuthClient) { + this.powerAuthClient = powerAuthClient; + } /** * Setter with optional user info provider bean. @@ -52,30 +66,44 @@ public void setActivationProvider(UserInfoProvider userInfoProvider) { /** * Fetch user info as a map of claims. * - * @param userId User ID. * @param activationId Activation ID. - * @param applicationId Application ID. * @return Map of claims. * @throws PowerAuthUserInfoException In case there is an error while fetching claims. */ - public Map fetchUserClaimsByUserId(String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { - final Map map = new LinkedHashMap<>(); - map.put("sub", userId); - map.put("jti", UUID.randomUUID().toString()); - map.put("iat", Instant.now().getEpochSecond()); + public Map fetchUserClaimsByActivationId(String activationId) throws PowerAuthUserInfoException { + try { + // Fetch activation details + final GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(activationId); + final String userId = activationStatusResponse.getUserId(); + final String applicationId = activationStatusResponse.getApplicationId(); + final ActivationStatus activationStatus = activationStatusResponse.getActivationStatus(); + + if (ActivationStatus.ACTIVE != activationStatus) { // only allow active state for now + throw new PowerAuthUserInfoException("Invalid activation status: " + activationStatus + ", for activation: " + activationId); + } + + final Map map = new LinkedHashMap<>(); + map.put("sub", userId); + map.put("jti", UUID.randomUUID().toString()); + map.put("iat", Instant.now().getEpochSecond()); - if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId)) { - final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); - if (claims != null) { - for (String key : claims.keySet()) { - map.put(key, claims.get(key)); + if (userInfoProvider != null) { + if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId)) { + final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); + if (claims != null) { + for (String key : claims.keySet()) { + map.put(key, claims.get(key)); + } } } } - } - return map; + return map; + } catch (PowerAuthClientException ex) { + logger.warn("Fetching user claims failed, error: {}", ex.getMessage()); + logger.debug(ex.getMessage(), ex); + throw new PowerAuthUserInfoException(ex); + } } } From ac954eda7d2bf154481aa7cbefb0aaed404136cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Dvo=C5=99=C3=A1k?= Date: Tue, 31 Jan 2023 23:07:58 +0100 Subject: [PATCH 14/64] Update powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: LuboÅĄ RačanskÃŊ --- .../powerauth/rest/api/spring/service/v3/UserInfoService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index 031af2b6..b8d93d12 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -100,9 +100,7 @@ public Map fetchUserClaimsByActivationId(String activationId) th return map; } catch (PowerAuthClientException ex) { - logger.warn("Fetching user claims failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthUserInfoException(ex); + throw new PowerAuthUserInfoException("Fetching user claims failed, activation ID: " + activationId, ex); } } From d0e97d3ee8c9e6328ded4767006d28aeb42339ac Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Tue, 31 Jan 2023 23:27:01 +0100 Subject: [PATCH 15/64] Fixed comments from code review --- .../exception/PowerAuthUserInfoException.java | 1 - .../api/spring/model/UserInfoContext.java | 57 +++++++++++++ .../spring/model/UserInfoContextBuilder.java | 79 +++++++++++++++++++ .../api/spring/provider/UserInfoProvider.java | 19 ++--- .../spring/service/v3/ActivationService.java | 34 ++++++-- .../spring/service/v3/UserInfoService.java | 16 ++-- 6 files changed, 182 insertions(+), 24 deletions(-) create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java index 4b04dd39..cb97a49f 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java @@ -26,7 +26,6 @@ */ public class PowerAuthUserInfoException extends Exception { - private static final long serialVersionUID = 5046389522294059168L; private static final String DEFAULT_CODE = "ERR_USER_INFO"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java new file mode 100644 index 00000000..e8130245 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java @@ -0,0 +1,57 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.model; + +import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Class for passing the context attributes to user info provider. + * + * @author Petr Dvorak, petr@wultra.com + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserInfoContext { + + /** + * Information about where the user info is requested from. + */ + private UserInfoStage stage; + + /** + * User ID. + */ + private String userId; + + /** + * Activation ID. + */ + private String activationId; + + /** + * Application ID. + */ + private String applicationId; + +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java new file mode 100644 index 00000000..998de029 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java @@ -0,0 +1,79 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.model; + +import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; + +/** + * Builder for the user info context class. + * + * @author Petr Dvorak, petr@wultra.com + */ +public class UserInfoContextBuilder { + + private UserInfoStage stage; + private String userId; + private String activationId; + private String applicationId; + + /** + * Setter for stage. + * @param stage Stage. + * @return This. + */ + public UserInfoContextBuilder setStage(UserInfoStage stage) { + this.stage = stage; + return this; + } + + /** + * Set user ID. + * @param userId User ID. + * @return This. + */ + public UserInfoContextBuilder setUserId(String userId) { + this.userId = userId; + return this; + } + + /** + * Set activation ID. + * @param activationId Activation ID. + * @return This. + */ + public UserInfoContextBuilder setActivationId(String activationId) { + this.activationId = activationId; + return this; + } + + /** + * Set application ID. + * @param applicationId Application ID. + * @return This. + */ + public UserInfoContextBuilder setApplicationId(String applicationId) { + this.applicationId = applicationId; + return this; + } + + public UserInfoContext build() { + return new UserInfoContext(stage, userId, activationId, applicationId); + } +} \ No newline at end of file diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index db7ffb60..774a27ef 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -21,7 +21,9 @@ import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; +import javax.annotation.Nonnull; import java.util.Map; /** @@ -35,15 +37,13 @@ public interface UserInfoProvider { * Determine if the user info should be returned during the provided stage. By default, the user info is only * available via a specialized /pa/v3/user/info endpoint. By overriding this method, the user info claims * might be also returned in the activation response body (inside the outer-encrypted layer). - * @param stage Information about where the user info is requested from. - * @param userId User ID. - * @param activationId Activation ID. - * @param applicationId Application ID. + * + * @param context User info context object. * @return True if the user info should be returned during the activation, false otherwise (user info is only * returned in the separate user info endpoint). */ - default boolean returnUserInfoDuringStage(UserInfoStage stage, String userId, String activationId, String applicationId) { - return stage == UserInfoStage.USER_INFO_ENDPOINT; + default boolean returnUserInfoDuringStage(@Nonnull UserInfoContext context) { + return UserInfoStage.USER_INFO_ENDPOINT == context.getStage(); } /** @@ -52,13 +52,10 @@ default boolean returnUserInfoDuringStage(UserInfoStage stage, String userId, St * authentication object provided by PowerAuth stack. This may be helpful, for example, to anonymize the user ID * contained in the "sub" claim. * - * @param stage Information about where the user info is requested from. - * @param userId User ID. - * @param activationId Activation ID. - * @param applicationId Application ID. + * @param context User info context object. * @return Map of claims obtained for a given user ID. */ - default Map fetchUserClaimsForUserId(UserInfoStage stage, String userId, String activationId, String applicationId) throws PowerAuthUserInfoException { + default Map fetchUserClaimsForUserId(UserInfoContext context) throws PowerAuthUserInfoException { return null; } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index c94ca46f..664906fd 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -32,6 +32,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.model.ActivationContext; +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContextBuilder; import io.getlime.security.powerauth.rest.api.spring.provider.CustomActivationProvider; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; @@ -193,8 +195,14 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId)) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE, userId, activationId, applicationId); + final UserInfoContext userInfoContext = new UserInfoContextBuilder() + .setStage(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE) + .setUserId(userId) + .setActivationId(activationId) + .setApplicationId(applicationId) + .build(); + if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } @@ -202,7 +210,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // In case a custom activation provider is enabled, process custom attributes and save any flags if (activationProvider != null) { processedCustomAttributes = activationProvider.processCustomActivationAttributes(customAttributes, activationId, userId, applicationId, ActivationType.CODE, context); - List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, activationId, userId, applicationId, ActivationType.CODE, context); + final List activationFlags = activationProvider.getActivationFlags(identity, processedCustomAttributes, activationId, userId, applicationId, ActivationType.CODE, context); if (activationFlags != null && !activationFlags.isEmpty()) { final AddActivationFlagsRequest flagsRequest = new AddActivationFlagsRequest(); flagsRequest.setActivationId(activationId); @@ -309,8 +317,14 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId)) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_CUSTOM, userId, activationId, applicationId); + final UserInfoContext userInfoContext = new UserInfoContextBuilder() + .setStage(UserInfoStage.ACTIVATION_PROCESS_CUSTOM) + .setUserId(userId) + .setActivationId(activationId) + .setApplicationId(applicationId) + .build(); + if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } @@ -408,8 +422,14 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId)) { - userInfo = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.ACTIVATION_PROCESS_RECOVERY, userId, activationId, applicationId); + final UserInfoContext userInfoContext = new UserInfoContextBuilder() + .setStage(UserInfoStage.ACTIVATION_PROCESS_RECOVERY) + .setUserId(userId) + .setActivationId(activationId) + .setApplicationId(applicationId) + .build(); + if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index 031af2b6..42905528 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -25,6 +25,8 @@ import com.wultra.security.powerauth.client.v3.GetActivationStatusResponse; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContextBuilder; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,12 +90,16 @@ public Map fetchUserClaimsByActivationId(String activationId) th map.put("iat", Instant.now().getEpochSecond()); if (userInfoProvider != null) { - if (userInfoProvider.returnUserInfoDuringStage(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId)) { - final Map claims = userInfoProvider.fetchUserClaimsForUserId(UserInfoStage.USER_INFO_ENDPOINT, userId, activationId, applicationId); + final UserInfoContext userInfoContext = new UserInfoContextBuilder() + .setStage(UserInfoStage.USER_INFO_ENDPOINT) + .setUserId(userId) + .setActivationId(activationId) + .setApplicationId(applicationId) + .build(); + if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + final Map claims = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); if (claims != null) { - for (String key : claims.keySet()) { - map.put(key, claims.get(key)); - } + map.putAll(claims); } } } From f0d5a6b4c5f4f135701d296120a1d6442afe32f3 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Tue, 31 Jan 2023 23:29:58 +0100 Subject: [PATCH 16/64] Fix exception constructor --- .../spring/exception/PowerAuthUserInfoException.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java index cb97a49f..30ba8cf3 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java @@ -54,6 +54,16 @@ public PowerAuthUserInfoException(Throwable cause) { super(cause); } + /** + * Constructor with a message and cause. + * @param message Error message. + * @param cause Error cause. + */ + public PowerAuthUserInfoException(String message, Throwable cause) { + super(message, cause); + } + + /** * Get default error code, used for example in the REST response. * @return Default error code. From d176e32054788c47341ce85002c84c9ca820dfc8 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Sat, 4 Feb 2023 10:53:49 +0100 Subject: [PATCH 17/64] Change logic based on discussion and code review --- .../api/spring/provider/UserInfoProvider.java | 31 +++++++++---- .../exception/PowerAuthExceptionHandler.java | 2 +- .../spring/service/v3/ActivationService.java | 6 +-- .../spring/service/v3/UserInfoService.java | 44 +++++++------------ 4 files changed, 43 insertions(+), 40 deletions(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index 774a27ef..eb3efb40 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -20,18 +20,20 @@ package io.getlime.security.powerauth.rest.api.spring.provider; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; import javax.annotation.Nonnull; +import java.time.Instant; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.UUID; /** * Interface for bean that provides information about a given user. * * @author Petr Dvorak, petr@wultra.com */ -public interface UserInfoProvider { +public class UserInfoProvider { /** * Determine if the user info should be returned during the provided stage. By default, the user info is only @@ -42,21 +44,32 @@ public interface UserInfoProvider { * @return True if the user info should be returned during the activation, false otherwise (user info is only * returned in the separate user info endpoint). */ - default boolean returnUserInfoDuringStage(@Nonnull UserInfoContext context) { + public boolean shouldReturnUserInfo(@Nonnull UserInfoContext context) { return UserInfoStage.USER_INFO_ENDPOINT == context.getStage(); } /** - * Fetch claims (as used, for example, in JWT) for a given user ID. The map may, but does not have to include claims - * "sub", "jti", and "iat". If these claims are set, they will override values which were automatically inferred from the - * authentication object provided by PowerAuth stack. This may be helpful, for example, to anonymize the user ID - * contained in the "sub" claim. + * Return claims (as used, for example, in JWT) for a given user ID. Default implementation returns minimal claims. * * @param context User info context object. * @return Map of claims obtained for a given user ID. */ - default Map fetchUserClaimsForUserId(UserInfoContext context) throws PowerAuthUserInfoException { - return null; + public Map fetchUserClaimsForUserId(@Nonnull UserInfoContext context) { + return this.minimalClaims(context); + } + + /** + * Prepare a set of minimal claims sub, jti and iat. + * + * @param context User info context object. + * @return Map of claims obtained for a given user ID. + */ + private Map minimalClaims(@Nonnull UserInfoContext context) { + final Map defaultClaims = new LinkedHashMap<>(); + defaultClaims.put("sub", context.getUserId()); + defaultClaims.put("jti", UUID.randomUUID().toString()); + defaultClaims.put("iat", Instant.now().getEpochSecond()); + return defaultClaims; } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java index 505cc721..20635bd2 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthExceptionHandler.java @@ -129,7 +129,7 @@ public class PowerAuthExceptionHandler { @ResponseStatus(value = HttpStatus.BAD_REQUEST) public @ResponseBody ErrorResponse handlePowerAuthUserInfoException(PowerAuthUserInfoException ex) { logger.warn(ex.getMessage(), ex); - return new ErrorResponse(ex.getDefaultCode(), ex.getDefaultError()); + return new ErrorResponse(ex.getDefaultCode(), ex.getMessage()); } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index 664906fd..0207d248 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -201,7 +201,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request .setActivationId(activationId) .setApplicationId(applicationId) .build(); - if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } @@ -323,7 +323,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request .setActivationId(activationId) .setApplicationId(applicationId) .build(); - if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } @@ -428,7 +428,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request .setActivationId(activationId) .setApplicationId(applicationId) .build(); - if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { + if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index 58b36cbc..36fbbe2e 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -28,15 +28,11 @@ import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContextBuilder; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.time.Instant; -import java.util.LinkedHashMap; +import java.util.Collections; import java.util.Map; -import java.util.UUID; /** * Service for obtaining user info as claims map. @@ -46,8 +42,6 @@ @Service public class UserInfoService { - private static final Logger logger = LoggerFactory.getLogger(UserInfoService.class); - private UserInfoProvider userInfoProvider; private final PowerAuthClient powerAuthClient; @@ -66,7 +60,7 @@ public void setActivationProvider(UserInfoProvider userInfoProvider) { } /** - * Fetch user info as a map of claims. + * Fetch user info as a map of claims. Returns empty map by default, i.e., if user info provider is not registered. * * @param activationId Activation ID. * @return Map of claims. @@ -74,6 +68,11 @@ public void setActivationProvider(UserInfoProvider userInfoProvider) { */ public Map fetchUserClaimsByActivationId(String activationId) throws PowerAuthUserInfoException { try { + + if (userInfoProvider == null) { + return Collections.emptyMap(); + } + // Fetch activation details final GetActivationStatusResponse activationStatusResponse = powerAuthClient.getActivationStatus(activationId); final String userId = activationStatusResponse.getUserId(); @@ -84,27 +83,18 @@ public Map fetchUserClaimsByActivationId(String activationId) th throw new PowerAuthUserInfoException("Invalid activation status: " + activationStatus + ", for activation: " + activationId); } - final Map map = new LinkedHashMap<>(); - map.put("sub", userId); - map.put("jti", UUID.randomUUID().toString()); - map.put("iat", Instant.now().getEpochSecond()); - - if (userInfoProvider != null) { - final UserInfoContext userInfoContext = new UserInfoContextBuilder() - .setStage(UserInfoStage.USER_INFO_ENDPOINT) - .setUserId(userId) - .setActivationId(activationId) - .setApplicationId(applicationId) - .build(); - if (userInfoProvider.returnUserInfoDuringStage(userInfoContext)) { - final Map claims = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); - if (claims != null) { - map.putAll(claims); - } - } + final UserInfoContext userInfoContext = new UserInfoContextBuilder() + .setStage(UserInfoStage.USER_INFO_ENDPOINT) + .setUserId(userId) + .setActivationId(activationId) + .setApplicationId(applicationId) + .build(); + if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { + return userInfoProvider.fetchUserClaimsForUserId(userInfoContext); + } else { + return Collections.emptyMap(); } - return map; } catch (PowerAuthClientException ex) { throw new PowerAuthUserInfoException("Fetching user claims failed, activation ID: " + activationId, ex); } From cfb6199863522bb1a2435d9c0bd24bc4a74b6c05 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Sat, 4 Feb 2023 11:10:17 +0100 Subject: [PATCH 18/64] Fix #370: Use Lombok for builder generation --- .../api/spring/model/UserInfoContext.java | 6 +- .../spring/model/UserInfoContextBuilder.java | 79 ------------------- .../spring/service/v3/ActivationService.java | 31 ++++---- .../spring/service/v3/UserInfoService.java | 11 ++- 4 files changed, 22 insertions(+), 105 deletions(-) delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java index e8130245..99b6993a 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContext.java @@ -20,9 +20,8 @@ package io.getlime.security.powerauth.rest.api.spring.model; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; -import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; -import lombok.NoArgsConstructor; /** * Class for passing the context attributes to user info provider. @@ -30,8 +29,7 @@ * @author Petr Dvorak, petr@wultra.com */ @Data -@NoArgsConstructor -@AllArgsConstructor +@Builder public class UserInfoContext { /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java deleted file mode 100644 index 998de029..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/UserInfoContextBuilder.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples and - * related software components - * - * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.model; - -import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; - -/** - * Builder for the user info context class. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class UserInfoContextBuilder { - - private UserInfoStage stage; - private String userId; - private String activationId; - private String applicationId; - - /** - * Setter for stage. - * @param stage Stage. - * @return This. - */ - public UserInfoContextBuilder setStage(UserInfoStage stage) { - this.stage = stage; - return this; - } - - /** - * Set user ID. - * @param userId User ID. - * @return This. - */ - public UserInfoContextBuilder setUserId(String userId) { - this.userId = userId; - return this; - } - - /** - * Set activation ID. - * @param activationId Activation ID. - * @return This. - */ - public UserInfoContextBuilder setActivationId(String activationId) { - this.activationId = activationId; - return this; - } - - /** - * Set application ID. - * @param applicationId Application ID. - * @return This. - */ - public UserInfoContextBuilder setApplicationId(String applicationId) { - this.applicationId = applicationId; - return this; - } - - public UserInfoContext build() { - return new UserInfoContext(stage, userId, activationId, applicationId); - } -} \ No newline at end of file diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java index 0207d248..45543cb3 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java @@ -33,7 +33,6 @@ import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.model.ActivationContext; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; -import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContextBuilder; import io.getlime.security.powerauth.rest.api.spring.provider.CustomActivationProvider; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; @@ -195,11 +194,11 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - final UserInfoContext userInfoContext = new UserInfoContextBuilder() - .setStage(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE) - .setUserId(userId) - .setActivationId(activationId) - .setApplicationId(applicationId) + final UserInfoContext userInfoContext = UserInfoContext.builder() + .stage(UserInfoStage.ACTIVATION_PROCESS_ACTIVATION_CODE) + .userId(userId) + .activationId(activationId) + .applicationId(applicationId) .build(); if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); @@ -317,11 +316,11 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - final UserInfoContext userInfoContext = new UserInfoContextBuilder() - .setStage(UserInfoStage.ACTIVATION_PROCESS_CUSTOM) - .setUserId(userId) - .setActivationId(activationId) - .setApplicationId(applicationId) + final UserInfoContext userInfoContext = UserInfoContext.builder() + .stage(UserInfoStage.ACTIVATION_PROCESS_CUSTOM) + .userId(userId) + .activationId(activationId) + .applicationId(applicationId) .build(); if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); @@ -422,11 +421,11 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Process user info Map userInfo = null; if (userInfoProvider != null) { - final UserInfoContext userInfoContext = new UserInfoContextBuilder() - .setStage(UserInfoStage.ACTIVATION_PROCESS_RECOVERY) - .setUserId(userId) - .setActivationId(activationId) - .setApplicationId(applicationId) + final UserInfoContext userInfoContext = UserInfoContext.builder() + .stage(UserInfoStage.ACTIVATION_PROCESS_RECOVERY) + .userId(userId) + .activationId(activationId) + .applicationId(applicationId) .build(); if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { userInfo = userInfoProvider.fetchUserClaimsForUserId(userInfoContext); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java index 36fbbe2e..b7052548 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java @@ -26,7 +26,6 @@ import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; -import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContextBuilder; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -83,11 +82,11 @@ public Map fetchUserClaimsByActivationId(String activationId) th throw new PowerAuthUserInfoException("Invalid activation status: " + activationStatus + ", for activation: " + activationId); } - final UserInfoContext userInfoContext = new UserInfoContextBuilder() - .setStage(UserInfoStage.USER_INFO_ENDPOINT) - .setUserId(userId) - .setActivationId(activationId) - .setApplicationId(applicationId) + final UserInfoContext userInfoContext = UserInfoContext.builder() + .stage(UserInfoStage.USER_INFO_ENDPOINT) + .userId(userId) + .activationId(activationId) + .applicationId(applicationId) .build(); if (userInfoProvider.shouldReturnUserInfo(userInfoContext)) { return userInfoProvider.fetchUserClaimsForUserId(userInfoContext); From 3788b272bb2bcedb92389c611b4c99fb05b579c1 Mon Sep 17 00:00:00 2001 From: Petr Dvorak Date: Sat, 4 Feb 2023 11:14:26 +0100 Subject: [PATCH 19/64] Fix #369: Docucheck warning --- docs/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Readme.md b/docs/Readme.md index 2d1b8b95..07fb8041 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -1,12 +1,12 @@ # PowerAuth RESTful Integration Libraries -In order to easily secure your RESTful APIs with PowerAuth, you can use our easy to use integration libraries for Java technology. Integration libraries are responsible for connecting to PowerAuth Server and for publishing required endpoints toward mobile apps. +In order to easily secure your RESTful APIs with PowerAuth, you can use our integration libraries for Spring technology. Integration libraries are responsible for connecting to PowerAuth Server and for publishing required endpoints toward mobile apps. -**Integration Tutorials** +## Integration Tutorials - [Introduction](./Introduction.md) - [Build Secure RESTful API (Spring)](./RESTful-API-for-Spring.md) -**Deployment Tutorials** +## Deployment Tutorials - [Deploy PowerAuth REST API Standalone Application](./Deploying-PowerAuth-Standard-RESTful-API.md) From af70b0b5a5118024dbc2f3ed5c7c51f5b5c73528 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Mon, 6 Feb 2023 09:06:28 +0100 Subject: [PATCH 20/64] Fix #373: Change UserInfoProvider from class to interface --- .../MinimalClaimsUserInfoProvider.java | 73 +++++++++++++++++++ .../api/spring/provider/UserInfoProvider.java | 27 ++----- 2 files changed, 78 insertions(+), 22 deletions(-) create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java new file mode 100644 index 00000000..a96775f1 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java @@ -0,0 +1,73 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.provider; + +import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; + +import javax.annotation.Nonnull; +import java.time.Instant; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; + +/** + * Specialization of {@link UserInfoProvider}. + * Claims {@code sub, jti, iat} are filled. + * UserInfo is always returned, even for activation. + * + * @author Lubos Racansky, lubos.racansky@wultra.com + */ +public class MinimalClaimsUserInfoProvider implements UserInfoProvider{ + + /** + * Always true, even for activation. + *

+ * {@inheritDoc} + */ + @Override + public boolean shouldReturnUserInfo(@Nonnull UserInfoContext context) { + return true; + } + + /** + * Fill claims {@code sub, jti, iat}. + *

+ * {@inheritDoc} + */ + @Override + public Map fetchUserClaimsForUserId(@Nonnull UserInfoContext context) { + return minimalClaims(context); + } + + /** + * Prepare a set of minimal claims sub, jti and iat. + * + * @param context User info context object. + * @return Map of claims obtained for a given user ID. + */ + private static Map minimalClaims(@Nonnull UserInfoContext context) { + final Map defaultClaims = new LinkedHashMap<>(); + defaultClaims.put("sub", context.getUserId()); + defaultClaims.put("jti", UUID.randomUUID().toString()); + defaultClaims.put("iat", Instant.now().getEpochSecond()); + return Collections.unmodifiableMap(defaultClaims); + } +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index eb3efb40..3eceb89d 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -23,17 +23,15 @@ import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; import javax.annotation.Nonnull; -import java.time.Instant; -import java.util.LinkedHashMap; +import java.util.Collections; import java.util.Map; -import java.util.UUID; /** * Interface for bean that provides information about a given user. * * @author Petr Dvorak, petr@wultra.com */ -public class UserInfoProvider { +public interface UserInfoProvider { /** * Determine if the user info should be returned during the provided stage. By default, the user info is only @@ -44,7 +42,7 @@ public class UserInfoProvider { * @return True if the user info should be returned during the activation, false otherwise (user info is only * returned in the separate user info endpoint). */ - public boolean shouldReturnUserInfo(@Nonnull UserInfoContext context) { + default boolean shouldReturnUserInfo(@Nonnull UserInfoContext context) { return UserInfoStage.USER_INFO_ENDPOINT == context.getStage(); } @@ -54,22 +52,7 @@ public boolean shouldReturnUserInfo(@Nonnull UserInfoContext context) { * @param context User info context object. * @return Map of claims obtained for a given user ID. */ - public Map fetchUserClaimsForUserId(@Nonnull UserInfoContext context) { - return this.minimalClaims(context); + default Map fetchUserClaimsForUserId(@Nonnull UserInfoContext context) { + return Collections.emptyMap(); } - - /** - * Prepare a set of minimal claims sub, jti and iat. - * - * @param context User info context object. - * @return Map of claims obtained for a given user ID. - */ - private Map minimalClaims(@Nonnull UserInfoContext context) { - final Map defaultClaims = new LinkedHashMap<>(); - defaultClaims.put("sub", context.getUserId()); - defaultClaims.put("jti", UUID.randomUUID().toString()); - defaultClaims.put("iat", Instant.now().getEpochSecond()); - return defaultClaims; - } - } From 11ba1a033426927c9c5b7fa10fe1df6db0708815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Feb 2023 10:43:52 +0000 Subject: [PATCH 21/64] Bump spring-boot-dependencies from 2.7.6 to 2.7.8 Bumps [spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 2.7.6 to 2.7.8. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.6...v2.7.8) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 711e8c02..ea598745 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.4.1 3.2.1 3.3.2 - 2.7.6 + 2.7.8 1.10.0 1.72 1.7.0-SNAPSHOT From 640526132a3ed61497d5ff3e61439a23f7108d43 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 7 Feb 2023 10:26:21 +0100 Subject: [PATCH 22/64] Fix #375: Use API and SPI document annotations from lime-core --- pom.xml | 14 +++++++++++++- powerauth-restful-model/pom.xml | 1 - .../pom.xml | 5 +++++ .../spring/provider/CustomActivationProvider.java | 2 ++ .../provider/MinimalClaimsUserInfoProvider.java | 2 ++ .../rest/api/spring/provider/UserInfoProvider.java | 2 ++ 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ea598745..f62ee8d9 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 2.7.8 1.10.0 1.72 - 1.7.0-SNAPSHOT + 1.7.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT @@ -114,6 +114,18 @@ ${project.version} + + io.getlime.core + annotations + ${wultra-core.version} + + + + io.getlime.core + rest-model-base + ${wultra-core.version} + + org.bouncycastle diff --git a/powerauth-restful-model/pom.xml b/powerauth-restful-model/pom.xml index 36e747f9..03089201 100644 --- a/powerauth-restful-model/pom.xml +++ b/powerauth-restful-model/pom.xml @@ -37,7 +37,6 @@ io.getlime.core rest-model-base - ${rest-model-base.version} diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index a1ae3b61..4d64e5b6 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -74,6 +74,11 @@ ${powerauth-rest-client-spring.version} + + io.getlime.core + annotations + + org.apache.commons diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java index e52ef4af..68cda128 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.provider; +import com.wultra.core.annotations.PublicSpi; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; @@ -34,6 +35,7 @@ * @author Petr Dvorak, petr@wultra.com * @author Roman Strobl, roman.strobl@wultra.com */ +@PublicSpi public interface CustomActivationProvider { /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java index a96775f1..6d457291 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/MinimalClaimsUserInfoProvider.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.provider; +import com.wultra.core.annotations.PublicSpi; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; import javax.annotation.Nonnull; @@ -35,6 +36,7 @@ * * @author Lubos Racansky, lubos.racansky@wultra.com */ +@PublicSpi public class MinimalClaimsUserInfoProvider implements UserInfoProvider{ /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java index 3eceb89d..ae7be0f4 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/UserInfoProvider.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.provider; +import com.wultra.core.annotations.PublicSpi; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; @@ -31,6 +32,7 @@ * * @author Petr Dvorak, petr@wultra.com */ +@PublicSpi public interface UserInfoProvider { /** From ecd8df03f653894906ddcd5ad92ed8c9295c0fbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 08:04:44 +0000 Subject: [PATCH 23/64] Bump maven-javadoc-plugin from 3.4.1 to 3.5.0 Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.1 to 3.5.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.1...maven-javadoc-plugin-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin 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 f62ee8d9..d7cb79c5 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 1.8 3.3.0 3.0.0 - 3.4.1 + 3.5.0 3.2.1 3.3.2 2.7.8 From d4fa8b2eaa50be9c12f548ea04c1adafe5116df2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:08:29 +0000 Subject: [PATCH 24/64] Bump maven-deploy-plugin from 3.0.0 to 3.1.0 Bumps [maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-3.0.0...maven-deploy-plugin-3.1.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin 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 d7cb79c5..f3df77fe 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 1.8 1.8 3.3.0 - 3.0.0 + 3.1.0 3.5.0 3.2.1 3.3.2 From f83935b316d010f5a0bdefa3a817d642246509c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 08:04:07 +0000 Subject: [PATCH 25/64] Bump spring-boot-dependencies from 2.7.8 to 2.7.9 Bumps [spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 2.7.8 to 2.7.9. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.8...v2.7.9) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 d7cb79c5..2cb2be31 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.5.0 3.2.1 3.3.2 - 2.7.8 + 2.7.9 1.10.0 1.72 1.7.0-SNAPSHOT From 3d143bb3e05e7495ad05f822c330b8b1b6e1a09e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:05:13 +0000 Subject: [PATCH 26/64] Bump maven-deploy-plugin from 3.1.0 to 3.1.1 Bumps [maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-3.1.0...maven-deploy-plugin-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin 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 b5a5c46f..44d23c5a 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ 1.8 1.8 3.3.0 - 3.1.0 + 3.1.1 3.5.0 3.2.1 3.3.2 From 21013299cf74722634bbdde190055db1672f6fc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:05:25 +0000 Subject: [PATCH 27/64] Bump spring-boot-dependencies from 2.7.9 to 2.7.10 Bumps [spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 2.7.9 to 2.7.10. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.9...v2.7.10) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 b5a5c46f..348a4f3b 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.5.0 3.2.1 3.3.2 - 2.7.9 + 2.7.10 1.10.0 1.72 1.7.0-SNAPSHOT From 9aa20c08cb6c2966cdabf4fbc05f8811b3851fb5 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Tue, 28 Mar 2023 08:17:18 +0200 Subject: [PATCH 28/64] Fix #386: Prefer Base64 Java 8 APIs over Guava --- .../PowerAuthNonPersonalizedEncryptor.java | 42 +++++++++---------- .../filter/EncryptionResponseBodyAdvice.java | 10 ++--- .../PowerAuthAuthenticationProvider.java | 4 +- .../PowerAuthEncryptionProviderBase.java | 22 +++++----- .../spring/service/v2/SecureVaultService.java | 4 +- .../spring/service/v3/SecureVaultService.java | 4 +- 6 files changed, 43 insertions(+), 43 deletions(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java index c36e8cd2..7e44541a 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; 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.NonPersonalizedEncryptor; @@ -32,6 +31,7 @@ import java.io.IOException; import java.security.InvalidKeyException; +import java.util.Base64; /** * Non-personalized encryptor class. @@ -53,10 +53,10 @@ public class PowerAuthNonPersonalizedEncryptor { * @param ephemeralPublicKeyBase64 Ephemeral public key. */ public PowerAuthNonPersonalizedEncryptor(String applicationKeyBase64, String sessionKeyBytesBase64, String sessionIndexBase64, String ephemeralPublicKeyBase64) { - final byte[] applicationKey = BaseEncoding.base64().decode(applicationKeyBase64); - final byte[] sessionIndex = BaseEncoding.base64().decode(sessionIndexBase64); - final byte[] sessionKeyBytes = BaseEncoding.base64().decode(sessionKeyBytesBase64); - final byte[] ephemeralKeyBytes = BaseEncoding.base64().decode(ephemeralPublicKeyBase64); + final byte[] applicationKey = Base64.getDecoder().decode(applicationKeyBase64); + final byte[] sessionIndex = Base64.getDecoder().decode(sessionIndexBase64); + final byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKeyBytesBase64); + final byte[] ephemeralKeyBytes = Base64.getDecoder().decode(ephemeralPublicKeyBase64); this.encryptor = new NonPersonalizedEncryptor(applicationKey, sessionKeyBytes, sessionIndex, ephemeralKeyBytes); } @@ -100,14 +100,14 @@ public ObjectResponse encrypt(byte[] origi } final NonPersonalizedEncryptedPayloadModel responseObject = new NonPersonalizedEncryptedPayloadModel(); - responseObject.setApplicationKey(BaseEncoding.base64().encode(message.getApplicationKey())); - responseObject.setEphemeralPublicKey(BaseEncoding.base64().encode(message.getEphemeralPublicKey())); - responseObject.setSessionIndex(BaseEncoding.base64().encode(message.getSessionIndex())); - responseObject.setAdHocIndex(BaseEncoding.base64().encode(message.getAdHocIndex())); - responseObject.setMacIndex(BaseEncoding.base64().encode(message.getMacIndex())); - responseObject.setNonce(BaseEncoding.base64().encode(message.getNonce())); - responseObject.setMac(BaseEncoding.base64().encode(message.getMac())); - responseObject.setEncryptedData(BaseEncoding.base64().encode(message.getEncryptedData())); + responseObject.setApplicationKey(Base64.getEncoder().encodeToString(message.getApplicationKey())); + responseObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(message.getEphemeralPublicKey())); + responseObject.setSessionIndex(Base64.getEncoder().encodeToString(message.getSessionIndex())); + responseObject.setAdHocIndex(Base64.getEncoder().encodeToString(message.getAdHocIndex())); + responseObject.setMacIndex(Base64.getEncoder().encodeToString(message.getMacIndex())); + responseObject.setNonce(Base64.getEncoder().encodeToString(message.getNonce())); + responseObject.setMac(Base64.getEncoder().encodeToString(message.getMac())); + responseObject.setEncryptedData(Base64.getEncoder().encodeToString(message.getEncryptedData())); return new ObjectResponse<>(responseObject); } @@ -134,14 +134,14 @@ public byte[] decrypt(ObjectRequest reques } final NonPersonalizedEncryptedMessage message = new NonPersonalizedEncryptedMessage(); - message.setApplicationKey(BaseEncoding.base64().decode(requestObject.getApplicationKey())); - message.setEphemeralPublicKey(BaseEncoding.base64().decode(requestObject.getEphemeralPublicKey())); - message.setSessionIndex(BaseEncoding.base64().decode(requestObject.getSessionIndex())); - message.setAdHocIndex(BaseEncoding.base64().decode(requestObject.getAdHocIndex())); - message.setMacIndex(BaseEncoding.base64().decode(requestObject.getMacIndex())); - message.setNonce(BaseEncoding.base64().decode(requestObject.getNonce())); - message.setMac(BaseEncoding.base64().decode(requestObject.getMac())); - message.setEncryptedData(BaseEncoding.base64().decode(requestObject.getEncryptedData())); + message.setApplicationKey(Base64.getDecoder().decode(requestObject.getApplicationKey())); + message.setEphemeralPublicKey(Base64.getDecoder().decode(requestObject.getEphemeralPublicKey())); + message.setSessionIndex(Base64.getDecoder().decode(requestObject.getSessionIndex())); + message.setAdHocIndex(Base64.getDecoder().decode(requestObject.getAdHocIndex())); + message.setMacIndex(Base64.getDecoder().decode(requestObject.getMacIndex())); + message.setNonce(Base64.getDecoder().decode(requestObject.getNonce())); + message.setMac(Base64.getDecoder().decode(requestObject.getMac())); + message.setEncryptedData(Base64.getDecoder().decode(requestObject.getEncryptedData())); return encryptor.decrypt(message); } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index fe13db0f..09f84214 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -20,13 +20,12 @@ package io.getlime.security.powerauth.rest.api.spring.filter; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; -import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; +import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -52,6 +51,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.List; /** @@ -124,8 +124,8 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa // Encrypt response using decryptor and return ECIES cryptogram final EciesDecryptor eciesDecryptor = eciesEncryption.getEciesDecryptor(); final EciesCryptogram cryptogram = eciesDecryptor.encryptResponse(responseBytes); - final String encryptedDataBase64 = BaseEncoding.base64().encode(cryptogram.getEncryptedData()); - final String macBase64 = BaseEncoding.base64().encode(cryptogram.getMac()); + final String encryptedDataBase64 = Base64.getEncoder().encodeToString(cryptogram.getEncryptedData()); + final String macBase64 = Base64.getEncoder().encodeToString(cryptogram.getMac()); // Return encrypted response with type given by converter class final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java index e499b167..bdd0045e 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java @@ -19,7 +19,6 @@ */ package io.getlime.security.powerauth.rest.api.spring.provider; -import com.google.common.io.BaseEncoding; import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.client.v3.*; @@ -56,6 +55,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Base64; import java.util.List; /** @@ -326,7 +326,7 @@ public PowerAuthApiAuthentication validateRequestSignature( final PowerAuthSignatureAuthenticationImpl powerAuthAuthentication = new PowerAuthSignatureAuthenticationImpl(); powerAuthAuthentication.setActivationId(header.getActivationId()); powerAuthAuthentication.setApplicationKey(header.getApplicationKey()); - powerAuthAuthentication.setNonce(BaseEncoding.base64().decode(header.getNonce())); + powerAuthAuthentication.setNonce(Base64.getDecoder().decode(header.getNonce())); powerAuthAuthentication.setSignatureType(header.getSignatureType()); powerAuthAuthentication.setSignature(header.getSignature()); powerAuthAuthentication.setHttpMethod(httpMethod); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index 04b100b4..cb2034ef 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -23,7 +23,6 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; -import com.google.common.io.BaseEncoding; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEnvelopeKey; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; @@ -34,14 +33,14 @@ import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; import io.getlime.security.powerauth.http.validator.PowerAuthEncryptionHttpHeaderValidator; import io.getlime.security.powerauth.http.validator.PowerAuthSignatureHttpHeaderValidator; +import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesDecryptorParameters; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +49,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Type; +import java.util.Base64; /** * Abstract class for PowerAuth encryption provider with common HTTP header parsing logic. The class is available for @@ -144,10 +144,10 @@ public abstract class PowerAuthEncryptionProviderBase { throw new PowerAuthEncryptionException(); } - final byte[] ephemeralPublicKeyBytes = BaseEncoding.base64().decode(ephemeralPublicKey); - final byte[] encryptedDataBytes = BaseEncoding.base64().decode(encryptedData); - final byte[] macBytes = BaseEncoding.base64().decode(mac); - final byte[] nonceBytes = nonce != null ? BaseEncoding.base64().decode(nonce) : null; + final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); + final byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData); + final byte[] macBytes = Base64.getDecoder().decode(mac); + final byte[] nonceBytes = nonce != null ? Base64.getDecoder().decode(nonce) : null; final String applicationKey = eciesEncryption.getContext().getApplicationKey(); final PowerAuthEciesDecryptorParameters decryptorParameters; @@ -170,9 +170,9 @@ public abstract class PowerAuthEncryptionProviderBase { } // Prepare envelope key and sharedInfo2 parameter for decryptor - final byte[] secretKey = BaseEncoding.base64().decode(decryptorParameters.getSecretKey()); + final byte[] secretKey = Base64.getDecoder().decode(decryptorParameters.getSecretKey()); final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); - final byte[] sharedInfo2 = BaseEncoding.base64().decode(decryptorParameters.getSharedInfo2()); + final byte[] sharedInfo2 = Base64.getDecoder().decode(decryptorParameters.getSharedInfo2()); // Construct decryptor and set it to the request for later encryption of response final EciesDecryptor eciesDecryptor = eciesFactory.getEciesDecryptor(envelopeKey, sharedInfo2); @@ -210,8 +210,8 @@ public abstract class PowerAuthEncryptionProviderBase { final byte[] responseData = serializeResponseData(responseObject); // Encrypt response using decryptor and return ECIES cryptogram final EciesCryptogram cryptogram = eciesEncryption.getEciesDecryptor().encryptResponse(responseData); - final String encryptedDataBase64 = BaseEncoding.base64().encode(cryptogram.getEncryptedData()); - final String macBase64 = BaseEncoding.base64().encode(cryptogram.getMac()); + final String encryptedDataBase64 = Base64.getEncoder().encodeToString(cryptogram.getEncryptedData()); + final String macBase64 = Base64.getEncoder().encodeToString(cryptogram.getMac()); return new EciesEncryptedResponse(encryptedDataBase64, macBase64); } catch (Exception ex) { logger.debug("Response encryption failed, error: " + ex.getMessage(), ex); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java index 67233b91..10a8aac3 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java @@ -19,7 +19,6 @@ */ package io.getlime.security.powerauth.rest.api.spring.service.v2; -import com.google.common.io.BaseEncoding; import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.client.v2.SignatureType; import io.getlime.security.powerauth.http.PowerAuthHttpBody; @@ -41,6 +40,7 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import java.util.Base64; /** * Service implementing secure vault functionality. @@ -135,7 +135,7 @@ public VaultUnlockResponse vaultUnlock(String signatureHeader, throw new PowerAuthSecureVaultException(); } - final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", BaseEncoding.base64().decode(nonce), requestBodyBytes); + final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", Base64.getDecoder().decode(nonce), requestBodyBytes); final com.wultra.security.powerauth.client.v2.VaultUnlockRequest unlockRequest = new com.wultra.security.powerauth.client.v2.VaultUnlockRequest(); unlockRequest.setActivationId(activationId); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java index 5d6f8cf9..c5081a35 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java @@ -19,7 +19,6 @@ */ package io.getlime.security.powerauth.rest.api.spring.service.v3; -import com.google.common.io.BaseEncoding; import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.client.v3.SignatureType; import com.wultra.security.powerauth.client.v3.VaultUnlockRequest; @@ -41,6 +40,7 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import java.util.Base64; /** * Service implementing secure vault functionality. @@ -109,7 +109,7 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, // Prepare data for signature to allow signature verification on PowerAuth server final byte[] requestBodyBytes = authenticationProvider.extractRequestBodyBytes(httpServletRequest); - final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", BaseEncoding.base64().decode(nonce), requestBodyBytes); + final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", Base64.getDecoder().decode(nonce), requestBodyBytes); // Verify signature and get encrypted vault encryption key from PowerAuth server final VaultUnlockRequest unlockRequest = new VaultUnlockRequest(); From 0ebf509385a55b8ac3b4ee3198b2be4651586e67 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Fri, 31 Mar 2023 11:05:00 +0200 Subject: [PATCH 29/64] Fix #388: UserInfoController throws NPE for failed encryption --- lombok.config | 1 + .../api/spring/controller/v3/UserInfoController.java | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 lombok.config diff --git a/lombok.config b/lombok.config new file mode 100644 index 00000000..2bb794fd --- /dev/null +++ b/lombok.config @@ -0,0 +1 @@ +lombok.log.fieldName=logger diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java index b5540cc8..15f0e4e1 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java @@ -24,8 +24,10 @@ import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.service.v3.UserInfoService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -45,6 +47,7 @@ */ @RestController @RequestMapping("/pa/v3/user") +@Slf4j public class UserInfoController { private final UserInfoService userInfoService; @@ -65,10 +68,16 @@ public UserInfoController(UserInfoService userInfoService) { * @param eciesContext PowerAuth ECIES encryption context. * @return Encrypted user info claims. * @throws PowerAuthUserInfoException In case there is an error while fetching claims. + * @throws PowerAuthEncryptionException In case of failed encryption. */ @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) @PostMapping("info") - public Map claims(@EncryptedRequestBody UserInfoRequest request, EciesEncryptionContext eciesContext) throws PowerAuthUserInfoException { + public Map claims(@EncryptedRequestBody UserInfoRequest request, EciesEncryptionContext eciesContext) throws PowerAuthUserInfoException, PowerAuthEncryptionException { + if (eciesContext == null) { + logger.error("Encryption failed"); + throw new PowerAuthEncryptionException("Encryption failed"); + } + return userInfoService.fetchUserClaimsByActivationId( eciesContext.getActivationId() ); From 84c93b265eaca0c7aea642eee8540bf6dd69f05b Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Mon, 3 Apr 2023 16:22:18 +0200 Subject: [PATCH 30/64] Fix #390: Upgrade Spring Boot 3 --- pom.xml | 2 +- .../support/PowerAuthAnnotationInterceptor.java | 4 ++-- .../support/PowerAuthEncryptionArgumentResolver.java | 2 +- .../annotation/support/PowerAuthWebArgumentResolver.java | 2 +- .../entrypoint/PowerAuthApiAuthenticationEntryPoint.java | 4 ++-- .../api/spring/filter/EncryptionResponseBodyAdvice.java | 2 +- .../rest/api/spring/filter/PowerAuthRequestFilter.java | 8 ++++---- .../api/spring/filter/PowerAuthRequestFilterBase.java | 2 +- .../spring/filter/ResettableStreamHttpServletRequest.java | 8 ++++---- .../provider/PowerAuthAuthenticationProviderBase.java | 2 +- .../spring/provider/PowerAuthEncryptionProviderBase.java | 2 +- .../api/spring/controller/v2/SecureVaultController.java | 2 +- .../api/spring/controller/v3/ActivationController.java | 2 +- .../api/spring/controller/v3/SecureVaultController.java | 2 +- .../rest/api/spring/controller/v3/UpgradeController.java | 2 +- .../rest/api/spring/service/v2/SecureVaultService.java | 2 +- .../rest/api/spring/service/v3/SecureVaultService.java | 2 +- .../rest/api/spring/service/v3/UpgradeService.java | 2 +- 18 files changed, 26 insertions(+), 26 deletions(-) diff --git a/pom.xml b/pom.xml index 348a4f3b..2e7c0983 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.5.0 3.2.1 3.3.2 - 2.7.10 + 3.0.5 1.10.0 1.72 1.7.0-SNAPSHOT diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java index f005ed3f..2b00991a 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java @@ -46,8 +46,8 @@ import org.springframework.web.servlet.AsyncHandlerInterceptor; import org.springframework.web.servlet.HandlerMapping; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.lang.reflect.Type; import java.util.Arrays; import java.util.List; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java index 4774c998..5eb1327c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java @@ -36,7 +36,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Type; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthWebArgumentResolver.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthWebArgumentResolver.java index e3b9260c..d3629c67 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthWebArgumentResolver.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthWebArgumentResolver.java @@ -30,7 +30,7 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Argument resolver for {@link PowerAuthApiAuthentication} objects. It enables automatic diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/entrypoint/PowerAuthApiAuthenticationEntryPoint.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/entrypoint/PowerAuthApiAuthenticationEntryPoint.java index 55889a17..4fe3fc97 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/entrypoint/PowerAuthApiAuthenticationEntryPoint.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/entrypoint/PowerAuthApiAuthenticationEntryPoint.java @@ -26,8 +26,8 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index 09f84214..94048cd0 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -46,7 +46,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilter.java index dcb9fb55..1ccea56e 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilter.java @@ -22,10 +22,10 @@ import org.springframework.lang.NonNull; import org.springframework.web.filter.OncePerRequestFilter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java index 58c68d98..82d56c2b 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java @@ -25,7 +25,7 @@ import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/ResettableStreamHttpServletRequest.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/ResettableStreamHttpServletRequest.java index fadc265a..ee6d03d1 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/ResettableStreamHttpServletRequest.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/ResettableStreamHttpServletRequest.java @@ -22,10 +22,10 @@ import com.google.common.io.ByteStreams; import javax.annotation.Nonnull; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; import java.io.*; import java.util.Arrays; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java index c5798279..6b4b0c73 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java @@ -31,7 +31,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index cb2034ef..fc75adf0 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -46,7 +46,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Type; import java.util.Base64; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java index bfd57d36..63106f61 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Controller implementing secure vault related end-points from the diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java index ab6f80a9..27b0f2f4 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java @@ -44,7 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Controller implementing activation related end-points from the PowerAuth diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java index d74593f3..dbf3cf95 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java @@ -34,7 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Controller implementing secure vault related end-points from the diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java index f0938ffd..519229ac 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; /** * Controller responsible for upgrade. diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java index 10a8aac3..681c950f 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java @@ -39,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Base64; /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java index c5081a35..3c695bc3 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java @@ -39,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Base64; /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java index 15aca850..dc6d802b 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java @@ -39,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.List; From 22ca9f6f0f15e2d7787eff4024406c8c2642fbdf Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Mon, 3 Apr 2023 16:26:58 +0200 Subject: [PATCH 31/64] Move CodeQL analysis to JDK 17 --- .github/workflows/codeql-analysis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 35b7856d..f49c1d13 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -42,6 +42,16 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'temurin' + server-id: jfrog-central + server-username: INTERNAL_USERNAME + server-password: INTERNAL_PASSWORD + cache: maven + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 From 0392962af33d1ff48314330fae79e1372c039d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Tue, 4 Apr 2023 12:40:44 +0200 Subject: [PATCH 32/64] Omit server properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: LuboÅĄ RačanskÃŊ --- .github/workflows/codeql-analysis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f49c1d13..226ec4fb 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,9 +47,6 @@ jobs: with: java-version: 17 distribution: 'temurin' - server-id: jfrog-central - server-username: INTERNAL_USERNAME - server-password: INTERNAL_PASSWORD cache: maven # Initializes the CodeQL tools for scanning. From e13dec4fbbacde854903207a7b5c8b4f9c1ad266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Fri, 14 Apr 2023 11:13:25 +0200 Subject: [PATCH 33/64] Fix #392: Remove V2 API support (#393) * Fix #392: Remove V2 API support * Remove v3 package and make it implicit --- .../{v3 => }/ActivationLayer1Request.java | 2 +- .../{v3 => }/ActivationLayer2Request.java | 2 +- .../{v3 => }/ActivationStatusRequest.java | 2 +- .../ConfirmRecoveryRequestPayload.java | 2 +- .../{v3 => }/EciesEncryptedRequest.java | 2 +- .../request/{v2 => }/TokenRemoveRequest.java | 2 +- .../request/{v3 => }/UserInfoRequest.java | 2 +- .../{v3 => }/VaultUnlockRequestPayload.java | 2 +- .../v2/ActivationCreateCustomRequest.java | 85 --------- .../request/v2/ActivationCreateRequest.java | 167 ----------------- .../request/v2/ActivationStatusRequest.java | 48 ----- .../model/request/v2/TokenCreateRequest.java | 46 ----- .../model/request/v2/VaultUnlockRequest.java | 46 ----- .../model/request/v3/TokenRemoveRequest.java | 49 ----- .../{v3 => }/ActivationLayer1Response.java | 2 +- .../{v3 => }/ActivationLayer2Response.java | 2 +- .../{v3 => }/ActivationRemoveResponse.java | 2 +- .../{v3 => }/ActivationStatusResponse.java | 2 +- .../ConfirmRecoveryResponsePayload.java | 2 +- .../{v3 => }/EciesEncryptedResponse.java | 2 +- .../{v3 => }/ServiceStatusResponse.java | 2 +- .../{v2 => }/TokenRemoveResponse.java | 2 +- .../{v3 => }/UpgradeResponsePayload.java | 2 +- .../{v3 => }/VaultUnlockResponsePayload.java | 2 +- .../response/v2/ActivationCreateResponse.java | 135 -------------- .../response/v2/ActivationRemoveResponse.java | 48 ----- .../response/v2/ActivationStatusResponse.java | 84 --------- .../response/v2/TokenCreateResponse.java | 63 ------- .../response/v2/VaultUnlockResponse.java | 65 ------- .../response/v3/TokenRemoveResponse.java | 50 ----- .../{v3 => }/ActivationContextConverter.java | 18 +- .../{v3 => }/ActivationStatusConverter.java | 6 +- .../{v2 => }/SignatureTypeConverter.java | 10 +- .../converter/v3/SignatureTypeConverter.java | 84 --------- .../spring/encryption/EncryptorFactory.java | 105 ----------- .../filter/EncryptionResponseBodyAdvice.java | 2 +- .../PowerAuthAuthenticationProvider.java | 14 +- .../provider/PowerAuthEncryptionProvider.java | 4 +- .../PowerAuthEncryptionProviderBase.java | 4 +- .../{v3 => }/ActivationController.java | 14 +- .../{v3 => }/RecoveryController.java | 8 +- .../{v3 => }/SecureVaultController.java | 8 +- .../{v3 => }/SignatureController.java | 2 +- .../controller/{v3 => }/TokenController.java | 12 +- .../{v3 => }/UpgradeController.java | 8 +- .../{v3 => }/UserInfoController.java | 6 +- .../controller/v2/ActivationController.java | 153 ---------------- .../controller/v2/SecureVaultController.java | 109 ----------- .../controller/v2/SignatureController.java | 78 -------- .../spring/controller/v2/TokenController.java | 143 --------------- .../service/{v3 => }/ActivationService.java | 38 ++-- .../service/{v3 => }/RecoveryService.java | 11 +- .../service/{v3 => }/SecureVaultService.java | 17 +- .../spring/service/{v3 => }/TokenService.java | 21 +-- .../service/{v3 => }/UpgradeService.java | 14 +- .../service/{v3 => }/UserInfoService.java | 6 +- .../spring/service/v2/ActivationService.java | 112 ------------ .../spring/service/v2/SecureVaultService.java | 172 ------------------ .../api/spring/service/v2/TokenService.java | 111 ----------- 59 files changed, 129 insertions(+), 2083 deletions(-) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/ActivationLayer1Request.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/ActivationLayer2Request.java (98%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/ActivationStatusRequest.java (96%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/ConfirmRecoveryRequestPayload.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/EciesEncryptedRequest.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v2 => }/TokenRemoveRequest.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/UserInfoRequest.java (93%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/{v3 => }/VaultUnlockRequestPayload.java (95%) delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateCustomRequest.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateRequest.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationStatusRequest.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenCreateRequest.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/VaultUnlockRequest.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/TokenRemoveRequest.java rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ActivationLayer1Response.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ActivationLayer2Response.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ActivationRemoveResponse.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ActivationStatusResponse.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ConfirmRecoveryResponsePayload.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/EciesEncryptedResponse.java (97%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/ServiceStatusResponse.java (98%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v2 => }/TokenRemoveResponse.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/UpgradeResponsePayload.java (95%) rename powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/{v3 => }/VaultUnlockResponsePayload.java (96%) delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationCreateResponse.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationRemoveResponse.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationStatusResponse.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenCreateResponse.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/VaultUnlockResponse.java delete mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/TokenRemoveResponse.java rename powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/{v3 => }/ActivationContextConverter.java (82%) rename powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/{v3 => }/ActivationStatusConverter.java (91%) rename powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/{v2 => }/SignatureTypeConverter.java (88%) delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/SignatureTypeConverter.java delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptorFactory.java rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/ActivationController.java (93%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/RecoveryController.java (94%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/SecureVaultController.java (94%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/SignatureController.java (99%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/TokenController.java (93%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/UpgradeController.java (95%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/{v3 => }/UserInfoController.java (95%) delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/ActivationController.java delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SignatureController.java delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/TokenController.java rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/ActivationService.java (95%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/RecoveryService.java (91%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/SecureVaultService.java (91%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/TokenService.java (89%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/UpgradeService.java (93%) rename powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/{v3 => }/UserInfoService.java (94%) delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/ActivationService.java delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java delete mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/TokenService.java diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer1Request.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer1Request.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer1Request.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer1Request.java index 892e74ec..057822b3 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer1Request.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer1Request.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer2Request.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer2Request.java similarity index 98% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer2Request.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer2Request.java index 431626cd..efafe64b 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationLayer2Request.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationLayer2Request.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object for activation layer 2 request. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationStatusRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationStatusRequest.java similarity index 96% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationStatusRequest.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationStatusRequest.java index 98875fcb..2004cfb6 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ActivationStatusRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ActivationStatusRequest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object for /pa/v3/activation/status end-point. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ConfirmRecoveryRequestPayload.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ConfirmRecoveryRequestPayload.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ConfirmRecoveryRequestPayload.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ConfirmRecoveryRequestPayload.java index 9bf9b8b9..1258d514 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/ConfirmRecoveryRequestPayload.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/ConfirmRecoveryRequestPayload.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object for confirm recovery code ECIES payload. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/EciesEncryptedRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/EciesEncryptedRequest.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java index 001876d6..fd018f39 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/EciesEncryptedRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object with data encrypted by ECIES encryption. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenRemoveRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/TokenRemoveRequest.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenRemoveRequest.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/TokenRemoveRequest.java index 5e6fbb61..231e828b 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenRemoveRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/TokenRemoveRequest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v2; +package io.getlime.security.powerauth.rest.api.model.request; /** * Class representing request transport object for token removal. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/UserInfoRequest.java similarity index 93% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/UserInfoRequest.java index bda06622..f9fa9b3f 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/UserInfoRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/UserInfoRequest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object for user info endpoint. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/VaultUnlockRequestPayload.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/VaultUnlockRequestPayload.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/VaultUnlockRequestPayload.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/VaultUnlockRequestPayload.java index 3f12a1f8..294f3dbb 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/VaultUnlockRequestPayload.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/VaultUnlockRequestPayload.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.request.v3; +package io.getlime.security.powerauth.rest.api.model.request; /** * Request object for vault unlock ECIES payload. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateCustomRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateCustomRequest.java deleted file mode 100644 index 2d6c278a..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateCustomRequest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v2; - -import java.util.Map; - -/** - * Request object for /pa/activation/direct/create end-point. - * - * Object representing an activation performed with given identity, custom (non-identity related) attributes, and - * PowerAuth activation object. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class ActivationCreateCustomRequest { - - private Map identity; - private Map customAttributes; - private ActivationCreateRequest powerauth; - - /** - * Get identity attributes. - * @return Identity attributes. - */ - public Map getIdentity() { - return identity; - } - - /** - * Set identity attributes. - * @param identity Identity attributes. - */ - public void setIdentity(Map identity) { - this.identity = identity; - } - - /** - * Get custom attributes. - * @return Custom attributes. - */ - public Map getCustomAttributes() { - return customAttributes; - } - - /** - * Set custom attributes. - * @param customAttributes Custom attributes. - */ - public void setCustomAttributes(Map customAttributes) { - this.customAttributes = customAttributes; - } - - /** - * Get PowerAuth activation data. - * @return PowerAuth activation data. - */ - public ActivationCreateRequest getPowerauth() { - return powerauth; - } - - /** - * Set PowerAuth activation data. - * @param powerauth PowerAuth activation data. - */ - public void setPowerauth(ActivationCreateRequest powerauth) { - this.powerauth = powerauth; - } -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateRequest.java deleted file mode 100644 index 71b0027c..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationCreateRequest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v2; - -/** - * Request object for /pa/activation/create end-point. - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class ActivationCreateRequest { - - private String activationIdShort; - private String activationNonce; - private String ephemeralPublicKey; - private String encryptedDevicePublicKey; - private String activationName; - private String extras; - private String applicationKey; - private String applicationSignature; - - /** - * Get activation ID short. - * @return Activation ID short. - */ - public String getActivationIdShort() { - return activationIdShort; - } - - /** - * Set activation ID short. - * @param activationIdShort Activation ID short. - */ - public void setActivationIdShort(String activationIdShort) { - this.activationIdShort = activationIdShort; - } - - /** - * Get activation nonce. - * @return Activation nonce. - */ - public String getActivationNonce() { - return activationNonce; - } - - /** - * Set activation nonce. - * @param activationNonce Activation nonce. - */ - public void setActivationNonce(String activationNonce) { - this.activationNonce = activationNonce; - } - - /** - * Get the ephemeral public key. - * @return Ephemeral public key. - */ - public String getEphemeralPublicKey() { - return ephemeralPublicKey; - } - - /** - * Set the ephemeral public key. - * @param ephemeralPublicKey Ephemeral public key. - */ - public void setEphemeralPublicKey(String ephemeralPublicKey) { - this.ephemeralPublicKey = ephemeralPublicKey; - } - - /** - * Get encrypted device public key. - * @return cDevicePublicKey - */ - public String getEncryptedDevicePublicKey() { - return encryptedDevicePublicKey; - } - - /** - * Set encrypted device public key. - * @param encryptedDevicePublicKey Encrypted device public key. - */ - public void setEncryptedDevicePublicKey(String encryptedDevicePublicKey) { - this.encryptedDevicePublicKey = encryptedDevicePublicKey; - } - - /** - * Get activation name. - * @return Activation name. - */ - public String getActivationName() { - return activationName; - } - - /** - * Set activation name. - * @param activationName Activation name. - */ - public void setActivationName(String activationName) { - this.activationName = activationName; - } - - /** - * Get extra parameter. - * @return Extra parameter. - */ - public String getExtras() { - return extras; - } - - /** - * Set extra parameter. - * @param extras Extra parameter. - */ - public void setExtras(String extras) { - this.extras = extras; - } - - /** - * Get application key. - * @return Application key. - */ - public String getApplicationKey() { - return applicationKey; - } - - /** - * Set application key. - * @param applicationKey Application key. - */ - public void setApplicationKey(String applicationKey) { - this.applicationKey = applicationKey; - } - - /** - * Get application signature. - * @return Application signature. - */ - public String getApplicationSignature() { - return applicationSignature; - } - - /** - * Set application signature. - * @param applicationSignature Application signature. - */ - public void setApplicationSignature(String applicationSignature) { - this.applicationSignature = applicationSignature; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationStatusRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationStatusRequest.java deleted file mode 100644 index eb3d10e0..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/ActivationStatusRequest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v2; - -/** - * Request object for /pa/activation/status end-point - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class ActivationStatusRequest { - - private String activationId; - - /** - * Get activation ID - * @return Activation ID - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID - * @param activationId Activation ID - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenCreateRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenCreateRequest.java deleted file mode 100644 index 48ec75ad..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/TokenCreateRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v2; - -/** - * Request object for the /pa/token endpoint, that enables fetching token for simple authentication. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class TokenCreateRequest { - - private String ephemeralPublicKey; - - /** - * Get ephemeral public key (Base64 encoded data). - * @return Ephemeral public key. - */ - public String getEphemeralPublicKey() { - return ephemeralPublicKey; - } - - /** - * Set ephemeral public key (Base64 encoded data). - * @param ephemeralPublicKey Ephemeral public key. - */ - public void setEphemeralPublicKey(String ephemeralPublicKey) { - this.ephemeralPublicKey = ephemeralPublicKey; - } -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/VaultUnlockRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/VaultUnlockRequest.java deleted file mode 100644 index 395c71e1..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v2/VaultUnlockRequest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v2; - -/** - * Request object for /pa/vault/unlock end-point used for unlocking the vault. - * - * @author Roman Strobl, roman.strobl@wultra.com - */ -public class VaultUnlockRequest { - - private String reason; - - /** - * Get reason why vault is being unlocked. - * @return Reason why vault is being unlocked. - */ - public String getReason() { - return reason; - } - - /** - * Set reason why vault is being unlocked. - * @param reason Reason why vault is being unlocked. - */ - public void setReason(String reason) { - this.reason = reason; - } -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/TokenRemoveRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/TokenRemoveRequest.java deleted file mode 100644 index c88dde3a..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/v3/TokenRemoveRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.request.v3; - -/** - * Class representing request transport object for token removal. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class TokenRemoveRequest { - - /** - * Token ID of the token to be removed. - */ - private String tokenId; - - /** - * Get token ID. - * @return Token ID. - */ - public String getTokenId() { - return tokenId; - } - - /** - * Set token ID. - * @param tokenId Token ID. - */ - public void setTokenId(String tokenId) { - this.tokenId = tokenId; - } -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer1Response.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer1Response.java index e9d3c6e9..5d9b764a 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer1Response.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer1Response.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; import java.util.Map; diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer2Response.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer2Response.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer2Response.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer2Response.java index 9254d071..43e54ffe 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationLayer2Response.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationLayer2Response.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; import io.getlime.security.powerauth.rest.api.model.entity.ActivationRecovery; diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationRemoveResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationRemoveResponse.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationRemoveResponse.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationRemoveResponse.java index af772b7c..0be0bd33 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationRemoveResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationRemoveResponse.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; /** * Response object for /pa/v3/activation/remove end-point. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationStatusResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationStatusResponse.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationStatusResponse.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationStatusResponse.java index b419ef10..2bfee56d 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ActivationStatusResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ActivationStatusResponse.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; import java.util.Map; diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ConfirmRecoveryResponsePayload.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ConfirmRecoveryResponsePayload.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ConfirmRecoveryResponsePayload.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ConfirmRecoveryResponsePayload.java index d885a5cc..41f1e8ed 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ConfirmRecoveryResponsePayload.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ConfirmRecoveryResponsePayload.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; /** * Response object for confirm recovery code ECIES payload. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/EciesEncryptedResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java similarity index 97% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/EciesEncryptedResponse.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java index 8692c29e..acd5517f 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/EciesEncryptedResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; /** * Response object for endpoints returning data encrypted by ECIES. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ServiceStatusResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServiceStatusResponse.java similarity index 98% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ServiceStatusResponse.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServiceStatusResponse.java index 985cba68..ece1596e 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/ServiceStatusResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServiceStatusResponse.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; import java.util.Date; diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenRemoveResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/TokenRemoveResponse.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenRemoveResponse.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/TokenRemoveResponse.java index db97b78b..a2faa8e0 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenRemoveResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/TokenRemoveResponse.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v2; +package io.getlime.security.powerauth.rest.api.model.response; /** * Class representing response transport object for token removal. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/UpgradeResponsePayload.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/UpgradeResponsePayload.java similarity index 95% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/UpgradeResponsePayload.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/UpgradeResponsePayload.java index 94424f3a..bd367b5d 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/UpgradeResponsePayload.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/UpgradeResponsePayload.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; /** * Response object for upgrade payload. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/VaultUnlockResponsePayload.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/VaultUnlockResponsePayload.java similarity index 96% rename from powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/VaultUnlockResponsePayload.java rename to powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/VaultUnlockResponsePayload.java index c7705dbc..a222f4bb 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/VaultUnlockResponsePayload.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/VaultUnlockResponsePayload.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.model.response.v3; +package io.getlime.security.powerauth.rest.api.model.response; /** * Response object for vault unlock payload. diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationCreateResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationCreateResponse.java deleted file mode 100644 index 6930649e..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationCreateResponse.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v2; - -import java.util.Map; - -/** - * Response object for /pa/activation/create end-point. - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class ActivationCreateResponse { - - private String activationId; - private String activationNonce; - private String ephemeralPublicKey; - private String encryptedServerPublicKey; - private String encryptedServerPublicKeySignature; - private Map customAttributes; - - /** - * Get activation ID - * @return Activation ID - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID - * @param activationId Activation ID - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - - /** - * Get activation nonce. - * @return Activation nonce. - */ - public String getActivationNonce() { - return activationNonce; - } - - /** - * Set activation nonce. - * @param activationNonce Activation nonce. - */ - public void setActivationNonce(String activationNonce) { - this.activationNonce = activationNonce; - } - - /** - * Get ephemeral public key. - * @return Ephemeral public key. - */ - public String getEphemeralPublicKey() { - return ephemeralPublicKey; - } - - /** - * Set ephemeral public key. - * @param ephemeralPublicKey Ephemeral public key. - */ - public void setEphemeralPublicKey(String ephemeralPublicKey) { - this.ephemeralPublicKey = ephemeralPublicKey; - } - - /** - * Get encrypted server public key. - * @return Encrypted server public key. - */ - public String getEncryptedServerPublicKey() { - return encryptedServerPublicKey; - } - - /** - * Set encrypted server public key. - * @param encryptedServerPublicKey Encrypted server public key. - */ - public void setEncryptedServerPublicKey(String encryptedServerPublicKey) { - this.encryptedServerPublicKey = encryptedServerPublicKey; - } - - /** - * Get server data signature. - * @return Server data signature. - */ - public String getEncryptedServerPublicKeySignature() { - return encryptedServerPublicKeySignature; - } - - /** - * Set server data signature. - * @param encryptedServerPublicKeySignature Server data signature. - */ - public void setEncryptedServerPublicKeySignature(String encryptedServerPublicKeySignature) { - this.encryptedServerPublicKeySignature = encryptedServerPublicKeySignature; - } - - /** - * Custom attributes for the response. - * @return Custom response attributes. - */ - public Map getCustomAttributes() { - return customAttributes; - } - - /** - * Custom attributes for the response. - * @param customAttributes Custom response attributes. - */ - public void setCustomAttributes(Map customAttributes) { - this.customAttributes = customAttributes; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationRemoveResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationRemoveResponse.java deleted file mode 100644 index 18535673..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationRemoveResponse.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v2; - -/** - * Response object for /pa/activation/remove end-point - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class ActivationRemoveResponse { - - private String activationId; - - /** - * Get activation ID - * @return Activation ID - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID - * @param activationId Activation ID - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationStatusResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationStatusResponse.java deleted file mode 100644 index d165efeb..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/ActivationStatusResponse.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v2; - -import java.util.Map; - -/** - * Response object for /pa/activation/status end-point - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class ActivationStatusResponse { - - private String activationId; - private String encryptedStatusBlob; - private Map customObject; - - /** - * Get activation ID - * @return Activation ID - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID - * @param activationId Activation ID - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - - /** - * Get encrypted activation status blob - * @return Encrypted activation status blob - */ - public String getEncryptedStatusBlob() { - return encryptedStatusBlob; - } - - /** - * Set encrypted activation status blob - * @param cStatusBlob encrypted activation status blob - */ - public void setEncryptedStatusBlob(String cStatusBlob) { - this.encryptedStatusBlob = cStatusBlob; - } - - /** - * Get custom associated object. - * @return Custom associated object - */ - public Map getCustomObject() { - return customObject; - } - - /** - * Set custom associated object - * @param customObject Custom associated object - */ - public void setCustomObject(Map customObject) { - this.customObject = customObject; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenCreateResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenCreateResponse.java deleted file mode 100644 index af8002ad..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/TokenCreateResponse.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v2; - -/** - * Response object for the /pa/token endpoint, that enables fetching token for simple authentication. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class TokenCreateResponse { - - private String mac; - private String encryptedData; - - /** - * Get MAC signature of the request. - * @return MAC of the request. - */ - public String getMac() { - return mac; - } - - /** - * Set MAC signature of the request. - * @param mac MAC of the request. - */ - public void setMac(String mac) { - this.mac = mac; - } - - /** - * Get encrypted data payload. - * @return Encrypted data. - */ - public String getEncryptedData() { - return encryptedData; - } - - /** - * Set encrypted data payload. - * @param encryptedData Encrypted data. - */ - public void setEncryptedData(String encryptedData) { - this.encryptedData = encryptedData; - } -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/VaultUnlockResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/VaultUnlockResponse.java deleted file mode 100644 index 55c53a95..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v2/VaultUnlockResponse.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v2; - -/** - * Response object for /pa/vault/unlock end-point. - * - * @author Petr Dvorak, petr@wultra.com - * - */ -public class VaultUnlockResponse { - - private String activationId; - private String encryptedVaultEncryptionKey; - - /** - * Get activation ID - * @return Activation ID - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID - * @param activationId Activation ID - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - - /** - * Get encrypted vault encryption key (using a key derived from the master transport key). - * @return Encrypted vault encryption key. - */ - public String getEncryptedVaultEncryptionKey() { - return encryptedVaultEncryptionKey; - } - - /** - * Set encrypted vault encryption key (using a key derived from the master transport key). - * @param encryptedVaultEncryptionKey Encrypted vault encryption key. - */ - public void setEncryptedVaultEncryptionKey(String encryptedVaultEncryptionKey) { - this.encryptedVaultEncryptionKey = encryptedVaultEncryptionKey; - } - -} diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/TokenRemoveResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/TokenRemoveResponse.java deleted file mode 100644 index 5d30fb68..00000000 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/v3/TokenRemoveResponse.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.model.response.v3; - -/** - * Class representing response transport object for token removal. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class TokenRemoveResponse { - - /** - * Token ID of the token to be removed. - */ - private String tokenId; - - /** - * Get token ID. - * @return Token ID. - */ - public String getTokenId() { - return tokenId; - } - - /** - * Set token ID. - * @param tokenId Token ID. - */ - public void setTokenId(String tokenId) { - this.tokenId = tokenId; - } - -} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationContextConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationContextConverter.java similarity index 82% rename from powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationContextConverter.java rename to powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationContextConverter.java index c140f9eb..bc6a6f5f 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationContextConverter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationContextConverter.java @@ -17,13 +17,13 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.converter.v3; +package io.getlime.security.powerauth.rest.api.spring.converter; -import com.wultra.security.powerauth.client.v3.GetActivationStatusResponse; +import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; import io.getlime.security.powerauth.rest.api.spring.model.ActivationContext; import org.springframework.stereotype.Component; -import javax.xml.datatype.XMLGregorianCalendar; +import java.util.Date; import java.util.List; /** @@ -66,17 +66,17 @@ public ActivationContext fromActivationDetailResponse(GetActivationStatusRespons if (activationFlags != null) { destination.getActivationFlags().addAll(activationFlags); } - final XMLGregorianCalendar timestampCreated = source.getTimestampCreated(); + final Date timestampCreated = source.getTimestampCreated(); if (timestampCreated != null) { - destination.setTimestampCreated(timestampCreated.toGregorianCalendar().toInstant()); + destination.setTimestampCreated(timestampCreated.toInstant()); } - final XMLGregorianCalendar timestampLastUsed = source.getTimestampLastUsed(); + final Date timestampLastUsed = source.getTimestampLastUsed(); if (timestampLastUsed != null) { - destination.setTimestampLastUsed(timestampLastUsed.toGregorianCalendar().toInstant()); + destination.setTimestampLastUsed(timestampLastUsed.toInstant()); } - final XMLGregorianCalendar timestampLastChange = source.getTimestampLastChange(); + final Date timestampLastChange = source.getTimestampLastChange(); if (timestampLastChange != null) { - destination.setTimestampLastChange(timestampLastChange.toGregorianCalendar().toInstant()); + destination.setTimestampLastChange(timestampLastChange.toInstant()); } return destination; } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationStatusConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java similarity index 91% rename from powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationStatusConverter.java rename to powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java index dd974ff0..5d87704b 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/ActivationStatusConverter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.converter.v3; +package io.getlime.security.powerauth.rest.api.spring.converter; import io.getlime.security.powerauth.rest.api.spring.model.ActivationStatus; import org.slf4j.Logger; @@ -35,11 +35,11 @@ public class ActivationStatusConverter { private static final Logger logger = LoggerFactory.getLogger(ActivationStatusConverter.class); /** - * Convert {@link ActivationStatus} from a {@link com.wultra.security.powerauth.client.v3.ActivationStatus} value. + * Convert {@link ActivationStatus} from a {@link com.wultra.security.powerauth.client.model.enumeration.ActivationStatus} value. * @param activationStatus Activation status from PowerAuth client model. * @return Activation status from Restful integration model. */ - public ActivationStatus convertFrom(com.wultra.security.powerauth.client.v3.ActivationStatus activationStatus) { + public ActivationStatus convertFrom(com.wultra.security.powerauth.client.model.enumeration.ActivationStatus activationStatus) { if (activationStatus == null) { return null; } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v2/SignatureTypeConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java similarity index 88% rename from powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v2/SignatureTypeConverter.java rename to powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java index 93149a46..f47a0f06 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v2/SignatureTypeConverter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java @@ -17,16 +17,16 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.converter.v2; +package io.getlime.security.powerauth.rest.api.spring.converter; -import com.wultra.security.powerauth.client.v2.SignatureType; +import com.wultra.security.powerauth.client.model.enumeration.SignatureType; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Helper class to convert from and to - * {@link com.wultra.security.powerauth.client.v2.SignatureType} class. + * {@link SignatureType} class. * * @author Petr Dvorak, petr@wultra.com */ @@ -35,7 +35,7 @@ public class SignatureTypeConverter { private static final Logger logger = LoggerFactory.getLogger(SignatureTypeConverter.class); /** - * Convert {@link com.wultra.security.powerauth.client.v2.SignatureType} + * Convert {@link SignatureType} * from a {@link String} value. * @param signatureTypeString String value representing signature type. * @return Signature type. @@ -49,7 +49,7 @@ public SignatureType convertFrom(String signatureTypeString) { // Try to convert signature type try { signatureTypeString = signatureTypeString.toUpperCase(); - return SignatureType.fromValue(signatureTypeString); + return SignatureType.enumFromString(signatureTypeString); } catch (IllegalArgumentException ex) { logger.warn("Invalid signature type, error: {}", ex.getMessage()); logger.debug("Error details", ex); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/SignatureTypeConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/SignatureTypeConverter.java deleted file mode 100644 index 6f6fde32..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/v3/SignatureTypeConverter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.converter.v3; - -import com.wultra.security.powerauth.client.v3.SignatureType; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Helper class to convert from and to - * {@link com.wultra.security.powerauth.client.v3.SignatureType} class. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class SignatureTypeConverter { - - private static final Logger logger = LoggerFactory.getLogger(SignatureTypeConverter.class); - - /** - * Convert {@link com.wultra.security.powerauth.client.v3.SignatureType} - * from a {@link String} value. - * @param signatureTypeString String value representing signature type. - * @return Signature type. - */ - public SignatureType convertFrom(String signatureTypeString) { - - if (signatureTypeString == null) { - return null; - } - - // Try to convert signature type - try { - signatureTypeString = signatureTypeString.toUpperCase(); - return SignatureType.fromValue(signatureTypeString); - } catch (IllegalArgumentException ex) { - logger.warn("Invalid signature type, error: {}", ex.getMessage()); - logger.debug("Error details", ex); - // Return null value which represents an unknown signature type - return null; - } - - } - - /** - * Convert {@link com.wultra.security.powerauth.client.v3.SignatureType} from {@link PowerAuthSignatureTypes}. - * @param powerAuthSignatureTypes Signature type from crypto representation. - * @return Signature type. - */ - public SignatureType convertFrom(PowerAuthSignatureTypes powerAuthSignatureTypes) { - switch (powerAuthSignatureTypes) { - case POSSESSION: - return SignatureType.POSSESSION; - case KNOWLEDGE: - return SignatureType.KNOWLEDGE; - case BIOMETRY: - return SignatureType.BIOMETRY; - case POSSESSION_KNOWLEDGE: - return SignatureType.POSSESSION_KNOWLEDGE; - case POSSESSION_BIOMETRY: - return SignatureType.POSSESSION_BIOMETRY; - default: - return null; - } - } - -} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptorFactory.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptorFactory.java deleted file mode 100644 index 30c0386d..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptorFactory.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.encryption; - -import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; -import com.wultra.security.powerauth.client.v2.GetNonPersonalizedEncryptionKeyRequest; -import com.wultra.security.powerauth.client.v2.GetNonPersonalizedEncryptionKeyResponse; -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.security.powerauth.rest.api.model.entity.NonPersonalizedEncryptedPayloadModel; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Class responsible for building encryptors. - * - * @author Petr Dvorak, petr@wultra.com - */ -@Component -public class EncryptorFactory { - - private static final Logger logger = LoggerFactory.getLogger(EncryptorFactory.class); - - private final PowerAuthClient powerAuthClient; - private final HttpCustomizationService httpCustomizationService; - - /** - * Factory constructor. - * @param powerAuthClient PowerAuth client. - * @param httpCustomizationService HTTP customization service. - */ - @Autowired - public EncryptorFactory(PowerAuthClient powerAuthClient, HttpCustomizationService httpCustomizationService) { - this.powerAuthClient = powerAuthClient; - this.httpCustomizationService = httpCustomizationService; - } - - /** - * Return a new instance of a non-personalized encryptor. - * @param object Request object to be used to initialize a new encryptor. - * @return New instance of a non-personalized encryptor. - * @throws PowerAuthEncryptionException Thrown in case encryptor could not be built. - */ - public PowerAuthNonPersonalizedEncryptor buildNonPersonalizedEncryptor(ObjectRequest object) throws PowerAuthEncryptionException { - return this.buildNonPersonalizedEncryptor( - object.getRequestObject().getApplicationKey(), - object.getRequestObject().getSessionIndex(), - object.getRequestObject().getEphemeralPublicKey() - ); - } - - /** - * Return a new instance of a non-personalized encryptor. - * @param applicationKeyBase64 Application key associated with an application master key used for encryption. - * @param sessionIndexBase64 Session index. - * @param ephemeralPublicKeyBase64 Ephemeral public key. - * @return New instance of a non-personalized encryptor. - * @throws PowerAuthEncryptionException Thrown in case encryptor could not be built. - */ - public PowerAuthNonPersonalizedEncryptor buildNonPersonalizedEncryptor(String applicationKeyBase64, String sessionIndexBase64, String ephemeralPublicKeyBase64) throws PowerAuthEncryptionException { - try { - final GetNonPersonalizedEncryptionKeyRequest encryptRequest = new GetNonPersonalizedEncryptionKeyRequest(); - encryptRequest.setApplicationKey(applicationKeyBase64); - encryptRequest.setEphemeralPublicKey(ephemeralPublicKeyBase64); - encryptRequest.setSessionIndex(sessionIndexBase64); - final GetNonPersonalizedEncryptionKeyResponse encryptionKeyResponse = powerAuthClient.v2().generateNonPersonalizedE2EEncryptionKey( - encryptRequest, - httpCustomizationService.getQueryParams(), - httpCustomizationService.getHttpHeaders() - ); - - return new PowerAuthNonPersonalizedEncryptor( - encryptionKeyResponse.getApplicationKey(), - encryptionKeyResponse.getEncryptionKey(), encryptionKeyResponse.getEncryptionKeyIndex(), - encryptionKeyResponse.getEphemeralPublicKey() - ); - } catch (PowerAuthClientException ex) { - logger.warn("Encryption failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthEncryptionException(); - } - } - -} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index 94048cd0..edd7ea71 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -22,7 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java index bdd0045e..13db7f98 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java @@ -20,8 +20,12 @@ package io.getlime.security.powerauth.rest.api.spring.provider; import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.SignatureType; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; -import com.wultra.security.powerauth.client.v3.*; +import com.wultra.security.powerauth.client.model.request.ValidateTokenRequest; +import com.wultra.security.powerauth.client.model.request.VerifySignatureRequest; +import com.wultra.security.powerauth.client.model.response.ValidateTokenResponse; +import com.wultra.security.powerauth.client.model.response.VerifySignatureResponse; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.http.PowerAuthHttpBody; import io.getlime.security.powerauth.http.PowerAuthHttpHeader; @@ -36,8 +40,8 @@ import io.getlime.security.powerauth.rest.api.spring.authentication.impl.PowerAuthApiAuthenticationImpl; import io.getlime.security.powerauth.rest.api.spring.authentication.impl.PowerAuthSignatureAuthenticationImpl; import io.getlime.security.powerauth.rest.api.spring.authentication.impl.PowerAuthTokenAuthenticationImpl; -import io.getlime.security.powerauth.rest.api.spring.converter.v3.ActivationStatusConverter; -import io.getlime.security.powerauth.rest.api.spring.converter.v3.SignatureTypeConverter; +import io.getlime.security.powerauth.rest.api.spring.converter.ActivationStatusConverter; +import io.getlime.security.powerauth.rest.api.spring.converter.SignatureTypeConverter; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthHeaderMissingException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; @@ -157,7 +161,7 @@ private PowerAuthApiAuthenticationImpl validateSignatureAuthentication(PowerAuth final AuthenticationContext authenticationContext = new AuthenticationContext(); authenticationContext.setValid(response.isSignatureValid()); authenticationContext.setRemainingAttempts(response.getRemainingAttempts() != null ? response.getRemainingAttempts().intValue() : null); - authenticationContext.setSignatureType(response.getSignatureType() != null ? PowerAuthSignatureTypes.getEnumFromString(response.getSignatureType().value()) : null); + authenticationContext.setSignatureType(response.getSignatureType() != null ? PowerAuthSignatureTypes.getEnumFromString(response.getSignatureType().name()) : null); final PowerAuthActivation activationContext = copyActivationAttributes(response.getActivationId(), response.getUserId(), activationStatus, response.getBlockedReason(), response.getActivationFlags(), authenticationContext, authentication.getVersion()); @@ -194,7 +198,7 @@ private PowerAuthApiAuthenticationImpl validateTokenAuthentication(PowerAuthToke final AuthenticationContext authenticationContext = new AuthenticationContext(); authenticationContext.setValid(response.isTokenValid()); authenticationContext.setRemainingAttempts(null); - authenticationContext.setSignatureType(response.getSignatureType() != null ? PowerAuthSignatureTypes.getEnumFromString(response.getSignatureType().value()) : null); + authenticationContext.setSignatureType(response.getSignatureType() != null ? PowerAuthSignatureTypes.getEnumFromString(response.getSignatureType().name()) : null); final PowerAuthActivation activationContext = copyActivationAttributes(response.getActivationId(), response.getUserId(), activationStatus, response.getBlockedReason(), response.getActivationFlags(), authenticationContext, authentication.getVersion()); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java index 8451c560..2b186eed 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java @@ -20,8 +20,8 @@ package io.getlime.security.powerauth.rest.api.spring.provider; import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v3.GetEciesDecryptorRequest; -import com.wultra.security.powerauth.client.v3.GetEciesDecryptorResponse; +import com.wultra.security.powerauth.client.model.request.GetEciesDecryptorRequest; +import com.wultra.security.powerauth.client.model.response.GetEciesDecryptorResponse; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesDecryptorParameters; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index fc75adf0..f076b4bc 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -33,8 +33,8 @@ import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; import io.getlime.security.powerauth.http.validator.PowerAuthEncryptionHttpHeaderValidator; import io.getlime.security.powerauth.http.validator.PowerAuthSignatureHttpHeaderValidator; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesDecryptorParameters; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java similarity index 93% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java index 27b0f2f4..12998c79 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/ActivationController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.ObjectResponse; @@ -30,15 +30,15 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationStatusRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationLayer1Response; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationRemoveResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationStatusResponse; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.ActivationStatusRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer1Response; +import io.getlime.security.powerauth.rest.api.model.response.ActivationRemoveResponse; +import io.getlime.security.powerauth.rest.api.model.response.ActivationStatusResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; -import io.getlime.security.powerauth.rest.api.spring.service.v3.ActivationService; +import io.getlime.security.powerauth.rest.api.spring.service.ActivationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/RecoveryController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java similarity index 94% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/RecoveryController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java index b4794e98..56f4dcc2 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/RecoveryController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java @@ -17,17 +17,17 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; -import io.getlime.security.powerauth.rest.api.spring.service.v3.RecoveryService; +import io.getlime.security.powerauth.rest.api.spring.service.RecoveryService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestBody; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java similarity index 94% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java index dbf3cf95..53e8b971 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; @@ -26,9 +26,9 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthSecureVaultException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.spring.service.v3.SecureVaultService; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.service.SecureVaultService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SignatureController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java similarity index 99% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SignatureController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java index 242cc9d8..fceed76f 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/SignatureController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.core.rest.model.base.response.Response; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/TokenController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java similarity index 93% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/TokenController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java index 48f3d8e7..47f16bd1 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/TokenController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.core.rest.model.base.request.ObjectRequest; import io.getlime.core.rest.model.base.response.ObjectResponse; @@ -26,12 +26,12 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.request.v3.TokenRemoveRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.TokenRemoveResponse; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.request.TokenRemoveRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.TokenRemoveResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; -import io.getlime.security.powerauth.rest.api.spring.service.v3.TokenService; +import io.getlime.security.powerauth.rest.api.spring.service.TokenService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java similarity index 95% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java index 519229ac..dfb856ae 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.core.rest.model.base.response.Response; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; @@ -28,9 +28,9 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUpgradeException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.spring.service.v3.UpgradeService; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.service.UpgradeService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java similarity index 95% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java index 15f0e4e1..00b22ade 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v3/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java @@ -17,16 +17,16 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.controller.v3; +package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.rest.api.model.request.v3.UserInfoRequest; +import io.getlime.security.powerauth.rest.api.model.request.UserInfoRequest; import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; -import io.getlime.security.powerauth.rest.api.spring.service.v3.UserInfoService; +import io.getlime.security.powerauth.rest.api.spring.service.UserInfoService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/ActivationController.java deleted file mode 100644 index 145335b0..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/ActivationController.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.controller.v2; - -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationCreateRequest; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationStatusRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationCreateResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationRemoveResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationStatusResponse; -import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -/** - * Controller implementing activation related end-points from the PowerAuth - * Standard API. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Petr Dvorak, petr@wultra.com - * - */ -@RestController("activationControllerV2") -@RequestMapping(value = "/pa/activation") -public class ActivationController { - - private static final Logger logger = LoggerFactory.getLogger(ActivationController.class); - - private io.getlime.security.powerauth.rest.api.spring.service.v2.ActivationService activationServiceV2; - private io.getlime.security.powerauth.rest.api.spring.service.v3.ActivationService activationServiceV3; - - private PowerAuthAuthenticationProvider authenticationProvider; - - /** - * Set the activation service via setter injection. - * @param activationServiceV2 Activation service (v2). - */ - @Autowired - public void setActivationServiceV2(io.getlime.security.powerauth.rest.api.spring.service.v2.ActivationService activationServiceV2) { - this.activationServiceV2 = activationServiceV2; - } - - /** - * Set the activation service via setter injection. - * @param activationServiceV3 Activation service (v3). - */ - @Autowired - public void setActivationServiceV3(io.getlime.security.powerauth.rest.api.spring.service.v3.ActivationService activationServiceV3) { - this.activationServiceV3 = activationServiceV3; - } - - /** - * Set the authentication provider via setter injection. - * @param authenticationProvider Authentication provider. - */ - @Autowired - public void setAuthenticationProvider(PowerAuthAuthenticationProvider authenticationProvider) { - this.authenticationProvider = authenticationProvider; - } - - /** - * Create a new activation. - * @param request PowerAuth RESTful request with {@link ActivationCreateRequest} payload. - * @return PowerAuth RESTful response with {@link ActivationCreateResponse} payload. - * @throws PowerAuthActivationException In case creating activation fails. - */ - @RequestMapping(value = "create", method = RequestMethod.POST) - public ObjectResponse createActivation( - @RequestBody ObjectRequest request - ) throws PowerAuthActivationException { - if (request.getRequestObject() == null || request.getRequestObject().getActivationIdShort() == null) { - logger.warn("Invalid request object in activation create"); - throw new PowerAuthActivationException(); - } - ActivationCreateResponse response = activationServiceV2.createActivation(request.getRequestObject()); - return new ObjectResponse<>(response); - } - - /** - * Get activation status. - * @param request PowerAuth RESTful request with {@link ActivationStatusRequest} payload. - * @return PowerAuth RESTful response with {@link ActivationStatusResponse} payload. - * @throws PowerAuthActivationException In case request fails. - */ - @RequestMapping(value = "status", method = RequestMethod.POST) - public ObjectResponse getActivationStatus( - @RequestBody ObjectRequest request - ) throws PowerAuthActivationException { - if (request.getRequestObject() == null || request.getRequestObject().getActivationId() == null) { - logger.warn("Invalid request object in activation status"); - throw new PowerAuthActivationException(); - } - ActivationStatusResponse response = activationServiceV3.getActivationStatus(request.getRequestObject()); - return new ObjectResponse<>(response); - } - - /** - * Remove activation. - * @param signatureHeader PowerAuth signature HTTP header. - * @return PowerAuth RESTful response with {@link ActivationRemoveResponse} payload. - * @throws PowerAuthActivationException In case activation access fails. - * @throws PowerAuthAuthenticationException In case the signature validation fails. - */ - @RequestMapping(value = "remove", method = RequestMethod.POST) - public ObjectResponse removeActivation( - @RequestHeader(value = PowerAuthSignatureHttpHeader.HEADER_NAME) String signatureHeader - ) throws PowerAuthActivationException, PowerAuthAuthenticationException { - // Request body needs to be set to null because the SDK uses null for the signature, although {} is sent as request body - PowerAuthApiAuthentication apiAuthentication = authenticationProvider.validateRequestSignature("POST", null, "/pa/activation/remove", signatureHeader); - if (apiAuthentication == null || apiAuthentication.getActivationContext().getActivationId() == null) { - logger.debug("Signature validation failed"); - throw new PowerAuthSignatureInvalidException(); - } - if (!"2.0".equals(apiAuthentication.getVersion()) && !"2.1".equals(apiAuthentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", apiAuthentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - ActivationRemoveResponse response = activationServiceV3.removeActivation(apiAuthentication); - return new ObjectResponse<>(response); - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java deleted file mode 100644 index 63106f61..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SecureVaultController.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.controller.v2; - -import io.getlime.core.rest.model.base.request.ObjectRequest; -import io.getlime.core.rest.model.base.response.ObjectResponse; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; -import io.getlime.security.powerauth.http.validator.PowerAuthSignatureHttpHeaderValidator; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthSecureVaultException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v2.VaultUnlockRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.VaultUnlockResponse; -import io.getlime.security.powerauth.rest.api.spring.service.v2.SecureVaultService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import jakarta.servlet.http.HttpServletRequest; - -/** - * Controller implementing secure vault related end-points from the - * PowerAuth Standard API. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Petr Dvorak, petr@wultra.com - */ -@RestController("secureVaultControllerV2") -@RequestMapping(value = "/pa/vault") -public class SecureVaultController { - - private static final Logger logger = LoggerFactory.getLogger(SecureVaultController.class); - - private SecureVaultService secureVaultServiceV2; - - /** - * Set the secure vault service via setter injection. - * @param secureVaultServiceV2 Secure vault service. - */ - @Autowired - public void setSecureVaultServiceV2(SecureVaultService secureVaultServiceV2) { - this.secureVaultServiceV2 = secureVaultServiceV2; - } - - /** - * Request the vault unlock key. - * @param signatureHeader PowerAuth signature HTTP header. - * @param request Vault unlock request data. - * @param httpServletRequest HTTP servlet request. - * @return PowerAuth RESTful response with {@link VaultUnlockResponse} payload. - * @throws PowerAuthAuthenticationException In case authentication fails. - * @throws PowerAuthSecureVaultException In case unlocking the vault fails. - */ - @RequestMapping(value = "unlock", method = RequestMethod.POST) - public ObjectResponse unlockVault( - @RequestHeader(value = PowerAuthSignatureHttpHeader.HEADER_NAME, defaultValue = "unknown") String signatureHeader, - @RequestBody(required=false) ObjectRequest request, - HttpServletRequest httpServletRequest) - throws PowerAuthAuthenticationException, PowerAuthSecureVaultException { - - // Request object is not validated - it is optional for version 2 - - // Parse the header - PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader().fromValue(signatureHeader); - - // Validate the header - try { - PowerAuthSignatureHttpHeaderValidator.validate(header); - } catch (InvalidPowerAuthHttpHeaderException ex) { - logger.warn("Signature HTTP header validation failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthSignatureInvalidException(); - } - - if (!"2.0".equals(header.getVersion()) && !"2.1".equals(header.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - - VaultUnlockResponse response = secureVaultServiceV2.vaultUnlock(signatureHeader, request.getRequestObject(), httpServletRequest); - return new ObjectResponse<>(response); - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SignatureController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SignatureController.java deleted file mode 100644 index 751b6166..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/SignatureController.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.controller.v2; - -import io.getlime.core.rest.model.base.response.Response; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; -import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -/** - * End-point for validating signatures. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Roman Strobl, roman.strobl@wultra.com - * - */ -@RestController("signatureControllerV2") -@RequestMapping(value = "/pa/signature") -public class SignatureController { - - private static final Logger logger = LoggerFactory.getLogger(SignatureController.class); - - /** - * Validate signature by validating any data sent in request to this end-point. - * @param auth Automatically injected PowerAuth authentication object. - * @return API response with success. - * @throws PowerAuthAuthenticationException In case any error occurs, including signature validation errors. - */ - @RequestMapping(value = "validate", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}) - @PowerAuth(resourceId = "/pa/signature/validate", signatureType = { - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, - PowerAuthSignatureTypes.POSSESSION_BIOMETRY, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY - }) - public Response validateSignature(PowerAuthApiAuthentication auth) throws PowerAuthAuthenticationException { - - if (auth == null || auth.getActivationContext().getActivationId() == null) { - logger.debug("Signature validation failed"); - throw new PowerAuthSignatureInvalidException(); - } - if (!"2.0".equals(auth.getVersion()) && !"2.1".equals(auth.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", auth.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - return new Response(); - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/TokenController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/TokenController.java deleted file mode 100644 index 837be333..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/v2/TokenController.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.controller.v2; - -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.enums.PowerAuthSignatureTypes; -import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v2.TokenCreateRequest; -import io.getlime.security.powerauth.rest.api.model.request.v3.TokenRemoveRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.TokenCreateResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.TokenRemoveResponse; -import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -/** - * Controller responsible for publishing services related to simple token-based authentication. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Petr Dvorak, petr@wultra.com - */ -@RestController("tokenControllerV2") -@RequestMapping("/pa/token") -public class TokenController { - - private static final Logger logger = LoggerFactory.getLogger(TokenController.class); - - private io.getlime.security.powerauth.rest.api.spring.service.v2.TokenService tokenServiceV2; - private io.getlime.security.powerauth.rest.api.spring.service.v3.TokenService tokenServiceV3; - - /** - * Set the token verification service via setter injection. - * @param tokenServiceV2 Token verification service (v2). - */ - @Autowired - public void setTokenServiceV2(io.getlime.security.powerauth.rest.api.spring.service.v2.TokenService tokenServiceV2) { - this.tokenServiceV2 = tokenServiceV2; - } - - /** - * Set the token verification service via setter injection. - * @param tokenServiceV3 Token verification service (v3). - */ - @Autowired - public void setTokenServiceV3(io.getlime.security.powerauth.rest.api.spring.service.v3.TokenService tokenServiceV3) { - this.tokenServiceV3 = tokenServiceV3; - } - - /** - * Create token. - * @param request Create token request. - * @param authentication PowerAuth API authentication object. - * @return Create token response. - * @throws PowerAuthAuthenticationException In case authentication fails or request is invalid. - */ - @RequestMapping(value = "create", method = RequestMethod.POST) - @PowerAuth(resourceId = "/pa/token/create", signatureType = { - PowerAuthSignatureTypes.POSSESSION, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, - PowerAuthSignatureTypes.POSSESSION_BIOMETRY, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY - }) - public ObjectResponse createToken( - @RequestBody ObjectRequest request, PowerAuthApiAuthentication authentication) throws PowerAuthAuthenticationException { - if (request.getRequestObject() == null) { - logger.warn("Invalid request object in create token"); - throw new PowerAuthInvalidRequestException(); - } - if (authentication == null || authentication.getActivationContext().getActivationId() == null) { - logger.debug("Signature validation failed"); - throw new PowerAuthSignatureInvalidException(); - } - if (!"2.0".equals(authentication.getVersion()) && !"2.1".equals(authentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - TokenCreateResponse response = tokenServiceV2.createToken(request.getRequestObject(), authentication); - return new ObjectResponse<>(response); - } - - /** - * Remove token. - * @param request Remove token request. - * @param authentication PowerAuth API authentication object. - * @return Remove token response. - * @throws PowerAuthAuthenticationException In case authentication fails or request is invalid. - */ - @RequestMapping(value = "remove", method = RequestMethod.POST) - @PowerAuth(resourceId = "/pa/token/remove", signatureType = { - PowerAuthSignatureTypes.POSSESSION, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, - PowerAuthSignatureTypes.POSSESSION_BIOMETRY, - PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE_BIOMETRY - }) - public ObjectResponse removeToken(@RequestBody ObjectRequest request, PowerAuthApiAuthentication authentication) throws PowerAuthAuthenticationException { - if (request.getRequestObject() == null) { - logger.warn("Invalid request object in create token"); - throw new PowerAuthInvalidRequestException(); - } - if (authentication == null || authentication.getActivationContext().getActivationId() == null) { - logger.debug("Signature validation failed"); - throw new PowerAuthSignatureInvalidException(); - } - if (!"2.0".equals(authentication.getVersion()) && !"2.1".equals(authentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - TokenRemoveResponse response = tokenServiceV3.removeToken(request.getRequestObject(), authentication); - return new ObjectResponse<>(response); - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java similarity index 95% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 45543cb3..97230c8d 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -17,16 +17,26 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; import com.wultra.security.powerauth.client.model.error.PowerAuthErrorRecovery; -import com.wultra.security.powerauth.client.v3.*; +import com.wultra.security.powerauth.client.model.request.*; +import com.wultra.security.powerauth.client.model.response.*; +import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; +import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; +import io.getlime.security.powerauth.rest.api.model.request.ActivationStatusRequest; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.ActivationLayer1Response; +import io.getlime.security.powerauth.rest.api.model.response.ActivationRemoveResponse; +import io.getlime.security.powerauth.rest.api.model.response.ActivationStatusResponse; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.application.PowerAuthApplicationConfiguration; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.converter.v3.ActivationContextConverter; +import io.getlime.security.powerauth.rest.api.spring.converter.ActivationContextConverter; import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; @@ -34,23 +44,12 @@ import io.getlime.security.powerauth.rest.api.spring.model.ActivationContext; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; import io.getlime.security.powerauth.rest.api.spring.provider.CustomActivationProvider; -import io.getlime.security.powerauth.rest.api.model.entity.ActivationType; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationLayer1Request; -import io.getlime.security.powerauth.rest.api.model.request.v3.ActivationStatusRequest; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationLayer1Response; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationRemoveResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.ActivationStatusResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.provider.UserInfoProvider; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; import java.time.Instant; import java.util.*; @@ -284,19 +283,16 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request final Integer maxFailed = activationProvider.getMaxFailedAttemptCount(identity, customAttributes, userId, ActivationType.CUSTOM, context); final Long maxFailedCount = maxFailed == null ? null : maxFailed.longValue(); final Long activationValidityPeriod = activationProvider.getValidityPeriodDuringActivation(identity, customAttributes, userId, ActivationType.CUSTOM, context); - XMLGregorianCalendar activationExpireXml = null; + Date activationExpire = null; if (activationValidityPeriod != null) { - Instant now = Instant.now(); - Instant expiration = now.plusMillis(activationValidityPeriod); - GregorianCalendar c = new GregorianCalendar(); - c.setTimeInMillis(expiration.toEpochMilli()); - activationExpireXml = DatatypeFactory.newInstance().newXMLGregorianCalendar(c); + final Instant expiration = Instant.now().plusMillis(activationValidityPeriod); + activationExpire = Date.from(expiration); } // Create activation for a looked up user and application related to the given application key final CreateActivationRequest createRequest = new CreateActivationRequest(); createRequest.setUserId(userId); - createRequest.setTimestampActivationExpire(activationExpireXml); + createRequest.setTimestampActivationExpire(activationExpire); createRequest.setGenerateRecoveryCodes(shouldGenerateRecoveryCodes); createRequest.setMaxFailureCount(maxFailedCount); createRequest.setApplicationKey(applicationKey); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/RecoveryService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java similarity index 91% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/RecoveryService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java index 7517c094..e02107c0 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/RecoveryService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java @@ -17,19 +17,18 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v3.ConfirmRecoveryCodeRequest; -import com.wultra.security.powerauth.client.v3.ConfirmRecoveryCodeResponse; +import com.wultra.security.powerauth.client.model.request.ConfirmRecoveryCodeRequest; +import com.wultra.security.powerauth.client.model.response.ConfirmRecoveryCodeResponse; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthRecoveryConfirmationException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java similarity index 91% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java index 3c695bc3..80c319d9 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java @@ -17,29 +17,28 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v3.SignatureType; -import com.wultra.security.powerauth.client.v3.VaultUnlockRequest; -import com.wultra.security.powerauth.client.v3.VaultUnlockResponse; +import com.wultra.security.powerauth.client.model.enumeration.SignatureType; +import com.wultra.security.powerauth.client.model.request.VaultUnlockRequest; +import com.wultra.security.powerauth.client.model.response.VaultUnlockResponse; import io.getlime.security.powerauth.http.PowerAuthHttpBody; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.spring.converter.SignatureTypeConverter; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthSecureVaultException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureTypeInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.spring.converter.v3.SignatureTypeConverter; import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import jakarta.servlet.http.HttpServletRequest; import java.util.Base64; /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java similarity index 89% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/TokenService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java index 05a8d8c1..074378e4 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/TokenService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java @@ -17,25 +17,24 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v3.CreateTokenRequest; -import com.wultra.security.powerauth.client.v3.CreateTokenResponse; -import com.wultra.security.powerauth.client.v3.RemoveTokenRequest; -import com.wultra.security.powerauth.client.v3.SignatureType; +import com.wultra.security.powerauth.client.model.enumeration.SignatureType; +import com.wultra.security.powerauth.client.model.request.CreateTokenRequest; +import com.wultra.security.powerauth.client.model.request.RemoveTokenRequest; +import com.wultra.security.powerauth.client.model.response.CreateTokenResponse; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.request.TokenRemoveRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; +import io.getlime.security.powerauth.rest.api.model.response.TokenRemoveResponse; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; +import io.getlime.security.powerauth.rest.api.spring.converter.SignatureTypeConverter; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureTypeInvalidException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthTokenErrorException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.request.v3.TokenRemoveRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.model.response.v3.TokenRemoveResponse; -import io.getlime.security.powerauth.rest.api.spring.converter.v3.SignatureTypeConverter; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java similarity index 93% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java index dc6d802b..3d233cd7 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UpgradeService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java @@ -17,29 +17,31 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v3.*; +import com.wultra.security.powerauth.client.model.request.CommitUpgradeRequest; +import com.wultra.security.powerauth.client.model.request.StartUpgradeRequest; +import com.wultra.security.powerauth.client.model.response.CommitUpgradeResponse; +import com.wultra.security.powerauth.client.model.response.StartUpgradeResponse; import io.getlime.core.rest.model.base.response.Response; import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; +import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; +import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUpgradeException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v3.EciesEncryptedRequest; -import io.getlime.security.powerauth.rest.api.model.response.v3.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.List; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java similarity index 94% rename from powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java rename to powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java index b7052548..70c6a546 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v3/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java @@ -17,12 +17,12 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -package io.getlime.security.powerauth.rest.api.spring.service.v3; +package io.getlime.security.powerauth.rest.api.spring.service; import com.wultra.security.powerauth.client.PowerAuthClient; +import com.wultra.security.powerauth.client.model.enumeration.ActivationStatus; import com.wultra.security.powerauth.client.model.error.PowerAuthClientException; -import com.wultra.security.powerauth.client.v3.ActivationStatus; -import com.wultra.security.powerauth.client.v3.GetActivationStatusResponse; +import com.wultra.security.powerauth.client.model.response.GetActivationStatusResponse; import io.getlime.security.powerauth.rest.api.model.entity.UserInfoStage; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.model.UserInfoContext; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/ActivationService.java deleted file mode 100644 index 018da600..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/ActivationService.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.service.v2; - -import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v2.PrepareActivationRequest; -import com.wultra.security.powerauth.client.v2.PrepareActivationResponse; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; -import io.getlime.security.powerauth.rest.api.model.request.v2.ActivationCreateRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.ActivationCreateResponse; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Service implementing activation functionality. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Roman Strobl, roman.strobl@wultra.com - * - */ -@Service("activationServiceV2") -public class ActivationService { - - private static final Logger logger = LoggerFactory.getLogger(ActivationService.class); - - private final PowerAuthClient powerAuthClient; - private final HttpCustomizationService httpCustomizationService; - - /** - * Service constructor. - * @param powerAuthClient PowerAuth client. - * @param httpCustomizationService HTTP customization service. - */ - @Autowired - public ActivationService(PowerAuthClient powerAuthClient, HttpCustomizationService httpCustomizationService) { - this.powerAuthClient = powerAuthClient; - this.httpCustomizationService = httpCustomizationService; - } - - /** - * Create activation. - * @param request Create activation request. - * @return Create activation response. - * @throws PowerAuthActivationException In case create activation fails. - */ - public ActivationCreateResponse createActivation(ActivationCreateRequest request) throws PowerAuthActivationException { - try { - final String activationIDShort = request.getActivationIdShort(); - final String activationNonce = request.getActivationNonce(); - final String cDevicePublicKey = request.getEncryptedDevicePublicKey(); - final String activationName = request.getActivationName(); - final String extras = request.getExtras(); - final String applicationKey = request.getApplicationKey(); - final String applicationSignature = request.getApplicationSignature(); - final String clientEphemeralKey = request.getEphemeralPublicKey(); - - final PrepareActivationRequest prepareRequest = new PrepareActivationRequest(); - prepareRequest.setActivationIdShort(activationIDShort); - prepareRequest.setActivationName(activationName); - prepareRequest.setActivationNonce(activationNonce); - prepareRequest.setEphemeralPublicKey(clientEphemeralKey); - prepareRequest.setEncryptedDevicePublicKey(cDevicePublicKey); - prepareRequest.setExtras(extras); - prepareRequest.setApplicationKey(applicationKey); - prepareRequest.setApplicationSignature(applicationSignature); - final PrepareActivationResponse paResponse = powerAuthClient.v2().prepareActivation( - prepareRequest, - httpCustomizationService.getQueryParams(), - httpCustomizationService.getHttpHeaders() - ); - - final ActivationCreateResponse response = new ActivationCreateResponse(); - response.setActivationId(paResponse.getActivationId()); - response.setActivationNonce(paResponse.getActivationNonce()); - response.setEncryptedServerPublicKey(paResponse.getEncryptedServerPublicKey()); - response.setEncryptedServerPublicKeySignature(paResponse.getEncryptedServerPublicKeySignature()); - response.setEphemeralPublicKey(paResponse.getEphemeralPublicKey()); - - return response; - } catch (Exception ex) { - logger.warn("Creating PowerAuth activation failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthActivationException(); - } - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java deleted file mode 100644 index 681c950f..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/SecureVaultService.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.service.v2; - -import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v2.SignatureType; -import io.getlime.security.powerauth.http.PowerAuthHttpBody; -import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; -import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; -import io.getlime.security.powerauth.http.validator.PowerAuthSignatureHttpHeaderValidator; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthSecureVaultException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureTypeInvalidException; -import io.getlime.security.powerauth.rest.api.model.request.v2.VaultUnlockRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.VaultUnlockResponse; -import io.getlime.security.powerauth.rest.api.spring.converter.v2.SignatureTypeConverter; -import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import jakarta.servlet.http.HttpServletRequest; -import java.util.Base64; - -/** - * Service implementing secure vault functionality. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Roman Strobl, roman.strobl@wultra.com - * - */ -@Service("secureVaultServiceV2") -public class SecureVaultService { - - private static final Logger logger = LoggerFactory.getLogger(SecureVaultService.class); - - private final PowerAuthClient powerAuthClient; - private final PowerAuthAuthenticationProvider authenticationProvider; - private final HttpCustomizationService httpCustomizationService; - - /** - * Service constructor. - * @param powerAuthClient PowerAuth client. - * @param authenticationProvider Authentication provider. - * @param httpCustomizationService HTTP customization service. - */ - @Autowired - public SecureVaultService(PowerAuthClient powerAuthClient, PowerAuthAuthenticationProvider authenticationProvider, HttpCustomizationService httpCustomizationService) { - this.powerAuthClient = powerAuthClient; - this.authenticationProvider = authenticationProvider; - this.httpCustomizationService = httpCustomizationService; - } - - /** - * Unlock secure vault. - * @param signatureHeader PowerAuth signature HTTP header. - * @param request Vault unlock request. - * @param httpServletRequest HTTP servlet request. - * @return Vault unlock response. - * @throws PowerAuthSecureVaultException In case vault unlock fails. - * @throws PowerAuthAuthenticationException In case authentication fails. - */ - public VaultUnlockResponse vaultUnlock(String signatureHeader, - VaultUnlockRequest request, - HttpServletRequest httpServletRequest) throws PowerAuthSecureVaultException, PowerAuthAuthenticationException { - try { - // Parse the header - final PowerAuthSignatureHttpHeader header = new PowerAuthSignatureHttpHeader().fromValue(signatureHeader); - - // Validate the header - try { - PowerAuthSignatureHttpHeaderValidator.validate(header); - } catch (InvalidPowerAuthHttpHeaderException ex) { - logger.warn("Signature HTTP header validation failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthSignatureTypeInvalidException(); - } - - final SignatureTypeConverter converter = new SignatureTypeConverter(); - - final String activationId = header.getActivationId(); - final String applicationKey = header.getApplicationKey(); - final String signature = header.getSignature(); - final SignatureType signatureType = converter.convertFrom(header.getSignatureType()); - if (signatureType == null) { - logger.warn("Invalid signature type: {}", header.getSignatureType()); - throw new PowerAuthSignatureTypeInvalidException(); - } - final String nonce = header.getNonce(); - - String reason = null; - byte[] requestBodyBytes; - - if ("2.0".equals(header.getVersion())) { - // Version 2.0 requires null data in signature for vault unlock. - requestBodyBytes = null; - } else if ("2.1".equals(header.getVersion())) { - // Version 2.1 or higher requires request data in signature (POST request body) for vault unlock. - if (request != null) { - // Send vault unlock reason, in case it is available. - if (request.getReason() != null) { - reason = request.getReason(); - } - } - - // Use POST request body as data for signature. - requestBodyBytes = authenticationProvider.extractRequestBodyBytes(httpServletRequest); - } else { - logger.warn("Invalid protocol version in secure vault: {}", header.getVersion()); - throw new PowerAuthSecureVaultException(); - } - - final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", Base64.getDecoder().decode(nonce), requestBodyBytes); - - final com.wultra.security.powerauth.client.v2.VaultUnlockRequest unlockRequest = new com.wultra.security.powerauth.client.v2.VaultUnlockRequest(); - unlockRequest.setActivationId(activationId); - unlockRequest.setApplicationKey(applicationKey); - unlockRequest.setData(data); - unlockRequest.setSignature(signature); - unlockRequest.setSignatureType(signatureType); - unlockRequest.setReason(reason); - final com.wultra.security.powerauth.client.v2.VaultUnlockResponse paResponse = powerAuthClient.v2().unlockVault( - unlockRequest, - httpCustomizationService.getQueryParams(), - httpCustomizationService.getHttpHeaders() - ); - - if (!paResponse.isSignatureValid()) { - logger.debug("Signature validation failed"); - throw new PowerAuthSignatureInvalidException(); - } - - final VaultUnlockResponse response = new VaultUnlockResponse(); - response.setActivationId(paResponse.getActivationId()); - response.setEncryptedVaultEncryptionKey(paResponse.getEncryptedVaultEncryptionKey()); - - return response; - } catch (PowerAuthAuthenticationException ex) { - throw ex; - } catch (Exception ex) { - logger.warn("PowerAuth vault unlock failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthSecureVaultException(); - } - } - -} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/TokenService.java deleted file mode 100644 index 0f5c5be7..00000000 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/v2/TokenService.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.service.v2; - -import com.wultra.security.powerauth.client.PowerAuthClient; -import com.wultra.security.powerauth.client.v2.CreateTokenResponse; -import com.wultra.security.powerauth.client.v2.CreateTokenRequest; -import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; -import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthTokenErrorException; -import io.getlime.security.powerauth.rest.api.model.request.v2.TokenCreateRequest; -import io.getlime.security.powerauth.rest.api.model.response.v2.TokenCreateResponse; -import io.getlime.security.powerauth.rest.api.spring.converter.v2.SignatureTypeConverter; -import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * Service implementing token functionality. - * - *

PowerAuth protocol versions: - *

    - *
  • 2.0
  • - *
  • 2.1
  • - *
- * - * @author Roman Strobl, roman.strobl@wultra.com - * - */ -@Service("tokenServiceV2") -public class TokenService { - - private static final Logger logger = LoggerFactory.getLogger(TokenService.class); - - private final PowerAuthClient powerAuthClient; - private final HttpCustomizationService httpCustomizationService; - - /** - * Service constructor. - * @param powerAuthClient PowerAuth client. - * @param httpCustomizationService HTTP customization service. - */ - @Autowired - public TokenService(PowerAuthClient powerAuthClient, HttpCustomizationService httpCustomizationService) { - this.powerAuthClient = powerAuthClient; - this.httpCustomizationService = httpCustomizationService; - } - - /** - * Create token. - * @param request Create token request. - * @param authentication PowerAuth API authentication. - * @return Create token response. - * @throws PowerAuthAuthenticationException In case token could not be created. - */ - public TokenCreateResponse createToken(TokenCreateRequest request, PowerAuthApiAuthentication authentication) throws PowerAuthAuthenticationException { - try { - // Fetch activation ID and signature type - final String activationId = authentication.getActivationContext().getActivationId(); - final PowerAuthSignatureTypes signatureFactors = authentication.getAuthenticationContext().getSignatureType(); - - // Fetch data from the request - final String ephemeralPublicKey = request.getEphemeralPublicKey(); - - // Prepare a signature type converter - SignatureTypeConverter converter = new SignatureTypeConverter(); - - // Create a token - final CreateTokenRequest tokenRequest = new CreateTokenRequest(); - tokenRequest.setActivationId(activationId); - tokenRequest.setEphemeralPublicKey(ephemeralPublicKey); - tokenRequest.setSignatureType(converter.convertFrom(signatureFactors)); - final CreateTokenResponse token = powerAuthClient.v2().createToken( - tokenRequest, - httpCustomizationService.getQueryParams(), - httpCustomizationService.getHttpHeaders() - ); - - // Prepare a response - final TokenCreateResponse response = new TokenCreateResponse(); - response.setMac(token.getMac()); - response.setEncryptedData(token.getEncryptedData()); - return response; - } catch (Exception ex) { - logger.warn("Creating PowerAuth token failed, error: {}", ex.getMessage()); - logger.debug(ex.getMessage(), ex); - throw new PowerAuthTokenErrorException(); - } - } - -} From 76ac8eb390a726806f2009666dad6a61b1c5e4e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:02:56 +0000 Subject: [PATCH 34/64] Bump bcprov-jdk18on from 1.72 to 1.73 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.72 to 1.73. - [Release notes](https://github.com/bcgit/bc-java/releases) - [Changelog](https://github.com/bcgit/bc-java/blob/master/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on 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 d79b5b0e..b79cf81a 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ 3.3.2 3.0.5 1.10.0 - 1.72 + 1.73 1.7.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT From 90c7f6813800633b9c8cf97adfa8b3d90b7f81fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Mon, 17 Apr 2023 12:30:20 +0200 Subject: [PATCH 35/64] Fix #395: Change shouldCreateRecoveryCodes to boolean (#396) * Fix #395: Change shouldCreateRecoveryCodes to boolean --- .../spring/provider/CustomActivationProvider.java | 11 +++++------ .../api/spring/service/ActivationService.java | 15 ++++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java index 68cda128..66311516 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/CustomActivationProvider.java @@ -110,21 +110,20 @@ default boolean shouldAutoCommitActivation(Map identityAttribute default void activationWasCommitted(Map identityAttributes, Map customAttributes, String activationId, String userId, String appId, ActivationType activationType, Map context) throws PowerAuthActivationException {} /** - * Method that indicates if recovery codes should be generated for a given activation or not. The method may return null, - * in such case, it uses settings of the PowerAuth Server to determine if the recovery codes should be generated or not. Also, - * just specifying true in the call will not result in generating recovery codes in case that recovery codes are + * Method that indicates if recovery codes should be generated for a given activation or not. + * Note that specifying true in the call will not result in generating recovery codes in case that recovery codes are * globally disabled at the PowerAuth Server. * * @param identityAttributes Identity related attributes. * @param customAttributes Custom attributes, not related to identity. * @param activationType Activation type. * @param context Context for passing parameters between activation provider calls. - * @return False to prevent generating recovery codes, "null" to let the PowerAuth Server decide, and true to generate recovery codes + * @return False to prevent generating recovery codes, true to generate recovery codes * in case that the feature is enabled globally on PowerAuth Server. * @throws PowerAuthActivationException In case of error in custom activation business logic that should terminate the rest of the activation. */ - default Boolean shouldCreateRecoveryCodes(Map identityAttributes, Map customAttributes, ActivationType activationType, Map context) throws PowerAuthActivationException { - return null; + default boolean shouldCreateRecoveryCodes(Map identityAttributes, Map customAttributes, ActivationType activationType, Map context) throws PowerAuthActivationException { + return true; } /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 97230c8d..481ed359 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -165,17 +165,11 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Create context for passing parameters between activation provider calls final Map context = new LinkedHashMap<>(); - // Decide if the recovery codes should be generated - Boolean shouldGenerateRecoveryCodes = null; - if (activationProvider != null) { - shouldGenerateRecoveryCodes = activationProvider.shouldCreateRecoveryCodes(identity, customAttributes, ActivationType.CODE, context); - } - // Call PrepareActivation method on PA server final PrepareActivationRequest prepareRequest = new PrepareActivationRequest(); prepareRequest.setActivationCode(activationCode); prepareRequest.setApplicationKey(applicationKey); - prepareRequest.setGenerateRecoveryCodes(shouldGenerateRecoveryCodes); + prepareRequest.setGenerateRecoveryCodes(shouldGenerateRecoveryCodes(identity, customAttributes, context)); prepareRequest.setEphemeralPublicKey(ephemeralPublicKey); prepareRequest.setEncryptedData(encryptedData); prepareRequest.setMac(mac); @@ -489,6 +483,13 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } } + private boolean shouldGenerateRecoveryCodes(final Map identity, final Map customAttributes, final Map context) throws PowerAuthActivationException { + if (activationProvider == null) { + return true; + } + return activationProvider.shouldCreateRecoveryCodes(identity, customAttributes, ActivationType.CODE, context); + } + /** * Get activation status. * From b88a4c84faac1e8709cddc800b006e34adb0c1ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 08:04:45 +0000 Subject: [PATCH 36/64] Bump maven-source-plugin from 3.2.1 to 3.3.0 Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.0. - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-source-plugin 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 b79cf81a..6b21ff7b 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ 3.3.0 3.1.1 3.5.0 - 3.2.1 + 3.3.0 3.3.2 3.0.5 1.10.0 From e8b1ee2fee54bcc3aea99a8e5068bd05c26862d9 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 24 May 2023 08:37:37 +0200 Subject: [PATCH 37/64] Fix #400: Update compiler to Java 17 --- pom.xml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b79cf81a..bc9c79e6 100644 --- a/pom.xml +++ b/pom.xml @@ -75,8 +75,9 @@ UTF-8 - 1.8 - 1.8 + 17 + ${java.version} + ${java.version} 3.3.0 3.1.1 3.5.0 @@ -135,6 +136,14 @@
+ + + org.projectlombok + lombok + provided + + + From 867aebe461214c678b4d08d8990856675ab9cab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Wed, 24 May 2023 11:55:38 +0200 Subject: [PATCH 38/64] Fix #397: Crypto 3.2: Time synchronization (#399) --- .../model/request/EciesEncryptedRequest.java | 17 +++++ .../response/EciesEncryptedResponse.java | 16 +++++ .../model/response/ServerStatusResponse.java | 47 +++++++++++++ .../pom.xml | 5 ++ powerauth-restful-security-spring/pom.xml | 7 ++ .../controller/ActivationController.java | 10 +-- .../spring/controller/RecoveryController.java | 11 ++-- .../controller/SecureVaultController.java | 6 +- .../controller/ServerStatusController.java | 66 +++++++++++++++++++ .../controller/SignatureController.java | 4 +- .../spring/controller/TokenController.java | 17 ++--- .../spring/controller/UpgradeController.java | 12 ++-- .../spring/controller/UserInfoController.java | 1 + 13 files changed, 194 insertions(+), 25 deletions(-) create mode 100644 powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java create mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java index fd018f39..5420b1a2 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java @@ -30,6 +30,7 @@ public class EciesEncryptedRequest { private String encryptedData; private String mac; private String nonce; + private Long timestamp; /** * Get Base64 encoded ephemeral public key. @@ -94,4 +95,20 @@ public String getNonce() { public void setNonce(String nonce) { this.nonce = nonce; } + + /** + * Get request timestamp as unix timestamp in milliseconds. + * @return Request timestamp. + */ + public long getTimestamp() { + return timestamp; + } + + /** + * Set request timestamp as unix timestamp in milliseconds. + * @param timestamp Request timestamp. + */ + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } } diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java index acd5517f..fef2a0ae 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java @@ -28,6 +28,7 @@ public class EciesEncryptedResponse { private String encryptedData; private String mac; + private Long timestamp; /** * Default constructor. @@ -77,4 +78,19 @@ public void setMac(String mac) { this.mac = mac; } + /** + * Get response timestamp as unix timestamp in milliseconds. + * @return Response timestamp. + */ + public long getTimestamp() { + return timestamp; + } + + /** + * Set response timestamp as unix timestamp in milliseconds. + * @param timestamp Response timestamp. + */ + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } } diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java new file mode 100644 index 00000000..3aca91bb --- /dev/null +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java @@ -0,0 +1,47 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.model.response; + +/** + * Response object for /pa/v3/status end-point. + * + * @author Roman Strobl, roman.strobl@wultra.com + * + */ +public class ServerStatusResponse { + + private final long serverTime; + + /** + * Class constructor. + * @param serverTime Server time as unix timestamp in milliseconds. + */ + public ServerStatusResponse(long serverTime) { + this.serverTime = serverTime; + } + + /** + * Get server time as unix timestamp in milliseconds. + * @return Server time. + */ + public long getServerTime() { + return serverTime; + } +} \ No newline at end of file diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 4d64e5b6..5b7ab658 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -85,6 +85,11 @@ commons-text ${commons-text.version} + + org.projectlombok + lombok + provided +
diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index 0212cb6c..5934b188 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -54,6 +54,13 @@ + + + org.projectlombok + lombok + provided + +
diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java index 12998c79..651a0ef6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java @@ -94,7 +94,7 @@ public void setAuthenticationProvider(PowerAuthAuthenticationProvider authentica * @throws PowerAuthActivationException In case activation fails. * @throws PowerAuthRecoveryException In case recovery PUK is invalid. */ - @RequestMapping(value = "create", method = RequestMethod.POST) + @PostMapping("create") @PowerAuthEncryption(scope = EciesScope.APPLICATION_SCOPE) public ActivationLayer1Response createActivation(@EncryptedRequestBody ActivationLayer1Request request, EciesEncryptionContext eciesContext) throws PowerAuthActivationException, PowerAuthRecoveryException { @@ -111,7 +111,7 @@ public ActivationLayer1Response createActivation(@EncryptedRequestBody Activatio * @return PowerAuth RESTful response with {@link ActivationStatusResponse} payload. * @throws PowerAuthActivationException In case request fails. */ - @RequestMapping(value = "status", method = RequestMethod.POST) + @PostMapping("status") public ObjectResponse getActivationStatus(@RequestBody ObjectRequest request) throws PowerAuthActivationException { if (request.getRequestObject() == null || request.getRequestObject().getActivationId() == null) { @@ -130,7 +130,7 @@ public ObjectResponse getActivationStatus(@RequestBody * @throws PowerAuthActivationException In case activation access fails. * @throws PowerAuthAuthenticationException In case the signature validation fails. */ - @RequestMapping(value = "remove", method = RequestMethod.POST) + @PostMapping("remove") public ObjectResponse removeActivation( @RequestHeader(value = PowerAuthSignatureHttpHeader.HEADER_NAME) String signatureHeader, HttpServletRequest httpServletRequest) @@ -141,7 +141,9 @@ public ObjectResponse removeActivation( logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(apiAuthentication.getVersion()) && !"3.1".equals(apiAuthentication.getVersion())) { + if (!"3.0".equals(apiAuthentication.getVersion()) + && !"3.1".equals(apiAuthentication.getVersion()) + && !"3.2".equals(apiAuthentication.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", apiAuthentication.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java index 56f4dcc2..a0ebd128 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java @@ -30,10 +30,7 @@ import io.getlime.security.powerauth.rest.api.spring.service.RecoveryService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; /** * Controller implementing recovery related end-points from the PowerAuth @@ -70,7 +67,7 @@ public RecoveryController(RecoveryService recoveryService) { * @return ECIES encrypted response. * @throws PowerAuthAuthenticationException In case confirm recovery fails. */ - @RequestMapping(value = "confirm", method = RequestMethod.POST) + @PostMapping("confirm") @PowerAuth(resourceId = "/pa/recovery/confirm", signatureType = { PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE }) @@ -83,7 +80,9 @@ public EciesEncryptedResponse confirmRecoveryCode(@RequestBody EciesEncryptedReq if (authentication == null || authentication.getActivationContext().getActivationId() == null) { throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion())) { + if (!"3.0".equals(authentication.getVersion()) + && !"3.1".equals(authentication.getVersion()) + && !"3.2".equals(authentication.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java index 53e8b971..8ca1b20c 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java @@ -74,7 +74,7 @@ public void setSecureVaultServiceV3(SecureVaultService secureVaultServiceV3) { * @throws PowerAuthAuthenticationException In case authentication fails. * @throws PowerAuthSecureVaultException In case unlocking the vault fails. */ - @RequestMapping(value = "unlock", method = RequestMethod.POST) + @PostMapping("unlock") public EciesEncryptedResponse unlockVault( @RequestHeader(value = PowerAuthSignatureHttpHeader.HEADER_NAME, defaultValue = "unknown") String signatureHeader, @RequestBody EciesEncryptedRequest request, @@ -98,7 +98,9 @@ public EciesEncryptedResponse unlockVault( throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion())) { + if (!"3.0".equals(header.getVersion()) + && !"3.1".equals(header.getVersion()) + && !"3.2".equals(header.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java new file mode 100644 index 00000000..6a01c1a7 --- /dev/null +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java @@ -0,0 +1,66 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.controller; + +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; +import io.getlime.security.powerauth.rest.api.model.request.UserInfoRequest; +import io.getlime.security.powerauth.rest.api.model.response.ServerStatusResponse; +import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; +import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; +import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; +import io.getlime.security.powerauth.rest.api.spring.service.UserInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Date; +import java.util.Map; + +/** + * Controller that provides a user information. + *

PowerAuth protocol versions: + *

    + *
  • 3.0
  • + *
  • 3.1
  • + *
  • 3.2
  • + *
+ * + * @author Petr Dvorak, petr@wultra.com + */ +@RestController +@RequestMapping("pa/v3") +@Slf4j +public class ServerStatusController { + + /** + * Obtain server status. + * @return Server status. + */ + @PostMapping("status") + public ServerStatusResponse getServerStatus() { + final long serverTime = new Date().getTime(); + return new ServerStatusResponse(serverTime); + } + +} diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java index fceed76f..195df04d 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java @@ -68,7 +68,9 @@ public Response validateSignature(PowerAuthApiAuthentication auth) throws PowerA logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(auth.getVersion()) && !"3.1".equals(auth.getVersion())) { + if (!"3.0".equals(auth.getVersion()) + && !"3.1".equals(auth.getVersion()) + && !"3.2".equals(auth.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", auth.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java index 47f16bd1..2fe425e0 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java @@ -35,10 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; /** * Controller responsible for publishing services related to simple token-based authentication. @@ -74,7 +71,7 @@ public void setTokenServiceV3(TokenService tokenServiceV3) { * @return ECIES encrypted create token response. * @throws PowerAuthAuthenticationException In case authentication fails or request is invalid. */ - @RequestMapping(value = "create", method = RequestMethod.POST) + @PostMapping("create") @PowerAuth(resourceId = "/pa/token/create", signatureType = { PowerAuthSignatureTypes.POSSESSION, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, @@ -92,7 +89,9 @@ public EciesEncryptedResponse createToken(@RequestBody EciesEncryptedRequest req logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion())) { + if (!"3.0".equals(authentication.getVersion()) + && !"3.1".equals(authentication.getVersion()) + && !"3.2".equals(authentication.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); throw new PowerAuthInvalidRequestException(); } @@ -110,7 +109,7 @@ public EciesEncryptedResponse createToken(@RequestBody EciesEncryptedRequest req * @return Remove token response. * @throws PowerAuthAuthenticationException In case authentication fails or request is invalid. */ - @RequestMapping(value = "remove", method = RequestMethod.POST) + @PostMapping("remove") @PowerAuth(resourceId = "/pa/token/remove", signatureType = { PowerAuthSignatureTypes.POSSESSION, PowerAuthSignatureTypes.POSSESSION_KNOWLEDGE, @@ -126,7 +125,9 @@ public ObjectResponse removeToken(@RequestBody ObjectReques if (authentication == null || authentication.getActivationContext().getActivationId() == null) { throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion())) { + if (!"3.0".equals(authentication.getVersion()) + && !"3.1".equals(authentication.getVersion()) + && !"3.2".equals(authentication.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java index dfb856ae..6327b055 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java @@ -73,7 +73,7 @@ public void setUpgradeService(UpgradeService upgradeService) { * @return ECIES encrypted response. * @throws PowerAuthUpgradeException In case upgrade fails. */ - @RequestMapping(value = "start", method = RequestMethod.POST) + @PostMapping("start") public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest request, @RequestHeader(value = PowerAuthEncryptionHttpHeader.HEADER_NAME, defaultValue = "unknown") String encryptionHeader) throws PowerAuthUpgradeException { @@ -95,7 +95,9 @@ public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest re throw new PowerAuthUpgradeException(); } - if (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion())) { + if (!"3.0".equals(header.getVersion()) + && !"3.1".equals(header.getVersion()) + && !"3.2".equals(header.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); throw new PowerAuthUpgradeException(); } @@ -118,7 +120,7 @@ public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest re * @throws PowerAuthAuthenticationException In case request signature is invalid. * @throws PowerAuthUpgradeException In case commit fails. */ - @RequestMapping(value = "commit", method = RequestMethod.POST) + @PostMapping("commit") public Response upgradeCommit(@RequestHeader(value = PowerAuthSignatureHttpHeader.HEADER_NAME) String signatureHeader, HttpServletRequest httpServletRequest) throws PowerAuthAuthenticationException, PowerAuthUpgradeException { @@ -135,7 +137,9 @@ public Response upgradeCommit(@RequestHeader(value = PowerAuthSignatureHttpHeade throw new PowerAuthUpgradeException(); } - if (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion())) { + if (!"3.0".equals(header.getVersion()) + && !"3.1".equals(header.getVersion()) + && !"3.2".equals(header.getVersion())) { logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); throw new PowerAuthInvalidRequestException(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java index 00b22ade..198723be 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java @@ -41,6 +41,7 @@ *
    *
  • 3.0
  • *
  • 3.1
  • + *
  • 3.2
  • *
* * @author Petr Dvorak, petr@wultra.com From badf8a36492fda595f8326426ba482d7121f11d8 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 24 May 2023 13:13:51 +0200 Subject: [PATCH 39/64] Fix #402: Review Java warnings - Add annotation @Serial - Enhance switch - Use pattern variable - Convert to record: ServerStatusResponse, PowerAuthEciesDecryptorParameters --- .../model/response/ServerStatusResponse.java | 22 ++---------- .../pom.xml | 5 --- .../PowerAuthAnnotationInterceptor.java | 4 +-- .../PowerAuthEncryptionArgumentResolver.java | 13 ++++--- .../impl/PowerAuthActivationImpl.java | 2 ++ .../impl/PowerAuthApiAuthenticationImpl.java | 6 ++-- .../PowerAuthSignatureAuthenticationImpl.java | 3 ++ .../converter/ActivationStatusConverter.java | 29 ++++----------- .../converter/SignatureTypeConverter.java | 22 +++++------- .../PowerAuthEciesDecryptorParameters.java | 36 ++----------------- .../encryption/PowerAuthEciesEncryption.java | 2 +- .../PowerAuthActivationException.java | 3 ++ .../PowerAuthAuthenticationException.java | 3 ++ .../PowerAuthEncryptionException.java | 3 ++ .../exception/PowerAuthRecoveryException.java | 3 ++ .../PowerAuthSecureVaultException.java | 3 ++ .../exception/PowerAuthUpgradeException.java | 3 ++ .../exception/PowerAuthUserInfoException.java | 3 ++ .../PowerAuthHeaderMissingException.java | 3 ++ .../PowerAuthInvalidRequestException.java | 3 ++ ...owerAuthRecoveryConfirmationException.java | 3 ++ .../PowerAuthRequestFilterException.java | 3 ++ .../PowerAuthSignatureErrorException.java | 3 ++ .../PowerAuthSignatureInvalidException.java | 3 ++ ...owerAuthSignatureTypeInvalidException.java | 3 ++ .../PowerAuthTokenErrorException.java | 3 ++ .../PowerAuthTokenInvalidException.java | 3 ++ .../filter/PowerAuthRequestFilterBase.java | 2 +- .../PowerAuthEncryptionProviderBase.java | 17 +++++---- powerauth-restful-security-spring/pom.xml | 7 ---- .../controller/ServerStatusController.java | 10 ------ .../api/spring/service/ActivationService.java | 17 ++++----- 32 files changed, 102 insertions(+), 143 deletions(-) diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java index 3aca91bb..16cb7eff 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/ServerStatusResponse.java @@ -22,26 +22,8 @@ /** * Response object for /pa/v3/status end-point. * + * @param serverTime Server time. * @author Roman Strobl, roman.strobl@wultra.com - * */ -public class ServerStatusResponse { - - private final long serverTime; - - /** - * Class constructor. - * @param serverTime Server time as unix timestamp in milliseconds. - */ - public ServerStatusResponse(long serverTime) { - this.serverTime = serverTime; - } - - /** - * Get server time as unix timestamp in milliseconds. - * @return Server time. - */ - public long getServerTime() { - return serverTime; - } +public record ServerStatusResponse(long serverTime) { } \ No newline at end of file diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 5b7ab658..4d64e5b6 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -85,11 +85,6 @@ commons-text ${commons-text.version} - - org.projectlombok - lombok - provided - diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java index 2b00991a..3be2e428 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthAnnotationInterceptor.java @@ -92,9 +92,7 @@ public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServl // This is to avoid issues with possible CORS requests )in case of // incorrect filter mapping) where there are special "pre-flight" // requests before the actual requests. - if (handler instanceof HandlerMethod) { - - final HandlerMethod handlerMethod = (HandlerMethod) handler; + if (handler instanceof final HandlerMethod handlerMethod) { // Obtain annotations PowerAuth powerAuthSignatureAnnotation = handlerMethod.getMethodAnnotation(PowerAuth.class); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java index 5eb1327c..346fc337 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java @@ -101,7 +101,7 @@ public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewCo */ private boolean validateEciesScope(EciesEncryptionContext eciesContext) { switch (eciesContext.getEciesScope()) { - case ACTIVATION_SCOPE: + case ACTIVATION_SCOPE -> { if (eciesContext.getApplicationKey() == null || eciesContext.getApplicationKey().isEmpty()) { logger.warn("ECIES activation scope is invalid because of missing application key"); return false; @@ -110,18 +110,17 @@ private boolean validateEciesScope(EciesEncryptionContext eciesContext) { logger.warn("ECIES activation scope is invalid because of missing activation ID"); return false; } - break; - - case APPLICATION_SCOPE: + } + case APPLICATION_SCOPE -> { if (eciesContext.getApplicationKey() == null || eciesContext.getApplicationKey().isEmpty()) { logger.warn("ECIES application scope is invalid because of missing application key"); return false; } - break; - - default: + } + default -> { logger.warn("Unsupported ECIES scope: {}", eciesContext.getEciesScope()); return false; + } } return true; } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthActivationImpl.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthActivationImpl.java index 52becd95..9d5e60b8 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthActivationImpl.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthActivationImpl.java @@ -23,6 +23,7 @@ import io.getlime.security.powerauth.rest.api.spring.model.ActivationStatus; import io.getlime.security.powerauth.rest.api.spring.model.AuthenticationContext; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -35,6 +36,7 @@ */ public class PowerAuthActivationImpl implements PowerAuthActivation, Serializable { + @Serial private static final long serialVersionUID = -2171754572617130041L; /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthApiAuthenticationImpl.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthApiAuthenticationImpl.java index 81a9aecc..b77bcce1 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthApiAuthenticationImpl.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthApiAuthenticationImpl.java @@ -28,6 +28,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -43,6 +44,7 @@ */ public class PowerAuthApiAuthenticationImpl extends AbstractAuthenticationToken implements PowerAuthApiAuthentication, Serializable { + @Serial private static final long serialVersionUID = -3790516505615465445L; /** @@ -145,9 +147,7 @@ public String getName() { @Override public Collection getAuthorities() { - ArrayList authorities = new ArrayList<>(1); - authorities.add(new SimpleGrantedAuthority("USER")); - return Collections.unmodifiableList(authorities); + return List.of(new SimpleGrantedAuthority("USER")); } @Override diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthSignatureAuthenticationImpl.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthSignatureAuthenticationImpl.java index 70cc1c50..b8b5624c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthSignatureAuthenticationImpl.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/authentication/impl/PowerAuthSignatureAuthenticationImpl.java @@ -23,6 +23,8 @@ import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthSignatureAuthentication; import org.springframework.security.authentication.AbstractAuthenticationToken; +import java.io.Serial; + /** * PowerAuth authentication object used between PowerAuth Client and intermediate server * application (such as mobile banking API). @@ -32,6 +34,7 @@ */ public class PowerAuthSignatureAuthenticationImpl extends AbstractAuthenticationToken implements PowerAuthSignatureAuthentication { + @Serial private static final long serialVersionUID = 6495166873663643144L; /** diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java index 5d87704b..ac2d8bdd 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/ActivationStatusConverter.java @@ -20,8 +20,6 @@ package io.getlime.security.powerauth.rest.api.spring.converter; import io.getlime.security.powerauth.rest.api.spring.model.ActivationStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** @@ -32,8 +30,6 @@ @Component public class ActivationStatusConverter { - private static final Logger logger = LoggerFactory.getLogger(ActivationStatusConverter.class); - /** * Convert {@link ActivationStatus} from a {@link com.wultra.security.powerauth.client.model.enumeration.ActivationStatus} value. * @param activationStatus Activation status from PowerAuth client model. @@ -44,24 +40,13 @@ public ActivationStatus convertFrom(com.wultra.security.powerauth.client.model.e return null; } - switch (activationStatus) { - case CREATED: - return ActivationStatus.CREATED; - - case PENDING_COMMIT: - return ActivationStatus.PENDING_COMMIT; - - case ACTIVE: - return ActivationStatus.ACTIVE; - - case BLOCKED: - return ActivationStatus.BLOCKED; - - case REMOVED: - return ActivationStatus.REMOVED; - } - - return null; + return switch (activationStatus) { + case CREATED -> ActivationStatus.CREATED; + case PENDING_COMMIT -> ActivationStatus.PENDING_COMMIT; + case ACTIVE -> ActivationStatus.ACTIVE; + case BLOCKED -> ActivationStatus.BLOCKED; + case REMOVED -> ActivationStatus.REMOVED; + }; } } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java index f47a0f06..3033573c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/converter/SignatureTypeConverter.java @@ -65,20 +65,14 @@ public SignatureType convertFrom(String signatureTypeString) { * @return Signature type. */ public SignatureType convertFrom(PowerAuthSignatureTypes powerAuthSignatureTypes) { - switch (powerAuthSignatureTypes) { - case POSSESSION: - return SignatureType.POSSESSION; - case KNOWLEDGE: - return SignatureType.KNOWLEDGE; - case BIOMETRY: - return SignatureType.BIOMETRY; - case POSSESSION_KNOWLEDGE: - return SignatureType.POSSESSION_KNOWLEDGE; - case POSSESSION_BIOMETRY: - return SignatureType.POSSESSION_BIOMETRY; - default: - return null; - } + return switch (powerAuthSignatureTypes) { + case POSSESSION -> SignatureType.POSSESSION; + case KNOWLEDGE -> SignatureType.KNOWLEDGE; + case BIOMETRY -> SignatureType.BIOMETRY; + case POSSESSION_KNOWLEDGE -> SignatureType.POSSESSION_KNOWLEDGE; + case POSSESSION_BIOMETRY -> SignatureType.POSSESSION_BIOMETRY; + default -> null; + }; } } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java index acdc2aa6..97d2a564 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java @@ -22,39 +22,9 @@ /** * Class used for storing ECIES decryptor parameters. * + * @param secretKey ECIES secret key + * @param sharedInfo2 Parameter sharedInfo2 for ECIES. * @author Roman Strobl, roman.strobl@wultra.com */ -public class PowerAuthEciesDecryptorParameters { - - private final String secretKey; - private final String sharedInfo2; - - /** - * Constructor with secretKey and sharedInfo2. - * - * @param secretKey ECIES secret key. - * @param sharedInfo2 Parameter sharedInfo2 for ECIES. - */ - public PowerAuthEciesDecryptorParameters(String secretKey, String sharedInfo2) { - this.secretKey = secretKey; - this.sharedInfo2 = sharedInfo2; - } - - /** - * Get ECIES secret key. - * - * @return ECIES secret key. - */ - public String getSecretKey() { - return secretKey; - } - - /** - * Get parameter sharedInfo2 for ECIES. - * @return Parameter sharedInfo2 for ECIES. - */ - public String getSharedInfo2() { - return sharedInfo2; - } - +public record PowerAuthEciesDecryptorParameters(String secretKey, String sharedInfo2) { } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java index 9a23808e..024d0764 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java @@ -24,7 +24,7 @@ /** * Class used for storing data used during ECIES decryption and encryption. A reference to an initialized ECIES decryptor * is also stored so that response can be encrypted using same decryptor as used for request decryption. - * + *

* Use the T parameter to specify the type of request object to be decrypted. * * @author Roman Strobl, roman.strobl@wultra.com diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthActivationException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthActivationException.java index fa201ca5..13dbf5ea 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthActivationException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthActivationException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception related to processes during a new activation process. * @@ -26,6 +28,7 @@ */ public class PowerAuthActivationException extends Exception { + @Serial private static final long serialVersionUID = -7975115359211508795L; private static final String DEFAULT_CODE = "ERR_ACTIVATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthAuthenticationException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthAuthenticationException.java index cbd8b8a8..1157e90c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthAuthenticationException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthAuthenticationException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception raised in case PowerAuth authentication fails. * @@ -27,6 +29,7 @@ */ public class PowerAuthAuthenticationException extends Exception { + @Serial private static final long serialVersionUID = 4280095091435126237L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthEncryptionException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthEncryptionException.java index 64ae1c04..0151dfc6 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthEncryptionException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthEncryptionException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception raised in case encryption or decryption fails. * @@ -27,6 +29,7 @@ */ public class PowerAuthEncryptionException extends Exception { + @Serial private static final long serialVersionUID = -4247463135868495185L; private static final String DEFAULT_CODE = "ERR_ENCRYPTION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthRecoveryException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthRecoveryException.java index 80721ccc..07e85ebe 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthRecoveryException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthRecoveryException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception thrown in case PowerAuth recovery fails, with optional current PUK index. * @@ -26,6 +28,7 @@ */ public class PowerAuthRecoveryException extends Exception { + @Serial private static final long serialVersionUID = 6497199187989286105L; private static final String DEFAULT_CODE = "ERR_RECOVERY"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthSecureVaultException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthSecureVaultException.java index e676947c..eeecd0c5 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthSecureVaultException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthSecureVaultException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception related to processes during a new secure vault unlocking. * @@ -26,6 +28,7 @@ */ public class PowerAuthSecureVaultException extends Exception { + @Serial private static final long serialVersionUID = -6996857964853505534L; private static final String DEFAULT_CODE = "ERR_SECURE_VAULT"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUpgradeException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUpgradeException.java index d5af05f7..d3f00c82 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUpgradeException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUpgradeException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception raised in case PowerAuth upgrade fails. * @@ -27,6 +29,7 @@ */ public class PowerAuthUpgradeException extends Exception { + @Serial private static final long serialVersionUID = -5750221213611810117L; private static final String DEFAULT_CODE = "ERR_UPGRADE"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java index 30ba8cf3..6a79d21f 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/PowerAuthUserInfoException.java @@ -19,6 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.exception; +import java.io.Serial; + /** * Exception for endpoints related to the user info endpoint. * @@ -26,6 +28,7 @@ */ public class PowerAuthUserInfoException extends Exception { + @Serial private static final long serialVersionUID = 5046389522294059168L; private static final String DEFAULT_CODE = "ERR_USER_INFO"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthHeaderMissingException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthHeaderMissingException.java index cc2a8652..c5dcea7b 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthHeaderMissingException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthHeaderMissingException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth HTTP header is missing. * @@ -29,6 +31,7 @@ */ public class PowerAuthHeaderMissingException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = -2359879611684674690L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java index 42ab5a21..7c745110 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth authentication request is invalid. * @@ -29,6 +31,7 @@ */ public class PowerAuthInvalidRequestException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = -6068516562428771519L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRecoveryConfirmationException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRecoveryConfirmationException.java index 5fd70d88..b0abc2ab 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRecoveryConfirmationException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRecoveryConfirmationException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth recovery confirmation fails with an error. * @@ -29,6 +31,7 @@ */ public class PowerAuthRecoveryConfirmationException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = 7840709829931142914L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRequestFilterException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRequestFilterException.java index 571368b1..6f9147d8 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRequestFilterException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthRequestFilterException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth authentication request filter is missing. * @@ -29,6 +31,7 @@ */ public class PowerAuthRequestFilterException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = -6832983011115467428L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureErrorException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureErrorException.java index 0a818b8e..1d72a09f 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureErrorException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureErrorException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth signature validation fails with an error. * @@ -29,6 +31,7 @@ */ public class PowerAuthSignatureErrorException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = 1428981649658439163L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureInvalidException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureInvalidException.java index 253ca895..31b150a7 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureInvalidException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureInvalidException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth signature validation fails. * @@ -29,6 +31,7 @@ */ public class PowerAuthSignatureInvalidException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = -8628851623611808408L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureTypeInvalidException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureTypeInvalidException.java index 678a7849..70339874 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureTypeInvalidException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthSignatureTypeInvalidException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth signature type is invalid. * @@ -29,6 +31,7 @@ */ public class PowerAuthSignatureTypeInvalidException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = 6914310542180702420L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenErrorException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenErrorException.java index 7d386678..a1e81c9a 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenErrorException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenErrorException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth token validation fails with an error. * @@ -29,6 +31,7 @@ */ public class PowerAuthTokenErrorException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = 3900547437080764802L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenInvalidException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenInvalidException.java index 50596161..044ebe40 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenInvalidException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthTokenInvalidException.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; +import java.io.Serial; + /** * Exception raised in case PowerAuth token validation fails. * @@ -29,6 +31,7 @@ */ public class PowerAuthTokenInvalidException extends PowerAuthAuthenticationException { + @Serial private static final long serialVersionUID = 1052831183125328518L; private static final String DEFAULT_CODE = "ERR_AUTHENTICATION"; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java index 82d56c2b..7ccc6e12 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/PowerAuthRequestFilterBase.java @@ -63,7 +63,7 @@ public static ResettableStreamHttpServletRequest filterRequest(HttpServletReques if (queryString != null && queryString.length() > 0) { // Decode the query string - queryString = URLDecoder.decode(queryString, "UTF-8"); + queryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8); // Get the canonized form final String signatureBaseStringData = PowerAuthRequestCanonizationUtils.canonizeGetParameters(queryString); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index f076b4bc..1d695bc0 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -41,12 +41,12 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Type; import java.util.Base64; @@ -153,26 +153,25 @@ public abstract class PowerAuthEncryptionProviderBase { final PowerAuthEciesDecryptorParameters decryptorParameters; // Obtain ECIES decryptor parameters from PowerAuth server switch (eciesScope) { - case ACTIVATION_SCOPE: + case ACTIVATION_SCOPE -> { final String activationId = eciesEncryption.getContext().getActivationId(); if (activationId == null) { logger.warn("Activation ID is required in ECIES activation scope"); throw new PowerAuthEncryptionException(); } decryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey); - break; - case APPLICATION_SCOPE: - decryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey); - break; - default: + } + case APPLICATION_SCOPE -> decryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey); + default -> { logger.warn("Unsupported ECIES scope: {}", eciesScope); throw new PowerAuthEncryptionException(); + } } // Prepare envelope key and sharedInfo2 parameter for decryptor - final byte[] secretKey = Base64.getDecoder().decode(decryptorParameters.getSecretKey()); + final byte[] secretKey = Base64.getDecoder().decode(decryptorParameters.secretKey()); final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); - final byte[] sharedInfo2 = Base64.getDecoder().decode(decryptorParameters.getSharedInfo2()); + final byte[] sharedInfo2 = Base64.getDecoder().decode(decryptorParameters.sharedInfo2()); // Construct decryptor and set it to the request for later encryption of response final EciesDecryptor eciesDecryptor = eciesFactory.getEciesDecryptor(envelopeKey, sharedInfo2); diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index 5934b188..0212cb6c 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -54,13 +54,6 @@ - - - org.projectlombok - lombok - provided - - diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java index 6a01c1a7..cba0f7fd 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java @@ -19,23 +19,13 @@ */ package io.getlime.security.powerauth.rest.api.spring.controller; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.rest.api.model.request.UserInfoRequest; import io.getlime.security.powerauth.rest.api.model.response.ServerStatusResponse; -import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; -import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; -import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; -import io.getlime.security.powerauth.rest.api.spring.service.UserInfoService; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; -import java.util.Map; /** * Controller that provides a user information. diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 481ed359..15c9b063 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -146,7 +146,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request switch (request.getType()) { // Regular activation which uses "code" identity attribute - case CODE: { + case CODE -> { // Check if identity attributes are present if (identity == null || identity.isEmpty()) { @@ -243,8 +243,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } + // Custom activation - case CUSTOM: { + case CUSTOM -> { // Check if there is a custom activation provider available, return an error in case it is not available. // Only for CUSTOM activations, proceeding without an activation provider does not make a sensible use-case. if (activationProvider == null) { @@ -271,7 +272,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Decide if the recovery codes should be generated - final Boolean shouldGenerateRecoveryCodes = activationProvider.shouldCreateRecoveryCodes(identity, customAttributes, ActivationType.CODE, context); + final boolean shouldGenerateRecoveryCodes = activationProvider.shouldCreateRecoveryCodes(identity, customAttributes, ActivationType.CODE, context); // Resolve maxFailedCount and activationExpireTimestamp parameters, null value means use value configured on PowerAuth server final Integer maxFailed = activationProvider.getMaxFailedAttemptCount(identity, customAttributes, userId, ActivationType.CUSTOM, context); @@ -352,8 +353,9 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } + // Activation using recovery code - case RECOVERY: { + case RECOVERY -> { // Check if identity attributes are present if (identity == null || identity.isEmpty()) { @@ -457,14 +459,13 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request // Prepare and return encrypted response return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); } - - default: + default -> { logger.warn("Invalid activation request"); throw new PowerAuthInvalidRequestException(); + } } } catch (PowerAuthClientException ex) { - if (ex.getPowerAuthError() instanceof PowerAuthErrorRecovery) { - final PowerAuthErrorRecovery errorRecovery = (PowerAuthErrorRecovery) ex.getPowerAuthError(); + if (ex.getPowerAuthError() instanceof final PowerAuthErrorRecovery errorRecovery) { logger.debug("Invalid recovery code, current PUK index: {}", errorRecovery.getCurrentRecoveryPukIndex()); throw new PowerAuthRecoveryException(ex.getMessage(), "INVALID_RECOVERY_CODE", errorRecovery.getCurrentRecoveryPukIndex()); } From afcca8f47ea6e4401db2abb200eb5340bf8a02be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 09:05:10 +0000 Subject: [PATCH 40/64] Bump spring-boot-dependencies from 3.0.5 to 3.1.0 Bumps [spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.0.5 to 3.1.0. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.0.5...v3.1.0) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 bc9c79e6..728319d9 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.5.0 3.2.1 3.3.2 - 3.0.5 + 3.1.0 1.10.0 1.73 1.7.0-SNAPSHOT From 8909c766d99ebae2da366ebf5e4528b66de33b8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:01:21 +0000 Subject: [PATCH 41/64] Bump bcprov-jdk18on from 1.73 to 1.74 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.73 to 1.74. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on 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 728319d9..752a7068 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.0 1.10.0 - 1.73 + 1.74 1.7.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT From a328c08dfb386f2c4cbc1a43590c0c107c41f555 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:01:26 +0000 Subject: [PATCH 42/64] Bump maven-war-plugin from 3.3.2 to 3.4.0 Bumps [maven-war-plugin](https://github.com/apache/maven-war-plugin) from 3.3.2 to 3.4.0. - [Commits](https://github.com/apache/maven-war-plugin/compare/maven-war-plugin-3.3.2...maven-war-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-war-plugin 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 728319d9..82706bbf 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.1.1 3.5.0 3.2.1 - 3.3.2 + 3.4.0 3.1.0 1.10.0 1.73 From e9a858b3f8288a2c42d06cd3d80d811fde733a15 Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Wed, 21 Jun 2023 10:33:14 +0200 Subject: [PATCH 43/64] Fix #408: Invalid primitive data type for getTimestamp --- .../powerauth/rest/api/model/request/EciesEncryptedRequest.java | 2 +- .../rest/api/model/response/EciesEncryptedResponse.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java index 5420b1a2..bc53a5d4 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/request/EciesEncryptedRequest.java @@ -100,7 +100,7 @@ public void setNonce(String nonce) { * Get request timestamp as unix timestamp in milliseconds. * @return Request timestamp. */ - public long getTimestamp() { + public Long getTimestamp() { return timestamp; } diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java index fef2a0ae..2d36dc0b 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java @@ -82,7 +82,7 @@ public void setMac(String mac) { * Get response timestamp as unix timestamp in milliseconds. * @return Response timestamp. */ - public long getTimestamp() { + public Long getTimestamp() { return timestamp; } From e8af2dfb0d60d1db749758a42ded2f9f72c40bbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 08:01:26 +0000 Subject: [PATCH 44/64] Bump bcprov-jdk18on from 1.74 to 1.75 Bumps [bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.74 to 1.75. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on 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 752a7068..c1d70a62 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.0 1.10.0 - 1.74 + 1.75 1.7.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT From ac96b07c0a0bf086526df9acf4fa8edd10b1332c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 05:29:19 +0000 Subject: [PATCH 45/64] Bump org.springframework.boot:spring-boot-dependencies Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.1.0 to 3.1.2. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.0...v3.1.2) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 c1d70a62..9ee6418b 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.5.0 3.2.1 3.3.2 - 3.1.0 + 3.1.2 1.10.0 1.75 1.7.0-SNAPSHOT From e4a3b8c6764bf9ccf846bdb6ef64b534742c9e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0trobl?= Date: Sun, 30 Jul 2023 00:43:48 +0200 Subject: [PATCH 46/64] Update ECIES implementation for crypto 3.2 (#413) --- .../response/EciesEncryptedResponse.java | 42 ++++++- .../encryption/EciesEncryptionContext.java | 17 +++ .../encryption/PowerAuthEciesEncryption.java | 35 ++++++ .../filter/EncryptionResponseBodyAdvice.java | 42 +++++-- .../provider/PowerAuthEncryptionProvider.java | 5 +- .../PowerAuthEncryptionProviderBase.java | 113 +++++++++++++++--- .../spring/controller/RecoveryController.java | 4 + .../controller/SecureVaultController.java | 5 + .../spring/controller/TokenController.java | 4 + .../spring/controller/UpgradeController.java | 5 + .../api/spring/service/ActivationService.java | 28 ++++- .../api/spring/service/RecoveryService.java | 6 +- .../spring/service/SecureVaultService.java | 6 +- .../rest/api/spring/service/TokenService.java | 7 ++ .../api/spring/service/UpgradeService.java | 6 + 15 files changed, 289 insertions(+), 36 deletions(-) diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java index 2d36dc0b..d44573fa 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java @@ -26,8 +26,10 @@ */ public class EciesEncryptedResponse { + private String ephemeralPublicKey; private String encryptedData; private String mac; + private String nonce; private Long timestamp; /** @@ -40,10 +42,32 @@ public EciesEncryptedResponse() { * Constructor with Base64 encoded encrypted data and MAC of key and data. * @param encryptedData Encrypted data. * @param mac MAC of key and data. + * @param ephemeralPublicKey Ephemeral public key. + * @param nonce ECIES nonce. + * @param timestamp Unix timestamp in milliseconds. */ - public EciesEncryptedResponse(String encryptedData, String mac) { + public EciesEncryptedResponse(String encryptedData, String mac, String ephemeralPublicKey, String nonce, Long timestamp) { this.encryptedData = encryptedData; this.mac = mac; + this.ephemeralPublicKey = ephemeralPublicKey; + this.nonce = nonce; + this.timestamp = timestamp; + } + + /** + * Get ephemeral public key. + * @return Ephemeral public key. + */ + public String getEphemeralPublicKey() { + return ephemeralPublicKey; + } + + /** + * Set ephemeral public key. + * @param ephemeralPublicKey Ephemeral public key. + */ + public void setEphemeralPublicKey(String ephemeralPublicKey) { + this.ephemeralPublicKey = ephemeralPublicKey; } /** @@ -78,6 +102,22 @@ public void setMac(String mac) { this.mac = mac; } + /** + * Get nonce. + * @return Nonce. + */ + public String getNonce() { + return nonce; + } + + /** + * Set nonce. + * @param nonce Nonce. + */ + public void setNonce(String nonce) { + this.nonce = nonce; + } + /** * Get response timestamp as unix timestamp in milliseconds. * @return Response timestamp. diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java index a02c9382..5104cb04 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java @@ -34,6 +34,7 @@ public class EciesEncryptionContext { private String activationId; private String version; private EciesScope eciesScope; + private String ephemeralPublicKey; private PowerAuthHttpHeader httpHeader; /** @@ -127,6 +128,22 @@ public void setEciesScope(EciesScope eciesScope) { this.eciesScope = eciesScope; } + /** + * Get ephemeral public key in Base64 encoding. + * @return Ephemeral public key. + */ + public String getEphemeralPublicKey() { + return ephemeralPublicKey; + } + + /** + * Set ephemeral public key bytes in Base64 encoding. + * @param ephemeralPublicKey Ephemeral public key bytes. + */ + public void setEphemeralPublicKey(String ephemeralPublicKey) { + this.ephemeralPublicKey = ephemeralPublicKey; + } + /** * Get PowerAuth HTTP header used for deriving ECIES encryption context. * diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java index 024d0764..c2f2715d 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java @@ -20,6 +20,7 @@ package io.getlime.security.powerauth.rest.api.spring.encryption; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; /** * Class used for storing data used during ECIES decryption and encryption. A reference to an initialized ECIES decryptor @@ -33,8 +34,10 @@ public class PowerAuthEciesEncryption { private final EciesEncryptionContext context; private EciesDecryptor eciesDecryptor; + private EciesEncryptor eciesEncryptor; private byte[] encryptedRequest; private byte[] decryptedRequest; + private byte[] associatedData; private Object requestObject; /** @@ -70,6 +73,22 @@ public void setEciesDecryptor(EciesDecryptor eciesDecryptor) { this.eciesDecryptor = eciesDecryptor; } + /** + * Get ECIES encryptor. + * @return eciesEncryptor ECIES encryptor. + */ + public EciesEncryptor getEciesEncryptor() { + return eciesEncryptor; + } + + /** + * Set ECIES encryptor. + * @param eciesEncryptor ECIES encryptor. + */ + public void setEciesEncryptor(EciesEncryptor eciesEncryptor) { + this.eciesEncryptor = eciesEncryptor; + } + /** * Get encrypted request data. * @return Encrypted request data. @@ -102,6 +121,22 @@ public void setDecryptedRequest(byte[] decryptedRequest) { this.decryptedRequest = decryptedRequest; } + /** + * Get ECIES data associated with request and response. + * @return ECIES data associated with request and response. + */ + public byte[] getAssociatedData() { + return associatedData; + } + + /** + * Set ECIES data associated with request and response. + * @param associatedData ECIES data associated with request and response. + */ + public void setAssociatedData(byte[] associatedData) { + this.associatedData = associatedData; + } + /** * Get decrypted request object. * @return Decrypted request object. diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index edd7ea71..968355f8 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -20,8 +20,10 @@ package io.getlime.security.powerauth.rest.api.spring.filter; import com.fasterxml.jackson.databind.ObjectMapper; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; +import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; @@ -52,6 +54,7 @@ import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.Date; import java.util.List; /** @@ -121,14 +124,37 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa try { byte[] responseBytes = serializeResponseObject(response); - // Encrypt response using decryptor and return ECIES cryptogram - final EciesDecryptor eciesDecryptor = eciesEncryption.getEciesDecryptor(); - final EciesCryptogram cryptogram = eciesDecryptor.encryptResponse(responseBytes); - final String encryptedDataBase64 = Base64.getEncoder().encodeToString(cryptogram.getEncryptedData()); - final String macBase64 = Base64.getEncoder().encodeToString(cryptogram.getMac()); + // Encrypt response using encryptor and return ECIES cryptogram + final EciesEncryptor eciesEncryptor = eciesEncryption.getEciesEncryptor(); + final String version = eciesEncryption.getContext().getVersion(); + final EciesParameters eciesParameters; + final String nonce; + final Long timestamp; + if ("3.2".equals(version)) { + final byte[] associatedData = eciesEncryption.getAssociatedData(); + final byte[] nonceBytes = new KeyGenerator().generateRandomBytes(16); + nonce = Base64.getEncoder().encodeToString(nonceBytes); + timestamp = new Date().getTime(); + eciesParameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); + } else if ("3.1".equals(version)) { + final byte[] nonceBytes = new KeyGenerator().generateRandomBytes(16); + nonce = Base64.getEncoder().encodeToString(nonceBytes); + timestamp = null; + eciesParameters = EciesParameters.builder().nonce(nonceBytes).build(); + } else { + nonce = null; + timestamp = null; + eciesParameters = EciesParameters.builder().build(); + } + + final EciesPayload payload = eciesEncryptor.encrypt(responseBytes, eciesParameters); + final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); + final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); + final String ephemeralPublicKey64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEphemeralPublicKey()); // Return encrypted response with type given by converter class - final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64); + final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64, ephemeralPublicKey64, + nonce, timestamp); if (converterClass.isAssignableFrom(MappingJackson2HttpMessageConverter.class)) { // Object conversion is done automatically using MappingJackson2HttpMessageConverter return encryptedResponse; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java index 2b186eed..d4706be6 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java @@ -59,12 +59,15 @@ public PowerAuthEncryptionProvider(PowerAuthClient powerAuthClient, HttpCustomiz } @Override - public @Nonnull PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey) throws PowerAuthEncryptionException { + public @Nonnull PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException { try { final GetEciesDecryptorRequest eciesDecryptorRequest = new GetEciesDecryptorRequest(); eciesDecryptorRequest.setActivationId(activationId); eciesDecryptorRequest.setApplicationKey(applicationKey); eciesDecryptorRequest.setEphemeralPublicKey(ephemeralPublicKey); + eciesDecryptorRequest.setProtocolVersion(version); + eciesDecryptorRequest.setNonce(nonce); + eciesDecryptorRequest.setTimestamp(timestamp); final GetEciesDecryptorResponse eciesDecryptorResponse = powerAuthClient.getEciesDecryptor( eciesDecryptorRequest, httpCustomizationService.getQueryParams(), diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index 1d695bc0..ed7afee7 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -24,10 +24,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEnvelopeKey; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; +import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; @@ -50,6 +55,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.Base64; +import java.util.Date; /** * Abstract class for PowerAuth encryption provider with common HTTP header parsing logic. The class is available for @@ -64,29 +70,35 @@ public abstract class PowerAuthEncryptionProviderBase { private final ObjectMapper objectMapper = new ObjectMapper(); private final EciesFactory eciesFactory = new EciesFactory(); + private final KeyGenerator keyGenerator = new KeyGenerator(); /** * Get ECIES decryptor parameters from PowerAuth server. * - * @param activationId Activation ID (only used in activation scope, in application scope use null). - * @param applicationKey Application key. + * @param activationId Activation ID (only used in activation scope, in application scope use null). + * @param applicationKey Application key. * @param ephemeralPublicKey Ephemeral public key for ECIES. + * @param version ECIES protocol version. + * @param nonce ECIES nonce. + * @param timestamp Timestamp for ECIES. * @return ECIES decryptor parameters. * @throws PowerAuthEncryptionException In case PowerAuth server call fails. */ - public abstract @Nonnull PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey) throws PowerAuthEncryptionException; + public abstract @Nonnull + PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException; /** * Decrypt HTTP request body and construct object with ECIES data. Use the requestType parameter to specify * the type of decrypted object. * - * @param request HTTP request. + * @param request HTTP request. * @param requestType Class of request object. - * @param eciesScope ECIES scope. + * @param eciesScope ECIES scope. * @return Object with ECIES data. * @throws PowerAuthEncryptionException In case request decryption fails. */ - public @Nonnull PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @Nonnull Type requestType, @Nonnull EciesScope eciesScope) throws PowerAuthEncryptionException { + public @Nonnull + PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @Nonnull Type requestType, @Nonnull EciesScope eciesScope) throws PowerAuthEncryptionException { // Only POST HTTP method is supported for ECIES if (!"POST".equals(request.getMethod())) { logger.warn("Invalid HTTP method: {}", request.getMethod()); @@ -133,6 +145,7 @@ public abstract class PowerAuthEncryptionProviderBase { final String encryptedData = eciesRequest.getEncryptedData(); final String mac = eciesRequest.getMac(); final String nonce = eciesRequest.getNonce(); + final Long timestamp = eciesRequest.getTimestamp(); // Verify ECIES request data. Nonce is required for protocol 3.1+ if (ephemeralPublicKey == null || encryptedData == null || mac == null) { @@ -143,6 +156,13 @@ public abstract class PowerAuthEncryptionProviderBase { logger.warn("Missing nonce in ECIES request data"); throw new PowerAuthEncryptionException(); } + if (timestamp == null && (!"3.0".equals(encryptionContext.getVersion()) && !"3.1".equals(encryptionContext.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); + throw new PowerAuthEncryptionException(); + } + + // Save ephemeral public key in context + eciesEncryption.getContext().setEphemeralPublicKey(ephemeralPublicKey); final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); final byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData); @@ -152,6 +172,7 @@ public abstract class PowerAuthEncryptionProviderBase { final String applicationKey = eciesEncryption.getContext().getApplicationKey(); final PowerAuthEciesDecryptorParameters decryptorParameters; // Obtain ECIES decryptor parameters from PowerAuth server + final byte[] associatedData; switch (eciesScope) { case ACTIVATION_SCOPE -> { final String activationId = eciesEncryption.getContext().getActivationId(); @@ -159,9 +180,13 @@ public abstract class PowerAuthEncryptionProviderBase { logger.warn("Activation ID is required in ECIES activation scope"); throw new PowerAuthEncryptionException(); } - decryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey); + decryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonce, timestamp); + associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, encryptionContext.getVersion(), applicationKey, activationId) : null; + } + case APPLICATION_SCOPE -> { + decryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonce, timestamp); + associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, encryptionContext.getVersion(), applicationKey, null) : null; } - case APPLICATION_SCOPE -> decryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey); default -> { logger.warn("Unsupported ECIES scope: {}", eciesScope); throw new PowerAuthEncryptionException(); @@ -173,15 +198,20 @@ public abstract class PowerAuthEncryptionProviderBase { final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); final byte[] sharedInfo2 = Base64.getDecoder().decode(decryptorParameters.sharedInfo2()); - // Construct decryptor and set it to the request for later encryption of response + // Construct decryptor and encryptor final EciesDecryptor eciesDecryptor = eciesFactory.getEciesDecryptor(envelopeKey, sharedInfo2); + final EciesEncryptor eciesEncryptor = eciesFactory.getEciesEncryptor(envelopeKey, sharedInfo2); eciesEncryption.setEciesDecryptor(eciesDecryptor); + eciesEncryption.setEciesEncryptor(eciesEncryptor); // Decrypt request data - final EciesCryptogram cryptogram = new EciesCryptogram(ephemeralPublicKeyBytes, macBytes, encryptedDataBytes, nonceBytes); - final byte[] decryptedData = eciesDecryptor.decryptRequest(cryptogram); + final EciesParameters parameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); + final EciesCryptogram cryptogram = EciesCryptogram.builder().encryptedData(encryptedDataBytes).mac(macBytes).ephemeralPublicKey(ephemeralPublicKeyBytes).build(); + final EciesPayload payload = new EciesPayload(cryptogram, parameters); + final byte[] decryptedData = eciesDecryptor.decrypt(payload); eciesEncryption.setEncryptedRequest(encryptedDataBytes); eciesEncryption.setDecryptedRequest(decryptedData); + eciesEncryption.setAssociatedData(associatedData); // Set the request object only in case when request data is sent if (decryptedData.length != 0) { eciesEncryption.setRequestObject(deserializeRequestData(decryptedData, requestType)); @@ -200,18 +230,64 @@ public abstract class PowerAuthEncryptionProviderBase { /** * Encrypt response using ECIES. * - * @param responseObject Response object which should be encrypted. + * @param responseObject Response object which should be encrypted. * @param eciesEncryption PowerAuth encryption object. * @return ECIES encrypted response. */ - public @Nullable EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull PowerAuthEciesEncryption eciesEncryption) { + public @Nullable + EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull PowerAuthEciesEncryption eciesEncryption) { try { + final EciesEncryptionContext encryptionContext = eciesEncryption.getContext(); + final EciesScope eciesScope = encryptionContext.getEciesScope(); + + final String applicationKey = eciesEncryption.getContext().getApplicationKey(); + final String ephemeralPublicKey = eciesEncryption.getContext().getEphemeralPublicKey(); + final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); + + final PowerAuthEciesDecryptorParameters encryptorParameters; + // Obtain ECIES decryptor parameters from PowerAuth server + final byte[] associatedData; + final String version = eciesEncryption.getContext().getVersion(); + final byte[] nonceBytesResponse = "3.2".equals(version) ? keyGenerator.generateRandomBytes(16) : null; + final String nonceResponse = Base64.getEncoder().encodeToString(nonceBytesResponse); + final Long timestampResponse = "3.2".equals(version) ? new Date().getTime() : null; + switch (eciesScope) { + case ACTIVATION_SCOPE -> { + final String activationId = eciesEncryption.getContext().getActivationId(); + if (activationId == null) { + logger.warn("Activation ID is required in ECIES activation scope"); + throw new PowerAuthEncryptionException(); + } + encryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonceResponse, timestampResponse); + associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, encryptionContext.getVersion(), applicationKey, activationId) : null; + } + case APPLICATION_SCOPE -> { + encryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonceResponse, timestampResponse); + associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, encryptionContext.getVersion(), applicationKey, null) : null; + } + default -> { + logger.warn("Unsupported ECIES scope: {}", eciesScope); + throw new PowerAuthEncryptionException(); + } + } + + // Prepare envelope key and sharedInfo2 parameter for encryptor + final byte[] secretKey = Base64.getDecoder().decode(encryptorParameters.secretKey()); + final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); + final byte[] sharedInfo2 = Base64.getDecoder().decode(encryptorParameters.sharedInfo2()); + final byte[] responseData = serializeResponseData(responseObject); - // Encrypt response using decryptor and return ECIES cryptogram - final EciesCryptogram cryptogram = eciesEncryption.getEciesDecryptor().encryptResponse(responseData); - final String encryptedDataBase64 = Base64.getEncoder().encodeToString(cryptogram.getEncryptedData()); - final String macBase64 = Base64.getEncoder().encodeToString(cryptogram.getMac()); - return new EciesEncryptedResponse(encryptedDataBase64, macBase64); + // Encrypt response using encryptor and return ECIES cryptogram + final EciesParameters parametersResponse = EciesParameters.builder().nonce(nonceBytesResponse).associatedData(associatedData).timestamp(timestampResponse).build(); + final EciesEncryptor encryptor = eciesFactory.getEciesEncryptor(envelopeKey, sharedInfo2); + // Store ECIES encryptor + eciesEncryption.setEciesEncryptor(encryptor); + + final EciesPayload payload = encryptor.encrypt(responseData, parametersResponse); + final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); + final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); + final String ephemeralPublicKey64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEphemeralPublicKey()); + return new EciesEncryptedResponse(encryptedDataBase64, macBase64, ephemeralPublicKey64, nonceResponse, timestampResponse); } catch (Exception ex) { logger.debug("Response encryption failed, error: " + ex.getMessage(), ex); return null; @@ -310,5 +386,4 @@ private EciesEncryptionContext extractEciesEncryptionContext(HttpServletRequest return new EciesEncryptionContext(applicationKey, activationId, version, header); } } - } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java index a0ebd128..bf37a9de 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java @@ -90,6 +90,10 @@ public EciesEncryptedResponse confirmRecoveryCode(@RequestBody EciesEncryptedReq logger.warn("Missing nonce in ECIES request data"); throw new PowerAuthInvalidRequestException(); } + if (request.getTimestamp() == null && (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); + throw new PowerAuthInvalidRequestException(); + } return recoveryService.confirmRecoveryCode(request, authentication); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java index 8ca1b20c..176c82ba 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java @@ -109,6 +109,11 @@ public EciesEncryptedResponse unlockVault( throw new PowerAuthInvalidRequestException(); } + if (request.getTimestamp() == null && (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); + throw new PowerAuthInvalidRequestException(); + } + return secureVaultServiceV3.vaultUnlock(header, request, httpServletRequest); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java index 2fe425e0..917d9cb4 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java @@ -99,6 +99,10 @@ public EciesEncryptedResponse createToken(@RequestBody EciesEncryptedRequest req logger.warn("Missing nonce in ECIES request data"); throw new PowerAuthInvalidRequestException(); } + if (request.getTimestamp() == null && (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); + throw new PowerAuthInvalidRequestException(); + } return tokenServiceV3.createToken(request, authentication); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java index 6327b055..df86489a 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java @@ -107,6 +107,11 @@ public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest re throw new PowerAuthUpgradeException(); } + if (request.getTimestamp() == null && (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); + throw new PowerAuthUpgradeException(); + } + return upgradeService.upgradeStart(request, header); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 15c9b063..13d8cc0e 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -135,12 +135,17 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request final String encryptedData = activationData.getEncryptedData(); final String mac = activationData.getMac(); final String nonce = activationData.getNonce(); + final Long timestamp = activationData.getTimestamp(); final Map identity = request.getIdentityAttributes(); final Map customAttributes = (request.getCustomAttributes() != null) ? request.getCustomAttributes() : new HashMap<>(); // Validate inner encryption if (nonce == null && !"3.0".equals(eciesContext.getVersion())) { - logger.warn("Missing nonce for protocol version: {}", eciesContext.getVersion()); + logger.warn("Missing nonce in ECIES request data"); + throw new PowerAuthActivationException(); + } + if (timestamp == null && (!"3.0".equals(eciesContext.getVersion()) && !"3.1".equals(eciesContext.getVersion()))) { + logger.warn("Missing timestamp in ECIES request data"); throw new PowerAuthActivationException(); } @@ -174,6 +179,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request prepareRequest.setEncryptedData(encryptedData); prepareRequest.setMac(mac); prepareRequest.setNonce(nonce); + prepareRequest.setProtocolVersion(eciesContext.getVersion()); + prepareRequest.setTimestamp(timestamp); final PrepareActivationResponse response = powerAuthClient.prepareActivation( prepareRequest, httpCustomizationService.getQueryParams(), @@ -240,7 +247,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare and return encrypted response - return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); + return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } @@ -295,6 +303,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request createRequest.setEncryptedData(encryptedData); createRequest.setMac(mac); createRequest.setNonce(nonce); + createRequest.setProtocolVersion(eciesContext.getVersion()); + createRequest.setTimestamp(timestamp); final CreateActivationResponse response = powerAuthClient.createActivation( createRequest, httpCustomizationService.getQueryParams(), @@ -350,7 +360,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare encrypted activation data - return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); + return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } @@ -400,6 +411,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request recoveryRequest.setEncryptedData(encryptedData); recoveryRequest.setMac(mac); recoveryRequest.setNonce(nonce); + recoveryRequest.setProtocolVersion(eciesContext.getVersion()); + recoveryRequest.setTimestamp(timestamp); final RecoveryCodeActivationResponse response = powerAuthClient.createActivationUsingRecoveryCode( recoveryRequest, httpCustomizationService.getQueryParams(), @@ -457,7 +470,8 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare and return encrypted response - return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), processedCustomAttributes, userInfo); + return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } default -> { logger.warn("Invalid activation request"); @@ -580,16 +594,20 @@ public ActivationRemoveResponse removeActivation(PowerAuthApiAuthentication apiA /** * Prepare payload for the encrypted response. * + * @param ephemeralPublicKey Ephemeral public key for ECIES. * @param encryptedData Encrypted data. * @param mac MAC code of the encrypted data. * @param processedCustomAttributes Custom attributes to be returned. * @return Encrypted response object. */ - private ActivationLayer1Response prepareEncryptedResponse(String encryptedData, String mac, Map processedCustomAttributes, Map userInfo) { + private ActivationLayer1Response prepareEncryptedResponse(String ephemeralPublicKey, String encryptedData, String mac, String nonce, Long timestmap, Map processedCustomAttributes, Map userInfo) { // Prepare encrypted response object for layer 2 final EciesEncryptedResponse encryptedResponseL2 = new EciesEncryptedResponse(); encryptedResponseL2.setEncryptedData(encryptedData); encryptedResponseL2.setMac(mac); + encryptedResponseL2.setEphemeralPublicKey(ephemeralPublicKey); + encryptedResponseL2.setNonce(nonce); + encryptedResponseL2.setTimestamp(timestmap); // The response is encrypted once more before sent to client using ResponseBodyAdvice final ActivationLayer1Response responseL1 = new ActivationLayer1Response(); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java index e02107c0..bf31208a 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java @@ -87,7 +87,10 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, confirmRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); confirmRequest.setEncryptedData(request.getEncryptedData()); confirmRequest.setMac(request.getMac()); + confirmRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); confirmRequest.setNonce(request.getNonce()); + confirmRequest.setProtocolVersion(httpHeader.getVersion()); + confirmRequest.setTimestamp(request.getTimestamp()); final ConfirmRecoveryCodeResponse paResponse = powerAuthClient.confirmRecoveryCode( confirmRequest, httpCustomizationService.getQueryParams(), @@ -97,7 +100,8 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, logger.warn("PowerAuth confirm recovery failed because of invalid activation ID in response"); throw new PowerAuthInvalidRequestException(); } - return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac()); + return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), paResponse.getEphemeralPublicKey(), + paResponse.getNonce(), paResponse.getTimestamp()); } catch (Exception ex) { logger.warn("PowerAuth confirm recovery failed, error: {}", ex.getMessage()); logger.debug(ex.getMessage(), ex); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java index 80c319d9..5fe74731 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java @@ -105,6 +105,7 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, final String encryptedData = request.getEncryptedData(); final String mac = request.getMac(); final String eciesNonce = request.getNonce(); + final Long timestamp = request.getTimestamp(); // Prepare data for signature to allow signature verification on PowerAuth server final byte[] requestBodyBytes = authenticationProvider.extractRequestBodyBytes(httpServletRequest); @@ -121,7 +122,9 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, unlockRequest.setEphemeralPublicKey(ephemeralPublicKey); unlockRequest.setEncryptedData(encryptedData); unlockRequest.setMac(mac); + unlockRequest.setEphemeralPublicKey(ephemeralPublicKey); unlockRequest.setNonce(eciesNonce); + unlockRequest.setTimestamp(timestamp); final VaultUnlockResponse paResponse = powerAuthClient.unlockVault( unlockRequest, httpCustomizationService.getQueryParams(), @@ -133,7 +136,8 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, throw new PowerAuthSignatureInvalidException(); } - return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac()); + return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), + paResponse.getEphemeralPublicKey(), paResponse.getNonce(), paResponse.getTimestamp()); } catch (PowerAuthAuthenticationException ex) { throw ex; } catch (Exception ex) { diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java index 074378e4..0e0ff211 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java @@ -89,6 +89,7 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, final String encryptedData = request.getEncryptedData(); final String mac = request.getMac(); final String nonce = request.getNonce(); + final Long timestamp = request.getTimestamp(); // Prepare a signature type converter final SignatureTypeConverter converter = new SignatureTypeConverter(); @@ -110,8 +111,11 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, tokenRequest.setEphemeralPublicKey(ephemeralPublicKey); tokenRequest.setEncryptedData(encryptedData); tokenRequest.setMac(mac); + tokenRequest.setEphemeralPublicKey(ephemeralPublicKey); tokenRequest.setNonce(nonce); tokenRequest.setSignatureType(signatureType); + tokenRequest.setProtocolVersion(httpHeader.getVersion()); + tokenRequest.setTimestamp(timestamp); final CreateTokenResponse token = powerAuthClient.createToken( tokenRequest, httpCustomizationService.getQueryParams(), @@ -122,6 +126,9 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, final EciesEncryptedResponse response = new EciesEncryptedResponse(); response.setMac(token.getMac()); response.setEncryptedData(token.getEncryptedData()); + response.setEphemeralPublicKey(token.getEphemeralPublicKey()); + response.setNonce(token.getNonce()); + response.setMac(token.getMac()); return response; } catch (Exception ex) { logger.warn("Creating PowerAuth token failed, error: {}", ex.getMessage()); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java index 3d233cd7..440a8242 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java @@ -94,6 +94,7 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA final String encryptedData = request.getEncryptedData(); final String mac = request.getMac(); final String nonce = request.getNonce(); + final Long timestamp = request.getTimestamp(); // Get ECIES headers final String activationId = header.getActivationId(); @@ -107,6 +108,8 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA upgradeRequest.setEncryptedData(encryptedData); upgradeRequest.setMac(mac); upgradeRequest.setNonce(nonce); + upgradeRequest.setProtocolVersion(header.getVersion()); + upgradeRequest.setTimestamp(timestamp); final StartUpgradeResponse upgradeResponse = powerAuthClient.startUpgrade( upgradeRequest, httpCustomizationService.getQueryParams(), @@ -117,6 +120,9 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA final EciesEncryptedResponse response = new EciesEncryptedResponse(); response.setMac(upgradeResponse.getMac()); response.setEncryptedData(upgradeResponse.getEncryptedData()); + response.setEphemeralPublicKey(upgradeResponse.getEphemeralPublicKey()); + response.setNonce(upgradeResponse.getNonce()); + response.setTimestamp(upgradeResponse.getTimestamp()); return response; } catch (Exception ex) { logger.warn("PowerAuth upgrade start failed, error: {}", ex.getMessage()); From 8bfbd6a868a8861b1aee5edcde7a99ce51e1da66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 07:19:29 +0000 Subject: [PATCH 47/64] Bump org.bouncycastle:bcprov-jdk18on from 1.75 to 1.76 Bumps [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.75 to 1.76. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcprov-jdk18on 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 9ee6418b..14760e79 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ 3.3.2 3.1.2 1.10.0 - 1.75 + 1.76 1.7.0-SNAPSHOT 1.5.0-SNAPSHOT 1.5.0-SNAPSHOT From c834becbe3be7a3688a08912265690a25c2df86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Tue, 1 Aug 2023 18:06:38 +0200 Subject: [PATCH 48/64] Fix #416: Do not use nonce for older protocols Remove "ephemeralPublicKey" from encrypted responses. --- .../response/EciesEncryptedResponse.java | 21 +------------------ .../filter/EncryptionResponseBodyAdvice.java | 9 +------- .../PowerAuthEncryptionProviderBase.java | 5 ++--- .../api/spring/service/ActivationService.java | 10 ++++----- .../api/spring/service/RecoveryService.java | 2 +- .../spring/service/SecureVaultService.java | 2 +- .../rest/api/spring/service/TokenService.java | 1 - .../api/spring/service/UpgradeService.java | 1 - 8 files changed, 10 insertions(+), 41 deletions(-) diff --git a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java index d44573fa..fc1ca2df 100644 --- a/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java +++ b/powerauth-restful-model/src/main/java/io/getlime/security/powerauth/rest/api/model/response/EciesEncryptedResponse.java @@ -26,7 +26,6 @@ */ public class EciesEncryptedResponse { - private String ephemeralPublicKey; private String encryptedData; private String mac; private String nonce; @@ -42,34 +41,16 @@ public EciesEncryptedResponse() { * Constructor with Base64 encoded encrypted data and MAC of key and data. * @param encryptedData Encrypted data. * @param mac MAC of key and data. - * @param ephemeralPublicKey Ephemeral public key. * @param nonce ECIES nonce. * @param timestamp Unix timestamp in milliseconds. */ - public EciesEncryptedResponse(String encryptedData, String mac, String ephemeralPublicKey, String nonce, Long timestamp) { + public EciesEncryptedResponse(String encryptedData, String mac, String nonce, Long timestamp) { this.encryptedData = encryptedData; this.mac = mac; - this.ephemeralPublicKey = ephemeralPublicKey; this.nonce = nonce; this.timestamp = timestamp; } - /** - * Get ephemeral public key. - * @return Ephemeral public key. - */ - public String getEphemeralPublicKey() { - return ephemeralPublicKey; - } - - /** - * Set ephemeral public key. - * @param ephemeralPublicKey Ephemeral public key. - */ - public void setEphemeralPublicKey(String ephemeralPublicKey) { - this.ephemeralPublicKey = ephemeralPublicKey; - } - /** * Get Base64 encoded encrypted data payload. * @return Encrypted data. diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index 968355f8..537bc65e 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -136,11 +136,6 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa nonce = Base64.getEncoder().encodeToString(nonceBytes); timestamp = new Date().getTime(); eciesParameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); - } else if ("3.1".equals(version)) { - final byte[] nonceBytes = new KeyGenerator().generateRandomBytes(16); - nonce = Base64.getEncoder().encodeToString(nonceBytes); - timestamp = null; - eciesParameters = EciesParameters.builder().nonce(nonceBytes).build(); } else { nonce = null; timestamp = null; @@ -150,11 +145,9 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa final EciesPayload payload = eciesEncryptor.encrypt(responseBytes, eciesParameters); final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); - final String ephemeralPublicKey64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEphemeralPublicKey()); // Return encrypted response with type given by converter class - final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64, ephemeralPublicKey64, - nonce, timestamp); + final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64, nonce, timestamp); if (converterClass.isAssignableFrom(MappingJackson2HttpMessageConverter.class)) { // Object conversion is done automatically using MappingJackson2HttpMessageConverter return encryptedResponse; diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index ed7afee7..db2928e3 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -249,7 +249,7 @@ EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull final byte[] associatedData; final String version = eciesEncryption.getContext().getVersion(); final byte[] nonceBytesResponse = "3.2".equals(version) ? keyGenerator.generateRandomBytes(16) : null; - final String nonceResponse = Base64.getEncoder().encodeToString(nonceBytesResponse); + final String nonceResponse = nonceBytesResponse != null ? Base64.getEncoder().encodeToString(nonceBytesResponse) : null; final Long timestampResponse = "3.2".equals(version) ? new Date().getTime() : null; switch (eciesScope) { case ACTIVATION_SCOPE -> { @@ -286,8 +286,7 @@ EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull final EciesPayload payload = encryptor.encrypt(responseData, parametersResponse); final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); - final String ephemeralPublicKey64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEphemeralPublicKey()); - return new EciesEncryptedResponse(encryptedDataBase64, macBase64, ephemeralPublicKey64, nonceResponse, timestampResponse); + return new EciesEncryptedResponse(encryptedDataBase64, macBase64, nonceResponse, timestampResponse); } catch (Exception ex) { logger.debug("Response encryption failed, error: " + ex.getMessage(), ex); return null; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 13d8cc0e..773c3606 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -247,7 +247,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare and return encrypted response - return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } @@ -360,7 +360,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare encrypted activation data - return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } @@ -470,7 +470,7 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request } // Prepare and return encrypted response - return prepareEncryptedResponse(response.getEphemeralPublicKey(), response.getEncryptedData(), response.getMac(), + return prepareEncryptedResponse(response.getEncryptedData(), response.getMac(), response.getNonce(), response.getTimestamp(), processedCustomAttributes, userInfo); } default -> { @@ -594,18 +594,16 @@ public ActivationRemoveResponse removeActivation(PowerAuthApiAuthentication apiA /** * Prepare payload for the encrypted response. * - * @param ephemeralPublicKey Ephemeral public key for ECIES. * @param encryptedData Encrypted data. * @param mac MAC code of the encrypted data. * @param processedCustomAttributes Custom attributes to be returned. * @return Encrypted response object. */ - private ActivationLayer1Response prepareEncryptedResponse(String ephemeralPublicKey, String encryptedData, String mac, String nonce, Long timestmap, Map processedCustomAttributes, Map userInfo) { + private ActivationLayer1Response prepareEncryptedResponse(String encryptedData, String mac, String nonce, Long timestmap, Map processedCustomAttributes, Map userInfo) { // Prepare encrypted response object for layer 2 final EciesEncryptedResponse encryptedResponseL2 = new EciesEncryptedResponse(); encryptedResponseL2.setEncryptedData(encryptedData); encryptedResponseL2.setMac(mac); - encryptedResponseL2.setEphemeralPublicKey(ephemeralPublicKey); encryptedResponseL2.setNonce(nonce); encryptedResponseL2.setTimestamp(timestmap); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java index bf31208a..0044091a 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java @@ -100,7 +100,7 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, logger.warn("PowerAuth confirm recovery failed because of invalid activation ID in response"); throw new PowerAuthInvalidRequestException(); } - return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), paResponse.getEphemeralPublicKey(), + return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), paResponse.getNonce(), paResponse.getTimestamp()); } catch (Exception ex) { logger.warn("PowerAuth confirm recovery failed, error: {}", ex.getMessage()); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java index 5fe74731..595f5fdd 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java @@ -137,7 +137,7 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, } return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), - paResponse.getEphemeralPublicKey(), paResponse.getNonce(), paResponse.getTimestamp()); + paResponse.getNonce(), paResponse.getTimestamp()); } catch (PowerAuthAuthenticationException ex) { throw ex; } catch (Exception ex) { diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java index 0e0ff211..b4d1913e 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java @@ -126,7 +126,6 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, final EciesEncryptedResponse response = new EciesEncryptedResponse(); response.setMac(token.getMac()); response.setEncryptedData(token.getEncryptedData()); - response.setEphemeralPublicKey(token.getEphemeralPublicKey()); response.setNonce(token.getNonce()); response.setMac(token.getMac()); return response; diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java index 440a8242..a3492afd 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java @@ -120,7 +120,6 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA final EciesEncryptedResponse response = new EciesEncryptedResponse(); response.setMac(upgradeResponse.getMac()); response.setEncryptedData(upgradeResponse.getEncryptedData()); - response.setEphemeralPublicKey(upgradeResponse.getEphemeralPublicKey()); response.setNonce(upgradeResponse.getNonce()); response.setTimestamp(upgradeResponse.getTimestamp()); return response; From 4461c89853a8245b8bee98cd7a8b770876f11e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= <1719814+hvge@users.noreply.github.com> Date: Fri, 4 Aug 2023 15:25:22 +0200 Subject: [PATCH 49/64] Fix #418: Use proper nonce to encrypt response for V3.1 (#419) --- .../encryption/PowerAuthEciesEncryption.java | 18 +++++ .../filter/EncryptionResponseBodyAdvice.java | 2 +- .../api/spring/model/ActivationContext.java | 3 + .../PowerAuthEncryptionProviderBase.java | 71 +------------------ .../api/spring/service/UserInfoService.java | 4 ++ 5 files changed, 29 insertions(+), 69 deletions(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java index c2f2715d..0ba04007 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java @@ -21,6 +21,8 @@ import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; +import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; /** * Class used for storing data used during ECIES decryption and encryption. A reference to an initialized ECIES decryptor @@ -35,6 +37,7 @@ public class PowerAuthEciesEncryption { private final EciesEncryptionContext context; private EciesDecryptor eciesDecryptor; private EciesEncryptor eciesEncryptor; + private EciesParameters requestParameters; private byte[] encryptedRequest; private byte[] decryptedRequest; private byte[] associatedData; @@ -153,4 +156,19 @@ public void setRequestObject(Object requestObject) { this.requestObject = requestObject; } + /** + * Set ECIES parameters for request decryption. + * @param requestParameters ECIES parameters. + */ + public void setRequestParameters(EciesParameters requestParameters) { + this.requestParameters = requestParameters; + } + + /** + * Get ECIES parameters for request decryption. + * @return ECIES parameters. + */ + public EciesParameters getRequestParameters() { + return requestParameters; + } } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index 537bc65e..0d810f53 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -139,7 +139,7 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa } else { nonce = null; timestamp = null; - eciesParameters = EciesParameters.builder().build(); + eciesParameters = eciesEncryption.getRequestParameters(); } final EciesPayload payload = eciesEncryptor.encrypt(responseBytes, eciesParameters); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/ActivationContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/ActivationContext.java index aa617838..967c227d 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/ActivationContext.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/model/ActivationContext.java @@ -46,6 +46,9 @@ public class ActivationContext { private String deviceInfo; private String extras; + /** + * Activation context constructor. + */ public ActivationContext() { this.activationFlags = new ArrayList<>(); } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index db2928e3..f9e111e9 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -70,7 +70,6 @@ public abstract class PowerAuthEncryptionProviderBase { private final ObjectMapper objectMapper = new ObjectMapper(); private final EciesFactory eciesFactory = new EciesFactory(); - private final KeyGenerator keyGenerator = new KeyGenerator(); /** * Get ECIES decryptor parameters from PowerAuth server. @@ -171,6 +170,7 @@ PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @No final String applicationKey = eciesEncryption.getContext().getApplicationKey(); final PowerAuthEciesDecryptorParameters decryptorParameters; + final PowerAuthEciesDecryptorParameters encryptorParameters; // Obtain ECIES decryptor parameters from PowerAuth server final byte[] associatedData; switch (eciesScope) { @@ -212,6 +212,7 @@ PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @No eciesEncryption.setEncryptedRequest(encryptedDataBytes); eciesEncryption.setDecryptedRequest(decryptedData); eciesEncryption.setAssociatedData(associatedData); + eciesEncryption.setRequestParameters(parameters); // Set the request object only in case when request data is sent if (decryptedData.length != 0) { eciesEncryption.setRequestObject(deserializeRequestData(decryptedData, requestType)); @@ -226,73 +227,7 @@ PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @No } return eciesEncryption; } - - /** - * Encrypt response using ECIES. - * - * @param responseObject Response object which should be encrypted. - * @param eciesEncryption PowerAuth encryption object. - * @return ECIES encrypted response. - */ - public @Nullable - EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull PowerAuthEciesEncryption eciesEncryption) { - try { - final EciesEncryptionContext encryptionContext = eciesEncryption.getContext(); - final EciesScope eciesScope = encryptionContext.getEciesScope(); - - final String applicationKey = eciesEncryption.getContext().getApplicationKey(); - final String ephemeralPublicKey = eciesEncryption.getContext().getEphemeralPublicKey(); - final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); - - final PowerAuthEciesDecryptorParameters encryptorParameters; - // Obtain ECIES decryptor parameters from PowerAuth server - final byte[] associatedData; - final String version = eciesEncryption.getContext().getVersion(); - final byte[] nonceBytesResponse = "3.2".equals(version) ? keyGenerator.generateRandomBytes(16) : null; - final String nonceResponse = nonceBytesResponse != null ? Base64.getEncoder().encodeToString(nonceBytesResponse) : null; - final Long timestampResponse = "3.2".equals(version) ? new Date().getTime() : null; - switch (eciesScope) { - case ACTIVATION_SCOPE -> { - final String activationId = eciesEncryption.getContext().getActivationId(); - if (activationId == null) { - logger.warn("Activation ID is required in ECIES activation scope"); - throw new PowerAuthEncryptionException(); - } - encryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonceResponse, timestampResponse); - associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, encryptionContext.getVersion(), applicationKey, activationId) : null; - } - case APPLICATION_SCOPE -> { - encryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonceResponse, timestampResponse); - associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, encryptionContext.getVersion(), applicationKey, null) : null; - } - default -> { - logger.warn("Unsupported ECIES scope: {}", eciesScope); - throw new PowerAuthEncryptionException(); - } - } - - // Prepare envelope key and sharedInfo2 parameter for encryptor - final byte[] secretKey = Base64.getDecoder().decode(encryptorParameters.secretKey()); - final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); - final byte[] sharedInfo2 = Base64.getDecoder().decode(encryptorParameters.sharedInfo2()); - - final byte[] responseData = serializeResponseData(responseObject); - // Encrypt response using encryptor and return ECIES cryptogram - final EciesParameters parametersResponse = EciesParameters.builder().nonce(nonceBytesResponse).associatedData(associatedData).timestamp(timestampResponse).build(); - final EciesEncryptor encryptor = eciesFactory.getEciesEncryptor(envelopeKey, sharedInfo2); - // Store ECIES encryptor - eciesEncryption.setEciesEncryptor(encryptor); - - final EciesPayload payload = encryptor.encrypt(responseData, parametersResponse); - final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); - final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); - return new EciesEncryptedResponse(encryptedDataBase64, macBase64, nonceResponse, timestampResponse); - } catch (Exception ex) { - logger.debug("Response encryption failed, error: " + ex.getMessage(), ex); - return null; - } - } - + /** * Convert byte[] request data to Object with given type. * diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java index 70c6a546..126730d8 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UserInfoService.java @@ -44,6 +44,10 @@ public class UserInfoService { private UserInfoProvider userInfoProvider; private final PowerAuthClient powerAuthClient; + /** + * Service constructor. + * @param powerAuthClient PowerAuthClient instance. + */ @Autowired public UserInfoService(PowerAuthClient powerAuthClient) { this.powerAuthClient = powerAuthClient; From 6053a54ab0e2e704a5cf4c5c7e9ff6c00deaface Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Fri, 4 Aug 2023 16:07:41 +0200 Subject: [PATCH 50/64] Fix #421: Protocol V2 is no longer supported --- .../PowerAuthNonPersonalizedEncryptor.java | 169 ------------------ 1 file changed, 169 deletions(-) delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java deleted file mode 100644 index 7e44541a..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthNonPersonalizedEncryptor.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.encryption; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -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.NonPersonalizedEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.model.NonPersonalizedEncryptedMessage; -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.rest.api.model.entity.NonPersonalizedEncryptedPayloadModel; - -import java.io.IOException; -import java.security.InvalidKeyException; -import java.util.Base64; - -/** - * Non-personalized encryptor class. - * - * @author Petr Dvorak, petr@wultra.com - */ -public class PowerAuthNonPersonalizedEncryptor { - - private final NonPersonalizedEncryptor encryptor; - - private final ObjectMapper mapper = new ObjectMapper(); - - /** - * Constructor with all mandatory parameters. - * - * @param applicationKeyBase64 Application key. - * @param sessionKeyBytesBase64 Session key. - * @param sessionIndexBase64 Session index. - * @param ephemeralPublicKeyBase64 Ephemeral public key. - */ - public PowerAuthNonPersonalizedEncryptor(String applicationKeyBase64, String sessionKeyBytesBase64, String sessionIndexBase64, String ephemeralPublicKeyBase64) { - final byte[] applicationKey = Base64.getDecoder().decode(applicationKeyBase64); - final byte[] sessionIndex = Base64.getDecoder().decode(sessionIndexBase64); - final byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKeyBytesBase64); - final byte[] ephemeralKeyBytes = Base64.getDecoder().decode(ephemeralPublicKeyBase64); - this.encryptor = new NonPersonalizedEncryptor(applicationKey, sessionKeyBytes, sessionIndex, ephemeralKeyBytes); - } - - /** - * Encrypt object. - * - * @param object Object to be encrypted. - * @return Encrypted object. - * @throws JsonProcessingException In case the resulting object cannot be encoded as JSON. - * @throws GenericCryptoException In case of a cryptography error. - * @throws CryptoProviderException In case of a cryptographic provider error. - * @throws InvalidKeyException In case the key provided for encryption is invalid. - */ - public ObjectResponse encrypt(Object object) throws JsonProcessingException, GenericCryptoException, CryptoProviderException, InvalidKeyException { - if (object == null) { - return null; - } - final byte[] originalData = mapper.writeValueAsBytes(object); - return this.encrypt(originalData); - } - - /** - * Encrypt data. - * - * @param originalData Bytes to be encrypted. - * @return Encrypted object. - * @throws GenericCryptoException In case of a cryptography error. - * @throws CryptoProviderException In case of a cryptographic provider error. - * @throws InvalidKeyException In case the key provided for encryption is invalid. - */ - public ObjectResponse encrypt(byte[] originalData) throws GenericCryptoException, CryptoProviderException, InvalidKeyException { - - if (originalData == null) { - return null; - } - - final NonPersonalizedEncryptedMessage message = encryptor.encrypt(originalData); - - if (message == null) { // this will happen only in case of an unlikely randomness error, or if keys are corrupted - return null; - } - - final NonPersonalizedEncryptedPayloadModel responseObject = new NonPersonalizedEncryptedPayloadModel(); - responseObject.setApplicationKey(Base64.getEncoder().encodeToString(message.getApplicationKey())); - responseObject.setEphemeralPublicKey(Base64.getEncoder().encodeToString(message.getEphemeralPublicKey())); - responseObject.setSessionIndex(Base64.getEncoder().encodeToString(message.getSessionIndex())); - responseObject.setAdHocIndex(Base64.getEncoder().encodeToString(message.getAdHocIndex())); - responseObject.setMacIndex(Base64.getEncoder().encodeToString(message.getMacIndex())); - responseObject.setNonce(Base64.getEncoder().encodeToString(message.getNonce())); - responseObject.setMac(Base64.getEncoder().encodeToString(message.getMac())); - responseObject.setEncryptedData(Base64.getEncoder().encodeToString(message.getEncryptedData())); - - return new ObjectResponse<>(responseObject); - } - - /** - * Decrypt an object. - * - * @param request Object with encrypted payload. - * @return Decrypted bytes. - * @throws GenericCryptoException In case of a cryptography error. - * @throws CryptoProviderException In case of a cryptographic provider error. - * @throws InvalidKeyException In case the key provided for encryption is invalid. - */ - public byte[] decrypt(ObjectRequest request) throws GenericCryptoException, CryptoProviderException, InvalidKeyException { - - if (request == null) { - return null; - } - - final NonPersonalizedEncryptedPayloadModel requestObject = request.getRequestObject(); - - if (requestObject == null) { - return null; - } - - final NonPersonalizedEncryptedMessage message = new NonPersonalizedEncryptedMessage(); - message.setApplicationKey(Base64.getDecoder().decode(requestObject.getApplicationKey())); - message.setEphemeralPublicKey(Base64.getDecoder().decode(requestObject.getEphemeralPublicKey())); - message.setSessionIndex(Base64.getDecoder().decode(requestObject.getSessionIndex())); - message.setAdHocIndex(Base64.getDecoder().decode(requestObject.getAdHocIndex())); - message.setMacIndex(Base64.getDecoder().decode(requestObject.getMacIndex())); - message.setNonce(Base64.getDecoder().decode(requestObject.getNonce())); - message.setMac(Base64.getDecoder().decode(requestObject.getMac())); - message.setEncryptedData(Base64.getDecoder().decode(requestObject.getEncryptedData())); - - return encryptor.decrypt(message); - } - - /** - * Decrypt data and serialize object. - * - * @param request Request with encrypted data. - * @param resultClass Result deserialized class. - * @param Specific type of the result class. - * @return Decrypted object of a provided type T. - * @throws IOException In case the JSON deserialization fails. - * @throws GenericCryptoException In case of a cryptography error. - * @throws CryptoProviderException In case of a cryptographic provider error. - * @throws InvalidKeyException In case the key provided for encryption is invalid. - */ - public T decrypt(ObjectRequest request, Class resultClass) throws IOException, GenericCryptoException, CryptoProviderException, InvalidKeyException { - final byte[] result = this.decrypt(request); - if (result == null) { - return null; - } - return mapper.readValue(result, resultClass); - } - -} From ed222ece427f95188323addf46d8e43f5a9d7f35 Mon Sep 17 00:00:00 2001 From: Jan Dusil <134381434+jandusil@users.noreply.github.com> Date: Fri, 18 Aug 2023 16:24:19 +0200 Subject: [PATCH 51/64] Fix #424: Add CodeQL Analysis (#425) - Add codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 85 ++++----------------------- 1 file changed, 12 insertions(+), 73 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 226ec4fb..d750a715 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,83 +1,22 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: "CodeQL" on: + workflow_dispatch: push: - branches: [ develop, master ] + branches: [ 'develop', 'master', 'releases/**' ] pull_request: # The branches below must be a subset of the branches above - branches: [ develop ] + branches: [ 'develop', 'master', 'releases/**' ] schedule: - cron: '0 2 * * 4' jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: 17 - distribution: 'temurin' - cache: maven - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" + codeql-analysis: + uses: wultra/wultra-infrastructure/.github/workflows/codeql-analysis.yml@develop + secrets: inherit + with: + languages: "['java']" + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support \ No newline at end of file From bc53a265579f3d2ff1b2d6621818a7537ddf0f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= <1719814+hvge@users.noreply.github.com> Date: Thu, 24 Aug 2023 11:26:59 +0200 Subject: [PATCH 52/64] Use general encryptor for E2EE (#423) * Fix #420: Use general encryptor for E2EE --------- Co-authored-by: Lubos Racansky --- docs/RESTful-API-for-Spring.md | 22 +- .../annotation/PowerAuthEncryption.java | 12 +- .../PowerAuthEncryptionArgumentResolver.java | 26 +-- .../encryption/EciesEncryptionContext.java | 164 --------------- .../spring/encryption/EncryptionContext.java | 55 +++++ .../spring/encryption/EncryptionScope.java | 57 +++++ .../encryption/PowerAuthEciesEncryption.java | 174 --------------- .../encryption/PowerAuthEncryptorData.java | 83 ++++++++ ...java => PowerAuthEncryptorParameters.java} | 8 +- .../filter/EncryptionResponseBodyAdvice.java | 54 ++--- .../PowerAuthAuthenticationProviderBase.java | 6 +- .../provider/PowerAuthEncryptionProvider.java | 6 +- .../PowerAuthEncryptionProviderBase.java | 199 +++++++++--------- .../controller/ActivationController.java | 14 +- .../spring/controller/UpgradeController.java | 3 +- .../spring/controller/UserInfoController.java | 14 +- .../api/spring/service/ActivationService.java | 14 +- .../api/spring/service/RecoveryService.java | 11 +- .../spring/service/SecureVaultService.java | 25 +-- .../rest/api/spring/service/TokenService.java | 19 +- .../api/spring/service/UpgradeService.java | 17 +- 21 files changed, 394 insertions(+), 589 deletions(-) delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionContext.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionScope.java delete mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java create mode 100644 powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorData.java rename powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/{PowerAuthEciesDecryptorParameters.java => PowerAuthEncryptorParameters.java} (80%) diff --git a/docs/RESTful-API-for-Spring.md b/docs/RESTful-API-for-Spring.md index 02f42ce5..81ff89e9 100644 --- a/docs/RESTful-API-for-Spring.md +++ b/docs/RESTful-API-for-Spring.md @@ -394,16 +394,16 @@ You can encrypt data in `application` scope (non-personalized) using following p public class EncryptedDataExchangeController { @RequestMapping(value = "application", method = RequestMethod.POST) - @PowerAuthEncryption(scope = EciesScope.APPLICATION_SCOPE) + @PowerAuthEncryption(scope = EncryptionScope.APPLICATION_SCOPE) public DataExchangeResponse exchangeInApplicationScope(@EncryptedRequestBody DataExchangeRequest request, - EciesEncryptionContext eciesContext) throws PowerAuthEncryptionException { + EncryptionContext encryptionContext) throws PowerAuthEncryptionException { - if (eciesContext == null) { + if (encryptionContext == null) { throw new PowerAuthEncryptionException(); } // Return a slightly different String containing original data in response - return new DataExchangeResponse("Server successfully decrypted signed data: " + (request == null ? "''" : request.getData()) + ", scope: " + eciesContext.getEciesScope()); + return new DataExchangeResponse("Server successfully decrypted signed data: " + (request == null ? "''" : request.getData()) + ", scope: " + encryptionContext.getEncryptionScope()); } } ``` @@ -422,16 +422,16 @@ You can encrypt data in `activation` scope (personalized) using following patter public class EncryptedDataExchangeController { @RequestMapping(value = "activation", method = RequestMethod.POST) - @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) + @PowerAuthEncryption(scope = EncryptionScope.ACTIVATION_SCOPE) public DataExchangeResponse exchangeInActivationScope(@EncryptedRequestBody DataExchangeRequest request, - EciesEncryptionContext eciesContext) throws PowerAuthEncryptionException { + EncryptionContext encryptionContext) throws PowerAuthEncryptionException { - if (eciesContext == null) { + if (encryptionContext == null) { throw new PowerAuthEncryptionException(); } // Return a slightly different String containing original data in response - return new DataExchangeResponse("Server successfully decrypted signed data: " + (request == null ? "''" : request.getData()) + ", scope: " + eciesContext.getEciesScope()); + return new DataExchangeResponse("Server successfully decrypted signed data: " + (request == null ? "''" : request.getData()) + ", scope: " + encryptionContext.getEncryptionScope()); } } ``` @@ -451,16 +451,16 @@ public class EncryptedDataExchangeController { @RequestMapping(value = "signed", method = RequestMethod.POST) @PowerAuth(resourceId = "/exchange/signed") - @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) + @PowerAuthEncryption(scope = EncryptionScope.ACTIVATION_SCOPE) public DataExchangeResponse exchangeSignedAndEncryptedData(@EncryptedRequestBody DataExchangeRequest request, - EciesEncryptionContext eciesContext, + EncryptionContext encryptionContext, PowerAuthApiAuthentication auth) throws PowerAuthAuthenticationException, PowerAuthEncryptionException { if (auth == null || auth.getUserId() == null) { throw new PowerAuthSignatureInvalidException(); } - if (eciesContext == null) { + if (encryptionContext == null) { throw new PowerAuthEncryptionException(); } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/PowerAuthEncryption.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/PowerAuthEncryption.java index f186fda5..814c59fd 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/PowerAuthEncryption.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/PowerAuthEncryption.java @@ -19,7 +19,8 @@ */ package io.getlime.security.powerauth.rest.api.spring.annotation; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionScope; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -27,7 +28,7 @@ import java.lang.annotation.Target; /** - * Annotation that simplifies end to end encryption. + * Annotation that simplifies end-to-end encryption. * * @author Roman Strobl, roman.strobl@wultra.com */ @@ -36,10 +37,9 @@ public @interface PowerAuthEncryption { /** - * Encryption scope, either EciesScope.ACTIVATION_SCOPE or EciesScope.APPLICATION_SCOPE. - * @see EciesScope + * Encryption scope, either {@link EncryptionScope#ACTIVATION_SCOPE} or {@link EncryptionScope#APPLICATION_SCOPE}. + * @see EncryptorScope * @return Encryption scope. */ - EciesScope scope() default EciesScope.ACTIVATION_SCOPE; - + EncryptionScope scope() default EncryptionScope.ACTIVATION_SCOPE; } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java index 346fc337..e90bc9cd 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java @@ -24,9 +24,10 @@ import com.fasterxml.jackson.databind.type.TypeFactory; import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorData; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.MethodParameter; @@ -36,13 +37,12 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Type; /** - * Argument resolver for {@link PowerAuthEciesEncryption} objects. It enables automatic - * parameter resolution for methods that are annotated via {@link PowerAuthEciesEncryption} annotation. + * Argument resolver for {@link PowerAuthEncryptorData} objects. It enables automatic + * parameter resolution for methods that are annotated via {@link PowerAuthEncryptorData} annotation. * * @author Roman Strobl, roman.strobl@wultra.com */ @@ -55,13 +55,13 @@ public class PowerAuthEncryptionArgumentResolver implements HandlerMethodArgumen @Override public boolean supportsParameter(@NonNull MethodParameter parameter) { return parameter.hasMethodAnnotation(PowerAuthEncryption.class) - && (parameter.hasParameterAnnotation(EncryptedRequestBody.class) || EciesEncryptionContext.class.isAssignableFrom(parameter.getParameterType())); + && (parameter.hasParameterAnnotation(EncryptedRequestBody.class) || EncryptionContext.class.isAssignableFrom(parameter.getParameterType())); } @Override public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewContainer mavContainer, @NonNull NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { final HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); - final PowerAuthEciesEncryption eciesObject = (PowerAuthEciesEncryption) request.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); + final PowerAuthEncryptorData eciesObject = (PowerAuthEncryptorData) request.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); // Decrypted object is inserted into parameter annotated by @EncryptedRequestBody annotation if (parameter.hasParameterAnnotation(EncryptedRequestBody.class) && eciesObject != null && eciesObject.getDecryptedRequest() != null) { final Type requestType = parameter.getGenericParameterType(); @@ -81,11 +81,11 @@ public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewCo } } // Ecies encryption object is inserted into parameter which is of type PowerAuthEciesEncryption - if (eciesObject != null && EciesEncryptionContext.class.isAssignableFrom(parameter.getParameterType())) { + if (eciesObject != null && EncryptionContext.class.isAssignableFrom(parameter.getParameterType())) { // Set ECIES scope in case it is specified by the @PowerAuthEncryption annotation - PowerAuthEncryption powerAuthEncryption = parameter.getMethodAnnotation(PowerAuthEncryption.class); + final PowerAuthEncryption powerAuthEncryption = parameter.getMethodAnnotation(io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption.class); if (powerAuthEncryption != null) { - EciesEncryptionContext eciesContext = eciesObject.getContext(); + EncryptionContext eciesContext = eciesObject.getContext(); boolean validScope = validateEciesScope(eciesContext); if (validScope) { return eciesContext; @@ -99,8 +99,8 @@ public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewCo * Validate that encryption HTTP header contains correct values for given ECIES scope. * @param eciesContext ECIES context. */ - private boolean validateEciesScope(EciesEncryptionContext eciesContext) { - switch (eciesContext.getEciesScope()) { + private boolean validateEciesScope(EncryptionContext eciesContext) { + switch (eciesContext.getEncryptionScope()) { case ACTIVATION_SCOPE -> { if (eciesContext.getApplicationKey() == null || eciesContext.getApplicationKey().isEmpty()) { logger.warn("ECIES activation scope is invalid because of missing application key"); @@ -118,7 +118,7 @@ private boolean validateEciesScope(EciesEncryptionContext eciesContext) { } } default -> { - logger.warn("Unsupported ECIES scope: {}", eciesContext.getEciesScope()); + logger.warn("Unsupported ECIES scope: {}", eciesContext.getEncryptionScope()); return false; } } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java deleted file mode 100644 index 5104cb04..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EciesEncryptionContext.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.encryption; - -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.http.PowerAuthHttpHeader; - -/** - * Class for storing ECIES encryption context derived from HTTP headers. - * - * @author Roman Strobl, roman.strobl@wultra.com - * - */ -public class EciesEncryptionContext { - - private String applicationKey; - private String activationId; - private String version; - private EciesScope eciesScope; - private String ephemeralPublicKey; - private PowerAuthHttpHeader httpHeader; - - /** - * Default constructor. - */ - public EciesEncryptionContext() { - } - - /** - * Constructor with all context parameters. - * - * @param applicationKey Application key. - * @param activationId Activation ID. - * @param version PowerAuth protocol version. - * @param httpHeader HTTP header used to derive ECIES encryption context. - */ - public EciesEncryptionContext(String applicationKey, String activationId, String version, PowerAuthHttpHeader httpHeader) { - this.applicationKey = applicationKey; - this.activationId = activationId; - this.version = version; - this.httpHeader = httpHeader; - } - - /** - * Get application key. - * - * @return Application key. - */ - public String getApplicationKey() { - return applicationKey; - } - - /** - * Set application key. - * - * @param applicationKey Application key. - */ - public void setApplicationKey(String applicationKey) { - this.applicationKey = applicationKey; - } - - /** - * Get activation ID. - * - * @return Activation ID. - */ - public String getActivationId() { - return activationId; - } - - /** - * Set activation ID. - * - * @param activationId Activation ID. - */ - public void setActivationId(String activationId) { - this.activationId = activationId; - } - - /** - * Get PowerAuth protocol version. - * - * @return PowerAuth protocol version. - */ - public String getVersion() { - return version; - } - - /** - * Set PowerAuth protocol version. - * - * @param version PowerAuth protocol version. - */ - public void setVersion(String version) { - this.version = version; - } - - /** - * Get ECIES scope (application or activation). - * @return ECIES scope. - */ - public EciesScope getEciesScope() { - return eciesScope; - } - - /** - * Set ECIES scope (application or activation). - * @param eciesScope ECIES scope. - */ - public void setEciesScope(EciesScope eciesScope) { - this.eciesScope = eciesScope; - } - - /** - * Get ephemeral public key in Base64 encoding. - * @return Ephemeral public key. - */ - public String getEphemeralPublicKey() { - return ephemeralPublicKey; - } - - /** - * Set ephemeral public key bytes in Base64 encoding. - * @param ephemeralPublicKey Ephemeral public key bytes. - */ - public void setEphemeralPublicKey(String ephemeralPublicKey) { - this.ephemeralPublicKey = ephemeralPublicKey; - } - - /** - * Get PowerAuth HTTP header used for deriving ECIES encryption context. - * - * @return PowerAuth HTTP header used for deriving ECIES encryption context. - */ - public PowerAuthHttpHeader getHttpHeader() { - return httpHeader; - } - - /** - * Set PowerAuth HTTP header used for deriving ECIES encryption context. - * - * @param httpHeader PowerAuth HTTP header used for deriving ECIES encryption context. - */ - public void setHttpHeader(PowerAuthHttpHeader httpHeader) { - this.httpHeader = httpHeader; - } -} \ No newline at end of file diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionContext.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionContext.java new file mode 100644 index 00000000..c919dbea --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionContext.java @@ -0,0 +1,55 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.encryption; + +import io.getlime.security.powerauth.http.PowerAuthHttpHeader; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Class for storing PowerAuth End-To-End encryption context derived from HTTP headers. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@Getter +@AllArgsConstructor +public class EncryptionContext { + /** + * Application key. + */ + private final String applicationKey; + /** + * Activation ID. + */ + private final String activationId; + /** + * Protocol version. + */ + private final String version; + /** + * PowerAuth HTTP header used for deriving ECIES encryption context. + */ + private final PowerAuthHttpHeader httpHeader; + /** + * Scope of the encryption. + */ + private final EncryptionScope encryptionScope; +} \ No newline at end of file diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionScope.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionScope.java new file mode 100644 index 00000000..36e945e4 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/EncryptionScope.java @@ -0,0 +1,57 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.encryption; + +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; + +/** + * Enumeration of application scopes for encryptor. + */ +public enum EncryptionScope { + + /** + * Application scope (non-personalized). + */ + APPLICATION_SCOPE, + + /** + * Activation scope (personalized). + */ + ACTIVATION_SCOPE; + + /** + * Translate this scope object into {@link EncryptorScope} used by low level PowerAuth Crypto library. + * @return Translated {@link EncryptorScope}. + */ + public EncryptorScope toEncryptorScope() { + switch (this) { + case APPLICATION_SCOPE -> { + return EncryptorScope.APPLICATION_SCOPE; + } + case ACTIVATION_SCOPE -> { + return EncryptorScope.ACTIVATION_SCOPE; + } + default -> { + throw new IllegalArgumentException("Unsupported scope " + this); + } + } + } +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java deleted file mode 100644 index 0ba04007..00000000 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesEncryption.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * PowerAuth integration libraries for RESTful API applications, examples 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 io.getlime.security.powerauth.rest.api.spring.encryption; - -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; - -/** - * Class used for storing data used during ECIES decryption and encryption. A reference to an initialized ECIES decryptor - * is also stored so that response can be encrypted using same decryptor as used for request decryption. - *

- * Use the T parameter to specify the type of request object to be decrypted. - * - * @author Roman Strobl, roman.strobl@wultra.com - */ -public class PowerAuthEciesEncryption { - - private final EciesEncryptionContext context; - private EciesDecryptor eciesDecryptor; - private EciesEncryptor eciesEncryptor; - private EciesParameters requestParameters; - private byte[] encryptedRequest; - private byte[] decryptedRequest; - private byte[] associatedData; - private Object requestObject; - - /** - * Initialize ECIES encryption object from either encryption or signature HTTP header. - * - * @param context PowerAuth encryption context derived from either encryption or signature HTTP header. - */ - public PowerAuthEciesEncryption(EciesEncryptionContext context) { - this.context = context; - } - - /** - * Get ECIES encryption context. - * @return ECIES encryption context. - */ - public EciesEncryptionContext getContext() { - return context; - } - - /** - * Get ECIES decryptor. - * @return ECIES decryptor. - */ - public EciesDecryptor getEciesDecryptor() { - return eciesDecryptor; - } - - /** - * Set ECIES decryptor. - * @param eciesDecryptor ECIES decryptor. - */ - public void setEciesDecryptor(EciesDecryptor eciesDecryptor) { - this.eciesDecryptor = eciesDecryptor; - } - - /** - * Get ECIES encryptor. - * @return eciesEncryptor ECIES encryptor. - */ - public EciesEncryptor getEciesEncryptor() { - return eciesEncryptor; - } - - /** - * Set ECIES encryptor. - * @param eciesEncryptor ECIES encryptor. - */ - public void setEciesEncryptor(EciesEncryptor eciesEncryptor) { - this.eciesEncryptor = eciesEncryptor; - } - - /** - * Get encrypted request data. - * @return Encrypted request data. - */ - public byte[] getEncryptedRequest() { - return encryptedRequest; - } - - /** - * Set encrypted request data. - * @param encryptedRequest Encrypted request data. - */ - public void setEncryptedRequest(byte[] encryptedRequest) { - this.encryptedRequest = encryptedRequest; - } - - /** - * Get decrypted request data. - * @return Decrypted request data. - */ - public byte[] getDecryptedRequest() { - return decryptedRequest; - } - - /** - * Set decrypted request data. - * @param decryptedRequest Decrypted request data. - */ - public void setDecryptedRequest(byte[] decryptedRequest) { - this.decryptedRequest = decryptedRequest; - } - - /** - * Get ECIES data associated with request and response. - * @return ECIES data associated with request and response. - */ - public byte[] getAssociatedData() { - return associatedData; - } - - /** - * Set ECIES data associated with request and response. - * @param associatedData ECIES data associated with request and response. - */ - public void setAssociatedData(byte[] associatedData) { - this.associatedData = associatedData; - } - - /** - * Get decrypted request object. - * @return Decrypted request object. - */ - public Object getRequestObject() { - return requestObject; - } - - /** - * Set decrypted request object. - * @param requestObject Decrypted request object. - */ - public void setRequestObject(Object requestObject) { - this.requestObject = requestObject; - } - - /** - * Set ECIES parameters for request decryption. - * @param requestParameters ECIES parameters. - */ - public void setRequestParameters(EciesParameters requestParameters) { - this.requestParameters = requestParameters; - } - - /** - * Get ECIES parameters for request decryption. - * @return ECIES parameters. - */ - public EciesParameters getRequestParameters() { - return requestParameters; - } -} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorData.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorData.java new file mode 100644 index 00000000..11caa171 --- /dev/null +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorData.java @@ -0,0 +1,83 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.encryption; + +import io.getlime.security.powerauth.crypto.lib.encryptor.ServerEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedRequest; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorId; +import lombok.Getter; +import lombok.Setter; + +/** + * Class used for storing data used during PowerAuth decryption and encryption. A reference to an initialized ServerEncryptor + * is also stored so that the response can be encrypted using the same object as used for request decryption. + */ +@Getter +@Setter +public class PowerAuthEncryptorData { + /** + * ECIES encryption context. + */ + private final EncryptionContext context; + /** + * {@link ServerEncryptor} implementation. + */ + private ServerEncryptor serverEncryptor; + /** + * Encrypted request data. + */ + private EncryptedRequest encryptedRequest; + /** + * Decrypted request data. + */ + private byte[] decryptedRequest; + /** + * Request object + */ + private Object requestObject; + + /** + * Initialize encryption object from either encryption or signature HTTP header. + * + * @param context PowerAuth encryption context derived from either encryption or signature HTTP header. + */ + public PowerAuthEncryptorData(EncryptionContext context) { + this.context = context; + } + + /** + * Get EncryptorId depending on scope of encryption. + * @return EncryptorId depending on scope of encryption. + */ + public EncryptorId getEncryptorId() { + switch (context.getEncryptionScope()) { + case ACTIVATION_SCOPE -> { + return EncryptorId.ACTIVATION_SCOPE_GENERIC; + } + case APPLICATION_SCOPE -> { + return EncryptorId.APPLICATION_SCOPE_GENERIC; + } + default -> { + throw new IllegalStateException("Unsupported scope " + this); + } + } + } +} diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorParameters.java similarity index 80% rename from powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java rename to powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorParameters.java index 97d2a564..2bb54b80 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEciesDecryptorParameters.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/encryption/PowerAuthEncryptorParameters.java @@ -20,11 +20,11 @@ package io.getlime.security.powerauth.rest.api.spring.encryption; /** - * Class used for storing ECIES decryptor parameters. + * Class used for storing encryptor parameters. * - * @param secretKey ECIES secret key - * @param sharedInfo2 Parameter sharedInfo2 for ECIES. + * @param secretKey Secret key. + * @param sharedInfo2 Parameter sharedInfo2 for ECIES (V3.x protocols). * @author Roman Strobl, roman.strobl@wultra.com */ -public record PowerAuthEciesDecryptorParameters(String secretKey, String sharedInfo2) { +public record PowerAuthEncryptorParameters(String secretKey, String sharedInfo2) { } diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java index 0d810f53..5de8617c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/filter/EncryptionResponseBodyAdvice.java @@ -20,14 +20,12 @@ package io.getlime.security.powerauth.rest.api.spring.filter; import com.fasterxml.jackson.databind.ObjectMapper; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptedResponse; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorData; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; +import jakarta.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -48,13 +46,10 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; -import jakarta.servlet.http.HttpServletRequest; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Date; import java.util.List; /** @@ -113,50 +108,33 @@ public Object beforeBodyWrite(Object response, @NonNull MethodParameter methodPa return null; } - // Extract ECIES encryption object from HTTP request + // Extract encryption object from HTTP request final HttpServletRequest httpServletRequest = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest(); - final PowerAuthEciesEncryption eciesEncryption = (PowerAuthEciesEncryption) httpServletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); - if (eciesEncryption == null) { + final PowerAuthEncryptorData encryption = (PowerAuthEncryptorData) httpServletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); + if (encryption == null || encryption.getServerEncryptor() == null) { return null; } // Convert response to JSON try { byte[] responseBytes = serializeResponseObject(response); - - // Encrypt response using encryptor and return ECIES cryptogram - final EciesEncryptor eciesEncryptor = eciesEncryption.getEciesEncryptor(); - final String version = eciesEncryption.getContext().getVersion(); - final EciesParameters eciesParameters; - final String nonce; - final Long timestamp; - if ("3.2".equals(version)) { - final byte[] associatedData = eciesEncryption.getAssociatedData(); - final byte[] nonceBytes = new KeyGenerator().generateRandomBytes(16); - nonce = Base64.getEncoder().encodeToString(nonceBytes); - timestamp = new Date().getTime(); - eciesParameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); - } else { - nonce = null; - timestamp = null; - eciesParameters = eciesEncryption.getRequestParameters(); - } - - final EciesPayload payload = eciesEncryptor.encrypt(responseBytes, eciesParameters); - final String encryptedDataBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getEncryptedData()); - final String macBase64 = Base64.getEncoder().encodeToString(payload.getCryptogram().getMac()); - + final EncryptedResponse encryptedResponse = encryption.getServerEncryptor().encryptResponse(responseBytes); // Return encrypted response with type given by converter class - final EciesEncryptedResponse encryptedResponse = new EciesEncryptedResponse(encryptedDataBase64, macBase64, nonce, timestamp); + final EciesEncryptedResponse encryptedResponseObject = new EciesEncryptedResponse( + encryptedResponse.getEncryptedData(), + encryptedResponse.getMac(), + encryptedResponse.getNonce(), + encryptedResponse.getTimestamp() + ); if (converterClass.isAssignableFrom(MappingJackson2HttpMessageConverter.class)) { // Object conversion is done automatically using MappingJackson2HttpMessageConverter - return encryptedResponse; + return encryptedResponseObject; } else if (converterClass.isAssignableFrom(StringHttpMessageConverter.class)) { // Conversion to byte[] is done using first applicable configured HTTP message converter, corresponding String is returned - return new String(convertEncryptedResponse(encryptedResponse, mediaType), StandardCharsets.UTF_8); + return new String(convertEncryptedResponse(encryptedResponseObject, mediaType), StandardCharsets.UTF_8); } else { // Conversion to byte[] is done using first applicable configured HTTP message converter - return convertEncryptedResponse(encryptedResponse, mediaType); + return convertEncryptedResponse(encryptedResponseObject, mediaType); } } catch (Exception ex) { logger.warn("Encryption failed, error: {}", ex.getMessage()); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java index 6b4b0c73..ee04280c 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProviderBase.java @@ -21,7 +21,7 @@ import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorData; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthRequestFilterException; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody; @@ -198,8 +198,8 @@ public abstract class PowerAuthAuthenticationProviderBase { */ public @Nullable byte[] extractRequestBodyBytes(@Nonnull HttpServletRequest servletRequest) throws PowerAuthAuthenticationException { if (servletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT) != null) { - // Implementation of sign-then-encrypt - in case the encryption object is present and signature is validate, use decrypted request data - PowerAuthEciesEncryption eciesEncryption = (PowerAuthEciesEncryption) servletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); + // Implementation of sign-then-encrypt - in case the encryption object is present and signature is valid, use decrypted request data + PowerAuthEncryptorData eciesEncryption = (PowerAuthEncryptorData) servletRequest.getAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT); return eciesEncryption.getDecryptedRequest(); } else { // Request data was not encrypted - use regular PowerAuth request body for signature validation diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java index d4706be6..9b04439d 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProvider.java @@ -22,7 +22,7 @@ import com.wultra.security.powerauth.client.PowerAuthClient; import com.wultra.security.powerauth.client.model.request.GetEciesDecryptorRequest; import com.wultra.security.powerauth.client.model.response.GetEciesDecryptorResponse; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesDecryptorParameters; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorParameters; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.service.HttpCustomizationService; import org.slf4j.Logger; @@ -59,7 +59,7 @@ public PowerAuthEncryptionProvider(PowerAuthClient powerAuthClient, HttpCustomiz } @Override - public @Nonnull PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException { + public @Nonnull PowerAuthEncryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException { try { final GetEciesDecryptorRequest eciesDecryptorRequest = new GetEciesDecryptorRequest(); eciesDecryptorRequest.setActivationId(activationId); @@ -74,7 +74,7 @@ public PowerAuthEncryptionProvider(PowerAuthClient powerAuthClient, HttpCustomiz httpCustomizationService.getHttpHeaders() ); - return new PowerAuthEciesDecryptorParameters(eciesDecryptorResponse.getSecretKey(), eciesDecryptorResponse.getSharedInfo2()); + return new PowerAuthEncryptorParameters(eciesDecryptorResponse.getSecretKey(), eciesDecryptorResponse.getSharedInfo2()); } catch (Exception ex) { logger.warn("Get ECIES decryptor call failed, error: {}", ex.getMessage()); logger.debug(ex.getMessage(), ex); diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java index f9e111e9..5376a3da 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthEncryptionProviderBase.java @@ -23,16 +23,10 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesDecryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEncryptor; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesEnvelopeKey; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.EciesFactory; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesCryptogram; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesParameters; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesPayload; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; -import io.getlime.security.powerauth.crypto.lib.generator.KeyGenerator; -import io.getlime.security.powerauth.crypto.lib.util.EciesUtils; +import io.getlime.security.powerauth.crypto.lib.encryptor.EncryptorFactory; +import io.getlime.security.powerauth.crypto.lib.encryptor.ServerEncryptor; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.*; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.v3.ServerEncryptorSecrets; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; @@ -40,9 +34,10 @@ import io.getlime.security.powerauth.http.validator.PowerAuthSignatureHttpHeaderValidator; import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesDecryptorParameters; -import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEciesEncryption; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionScope; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorParameters; +import io.getlime.security.powerauth.rest.api.spring.encryption.PowerAuthEncryptorData; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestBody; import io.getlime.security.powerauth.rest.api.spring.model.PowerAuthRequestObjects; @@ -55,7 +50,6 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.Base64; -import java.util.Date; /** * Abstract class for PowerAuth encryption provider with common HTTP header parsing logic. The class is available for @@ -69,7 +63,7 @@ public abstract class PowerAuthEncryptionProviderBase { private static final Logger logger = LoggerFactory.getLogger(PowerAuthEncryptionProviderBase.class); private final ObjectMapper objectMapper = new ObjectMapper(); - private final EciesFactory eciesFactory = new EciesFactory(); + private final EncryptorFactory encryptorFactory = new EncryptorFactory(); /** * Get ECIES decryptor parameters from PowerAuth server. @@ -84,20 +78,18 @@ public abstract class PowerAuthEncryptionProviderBase { * @throws PowerAuthEncryptionException In case PowerAuth server call fails. */ public abstract @Nonnull - PowerAuthEciesDecryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException; + PowerAuthEncryptorParameters getEciesDecryptorParameters(@Nullable String activationId, @Nonnull String applicationKey, @Nonnull String ephemeralPublicKey, @Nonnull String version, String nonce, Long timestamp) throws PowerAuthEncryptionException; /** * Decrypt HTTP request body and construct object with ECIES data. Use the requestType parameter to specify * the type of decrypted object. * - * @param request HTTP request. - * @param requestType Class of request object. - * @param eciesScope ECIES scope. - * @return Object with ECIES data. + * @param request HTTP request. + * @param requestType Class of request object. + * @param encryptionScope Encryption scope. * @throws PowerAuthEncryptionException In case request decryption fails. */ - public @Nonnull - PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @Nonnull Type requestType, @Nonnull EciesScope eciesScope) throws PowerAuthEncryptionException { + public void decryptRequest(@Nonnull HttpServletRequest request, @Nonnull Type requestType, @Nonnull EncryptionScope encryptionScope) throws PowerAuthEncryptionException { // Only POST HTTP method is supported for ECIES if (!"POST".equals(request.getMethod())) { logger.warn("Invalid HTTP method: {}", request.getMethod()); @@ -105,13 +97,10 @@ PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @No } // Resolve either signature or encryption HTTP header for ECIES - final EciesEncryptionContext encryptionContext = extractEciesEncryptionContext(request); + final EncryptionContext encryptionContext = extractEciesEncryptionContext(request, encryptionScope); // Construct ECIES encryption object from HTTP header - final PowerAuthEciesEncryption eciesEncryption = new PowerAuthEciesEncryption(encryptionContext); - - // Save ECIES scope in context - eciesEncryption.getContext().setEciesScope(eciesScope); + final PowerAuthEncryptorData encryptorData = new PowerAuthEncryptorData(encryptionContext); try { // Parse ECIES cryptogram from request body @@ -133,99 +122,106 @@ PowerAuthEciesEncryption decryptRequest(@Nonnull HttpServletRequest request, @No logger.debug(ex.getMessage(), ex); throw new PowerAuthEncryptionException(); } - if (eciesRequest == null) { logger.warn("Deserialization of request body bytes resulted in null value."); throw new PowerAuthEncryptionException(); } - // Prepare ephemeral public key - final String ephemeralPublicKey = eciesRequest.getEphemeralPublicKey(); - final String encryptedData = eciesRequest.getEncryptedData(); - final String mac = eciesRequest.getMac(); - final String nonce = eciesRequest.getNonce(); - final Long timestamp = eciesRequest.getTimestamp(); + // Extract useful properties in advance + final String version = encryptionContext.getVersion(); + final String applicationKey = encryptionContext.getApplicationKey(); + final String activationId = encryptionContext.getActivationId(); - // Verify ECIES request data. Nonce is required for protocol 3.1+ - if (ephemeralPublicKey == null || encryptedData == null || mac == null) { - logger.warn("Invalid ECIES request data"); + // Prepare and validate EncryptedRequest object + final EncryptedRequest encryptedRequest = new EncryptedRequest( + eciesRequest.getEphemeralPublicKey(), + eciesRequest.getEncryptedData(), + eciesRequest.getMac(), + eciesRequest.getNonce(), + eciesRequest.getTimestamp() + ); + if (!encryptorFactory.getRequestResponseValidator(version).validateEncryptedRequest(encryptedRequest)) { + logger.warn("Invalid encrypted request data"); throw new PowerAuthEncryptionException(); } - if (nonce == null && !"3.0".equals(encryptionContext.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); + // Validate presence of activation id for activation scope. + if (encryptionScope == EncryptionScope.ACTIVATION_SCOPE && activationId == null) { + logger.warn("Activation ID is required for activation scope"); throw new PowerAuthEncryptionException(); } - if (timestamp == null && (!"3.0".equals(encryptionContext.getVersion()) && !"3.1".equals(encryptionContext.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthEncryptionException(); - } - - // Save ephemeral public key in context - eciesEncryption.getContext().setEphemeralPublicKey(ephemeralPublicKey); - - final byte[] ephemeralPublicKeyBytes = Base64.getDecoder().decode(ephemeralPublicKey); - final byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData); - final byte[] macBytes = Base64.getDecoder().decode(mac); - final byte[] nonceBytes = nonce != null ? Base64.getDecoder().decode(nonce) : null; - - final String applicationKey = eciesEncryption.getContext().getApplicationKey(); - final PowerAuthEciesDecryptorParameters decryptorParameters; - final PowerAuthEciesDecryptorParameters encryptorParameters; - // Obtain ECIES decryptor parameters from PowerAuth server - final byte[] associatedData; - switch (eciesScope) { - case ACTIVATION_SCOPE -> { - final String activationId = eciesEncryption.getContext().getActivationId(); - if (activationId == null) { - logger.warn("Activation ID is required in ECIES activation scope"); - throw new PowerAuthEncryptionException(); - } - decryptorParameters = getEciesDecryptorParameters(activationId, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonce, timestamp); - associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.ACTIVATION_SCOPE, encryptionContext.getVersion(), applicationKey, activationId) : null; - } - case APPLICATION_SCOPE -> { - decryptorParameters = getEciesDecryptorParameters(null, applicationKey, ephemeralPublicKey, encryptionContext.getVersion(), nonce, timestamp); - associatedData = "3.2".equals(encryptionContext.getVersion()) ? EciesUtils.deriveAssociatedData(EciesScope.APPLICATION_SCOPE, encryptionContext.getVersion(), applicationKey, null) : null; - } - default -> { - logger.warn("Unsupported ECIES scope: {}", eciesScope); - throw new PowerAuthEncryptionException(); - } - } + // Get encryptor parameters from the PowerAuth Server. + final PowerAuthEncryptorParameters encryptorParameters = getEciesDecryptorParameters( + activationId, + applicationKey, + encryptedRequest.getEphemeralPublicKey(), + version, + encryptedRequest.getNonce(), + encryptedRequest.getTimestamp() + ); + // Build server encryptor with obtained encryptor parameters + final byte[] secretKeyBytes = Base64.getDecoder().decode(encryptorParameters.secretKey()); + final byte[] sharedInfo2Base = Base64.getDecoder().decode(encryptorParameters.sharedInfo2()); + final ServerEncryptor serverEncryptor = encryptorFactory.getServerEncryptor( + encryptorData.getEncryptorId(), + new EncryptorParameters(version, applicationKey, activationId), + new ServerEncryptorSecrets(secretKeyBytes, sharedInfo2Base) + ); - // Prepare envelope key and sharedInfo2 parameter for decryptor - final byte[] secretKey = Base64.getDecoder().decode(decryptorParameters.secretKey()); - final EciesEnvelopeKey envelopeKey = new EciesEnvelopeKey(secretKey, ephemeralPublicKeyBytes); - final byte[] sharedInfo2 = Base64.getDecoder().decode(decryptorParameters.sharedInfo2()); + // Try to decrypt request data + final byte[] decryptedData = serverEncryptor.decryptRequest(encryptedRequest); - // Construct decryptor and encryptor - final EciesDecryptor eciesDecryptor = eciesFactory.getEciesDecryptor(envelopeKey, sharedInfo2); - final EciesEncryptor eciesEncryptor = eciesFactory.getEciesEncryptor(envelopeKey, sharedInfo2); - eciesEncryption.setEciesDecryptor(eciesDecryptor); - eciesEncryption.setEciesEncryptor(eciesEncryptor); + encryptorData.setEncryptedRequest(encryptedRequest); + encryptorData.setDecryptedRequest(decryptedData); + encryptorData.setServerEncryptor(serverEncryptor); - // Decrypt request data - final EciesParameters parameters = EciesParameters.builder().nonce(nonceBytes).associatedData(associatedData).timestamp(timestamp).build(); - final EciesCryptogram cryptogram = EciesCryptogram.builder().encryptedData(encryptedDataBytes).mac(macBytes).ephemeralPublicKey(ephemeralPublicKeyBytes).build(); - final EciesPayload payload = new EciesPayload(cryptogram, parameters); - final byte[] decryptedData = eciesDecryptor.decrypt(payload); - eciesEncryption.setEncryptedRequest(encryptedDataBytes); - eciesEncryption.setDecryptedRequest(decryptedData); - eciesEncryption.setAssociatedData(associatedData); - eciesEncryption.setRequestParameters(parameters); // Set the request object only in case when request data is sent if (decryptedData.length != 0) { - eciesEncryption.setRequestObject(deserializeRequestData(decryptedData, requestType)); + encryptorData.setRequestObject(deserializeRequestData(decryptedData, requestType)); } // Set encryption object in HTTP servlet request - request.setAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT, eciesEncryption); + request.setAttribute(PowerAuthRequestObjects.ENCRYPTION_OBJECT, encryptorData); } catch (Exception ex) { logger.warn("Request decryption failed, error: " + ex.getMessage()); logger.debug(ex.getMessage(), ex); throw new PowerAuthEncryptionException(); } - return eciesEncryption; + } + + /** + * Encrypt response using End-To-End Encryptor. + * + * @param responseObject Response object which should be encrypted. + * @param encryption PowerAuth encryption object. + * @return ECIES encrypted response. + */ + public @Nullable + EciesEncryptedResponse encryptResponse(@Nonnull Object responseObject, @Nonnull PowerAuthEncryptorData encryption) { + try { + final EncryptionContext encryptionContext = encryption.getContext(); + final ServerEncryptor serverEncryptor = encryption.getServerEncryptor(); + if (encryptionContext == null) { + logger.warn("Encryption context is not prepared"); + throw new PowerAuthEncryptionException(); + } + if (serverEncryptor == null || serverEncryptor.canEncryptResponse()) { + logger.warn("Encryptor is not available or not prepared for encryption. Scope: {}", encryptionContext.getEncryptionScope()); + throw new PowerAuthEncryptionException(); + } + // Serialize response data + final byte[] responseData = serializeResponseData(responseObject); + // Encrypt response + final EncryptedResponse encryptedResponse = serverEncryptor.encryptResponse(responseData); + return new EciesEncryptedResponse( + encryptedResponse.getEncryptedData(), + encryptedResponse.getMac(), + encryptedResponse.getNonce(), + encryptedResponse.getTimestamp() + ); + } catch (Exception ex) { + logger.debug("Response encryption failed, error: " + ex.getMessage(), ex); + return null; + } } /** @@ -268,10 +264,11 @@ private byte[] serializeResponseData(Object responseObject) throws JsonProcessin * Extract context required for ECIES encryption from either encryption or signature HTTP header. * * @param request HTTP servlet request. + * @param encryptorScope Scope of encryption. * @return Context for ECIES encryption. * @throws PowerAuthEncryptionException Thrown when HTTP header with ECIES data is invalid. */ - private EciesEncryptionContext extractEciesEncryptionContext(HttpServletRequest request) throws PowerAuthEncryptionException { + private EncryptionContext extractEciesEncryptionContext(HttpServletRequest request, EncryptionScope encryptorScope) throws PowerAuthEncryptionException { final String encryptionHttpHeader = request.getHeader(PowerAuthEncryptionHttpHeader.HEADER_NAME); final String signatureHttpHeader = request.getHeader(PowerAuthSignatureHttpHeader.HEADER_NAME); @@ -299,14 +296,14 @@ private EciesEncryptionContext extractEciesEncryptionContext(HttpServletRequest final String applicationKey = header.getApplicationKey(); final String activationId = header.getActivationId(); final String version = header.getVersion(); - return new EciesEncryptionContext(applicationKey, activationId, version, header); + return new EncryptionContext(applicationKey, activationId, version, header, encryptorScope); } else { // Parse encryption HTTP header final PowerAuthEncryptionHttpHeader header = new PowerAuthEncryptionHttpHeader().fromValue(encryptionHttpHeader); // Validate the encryption HTTP header try { - PowerAuthEncryptionHttpHeaderValidator.validate(header); + PowerAuthEncryptionHttpHeaderValidator.validate(header, encryptorScope.toEncryptorScope()); } catch (InvalidPowerAuthHttpHeaderException ex) { logger.warn("Encryption validation failed, error: {}", ex.getMessage()); logger.debug(ex.getMessage(), ex); @@ -317,7 +314,7 @@ private EciesEncryptionContext extractEciesEncryptionContext(HttpServletRequest final String applicationKey = header.getApplicationKey(); final String activationId = header.getActivationId(); final String version = header.getVersion(); - return new EciesEncryptionContext(applicationKey, activationId, version, header); + return new EncryptionContext(applicationKey, activationId, version, header, encryptorScope); } } } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java index 651a0ef6..9f51d488 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java @@ -21,10 +21,10 @@ 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.ecies.model.EciesScope; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionScope; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; @@ -89,20 +89,20 @@ public void setAuthenticationProvider(PowerAuthAuthenticationProvider authentica /** * Create activation. * @param request Encrypted activation layer 1 request. - * @param eciesContext ECIES encryption context. + * @param context Encryption context. * @return Activation layer 1 response. * @throws PowerAuthActivationException In case activation fails. * @throws PowerAuthRecoveryException In case recovery PUK is invalid. */ @PostMapping("create") - @PowerAuthEncryption(scope = EciesScope.APPLICATION_SCOPE) + @PowerAuthEncryption(scope = EncryptionScope.APPLICATION_SCOPE) public ActivationLayer1Response createActivation(@EncryptedRequestBody ActivationLayer1Request request, - EciesEncryptionContext eciesContext) throws PowerAuthActivationException, PowerAuthRecoveryException { - if (request == null || eciesContext == null) { + EncryptionContext context) throws PowerAuthActivationException, PowerAuthRecoveryException { + if (request == null || context == null) { logger.warn("Invalid request in activation create"); throw new PowerAuthActivationException(); } - return activationServiceV3.createActivation(request, eciesContext); + return activationServiceV3.createActivation(request, context); } /** diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java index df86489a..7e97a224 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java @@ -20,6 +20,7 @@ package io.getlime.security.powerauth.rest.api.spring.controller; import io.getlime.core.rest.model.base.response.Response; +import io.getlime.security.powerauth.crypto.lib.encryptor.model.EncryptorScope; import io.getlime.security.powerauth.http.PowerAuthEncryptionHttpHeader; import io.getlime.security.powerauth.http.PowerAuthSignatureHttpHeader; import io.getlime.security.powerauth.http.validator.InvalidPowerAuthHttpHeaderException; @@ -88,7 +89,7 @@ public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest re // Validate the encryption header try { - PowerAuthEncryptionHttpHeaderValidator.validate(header); + PowerAuthEncryptionHttpHeaderValidator.validate(header, EncryptorScope.ACTIVATION_SCOPE); } catch (InvalidPowerAuthHttpHeaderException ex) { logger.warn("Encryption validation failed, error: {}", ex.getMessage()); logger.debug(ex.getMessage(), ex); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java index 198723be..f922524b 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UserInfoController.java @@ -19,11 +19,11 @@ */ package io.getlime.security.powerauth.rest.api.spring.controller; -import io.getlime.security.powerauth.crypto.lib.encryptor.ecies.model.EciesScope; import io.getlime.security.powerauth.rest.api.model.request.UserInfoRequest; import io.getlime.security.powerauth.rest.api.spring.annotation.EncryptedRequestBody; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionScope; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthEncryptionException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthUserInfoException; import io.getlime.security.powerauth.rest.api.spring.service.UserInfoService; @@ -66,21 +66,21 @@ public UserInfoController(UserInfoService userInfoService) { * Fetch user info. * * @param request Request with user info service. - * @param eciesContext PowerAuth ECIES encryption context. + * @param encryptionContext PowerAuth ECIES encryption context. * @return Encrypted user info claims. * @throws PowerAuthUserInfoException In case there is an error while fetching claims. * @throws PowerAuthEncryptionException In case of failed encryption. */ - @PowerAuthEncryption(scope = EciesScope.ACTIVATION_SCOPE) + @PowerAuthEncryption(scope = EncryptionScope.ACTIVATION_SCOPE) @PostMapping("info") - public Map claims(@EncryptedRequestBody UserInfoRequest request, EciesEncryptionContext eciesContext) throws PowerAuthUserInfoException, PowerAuthEncryptionException { - if (eciesContext == null) { + public Map claims(@EncryptedRequestBody UserInfoRequest request, EncryptionContext encryptionContext) throws PowerAuthUserInfoException, PowerAuthEncryptionException { + if (encryptionContext == null) { logger.error("Encryption failed"); throw new PowerAuthEncryptionException("Encryption failed"); } return userInfoService.fetchUserClaimsByActivationId( - eciesContext.getActivationId() + encryptionContext.getActivationId() ); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java index 773c3606..1d2b9cf0 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/ActivationService.java @@ -37,7 +37,7 @@ import io.getlime.security.powerauth.rest.api.spring.application.PowerAuthApplicationConfiguration; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.converter.ActivationContextConverter; -import io.getlime.security.powerauth.rest.api.spring.encryption.EciesEncryptionContext; +import io.getlime.security.powerauth.rest.api.spring.encryption.EncryptionContext; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; @@ -126,7 +126,7 @@ public void setUserInfoProvider(UserInfoProvider userInfoProvider) { * @throws PowerAuthActivationException In case create activation fails. * @throws PowerAuthRecoveryException In case activation recovery fails. */ - public ActivationLayer1Response createActivation(ActivationLayer1Request request, EciesEncryptionContext eciesContext) throws PowerAuthActivationException, PowerAuthRecoveryException { + public ActivationLayer1Response createActivation(ActivationLayer1Request request, EncryptionContext eciesContext) throws PowerAuthActivationException, PowerAuthRecoveryException { try { final String applicationKey = eciesContext.getApplicationKey(); @@ -139,16 +139,6 @@ public ActivationLayer1Response createActivation(ActivationLayer1Request request final Map identity = request.getIdentityAttributes(); final Map customAttributes = (request.getCustomAttributes() != null) ? request.getCustomAttributes() : new HashMap<>(); - // Validate inner encryption - if (nonce == null && !"3.0".equals(eciesContext.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); - throw new PowerAuthActivationException(); - } - if (timestamp == null && (!"3.0".equals(eciesContext.getVersion()) && !"3.1".equals(eciesContext.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthActivationException(); - } - switch (request.getType()) { // Regular activation which uses "code" identity attribute case CODE -> { diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java index 0044091a..0ea79a6f 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/RecoveryService.java @@ -76,8 +76,7 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, final String activationId = authentication.getActivationContext().getActivationId(); final PowerAuthSignatureHttpHeader httpHeader = (PowerAuthSignatureHttpHeader) authentication.getHttpHeader(); final String applicationKey = httpHeader.getApplicationKey(); - if (activationId == null || applicationKey == null || request.getEphemeralPublicKey() == null - || request.getEncryptedData() == null || request.getMac() == null) { + if (activationId == null || applicationKey == null) { logger.warn("PowerAuth confirm recovery failed because of invalid request"); throw new PowerAuthInvalidRequestException(); } @@ -87,7 +86,6 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, confirmRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); confirmRequest.setEncryptedData(request.getEncryptedData()); confirmRequest.setMac(request.getMac()); - confirmRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); confirmRequest.setNonce(request.getNonce()); confirmRequest.setProtocolVersion(httpHeader.getVersion()); confirmRequest.setTimestamp(request.getTimestamp()); @@ -100,8 +98,11 @@ public EciesEncryptedResponse confirmRecoveryCode(EciesEncryptedRequest request, logger.warn("PowerAuth confirm recovery failed because of invalid activation ID in response"); throw new PowerAuthInvalidRequestException(); } - return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), - paResponse.getNonce(), paResponse.getTimestamp()); + return new EciesEncryptedResponse( + paResponse.getEncryptedData(), + paResponse.getMac(), + paResponse.getNonce(), + paResponse.getTimestamp()); } catch (Exception ex) { logger.warn("PowerAuth confirm recovery failed, error: {}", ex.getMessage()); logger.debug(ex.getMessage(), ex); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java index 595f5fdd..f0304ba6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/SecureVaultService.java @@ -100,13 +100,6 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, final String signatureVersion = header.getVersion(); final String nonce = header.getNonce(); - // Fetch data from the request - final String ephemeralPublicKey = request.getEphemeralPublicKey(); - final String encryptedData = request.getEncryptedData(); - final String mac = request.getMac(); - final String eciesNonce = request.getNonce(); - final Long timestamp = request.getTimestamp(); - // Prepare data for signature to allow signature verification on PowerAuth server final byte[] requestBodyBytes = authenticationProvider.extractRequestBodyBytes(httpServletRequest); final String data = PowerAuthHttpBody.getSignatureBaseString("POST", "/pa/vault/unlock", Base64.getDecoder().decode(nonce), requestBodyBytes); @@ -119,12 +112,11 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, unlockRequest.setSignatureType(signatureType); unlockRequest.setSignatureVersion(signatureVersion); unlockRequest.setSignedData(data); - unlockRequest.setEphemeralPublicKey(ephemeralPublicKey); - unlockRequest.setEncryptedData(encryptedData); - unlockRequest.setMac(mac); - unlockRequest.setEphemeralPublicKey(ephemeralPublicKey); - unlockRequest.setNonce(eciesNonce); - unlockRequest.setTimestamp(timestamp); + unlockRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); + unlockRequest.setEncryptedData(request.getEncryptedData()); + unlockRequest.setMac(request.getMac()); + unlockRequest.setNonce(request.getNonce()); + unlockRequest.setTimestamp(request.getTimestamp()); final VaultUnlockResponse paResponse = powerAuthClient.unlockVault( unlockRequest, httpCustomizationService.getQueryParams(), @@ -136,8 +128,11 @@ public EciesEncryptedResponse vaultUnlock(PowerAuthSignatureHttpHeader header, throw new PowerAuthSignatureInvalidException(); } - return new EciesEncryptedResponse(paResponse.getEncryptedData(), paResponse.getMac(), - paResponse.getNonce(), paResponse.getTimestamp()); + return new EciesEncryptedResponse( + paResponse.getEncryptedData(), + paResponse.getMac(), + paResponse.getNonce(), + paResponse.getTimestamp()); } catch (PowerAuthAuthenticationException ex) { throw ex; } catch (Exception ex) { diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java index b4d1913e..f43693a9 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java @@ -84,13 +84,6 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, // Fetch activation ID and signature type final PowerAuthSignatureTypes signatureFactors = authentication.getAuthenticationContext().getSignatureType(); - // Fetch data from the request - final String ephemeralPublicKey = request.getEphemeralPublicKey(); - final String encryptedData = request.getEncryptedData(); - final String mac = request.getMac(); - final String nonce = request.getNonce(); - final Long timestamp = request.getTimestamp(); - // Prepare a signature type converter final SignatureTypeConverter converter = new SignatureTypeConverter(); final SignatureType signatureType = converter.convertFrom(signatureFactors); @@ -108,14 +101,13 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, final CreateTokenRequest tokenRequest = new CreateTokenRequest(); tokenRequest.setActivationId(activationId); tokenRequest.setApplicationKey(applicationKey); - tokenRequest.setEphemeralPublicKey(ephemeralPublicKey); - tokenRequest.setEncryptedData(encryptedData); - tokenRequest.setMac(mac); - tokenRequest.setEphemeralPublicKey(ephemeralPublicKey); - tokenRequest.setNonce(nonce); + tokenRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); + tokenRequest.setEncryptedData(request.getEncryptedData()); + tokenRequest.setMac(request.getMac()); + tokenRequest.setNonce(request.getNonce()); tokenRequest.setSignatureType(signatureType); tokenRequest.setProtocolVersion(httpHeader.getVersion()); - tokenRequest.setTimestamp(timestamp); + tokenRequest.setTimestamp(request.getTimestamp()); final CreateTokenResponse token = powerAuthClient.createToken( tokenRequest, httpCustomizationService.getQueryParams(), @@ -128,6 +120,7 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, response.setEncryptedData(token.getEncryptedData()); response.setNonce(token.getNonce()); response.setMac(token.getMac()); + response.setTimestamp(token.getTimestamp()); return response; } catch (Exception ex) { logger.warn("Creating PowerAuth token failed, error: {}", ex.getMessage()); diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java index a3492afd..c8bfa948 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/UpgradeService.java @@ -89,13 +89,6 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA throws PowerAuthUpgradeException { try { - // Fetch data from the request - final String ephemeralPublicKey = request.getEphemeralPublicKey(); - final String encryptedData = request.getEncryptedData(); - final String mac = request.getMac(); - final String nonce = request.getNonce(); - final Long timestamp = request.getTimestamp(); - // Get ECIES headers final String activationId = header.getActivationId(); final String applicationKey = header.getApplicationKey(); @@ -104,12 +97,12 @@ public EciesEncryptedResponse upgradeStart(EciesEncryptedRequest request, PowerA final StartUpgradeRequest upgradeRequest = new StartUpgradeRequest(); upgradeRequest.setActivationId(activationId); upgradeRequest.setApplicationKey(applicationKey); - upgradeRequest.setEphemeralPublicKey(ephemeralPublicKey); - upgradeRequest.setEncryptedData(encryptedData); - upgradeRequest.setMac(mac); - upgradeRequest.setNonce(nonce); + upgradeRequest.setEphemeralPublicKey(request.getEphemeralPublicKey()); + upgradeRequest.setEncryptedData(request.getEncryptedData()); + upgradeRequest.setMac(request.getMac()); + upgradeRequest.setNonce(request.getNonce()); upgradeRequest.setProtocolVersion(header.getVersion()); - upgradeRequest.setTimestamp(timestamp); + upgradeRequest.setTimestamp(request.getTimestamp()); final StartUpgradeResponse upgradeResponse = powerAuthClient.startUpgrade( upgradeRequest, httpCustomizationService.getQueryParams(), From a4b7775b9294d33e644642c3796adfab8b7fee12 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 24 Aug 2023 11:31:50 +0200 Subject: [PATCH 53/64] Fix #427: Set release version to 1.5.0 --- pom.xml | 2 +- powerauth-restful-model/pom.xml | 2 +- powerauth-restful-security-spring-annotation/pom.xml | 2 +- powerauth-restful-security-spring/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 14760e79..329b7f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.5.0-SNAPSHOT + 1.5.0 pom 2017 diff --git a/powerauth-restful-model/pom.xml b/powerauth-restful-model/pom.xml index 03089201..3ee6c82c 100644 --- a/powerauth-restful-model/pom.xml +++ b/powerauth-restful-model/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 4d64e5b6..b2416aee 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.5.0-SNAPSHOT + 1.5.0 diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index 0212cb6c..b4c031e9 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -30,7 +30,7 @@ io.getlime.security powerauth-restful-integration-parent - 1.5.0-SNAPSHOT + 1.5.0 From 7ec98b1beeebeb698f5e0d379b13110bfc3fb165 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 24 Aug 2023 11:46:17 +0200 Subject: [PATCH 54/64] Fix #429: Update to non-snapshot dependencies --- pom.xml | 7 +++---- powerauth-restful-security-spring-annotation/pom.xml | 6 +++--- powerauth-restful-security-spring/pom.xml | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 14760e79..93b43c4a 100644 --- a/pom.xml +++ b/pom.xml @@ -86,10 +86,9 @@ 3.1.2 1.10.0 1.76 - 1.7.0-SNAPSHOT - 1.5.0-SNAPSHOT - 1.5.0-SNAPSHOT - 1.5.0-SNAPSHOT + 1.7.0 + 1.5.0 + 1.5.0 diff --git a/powerauth-restful-security-spring-annotation/pom.xml b/powerauth-restful-security-spring-annotation/pom.xml index 4d64e5b6..0ef3772c 100644 --- a/powerauth-restful-security-spring-annotation/pom.xml +++ b/powerauth-restful-security-spring-annotation/pom.xml @@ -61,17 +61,17 @@ io.getlime.security powerauth-java-crypto - ${powerauth-java-crypto.version} + ${powerauth-crypto.version} io.getlime.security powerauth-java-http - ${powerauth-java-http.version} + ${powerauth-crypto.version} io.getlime.security powerauth-rest-client-spring - ${powerauth-rest-client-spring.version} + ${powerauth.version} diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index 0212cb6c..07d16984 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -45,7 +45,7 @@ io.getlime.security powerauth-rest-client-spring - ${powerauth-rest-client-spring.version} + ${powerauth.version} log4j-to-slf4j From ffc685b15d0f523825b5d003550aa6aac7915bb5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 07:06:16 +0000 Subject: [PATCH 55/64] Bump org.springframework.boot:spring-boot-dependencies Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.1.2...v3.1.3) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-dependencies 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 14760e79..610ca681 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ 3.5.0 3.2.1 3.3.2 - 3.1.2 + 3.1.3 1.10.0 1.76 1.7.0-SNAPSHOT From f9be3885c0d1a375204899cfa30b956c7b5aa148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20=C4=8Eurech?= Date: Thu, 31 Aug 2023 09:10:16 +0200 Subject: [PATCH 56/64] Fix #432: Wrap ServerStatusResponse into ObjectResponse --- .../rest/api/spring/controller/ServerStatusController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java index cba0f7fd..9e422a91 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ServerStatusController.java @@ -19,6 +19,7 @@ */ package io.getlime.security.powerauth.rest.api.spring.controller; +import io.getlime.core.rest.model.base.response.ObjectResponse; import io.getlime.security.powerauth.rest.api.model.response.ServerStatusResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -48,9 +49,10 @@ public class ServerStatusController { * @return Server status. */ @PostMapping("status") - public ServerStatusResponse getServerStatus() { + public ObjectResponse getServerStatus() { final long serverTime = new Date().getTime(); - return new ServerStatusResponse(serverTime); + final ServerStatusResponse response = new ServerStatusResponse(serverTime); + return new ObjectResponse<>(response); } } From e56740b6082c288a3f2f8d99842744653c12cd53 Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Thu, 7 Sep 2023 20:07:30 +0200 Subject: [PATCH 57/64] Fix #435: Add protocol version into token verification endpoint --- .../api/spring/provider/PowerAuthAuthenticationProvider.java | 1 + 1 file changed, 1 insertion(+) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java index 13db7f98..e7ce01d4 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/provider/PowerAuthAuthenticationProvider.java @@ -187,6 +187,7 @@ private PowerAuthApiAuthenticationImpl validateTokenAuthentication(PowerAuthToke validateRequest.setTokenDigest(authentication.getTokenDigest()); validateRequest.setNonce(authentication.getNonce()); validateRequest.setTimestamp(Long.parseLong(authentication.getTimestamp())); + validateRequest.setProtocolVersion(authentication.getVersion()); final ValidateTokenResponse response = powerAuthClient.validateToken( validateRequest, From 5044fce8ab080e63469005ebf863f49064d525fe Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Wed, 13 Sep 2023 08:26:54 +0200 Subject: [PATCH 58/64] Fix #437: Missing override annotation in PowerAuthInvalidRequestException --- .../authentication/PowerAuthInvalidRequestException.java | 1 + 1 file changed, 1 insertion(+) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java index 7c745110..0a84741f 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/exception/authentication/PowerAuthInvalidRequestException.java @@ -64,6 +64,7 @@ public PowerAuthInvalidRequestException(Throwable cause) { * Get the default error code, used for example in REST response. * @return Default error code. */ + @Override public String getDefaultCode() { return DEFAULT_CODE; } From d38b17a69b42a69a87d6a495ef79e4009cec377c Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Wed, 13 Sep 2023 19:32:59 +0200 Subject: [PATCH 59/64] Fix #439: Incorrect usage of fully qualified name for class PowerAuthEncryption --- .../annotation/support/PowerAuthEncryptionArgumentResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java index e90bc9cd..3abcffe3 100644 --- a/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java +++ b/powerauth-restful-security-spring-annotation/src/main/java/io/getlime/security/powerauth/rest/api/spring/annotation/support/PowerAuthEncryptionArgumentResolver.java @@ -83,7 +83,7 @@ public Object resolveArgument(@NonNull MethodParameter parameter, ModelAndViewCo // Ecies encryption object is inserted into parameter which is of type PowerAuthEciesEncryption if (eciesObject != null && EncryptionContext.class.isAssignableFrom(parameter.getParameterType())) { // Set ECIES scope in case it is specified by the @PowerAuthEncryption annotation - final PowerAuthEncryption powerAuthEncryption = parameter.getMethodAnnotation(io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption.class); + final PowerAuthEncryption powerAuthEncryption = parameter.getMethodAnnotation(PowerAuthEncryption.class); if (powerAuthEncryption != null) { EncryptionContext eciesContext = eciesObject.getContext(); boolean validScope = validateEciesScope(eciesContext); From 60a332e46f066dd6629f5ad5cd1bade10092abf0 Mon Sep 17 00:00:00 2001 From: "roman.strobl@wultra.com" Date: Wed, 13 Sep 2023 20:04:23 +0200 Subject: [PATCH 60/64] Fix #441: Duplicate call in createToken method --- .../security/powerauth/rest/api/spring/service/TokenService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java index f43693a9..56312032 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/service/TokenService.java @@ -119,7 +119,6 @@ public EciesEncryptedResponse createToken(EciesEncryptedRequest request, response.setMac(token.getMac()); response.setEncryptedData(token.getEncryptedData()); response.setNonce(token.getNonce()); - response.setMac(token.getMac()); response.setTimestamp(token.getTimestamp()); return response; } catch (Exception ex) { From 6fa273b533d78627485f56d3891bf13d0c96f714 Mon Sep 17 00:00:00 2001 From: Lubos Racansky Date: Thu, 14 Sep 2023 06:51:34 +0200 Subject: [PATCH 61/64] Remove owasp-dependency-check GitHub Action configuration --- .github/workflows/owas-dependecy-check.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/workflows/owas-dependecy-check.yml diff --git a/.github/workflows/owas-dependecy-check.yml b/.github/workflows/owas-dependecy-check.yml deleted file mode 100644 index c79178b2..00000000 --- a/.github/workflows/owas-dependecy-check.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Run OWASP Dependency Check -on: - workflow_dispatch: - - push: - branches: - - 'develop' - -jobs: - owasp-check: - uses: wultra/wultra-infrastructure/.github/workflows/owasp-dependency-check.yml@develop - secrets: inherit \ No newline at end of file From 78c3f2ca79807cb31aa7d4f9a5d8113810627af6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 07:25:36 +0000 Subject: [PATCH 62/64] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0 Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin 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 610ca681..c19e1f7f 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ ${java.version} 3.3.0 3.1.1 - 3.5.0 + 3.6.0 3.2.1 3.3.2 3.1.3 From 55bbeecfcbb3740744d76abbea6fe1c7cc8367ec Mon Sep 17 00:00:00 2001 From: Jan Dusil <134381434+jandusil@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:47:38 +0200 Subject: [PATCH 63/64] Fix #424: Improve checking of supported versions (#443) * Fix #424: Improve checking of supported versions - Introduce new util class - Substitute repetitive code - Add test --- powerauth-restful-security-spring/pom.xml | 7 + .../controller/ActivationController.java | 10 +- .../spring/controller/RecoveryController.java | 21 +-- .../controller/SecureVaultController.java | 18 +-- .../controller/SignatureController.java | 12 +- .../spring/controller/TokenController.java | 28 +--- .../spring/controller/UpgradeController.java | 31 +--- .../api/spring/util/PowerAuthVersionUtil.java | 149 ++++++++++++++++++ .../api/spring/PowerAuthVersionUtilTest.java | 65 ++++++++ 9 files changed, 255 insertions(+), 86 deletions(-) create mode 100644 powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/util/PowerAuthVersionUtil.java create mode 100644 powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/PowerAuthVersionUtilTest.java diff --git a/powerauth-restful-security-spring/pom.xml b/powerauth-restful-security-spring/pom.xml index 0212cb6c..f820891c 100644 --- a/powerauth-restful-security-spring/pom.xml +++ b/powerauth-restful-security-spring/pom.xml @@ -54,6 +54,13 @@ + + + org.junit.jupiter + junit-jupiter-engine + test + + diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java index 9f51d488..93e41720 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/ActivationController.java @@ -28,7 +28,6 @@ import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthActivationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthRecoveryException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; import io.getlime.security.powerauth.rest.api.model.request.ActivationLayer1Request; import io.getlime.security.powerauth.rest.api.model.request.ActivationStatusRequest; @@ -39,6 +38,7 @@ import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthEncryption; import io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider; import io.getlime.security.powerauth.rest.api.spring.service.ActivationService; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -141,12 +141,8 @@ public ObjectResponse removeActivation( logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(apiAuthentication.getVersion()) - && !"3.1".equals(apiAuthentication.getVersion()) - && !"3.2".equals(apiAuthentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", apiAuthentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } + PowerAuthVersionUtil.checkUnsupportedVersion(apiAuthentication.getVersion()); + ActivationRemoveResponse response = activationServiceV3.removeActivation(apiAuthentication); return new ObjectResponse<>(response); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java index bf37a9de..45c1258d 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/RecoveryController.java @@ -28,10 +28,12 @@ import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; import io.getlime.security.powerauth.rest.api.spring.service.RecoveryService; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; + /** * Controller implementing recovery related end-points from the PowerAuth * Standard API. @@ -80,20 +82,11 @@ public EciesEncryptedResponse confirmRecoveryCode(@RequestBody EciesEncryptedReq if (authentication == null || authentication.getActivationContext().getActivationId() == null) { throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) - && !"3.1".equals(authentication.getVersion()) - && !"3.2".equals(authentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - if (request.getNonce() == null && !"3.0".equals(authentication.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } - if (request.getTimestamp() == null && (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } + + PowerAuthVersionUtil.checkUnsupportedVersion(authentication.getVersion()); + PowerAuthVersionUtil.checkMissingRequiredNonce(authentication.getVersion(), request.getNonce()); + PowerAuthVersionUtil.checkMissingRequiredTimestamp(authentication.getVersion(), request.getTimestamp()); + return recoveryService.confirmRecoveryCode(request, authentication); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java index 176c82ba..875c6cc6 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SecureVaultController.java @@ -29,6 +29,7 @@ import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.service.SecureVaultService; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -98,21 +99,10 @@ public EciesEncryptedResponse unlockVault( throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(header.getVersion()) - && !"3.1".equals(header.getVersion()) - && !"3.2".equals(header.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - if (request.getNonce() == null && !"3.0".equals(header.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } + PowerAuthVersionUtil.checkUnsupportedVersion(header.getVersion()); + PowerAuthVersionUtil.checkMissingRequiredNonce(header.getVersion(), request.getNonce()); + PowerAuthVersionUtil.checkMissingRequiredTimestamp(header.getVersion(), request.getTimestamp()); - if (request.getTimestamp() == null && (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } return secureVaultServiceV3.vaultUnlock(header, request, httpServletRequest); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java index 195df04d..a30526f4 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/SignatureController.java @@ -23,7 +23,6 @@ import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; import io.getlime.security.powerauth.rest.api.spring.authentication.PowerAuthApiAuthentication; import io.getlime.security.powerauth.rest.api.spring.exception.PowerAuthAuthenticationException; -import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthSignatureInvalidException; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; import org.slf4j.Logger; @@ -32,6 +31,8 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; + /** * End-point for validating signatures. * @@ -68,12 +69,9 @@ public Response validateSignature(PowerAuthApiAuthentication auth) throws PowerA logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(auth.getVersion()) - && !"3.1".equals(auth.getVersion()) - && !"3.2".equals(auth.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", auth.getVersion()); - throw new PowerAuthInvalidRequestException(); - } + + PowerAuthVersionUtil.checkUnsupportedVersion(auth.getVersion()); + return new Response(); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java index 917d9cb4..23433749 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/TokenController.java @@ -32,6 +32,7 @@ import io.getlime.security.powerauth.rest.api.model.response.TokenRemoveResponse; import io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuth; import io.getlime.security.powerauth.rest.api.spring.service.TokenService; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -89,20 +90,10 @@ public EciesEncryptedResponse createToken(@RequestBody EciesEncryptedRequest req logger.debug("Signature validation failed"); throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) - && !"3.1".equals(authentication.getVersion()) - && !"3.2".equals(authentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } - if (request.getNonce() == null && !"3.0".equals(authentication.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } - if (request.getTimestamp() == null && (!"3.0".equals(authentication.getVersion()) && !"3.1".equals(authentication.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthInvalidRequestException(); - } + PowerAuthVersionUtil.checkUnsupportedVersion(authentication.getVersion()); + PowerAuthVersionUtil.checkMissingRequiredNonce(authentication.getVersion(), request.getNonce()); + PowerAuthVersionUtil.checkMissingRequiredTimestamp(authentication.getVersion(), request.getTimestamp()); + return tokenServiceV3.createToken(request, authentication); } @@ -129,12 +120,9 @@ public ObjectResponse removeToken(@RequestBody ObjectReques if (authentication == null || authentication.getActivationContext().getActivationId() == null) { throw new PowerAuthSignatureInvalidException(); } - if (!"3.0".equals(authentication.getVersion()) - && !"3.1".equals(authentication.getVersion()) - && !"3.2".equals(authentication.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", authentication.getVersion()); - throw new PowerAuthInvalidRequestException(); - } + + PowerAuthVersionUtil.checkUnsupportedVersion(authentication.getVersion()); + TokenRemoveResponse response = tokenServiceV3.removeToken(request.getRequestObject(), authentication); return new ObjectResponse<>(response); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java index 7e97a224..4fb94ea8 100644 --- a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/controller/UpgradeController.java @@ -32,6 +32,7 @@ import io.getlime.security.powerauth.rest.api.model.request.EciesEncryptedRequest; import io.getlime.security.powerauth.rest.api.model.response.EciesEncryptedResponse; import io.getlime.security.powerauth.rest.api.spring.service.UpgradeService; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -76,8 +77,8 @@ public void setUpgradeService(UpgradeService upgradeService) { */ @PostMapping("start") public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest request, - @RequestHeader(value = PowerAuthEncryptionHttpHeader.HEADER_NAME, defaultValue = "unknown") String encryptionHeader) - throws PowerAuthUpgradeException { + @RequestHeader(value = PowerAuthEncryptionHttpHeader.HEADER_NAME, defaultValue = "unknown") String encryptionHeader) + throws PowerAuthUpgradeException, PowerAuthInvalidRequestException { if (request == null) { logger.warn("Invalid request object in upgrade start"); @@ -96,22 +97,9 @@ public EciesEncryptedResponse upgradeStart(@RequestBody EciesEncryptedRequest re throw new PowerAuthUpgradeException(); } - if (!"3.0".equals(header.getVersion()) - && !"3.1".equals(header.getVersion()) - && !"3.2".equals(header.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); - throw new PowerAuthUpgradeException(); - } - - if (request.getNonce() == null && !"3.0".equals(header.getVersion())) { - logger.warn("Missing nonce in ECIES request data"); - throw new PowerAuthUpgradeException(); - } - - if (request.getTimestamp() == null && (!"3.0".equals(header.getVersion()) && !"3.1".equals(header.getVersion()))) { - logger.warn("Missing timestamp in ECIES request data"); - throw new PowerAuthUpgradeException(); - } + PowerAuthVersionUtil.checkUnsupportedVersion(header.getVersion()); + PowerAuthVersionUtil.checkMissingRequiredNonce(header.getVersion(), request.getNonce()); + PowerAuthVersionUtil.checkMissingRequiredTimestamp(header.getVersion(), request.getTimestamp()); return upgradeService.upgradeStart(request, header); @@ -143,12 +131,7 @@ public Response upgradeCommit(@RequestHeader(value = PowerAuthSignatureHttpHeade throw new PowerAuthUpgradeException(); } - if (!"3.0".equals(header.getVersion()) - && !"3.1".equals(header.getVersion()) - && !"3.2".equals(header.getVersion())) { - logger.warn("Endpoint does not support PowerAuth protocol version {}", header.getVersion()); - throw new PowerAuthInvalidRequestException(); - } + PowerAuthVersionUtil.checkUnsupportedVersion(header.getVersion()); return upgradeService.upgradeCommit(signatureHeader, httpServletRequest); } diff --git a/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/util/PowerAuthVersionUtil.java b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/util/PowerAuthVersionUtil.java new file mode 100644 index 00000000..cad9ecf7 --- /dev/null +++ b/powerauth-restful-security-spring/src/main/java/io/getlime/security/powerauth/rest/api/spring/util/PowerAuthVersionUtil.java @@ -0,0 +1,149 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring.util; + +import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; +import lombok.extern.slf4j.Slf4j; + +import java.util.Set; + +/** + * Utility class to assist with PowerAuth version checks and related functionalities. + * This class provides methods to validate different aspects of the PowerAuth protocol, + * such as version checks, nonce verification, and timestamp checks. + *

+ * Note: The usage of these utility methods ensures the protocol adheres to the correct + * PowerAuth versions and avoids potential issues in processing requests. + *

+ * @author Jan Dusil, jan.dusil@wultra.com + */ +@Slf4j +public final class PowerAuthVersionUtil { + + /** + * Prevent instantiation of utility class. + */ + private PowerAuthVersionUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Set containing all the supported versions of PowerAuth. + */ + private static final Set SUPPORTED_VERSIONS = Set.of("3.0", "3.1", "3.2"); + + /** + * Check if the provided version string is "3.0". + * + * @param version Version string to be checked. + * @return true if the version is "3.0", false otherwise. + */ + private static boolean isVersion3_0(final String version) { + return "3.0".equals(version); + } + + /** + * Check if the provided version string is "3.1". + * + * @param version Version string to be checked. + * @return true if the version is "3.1", false otherwise. + */ + private static boolean isVersion3_1(final String version) { + return "3.1".equals(version); + } + + /** + * Checks if the provided PowerAuth protocol version is unsupported. + * Throws an exception if the version is unsupported. + * + * @param version Version string to be checked. + * @throws PowerAuthInvalidRequestException If the provided version is unsupported. + */ + public static void checkUnsupportedVersion(String version) throws PowerAuthInvalidRequestException { + if (isUnsupportedVersion(version)) { + logger.warn("Endpoint does not support PowerAuth protocol version {}", version); + throw new PowerAuthInvalidRequestException("Endpoint does not support PowerAuth protocol version " + version); + } + } + + /** + * Checks if nonce is missing for the provided PowerAuth protocol version. + * Throws an exception if nonce is required and missing. + * + * @param version Version string to be checked. + * @param nonce Nonce string to be verified. + * @throws PowerAuthInvalidRequestException If nonce is required and missing. + */ + public static void checkMissingRequiredNonce(String version, String nonce) throws PowerAuthInvalidRequestException { + if (isMissingRequiredNonce(version, nonce)) { + logger.warn("Missing nonce in ECIES request data"); + throw new PowerAuthInvalidRequestException("Missing nonce in ECIES request data"); + } + } + + /** + * Checks if timestamp is missing for the provided PowerAuth protocol version. + * Throws an exception if the timestamp is required and missing. + * + * @param version Version string to be checked. + * @param timestamp Timestamp value to be verified. + * @throws PowerAuthInvalidRequestException If timestamp is required and missing. + */ + public static void checkMissingRequiredTimestamp(String version, Long timestamp) throws PowerAuthInvalidRequestException { + if (isMissingRequiredTimestamp(version, timestamp)) { + logger.warn("Missing timestamp in ECIES request data for version {}", version); + throw new PowerAuthInvalidRequestException("Missing timestamp in ECIES request data for version " + version); + } + } + + /** + * Checks if the provided PowerAuth protocol version is unsupported. + * + * @param version Version string to be checked. + * @return true if the version is unsupported, false otherwise. + */ + private static boolean isUnsupportedVersion(String version) { + return !SUPPORTED_VERSIONS.contains(version); + } + + /** + * Checks if nonce is missing for the provided PowerAuth protocol version. + * + * @param version Version string to be checked. + * @param nonce Nonce string to be verified. + * @return true if nonce is required and missing, false otherwise. + */ + private static boolean isMissingRequiredNonce(String version, String nonce) { + return nonce == null && !isVersion3_0(version); + } + + /** + * Checks if timestamp is missing for the provided PowerAuth protocol version. + * + * @param version Version string to be checked. + * @param timestamp Timestamp value to be verified. + * @return true if timestamp is required and missing, false otherwise. + */ + private static boolean isMissingRequiredTimestamp(String version, Long timestamp) { + return timestamp == null && + !isVersion3_0(version) && + !isVersion3_1(version); + } +} diff --git a/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/PowerAuthVersionUtilTest.java b/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/PowerAuthVersionUtilTest.java new file mode 100644 index 00000000..6d15f81a --- /dev/null +++ b/powerauth-restful-security-spring/src/test/java/io/getlime/security/powerauth/rest/api/spring/PowerAuthVersionUtilTest.java @@ -0,0 +1,65 @@ +/* + * PowerAuth integration libraries for RESTful API applications, examples and + * related software components + * + * Copyright (C) 2023 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 io.getlime.security.powerauth.rest.api.spring; + +import io.getlime.security.powerauth.rest.api.spring.exception.authentication.PowerAuthInvalidRequestException; +import io.getlime.security.powerauth.rest.api.spring.util.PowerAuthVersionUtil; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * This class provides tests for the {@link PowerAuthVersionUtil} utility class, + * ensuring that the PowerAuth version checks and related functionalities work as expected. + * + * @author Jan Dusil, jan.dusil@wultra.com + */ +class PowerAuthVersionUtilTest { + + /** + * Tests the behavior of checking unsupported PowerAuth versions. + */ + @Test + void testUnsupportedVersion() { + assertThrows(PowerAuthInvalidRequestException.class, () -> PowerAuthVersionUtil.checkUnsupportedVersion("4.0")); + assertDoesNotThrow(() -> PowerAuthVersionUtil.checkUnsupportedVersion("3.1")); + } + + /** + * Tests the behavior of checking for missing required nonces based on the PowerAuth version. + */ + @Test + void testMissingRequiredNonce() { + assertThrows(PowerAuthInvalidRequestException.class, () -> PowerAuthVersionUtil.checkMissingRequiredNonce("3.1", null)); + assertDoesNotThrow(() -> PowerAuthVersionUtil.checkMissingRequiredNonce("3.0", null)); + assertDoesNotThrow(() -> PowerAuthVersionUtil.checkMissingRequiredNonce("3.1", "testNonce")); + } + + /** + * Tests the behavior of checking for missing required timestamps based on the PowerAuth version. + */ + @Test + void testMissingRequiredTimestamp() { + assertThrows(PowerAuthInvalidRequestException.class, () -> PowerAuthVersionUtil.checkMissingRequiredTimestamp("3.2", null)); + assertDoesNotThrow(() -> PowerAuthVersionUtil.checkMissingRequiredTimestamp("3.1", null)); + assertDoesNotThrow(() -> PowerAuthVersionUtil.checkMissingRequiredTimestamp("3.2", 1630234567890L)); + } +} \ No newline at end of file From 52c69938df7fdf80dae94e1c2b23aa4d63793e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Ra=C4=8Dansk=C3=BD?= Date: Tue, 19 Sep 2023 12:57:53 +0200 Subject: [PATCH 64/64] Fix #446: Update Powerauth Crypto to 1.5.1 (#447) * Fix #446: Update Powerauth Crypto to 1.5.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5da8548a..c2303f8b 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 1.76 1.7.0 1.5.0 - 1.5.0 + 1.5.1