diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 04e04ece..c502bf2b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,67 +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: '19 8 * * 5' jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - 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 - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # 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. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # 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@v2 - - # ℹī¸ 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 - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + 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 diff --git a/.github/workflows/owas-dependecy-check.yml b/.github/workflows/owas-dependecy-check.yml deleted file mode 100644 index c4d5d262..00000000 --- a/.github/workflows/owas-dependecy-check.yml +++ /dev/null @@ -1,14 +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 - with: - directory_path: powerauth-data-adapter \ No newline at end of file diff --git a/.run/DataAdapterApplication.run.xml b/.run/DataAdapterApplication.run.xml new file mode 100644 index 00000000..8a01e6f5 --- /dev/null +++ b/.run/DataAdapterApplication.run.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 42e30564..00000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: java -jdk: - - openjdk11 -script: mvn -f powerauth-data-adapter/pom.xml clean package -branches: - only: - - master - - coverity_scan -env: - global: - - secure: "ZeE+S5KU4rA0zta+udAFBIEETAqTg5SExaFtoNur/2DG79hcGGO/nC1VouwbwYnR81xNc3A5LniTsqwYjzFFstCRUPR7zjeYIq4B9v5bdNqdLiRvY/Re9Rk9f4hVf3039SnKGaEC+iCMzs/BxFW5+y68Oe1RKGh9yI0I2WKglkIw3NHLx+qI4HBhWwgso2USBNGGfEPOwJAR0940DxLywOxNFPUuMjYIFXY7Yx6Hko0L7BX+TRERmJuxK+cwoTWkFdmAzNIsau2WpSHN2/V+kIP8sr9eeUc33pY9ztW+oir3kteDhNjPeg9NA+FG6bGC8D8hPzNIMEED/OPs/Zj3G0oOLLTS/fjulSAiTAK6afkEyffNjVfh7dJQxvfGhHBJs1PDD0+a7sYogmf/eisxO6qYI+hRZMpkjjJL590Ovk6do9anzzmJ8lSSH6r8NVCANt2q5fnjp5BOOPFWGolWMvH2r699TiL3azBM1lWz3spvvk11DbtWqDJCOFmtD4SluTFAKuZjageQY69nPpB/w3Q+ThpYJqTNNrHD1i/b5daAi8aIGZud5vvwTUC5ItGzSGhjizTFxps7FOa77P//YIQhdirURvgIkuCf0A5vGBABuyeVOmz3pkx36sO4va1ZqNNYY9tbv5rdCBynU0KgmrOr6J3Q6IwMSxrc85ykSlI=" - -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-webflow-customization" - description: "Build submitted via Travis CI" - notification_email: roman.strobl@wultra.com - build_command_prepend: "mvn -f powerauth-data-adapter/pom.xml clean" - build_command: "mvn -DskipTests=true -f powerauth-data-adapter/pom.xml compile" - branch_pattern: coverity_scan diff --git a/doc-private/Developer-How-To-Start.md b/doc-private/Developer-How-To-Start.md new file mode 100644 index 00000000..6a2538d1 --- /dev/null +++ b/doc-private/Developer-How-To-Start.md @@ -0,0 +1,24 @@ +# Developer - How to Start Guide + + +## PowerAuth Data Adapter + + +### Standalone Run + +- Enable maven profile `standalone` +- Use IntelliJ Idea run configuration at `../.run/DataAdapterApplication.run.xml` +- Open [http://localhost:9090/powerauth-data-adapter/actuator/health](http://localhost:9090/powerauth-data-adapter/actuator/health) and you should get `{"status":"UP"}` + + +### Database + +Database changes are driven by Liquibase. + +This is an example how to manually check the Liquibase status. +Important and fixed parameter is `changelog-file`. +Others (like URL, username, password) depend on your environment. + +```shell +liquibase --changelog-file=./docs/db/changelog/changesets/powerauth-data-adapter/db.changelog-module.xml --url=jdbc:postgresql://localhost:5432/powerauth --username=powerauth --hub-mode=off status +``` diff --git a/docs/Deploying-Wildfly.md b/docs/Deploying-Wildfly.md index 5d726f6f..63e4fe62 100644 --- a/docs/Deploying-Wildfly.md +++ b/docs/Deploying-Wildfly.md @@ -19,7 +19,7 @@ Data Adapter contains the following configuration in `jboss-deployment-structure - + diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230326-init-db.xml b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230326-init-db.xml new file mode 100644 index 00000000..5f6bc55b --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230326-init-db.xml @@ -0,0 +1,76 @@ + + + + + + + + + + Create a new table da_sms_authorization + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create a new table da_user_credentials + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230327-add-tag-1.4.0.xml b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230327-add-tag-1.4.0.xml new file mode 100644 index 00000000..46995de0 --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/20230327-add-tag-1.4.0.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/db.changelog-version.xml b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/db.changelog-version.xml new file mode 100644 index 00000000..c28af570 --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/1.4.x/db.changelog-version.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/20230905-add-tag-1.5.0.xml b/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/20230905-add-tag-1.5.0.xml new file mode 100644 index 00000000..3e2e54a5 --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/20230905-add-tag-1.5.0.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/db.changelog-version.xml b/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/db.changelog-version.xml new file mode 100644 index 00000000..b571e45e --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/1.5.x/db.changelog-version.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/docs/db/changelog/changesets/powerauth-data-adapter/db.changelog-module.xml b/docs/db/changelog/changesets/powerauth-data-adapter/db.changelog-module.xml new file mode 100644 index 00000000..9599a2fe --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-data-adapter/db.changelog-module.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/db/changelog/db.changelog-master.xml b/docs/db/changelog/db.changelog-master.xml new file mode 100644 index 00000000..8aadb531 --- /dev/null +++ b/docs/db/changelog/db.changelog-master.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/powerauth-data-adapter/pom.xml b/powerauth-data-adapter/pom.xml index 5ae9227b..a7dba6f6 100644 --- a/powerauth-data-adapter/pom.xml +++ b/powerauth-data-adapter/pom.xml @@ -5,7 +5,7 @@ powerauth-data-adapter io.getlime.security - 1.4.0 + 1.5.0 war powerauth-data-adapter @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.14 + 3.1.3 @@ -62,13 +62,11 @@ - UTF-8 - 11 - 11 - 3.3.2 + 2.2.0 + 7.4 - 1.4.0 - 1.4.0 + 1.5.1 + 1.5.0 @@ -81,6 +79,10 @@ log4j-to-slf4j org.apache.logging.log4j + + org.springframework.boot + spring-boot-starter-tomcat + @@ -96,10 +98,16 @@ spring-boot-starter-actuator - + - tomcat-embed-websocket - org.apache.tomcat.embed + org.postgresql + postgresql + + + + + jakarta.servlet + jakarta.servlet-api provided @@ -123,32 +131,22 @@ org.bouncycastle bcprov-jdk18on - 1.72 + 1.76 - - - javax.xml.bind - jaxb-api - + - org.glassfish.jaxb - jaxb-runtime + net.logstash.logback + logstash-logback-encoder + ${logstash.version} org.springdoc - springdoc-openapi-ui - 1.6.14 + springdoc-openapi-starter-webmvc-ui + ${springdoc-openapi-starter-webmvc-ui.version} - - - com.google.guava - guava - 31.1-jre - - @@ -165,6 +163,28 @@ + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-banned-dependencies + + enforce + + + + + + org.apache.tomcat.embed:*:*:*:compile + + + + + + + @@ -218,6 +238,55 @@ true + + + standalone + + + tomcat-embed-websocket + org.apache.tomcat.embed + provided + + + + + + liquibase + + + org.liquibase + liquibase-core + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + process-resources + + copy-resources + + + ${basedir}/target/classes/db/changelog + + + ../docs/db/changelog/changesets/${project.artifactId} + + **/*.* + + + + + + + + + + diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/DataAdapterApplication.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/DataAdapterApplication.java index c3d0672c..d0ce0c86 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/DataAdapterApplication.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/DataAdapterApplication.java @@ -15,9 +15,12 @@ */ package io.getlime.security.powerauth.app.dataadapter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.security.Security; + /** * Spring Boot application main class. * @author Roman Strobl, roman.strobl@wultra.com @@ -26,6 +29,7 @@ public class DataAdapterApplication { public static void main(String[] args) { + Security.addProvider(new BouncyCastleProvider()); SpringApplication.run(DataAdapterApplication.class, args); } } diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/OpenApiConfiguration.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/OpenApiConfiguration.java index bf94dfa0..b8c003d7 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/OpenApiConfiguration.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/OpenApiConfiguration.java @@ -19,7 +19,7 @@ import io.swagger.v3.oas.annotations.info.Contact; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.License; -import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/SecurityConfiguration.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/SecurityConfiguration.java index 1c0d26e3..ad07dc13 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/SecurityConfiguration.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/configuration/SecurityConfiguration.java @@ -16,9 +16,12 @@ package io.getlime.security.powerauth.app.dataadapter.configuration; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; /** * Default Spring Security configuration. @@ -26,17 +29,20 @@ * @author Petr Dvorak, petr@wultra.com */ @Configuration -public class SecurityConfiguration extends WebSecurityConfigurerAdapter { +@EnableWebSecurity +public class SecurityConfiguration { /** * Configures HTTP security. * @param http HTTP security. * @throws Exception Thrown when configuration fails. */ - @Override - protected void configure(HttpSecurity http) throws Exception { - http.httpBasic().disable(); - http.csrf().disable(); + @Bean + public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception { + return http + .httpBasic(AbstractHttpConfigurer::disable) + .csrf(AbstractHttpConfigurer::disable) + .build(); } } \ No newline at end of file diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AfsController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AfsController.java index 6e2fb56d..974801d0 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AfsController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AfsController.java @@ -59,7 +59,7 @@ public AfsController(DataAdapter dataAdapter) { * @throws DataAdapterRemoteException In case communication with remote system fails. * @throws InvalidOperationContextException In case operation context is invalid. */ - @RequestMapping(value = "/execute", method = RequestMethod.POST) + @PostMapping("/execute") public ObjectResponse executeAfsAction(@RequestBody ObjectRequest request) throws DataAdapterRemoteException, InvalidOperationContextException { logger.info("Received executeAfsAction request for user: {}, operation ID: {}", request.getRequestObject().getUserId(), request.getRequestObject().getOperationContext().getId()); diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthMethodController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthMethodController.java index d85e5761..ba2ea8d0 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthMethodController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthMethodController.java @@ -25,14 +25,13 @@ import io.getlime.security.powerauth.lib.dataadapter.model.request.InitAuthMethodRequest; import io.getlime.security.powerauth.lib.dataadapter.model.response.InitAuthMethodResponse; import io.getlime.security.powerauth.lib.nextstep.model.enumeration.AuthMethod; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; - /** * Controller class which handles authentication method configuration. * diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthenticationController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthenticationController.java index cb7dea69..5eae42b7 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthenticationController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/AuthenticationController.java @@ -28,14 +28,13 @@ import io.getlime.security.powerauth.lib.dataadapter.model.request.UserLookupRequest; import io.getlime.security.powerauth.lib.dataadapter.model.response.UserAuthenticationResponse; import io.getlime.security.powerauth.lib.dataadapter.model.response.UserDetailResponse; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; - /** * Controller class which handles user authentication. * diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/CertificateController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/CertificateController.java index 0c784462..289d763a 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/CertificateController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/CertificateController.java @@ -27,13 +27,13 @@ import io.getlime.security.powerauth.lib.dataadapter.model.response.VerifyCertificateResponse; import io.getlime.security.powerauth.lib.nextstep.model.enumeration.AuthInstrument; import io.getlime.security.powerauth.lib.nextstep.model.enumeration.AuthMethod; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; /** * Controller class which handles SMS OTP authorization. diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ConsentController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ConsentController.java index 7d7cfe21..41065f33 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ConsentController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ConsentController.java @@ -33,13 +33,13 @@ import io.getlime.security.powerauth.lib.dataadapter.model.response.InitConsentFormResponse; import io.getlime.security.powerauth.lib.dataadapter.model.response.SaveConsentFormResponse; import io.getlime.security.powerauth.lib.dataadapter.model.response.ValidateConsentFormResponse; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; import java.util.List; /** diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/OperationChangeController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/OperationChangeController.java index a4c17d03..d079d3f0 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/OperationChangeController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/OperationChangeController.java @@ -64,7 +64,7 @@ public OperationChangeController(DataAdapter dataAdapter) { * @throws InvalidOperationContextException In case provided information is not sufficient for creating * the correct implicit login operation. */ - @RequestMapping(value = "/create", method = RequestMethod.POST) + @PostMapping("/create") public ObjectResponse createImplicitLoginOperation(@RequestBody ObjectRequest request) throws DataAdapterRemoteException, InvalidOperationContextException { final CreateImplicitLoginOperationRequest requestObject = request.getRequestObject(); final String clientId = requestObject.getClientId(); @@ -106,7 +106,7 @@ public Response operationChangedNotification(@RequestBody ObjectRequest getPAOperationMapping(@RequestBody ObjectRequest request) throws DataAdapterRemoteException { logger.info("Received getPAOperationMapping request for user: {}, operation ID: {}", request.getRequestObject().getUserId(), request.getRequestObject().getOperationContext().getId()); diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ServiceController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ServiceController.java index 13377134..42250b86 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ServiceController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/ServiceController.java @@ -35,7 +35,7 @@ * @author Petr Dvorak, petr@wultra.com */ @RestController -@RequestMapping(value = "/api/service") +@RequestMapping("/api/service") public class ServiceController { private static final Logger logger = LoggerFactory.getLogger(ServiceController.class); diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/SmsAuthorizationController.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/SmsAuthorizationController.java index b3a838ef..706eb00c 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/SmsAuthorizationController.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/controller/SmsAuthorizationController.java @@ -33,14 +33,13 @@ import io.getlime.security.powerauth.lib.dataadapter.model.response.VerifySmsAndPasswordResponse; import io.getlime.security.powerauth.lib.dataadapter.model.response.VerifySmsAuthorizationResponse; import io.getlime.security.powerauth.lib.nextstep.model.enumeration.AuthMethod; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; - /** * Controller class which handles SMS OTP authorization. * diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/DataAdapterService.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/DataAdapterService.java index 853416df..c828ef7f 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/DataAdapterService.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/DataAdapterService.java @@ -77,7 +77,7 @@ public DataAdapterService(DataAdapterI18NService dataAdapterI18NService, SmsPers } @Override - public UserDetailResponse lookupUser(String username, String organizationId, String clientCertificate, OperationContext operationContext) throws DataAdapterRemoteException, UserNotFoundException { + public UserDetailResponse lookupUser(String username, String organizationId, String clientCertificate, OperationContext operationContext) { // The sample Data Adapter code uses 1:1 mapping of username to user ID. In real implementation the userId usually differs from the username, so translation of username to user ID is required. // If the user does not exist, return null values for user ID and organization ID. // If user account account is blocked, return AccountStatus.NOT_ACTIVE as account status. @@ -94,7 +94,7 @@ public UserDetailResponse lookupUser(String username, String organizationId, Str } @Override - public UserAuthenticationResponse authenticateUser(String userId, String password, AuthenticationContext authenticationContext, String organizationId, OperationContext operationContext) throws DataAdapterRemoteException { + public UserAuthenticationResponse authenticateUser(String userId, String password, AuthenticationContext authenticationContext, String organizationId, OperationContext operationContext) { // Here will be the real authentication - call to the backend providing authentication. // Return a response with UserAuthenticationResult based on the actual authentication result. // The password is optionally encrypted, the authentication context contains information about encryption. @@ -103,17 +103,11 @@ public UserAuthenticationResponse authenticateUser(String userId, String passwor PasswordProtectionType passwordProtection = authenticationContext.getPasswordProtection(); UserAuthenticationResponse authResponse = new UserAuthenticationResponse(); if (passwordProtection == PasswordProtectionType.NO_PROTECTION && "test".equals(password)) { - try { - UserDetailResponse userDetail = fetchUserDetail(userId, organizationId, operationContext); - // The organization needs to be set in response (e.g. client authenticated against RETAIL organization or SME organization). - userDetail.setOrganizationId(organizationId); - authResponse.setAuthenticationResult(UserAuthenticationResult.SUCCEEDED); - return authResponse; - } catch (UserNotFoundException e) { - authResponse.setAuthenticationResult(UserAuthenticationResult.FAILED); - authResponse.setErrorMessage(AUTHENTICATION_FAILED); - return authResponse; - } + UserDetailResponse userDetail = fetchUserDetail(userId, organizationId, operationContext); + // The organization needs to be set in response (e.g. client authenticated against RETAIL organization or SME organization). + userDetail.setOrganizationId(organizationId); + authResponse.setAuthenticationResult(UserAuthenticationResult.SUCCEEDED); + return authResponse; } authResponse.setAuthenticationResult(UserAuthenticationResult.FAILED); authResponse.setErrorMessage(AUTHENTICATION_FAILED); @@ -131,7 +125,7 @@ public UserAuthenticationResponse authenticateUser(String userId, String passwor } @Override - public UserDetailResponse fetchUserDetail(String userId, String organizationId, OperationContext operationContext) throws DataAdapterRemoteException, UserNotFoundException { + public UserDetailResponse fetchUserDetail(String userId, String organizationId, OperationContext operationContext) { // Fetch user details here ... // In case that user is not found, throw a UserNotFoundException. // The operation context may be null in case the method is called outside of an active operation (e.g. OAuth user profile request). @@ -147,14 +141,14 @@ public UserDetailResponse fetchUserDetail(String userId, String organizationId, } @Override - public InitAuthMethodResponse initAuthMethod(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) throws DataAdapterRemoteException, InvalidOperationContextException { + public InitAuthMethodResponse initAuthMethod(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) { // Implement logic for initial configuration of authentication methods. // Certificate-based authentication can be enabled and the certificate verification URL can be specified based on operation context. return new InitAuthMethodResponse(CertificateAuthenticationMode.NOT_AVAILABLE); } @Override - public DecorateOperationFormDataResponse decorateFormData(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) throws DataAdapterRemoteException, UserNotFoundException { + public DecorateOperationFormDataResponse decorateFormData(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) { String operationName = operationContext.getName(); FormData formData = operationContext.getFormData(); // Fetch bank account list for given user here from the bank backend. @@ -216,16 +210,14 @@ public DecorateOperationFormDataResponse decorateFormData(String userId, String } @Override - public void formDataChangedNotification(String userId, String organizationId, FormDataChange change, OperationContext operationContext) throws DataAdapterRemoteException { + public void formDataChangedNotification(String userId, String organizationId, FormDataChange change, OperationContext operationContext) { String operationId = operationContext.getId(); - if (change instanceof BankAccountChoice) { + if (change instanceof final BankAccountChoice bankAccountChoice) { // Handle bank account choice here (e.g. send notification to bank backend). - BankAccountChoice bankAccountChoice = (BankAccountChoice) change; logger.info("Bank account chosen: {}, operation ID: {}", bankAccountChoice.getBankAccountId(), operationId); return; - } else if (change instanceof AuthMethodChoice) { + } else if (change instanceof final AuthMethodChoice authMethodChoice) { // Handle authorization method choice here (e.g. send notification to bank backend). - AuthMethodChoice authMethodChoice = (AuthMethodChoice) change; logger.info("Authorization method chosen: {}, operation ID: {}", authMethodChoice.getChosenAuthMethod().toString(), operationId); return; } @@ -233,7 +225,7 @@ public void formDataChangedNotification(String userId, String organizationId, Fo } @Override - public CreateImplicitLoginOperationResponse createImplicitLoginOperation(String clientId, String[] scopes) throws DataAdapterRemoteException { + public CreateImplicitLoginOperationResponse createImplicitLoginOperation(String clientId, String[] scopes) { // Make sure there is only one item in scopes if (scopes == null || scopes.length != 1) { return null; @@ -267,7 +259,7 @@ public CreateImplicitLoginOperationResponse createImplicitLoginOperation(String } @Override - public GetPAOperationMappingResponse getPAOperationMapping(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) throws DataAdapterRemoteException { + public GetPAOperationMappingResponse getPAOperationMapping(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) { GetPAOperationMappingResponse response = new GetPAOperationMappingResponse(); switch (operationContext.getName()) { @@ -303,14 +295,14 @@ public GetPAOperationMappingResponse getPAOperationMapping(String userId, String } @Override - public void operationChangedNotification(String userId, String organizationId, OperationChange change, OperationContext operationContext) throws DataAdapterRemoteException { + public void operationChangedNotification(String userId, String organizationId, OperationChange change, OperationContext operationContext) { String operationId = operationContext.getId(); // Handle operation change here (e.g. send notification to bank backend). logger.info("Operation changed, status: {}, operation ID: {}", change.toString(), operationId); } @Override - public CreateSmsAuthorizationResponse createAndSendAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, AuthMethod authMethod, OperationContext operationContext, String lang) throws InvalidOperationContextException, DataAdapterRemoteException { + public CreateSmsAuthorizationResponse createAndSendAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, AuthMethod authMethod, OperationContext operationContext, String lang) throws InvalidOperationContextException { CreateSmsAuthorizationResponse response = new CreateSmsAuthorizationResponse(); // MessageId is generated as random UUID, it can be overridden to provide a real message identification String messageId = UUID.randomUUID().toString(); @@ -337,7 +329,7 @@ public CreateSmsAuthorizationResponse createAndSendAuthorizationSms(String userI } @Override - public SendAuthorizationSmsResponse sendAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, AuthMethod authMethod, OperationContext operationContext, String messageId, String authorizationCode, String lang) throws InvalidOperationContextException, DataAdapterRemoteException { + public SendAuthorizationSmsResponse sendAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, AuthMethod authMethod, OperationContext operationContext, String messageId, String authorizationCode, String lang) throws InvalidOperationContextException { SendAuthorizationSmsResponse response = new SendAuthorizationSmsResponse(); // Message ID is taken from request response.setMessageId(messageId); @@ -357,7 +349,7 @@ public SendAuthorizationSmsResponse sendAuthorizationSms(String userId, String o } @Override - public VerifySmsAuthorizationResponse verifyAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, String messageId, String authorizationCode, OperationContext operationContext) throws DataAdapterRemoteException, InvalidOperationContextException { + public VerifySmsAuthorizationResponse verifyAuthorizationSms(String userId, String organizationId, AccountStatus accountStatus, String messageId, String authorizationCode, OperationContext operationContext) { // You can override this logic in case more complex handling of SMS verification is required. VerifySmsAuthorizationResponse response; @@ -379,7 +371,7 @@ public VerifySmsAuthorizationResponse verifyAuthorizationSms(String userId, Stri } @Override - public VerifySmsAndPasswordResponse verifyAuthorizationSmsAndPassword(String userId, String organizationId, AccountStatus accountStatus, String messageId, String authorizationCode, OperationContext operationContext, AuthenticationContext authenticationContext, String password) throws DataAdapterRemoteException, InvalidOperationContextException { + public VerifySmsAndPasswordResponse verifyAuthorizationSmsAndPassword(String userId, String organizationId, AccountStatus accountStatus, String messageId, String authorizationCode, OperationContext operationContext, AuthenticationContext authenticationContext, String password) { VerifySmsAndPasswordResponse response = new VerifySmsAndPasswordResponse(); // Skip credentials verification for non-existent user accounts or blocked user accounts, such request would always fail. @@ -414,20 +406,20 @@ public VerifySmsAndPasswordResponse verifyAuthorizationSmsAndPassword(String use } @Override - public VerifyCertificateResponse verifyCertificate(String userId, String organizationId, String certificate, String signedMessage, AuthInstrument authInstrument, AuthMethod authMethod, AccountStatus accountStatus, OperationContext operationContext) throws DataAdapterRemoteException, InvalidOperationContextException { + public VerifyCertificateResponse verifyCertificate(String userId, String organizationId, String certificate, String signedMessage, AuthInstrument authInstrument, AuthMethod authMethod, AccountStatus accountStatus, OperationContext operationContext) { // This method should implement client TLS certificate and/or qualified certificate verification. The stub implementation always succeeds. CertificateVerificationResult verificationResult = CertificateVerificationResult.SUCCEEDED; return new VerifyCertificateResponse(verificationResult); } @Override - public InitConsentFormResponse initConsentForm(String userId, String organizationId, OperationContext operationContext) throws DataAdapterRemoteException, InvalidOperationContextException, InvalidConsentDataException { + public InitConsentFormResponse initConsentForm(String userId, String organizationId, OperationContext operationContext) { // Override this logic in case consent form should be displayed conditionally for given operation context. return new InitConsentFormResponse(true); } @Override - public CreateConsentFormResponse createConsentForm(String userId, String organizationId, OperationContext operationContext, String lang) throws DataAdapterRemoteException, InvalidOperationContextException, InvalidConsentDataException { + public CreateConsentFormResponse createConsentForm(String userId, String organizationId, OperationContext operationContext, String lang) throws InvalidOperationContextException { // Fallback to English for unsupported languages, see: https://github.com/wultra/powerauth-webflow-customization/issues/104 if (!"cs".equals(lang) && !"en".equals(lang)) { lang = "en"; @@ -488,7 +480,7 @@ public CreateConsentFormResponse createConsentForm(String userId, String organiz } @Override - public ValidateConsentFormResponse validateConsentForm(String userId, String organizationId, OperationContext operationContext, String lang, List options) throws DataAdapterRemoteException, InvalidOperationContextException, InvalidConsentDataException { + public ValidateConsentFormResponse validateConsentForm(String userId, String organizationId, OperationContext operationContext, String lang, List options) throws InvalidOperationContextException, InvalidConsentDataException { // Fallback to English for unsupported languages, see: https://github.com/wultra/powerauth-webflow-customization/issues/104 if (!"cs".equals(lang) && !"en".equals(lang)) { lang = "en"; @@ -577,7 +569,7 @@ public ValidateConsentFormResponse validateConsentForm(String userId, String org } @Override - public SaveConsentFormResponse saveConsentForm(String userId, String organizationId, OperationContext operationContext, List options) throws DataAdapterRemoteException, InvalidOperationContextException, InvalidConsentDataException { + public SaveConsentFormResponse saveConsentForm(String userId, String organizationId, OperationContext operationContext, List options) { // Save consent form options selected by the user. The sample implementation only logs the selected options. logger.info("Saving consent form for user: {}, operation ID: {}", userId, operationContext.getId()); for (ConsentOption option: options) { @@ -587,7 +579,7 @@ public SaveConsentFormResponse saveConsentForm(String userId, String organizatio } @Override - public AfsResponse executeAfsAction(String userId, String organizationId, OperationContext operationContext, AfsRequestParameters afsRequestParameters, Map extras) throws DataAdapterRemoteException, InvalidOperationContextException { + public AfsResponse executeAfsAction(String userId, String organizationId, OperationContext operationContext, AfsRequestParameters afsRequestParameters, Map extras) throws InvalidOperationContextException { if (userId == null || organizationId == null || operationContext == null || afsRequestParameters == null || afsRequestParameters.getAfsAction() == null || afsRequestParameters.getAfsType() == null) { logger.warn("Invalid AFS request received"); @@ -598,15 +590,12 @@ public AfsResponse executeAfsAction(String userId, String organizationId, Operat // a mocked response is returned with static 2FA AFS label except for the case of payment with low amount. AfsResponse response = new AfsResponse(); switch (afsRequestParameters.getAfsAction()) { - case LOGIN_INIT: - case LOGIN_AUTH: - case APPROVAL_AUTH: + case LOGIN_INIT, LOGIN_AUTH, APPROVAL_AUTH -> { // Return AFS label, but do not apply response parameters on authentication form response.setAfsResponseApplied(false); response.setAfsLabel("2FA"); - break; - - case APPROVAL_INIT: + } + case APPROVAL_INIT -> { // Apply AFS response parameters on authentication form. // This example performs step-down from 2FA to 1FA in case of payment in CZK with low amount. AmountAttribute amountAttribute = operationValueExtractionService.getAmount(operationContext); @@ -621,13 +610,10 @@ public AfsResponse executeAfsAction(String userId, String organizationId, Operat response.setAfsResponseApplied(false); response.setAfsLabel("2FA"); } - break; - - case LOGOUT: + } + case LOGOUT -> // Do not apply response parameters - response.setAfsResponseApplied(false); - break; - + response.setAfsResponseApplied(false); } return response; } diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/SmsDeliveryService.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/SmsDeliveryService.java index 70c850a7..979d6b8f 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/SmsDeliveryService.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/service/SmsDeliveryService.java @@ -15,7 +15,6 @@ */ package io.getlime.security.powerauth.app.dataadapter.impl.service; -import io.getlime.security.powerauth.app.dataadapter.exception.DataAdapterRemoteException; import io.getlime.security.powerauth.app.dataadapter.exception.InvalidOperationContextException; import io.getlime.security.powerauth.app.dataadapter.service.DataAdapterI18NService; import io.getlime.security.powerauth.crypto.server.util.DataDigest; @@ -59,27 +58,16 @@ public SmsDeliveryService(DataAdapterI18NService dataAdapterI18NService, Operati * @param operationContext Operation context. * @return Authorization code. * @throws InvalidOperationContextException Thrown when operation context is invalid. - * @throws DataAdapterRemoteException Thrown when remote communication fails. */ - public AuthorizationCode generateAuthorizationCode(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) throws InvalidOperationContextException, DataAdapterRemoteException { + public AuthorizationCode generateAuthorizationCode(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext) throws InvalidOperationContextException { String operationName = operationContext.getName(); List digestItems = new ArrayList<>(); switch (operationName) { - case "login": - case "login_sca": - digestItems.add("login"); - break; - - case "authorize_payment": - case "authorize_payment_sca": + case "login", "login_sca" -> digestItems.add("login"); + case "authorize_payment", "authorize_payment_sca" -> { switch (authMethod) { - case LOGIN_SCA: - digestItems.add("login"); - break; - - case APPROVAL_SCA: - case SMS_KEY: - case POWERAUTH_TOKEN: + case LOGIN_SCA -> digestItems.add("login"); + case APPROVAL_SCA, SMS_KEY, POWERAUTH_TOKEN -> { AmountAttribute amountAttribute = operationValueExtractionService.getAmount(operationContext); String account = operationValueExtractionService.getAccount(operationContext); BigDecimal amount = amountAttribute.getAmount(); @@ -87,16 +75,13 @@ public AuthorizationCode generateAuthorizationCode(String userId, String organiz digestItems.add(amount.toPlainString()); digestItems.add(currency); digestItems.add(account); - break; - - default: - throw new InvalidOperationContextException("Unsupported authentication method: " + authMethod); + } + default -> throw new InvalidOperationContextException("Unsupported authentication method: " + authMethod); } - break; + } // Add new operations here. - default: - throw new InvalidOperationContextException("Unsupported operation: " + operationName); + default -> throw new InvalidOperationContextException("Unsupported operation: " + operationName); } final DataDigest.Result digestResult = new DataDigest().generateDigest(digestItems); @@ -115,46 +100,36 @@ public AuthorizationCode generateAuthorizationCode(String userId, String organiz * @param lang Language for localization. * @return Generated SMS text with authorization code. * @throws InvalidOperationContextException Thrown when operation context is invalid. - * @throws DataAdapterRemoteException Thrown when remote communication fails. */ - public String generateSmsText(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext, AuthorizationCode authorizationCode, String lang) throws InvalidOperationContextException, DataAdapterRemoteException { + public String generateSmsText(String userId, String organizationId, AuthMethod authMethod, OperationContext operationContext, AuthorizationCode authorizationCode, String lang) throws InvalidOperationContextException { String operationName = operationContext.getName(); String[] messageArgs; String messageResourcePrefix; switch (operationName) { - case "login": - case "login_sca": + case "login", "login_sca" -> { messageResourcePrefix = "login"; - messageArgs = new String[]{authorizationCode.getCode()}; - break; - - case "authorize_payment": - case "authorize_payment_sca": + messageArgs = new String[]{authorizationCode.code()}; + } + case "authorize_payment", "authorize_payment_sca" -> { switch (authMethod) { - case LOGIN_SCA: + case LOGIN_SCA -> { messageResourcePrefix = "login"; - messageArgs = new String[]{authorizationCode.getCode()}; - break; - - case APPROVAL_SCA: - case SMS_KEY: - case POWERAUTH_TOKEN: + messageArgs = new String[]{authorizationCode.code()}; + } + case APPROVAL_SCA, SMS_KEY, POWERAUTH_TOKEN -> { messageResourcePrefix = "authorize_payment"; AmountAttribute amountAttribute = operationValueExtractionService.getAmount(operationContext); String account = operationValueExtractionService.getAccount(operationContext); BigDecimal amount = amountAttribute.getAmount(); String currency = amountAttribute.getCurrency(); - messageArgs = new String[]{amount.toPlainString(), currency, account, authorizationCode.getCode()}; - break; - - default: - throw new InvalidOperationContextException("Unsupported authentication method: " + authMethod); + messageArgs = new String[]{amount.toPlainString(), currency, account, authorizationCode.code()}; + } + default -> throw new InvalidOperationContextException("Unsupported authentication method: " + authMethod); } - break; + } // Add new operations here. - default: - throw new InvalidOperationContextException("Unsupported operation: " + operationName); + default -> throw new InvalidOperationContextException("Unsupported operation: " + operationName); } return dataAdapterI18NService.messageSource().getMessage(messageResourcePrefix + ".smsText", messageArgs, new Locale(lang)); @@ -167,10 +142,8 @@ public String generateSmsText(String userId, String organizationId, AuthMethod a * @param messageId Message ID. * @param messageText Text of SMS message. * @param operationContext Operation context. - * @throws InvalidOperationContextException Thrown when operation context is invalid. - * @throws DataAdapterRemoteException Thrown when remote communication fails or SMS message could not be delivered. */ - public SmsDeliveryResult sendAuthorizationSms(String userId, String organizationId, String messageId, String messageText, OperationContext operationContext) throws InvalidOperationContextException, DataAdapterRemoteException { + public SmsDeliveryResult sendAuthorizationSms(String userId, String organizationId, String messageId, String messageText, OperationContext operationContext) { // Add here code to send the SMS OTP message to user identified by userId with messageText. // The message entity can be extracted using message ID from table da_sms_authorization. // In case message delivery fails, throw a DataAdapterRemoteException. diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthMethodRequestValidator.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthMethodRequestValidator.java index 20774a46..067f94bc 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthMethodRequestValidator.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthMethodRequestValidator.java @@ -28,7 +28,7 @@ /** * Defines validations for input fields in authentication method requests. - * + *

* Additional validation logic can be added if applicable. * * @author Roman Strobl, roman.strobl@wultra.com @@ -62,7 +62,7 @@ public boolean supports(@NonNull Class clazz) { */ @Override public void validate(@Nullable Object o, @NonNull Errors errors) { - ObjectRequest objectRequest = (ObjectRequest) o; + final ObjectRequest objectRequest = (ObjectRequest) o; if (objectRequest == null) { errors.rejectValue(OPERATION_CONTEXT_FIELD, MISSING_OPERATION_CONTEXT_ERROR_CODE); return; diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthenticationRequestValidator.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthenticationRequestValidator.java index f50c1ba8..ae3025b9 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthenticationRequestValidator.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthenticationRequestValidator.java @@ -30,7 +30,7 @@ /** * Defines validations for input fields in user lookup and authentication requests. - * + *

* Additional validation logic can be added if applicable. * * @author Roman Strobl, roman.strobl@wultra.com @@ -60,7 +60,7 @@ public boolean supports(@NonNull Class clazz) { */ @Override public void validate(@Nullable Object o, @NonNull Errors errors) { - ObjectRequest objectRequest = (ObjectRequest) o; + final ObjectRequest objectRequest = (ObjectRequest) o; if (objectRequest == null) { errors.rejectValue(OPERATION_CONTEXT_FIELD, MISSING_OPERATION_CONTEXT_ERROR_CODE); return; @@ -72,7 +72,7 @@ public void validate(@Nullable Object o, @NonNull Errors errors) { } } - private void validateUserLookupRequest(ObjectRequest objectRequest, Errors errors) { + private void validateUserLookupRequest(ObjectRequest objectRequest, Errors errors) { UserLookupRequest authRequest = (UserLookupRequest) objectRequest.getRequestObject(); // update validation logic based on the real Data Adapter requirements @@ -98,7 +98,7 @@ private void validateUserLookupRequest(ObjectRequest objectRequest, Errors error } } - private void validateUserAuthenticationRequest(ObjectRequest objectRequest, Errors errors) { + private void validateUserAuthenticationRequest(ObjectRequest objectRequest, Errors errors) { UserAuthenticationRequest authRequest = (UserAuthenticationRequest) objectRequest.getRequestObject(); // update validation logic based on the real Data Adapter requirements diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthorizationSmsRequestValidator.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthorizationSmsRequestValidator.java index 3d79e220..f803ce7f 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthorizationSmsRequestValidator.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/AuthorizationSmsRequestValidator.java @@ -34,7 +34,7 @@ /** * Validator for SMS OTP authorization requests. - * + *

* Additional validation logic can be added if applicable. * * @author Roman Strobl, roman.strobl@wultra.com diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/CertificateRequestValidator.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/CertificateRequestValidator.java index 19e5d3e9..9200d0ba 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/CertificateRequestValidator.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/CertificateRequestValidator.java @@ -26,7 +26,7 @@ /** * Validator for certificate verification requests. - * + *

* Additional validation logic can be added if applicable. * * @author Roman Strobl, roman.strobl@wultra.com diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/ConsentFormRequestValidator.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/ConsentFormRequestValidator.java index fb736a5b..8d598cf1 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/ConsentFormRequestValidator.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/impl/validation/ConsentFormRequestValidator.java @@ -33,7 +33,7 @@ /** * Validator for request to create OAuth 2.0 consent form. - * + *

* Additional validation logic can be added if applicable. * * @author Roman Strobl, roman.strobl@wultra.com @@ -61,7 +61,7 @@ public boolean supports(@NonNull Class clazz) { @Override @SuppressWarnings("unchecked") public void validate(@Nullable Object o, @NonNull Errors errors) { - ObjectRequest objectRequest = (ObjectRequest) o; + final ObjectRequest objectRequest = (ObjectRequest) o; if (objectRequest == null) { errors.rejectValue("requestObject.operationContext", "operationContext.missing"); return; diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/repository/model/entity/SmsAuthorizationEntity.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/repository/model/entity/SmsAuthorizationEntity.java index c40dea6f..d813dfd2 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/repository/model/entity/SmsAuthorizationEntity.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/repository/model/entity/SmsAuthorizationEntity.java @@ -15,10 +15,12 @@ */ package io.getlime.security.powerauth.app.dataadapter.repository.model.entity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import java.io.Serial; import java.io.Serializable; import java.util.Date; @@ -31,6 +33,7 @@ @Table(name = "da_sms_authorization") public class SmsAuthorizationEntity implements Serializable { + @Serial private static final long serialVersionUID = 6432269422572862762L; @Id diff --git a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/service/SmsPersistenceService.java b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/service/SmsPersistenceService.java index 27dd93c6..98e6295a 100644 --- a/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/service/SmsPersistenceService.java +++ b/powerauth-data-adapter/src/main/java/io/getlime/security/powerauth/app/dataadapter/service/SmsPersistenceService.java @@ -70,8 +70,8 @@ public SmsAuthorizationEntity createAuthorizationSms(String userId, String organ smsEntity.setUserId(userId); smsEntity.setOrganizationId(organizationId); smsEntity.setOperationName(operationContext.getName()); - smsEntity.setAuthorizationCode(authorizationCode.getCode()); - smsEntity.setSalt(authorizationCode.getSalt()); + smsEntity.setAuthorizationCode(authorizationCode.code()); + smsEntity.setSalt(authorizationCode.salt()); smsEntity.setMessageText(messageText); smsEntity.setVerifyRequestCount(0); smsEntity.setTimestampCreated(new Date()); @@ -96,7 +96,7 @@ public SmsAuthorizationEntity createAuthorizationSms(String userId, String organ public VerifySmsAuthorizationResponse verifyAuthorizationSms(String messageId, String authorizationCode, boolean allowMultipleVerifications) { Optional smsEntityOptional = smsAuthorizationRepository.findById(messageId); VerifySmsAuthorizationResponse response = new VerifySmsAuthorizationResponse(); - if (!smsEntityOptional.isPresent()) { + if (smsEntityOptional.isEmpty()) { response.setSmsAuthorizationResult(SmsAuthorizationResult.FAILED); response.setErrorMessage("smsAuthorization.invalidMessage"); return response; diff --git a/powerauth-data-adapter/src/main/resources/application-dev.properties b/powerauth-data-adapter/src/main/resources/application-dev.properties new file mode 100644 index 00000000..524c75a0 --- /dev/null +++ b/powerauth-data-adapter/src/main/resources/application-dev.properties @@ -0,0 +1,3 @@ +# Liquibase +spring.liquibase.enabled=true +spring.liquibase.change-log=classpath:db/changelog/db.changelog-module.xml diff --git a/powerauth-data-adapter/src/main/resources/application.properties b/powerauth-data-adapter/src/main/resources/application.properties index 474b7905..4d00f3d4 100644 --- a/powerauth-data-adapter/src/main/resources/application.properties +++ b/powerauth-data-adapter/src/main/resources/application.properties @@ -2,11 +2,12 @@ spring.profiles.active=ext # Database Configuration - PostgreSQL -spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.url=jdbc:postgresql://localhost:5432/powerauth spring.datasource.username=powerauth spring.datasource.password= +spring.datasource.hikari.auto-commit=false spring.datasource.driver-class-name=org.postgresql.Driver -spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.properties.hibernate.connection.characterEncoding=utf8 spring.jpa.properties.hibernate.connection.useUnicode=true @@ -16,15 +17,6 @@ spring.jpa.properties.hibernate.connection.useUnicode=true #spring.datasource.password= #spring.datasource.driver-class-name=oracle.jdbc.OracleDriver # The following property speeds up Spring Boot startup -#spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false - -# Database Configuration - MySQL -#spring.datasource.url=jdbc:mysql://localhost:3306/powerauth -#spring.datasource.username=powerauth -#spring.datasource.password= -#spring.datasource.driver-class-name=com.mysql.jdbc.Driver -#spring.jpa.properties.hibernate.connection.characterEncoding=utf8 -#spring.jpa.properties.hibernate.connection.useUnicode=true # SMS OTP expiration time in seconds powerauth.authorization.sms-otp.expiration-time-in-seconds=300 @@ -43,4 +35,6 @@ powerauth.dataAdapter.service.applicationEnvironment= spring.jpa.open-in-view=false # Disable swagger-ui default petstore url -springdoc.swagger-ui.disable-swagger-default-url=true \ No newline at end of file +springdoc.swagger-ui.disable-swagger-default-url=true + +logging.config=${POWERAUTH_DATA_ADAPTER_LOGGING:} diff --git a/powerauth-data-adapter/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/powerauth-data-adapter/src/main/webapp/WEB-INF/jboss-deployment-structure.xml index 82d5a46a..0d258a38 100644 --- a/powerauth-data-adapter/src/main/webapp/WEB-INF/jboss-deployment-structure.xml +++ b/powerauth-data-adapter/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -12,7 +12,7 @@ - +