diff --git a/docs/Configuring-REST-Client-for-Spring.md b/docs/Configuring-REST-Client-for-Spring.md index bb88500c3..122973cf9 100644 --- a/docs/Configuring-REST-Client-for-Spring.md +++ b/docs/Configuring-REST-Client-for-Spring.md @@ -28,7 +28,6 @@ In order to connect to the correct PowerAuth Server, you need to add following c ```java @Configuration -@ComponentScan(basePackages = {"com.wultra.security.powerauth"}) public class PowerAuthClientConfiguration { @Value("${powerauth.rest.url}") @@ -36,23 +35,38 @@ public class PowerAuthClientConfiguration { @Bean public PowerAuthClient powerAuthRestClient() { - return new PowerAuthRestClient(powerAuthRestUrl); + try { + return new PowerAuthRestClient(powerAuthRestUrl); + } catch (PowerAuthClientException ex) { + logger.warn(ex.getMessage(), ex); + } } } ``` -In case you need to configure the client, use: +The `PowerAuthClientException` is thrown only in case the provided base URL is invalid. The error can occur when the URL is constructed dynamically, for correctly specified static URLs you can skip the error handling. + +In case you need to configure the client, use e.g.: ```java @Bean public PowerAuthRestClient powerAuthRestClient() { PowerAuthRestClientConfiguration config = new PowerAuthRestClientConfiguration(); + config.setPowerAuthClientToken(clientToken); + config.setPowerAuthClientSecret(clientSecret); + config.setAcceptInvalidSslCertificate(acceptInvalidSslCertificate); config.setConnectTimeout(3000); ... - return new PowerAuthRestClient(powerAuthRestUrl, config); + try { + return new PowerAuthRestClient(powerAuthRestUrl, config); + } catch (PowerAuthClientException ex) { + logger.warn(ex.getMessage(), ex); + } } ``` +The `PowerAuthClientException` is thrown in case the provided URL is invalid or REST client configuration is invalid. + The following REST client options are available: - `maxMemorySize` - configures maximum memory size per request, default 1 MB diff --git a/docs/Database-Structure.md b/docs/Database-Structure.md index 262466a48..1436f9bdc 100644 --- a/docs/Database-Structure.md +++ b/docs/Database-Structure.md @@ -14,7 +14,7 @@ The drop scripts are available for supported databases: - [MySQL - Drop Tables](./sql/mysql/delete_schema.sql) - [PostgreSQL - Drop Tables and Sequences](./sql/postgresql/delete_schema.sql) -See the overall database schema in this [MySQL Workbench file](./sql/mysql/mysql-workbench-model.mwb): +See the overall database schema: ![Database structure](./images/arch_db_structure.png) @@ -23,7 +23,7 @@ See the overall database schema in this [MySQL Workbench file](./sql/mysql/mysql The PowerAuth Server uses ShedLock to synchronize scheduled operations. You need to create appropriate DB table, i.e.: ```sql -CREATE TABLE "shedlock" ( +CREATE TABLE shedlock ( name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, diff --git a/docs/PowerAuth-Server-1.1.0.md b/docs/PowerAuth-Server-1.1.0.md index f207f98f2..06f6477a3 100644 --- a/docs/PowerAuth-Server-1.1.0.md +++ b/docs/PowerAuth-Server-1.1.0.md @@ -2,6 +2,26 @@ This guide contains instructions for migration from PowerAuth Server version `1.0.x` to version `1.1.x`. +## Partial Package Name Migration + +Our original package name used to start with `io.getlime.*`. In `1.1.x`, we partially migrated our components to a new package name `com.wultra.*`, while some components still use the legacy package name. When autowiring dependencies, make sure to account for both package name if needed: + +```java +@Configuration +@ComponentScan(basePackages = {"io.getlime.security.powerauth","com.wultra.security.powerauth"}) +public class PowerAuthWebServiceConfiguration { +} +``` + +In case you do not provide the component scan hints mentioned above, you may see issues with autowiring, i.e.: + +``` +Parameter 0 of method setAuthenticationProvider in io.getlime.security.powerauth.rest.api.spring.annotation.PowerAuthAnnotationInterceptor required a bean of type 'io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider' that could not be found. + +Action: +Consider defining a bean of type 'io.getlime.security.powerauth.rest.api.spring.provider.PowerAuthAuthenticationProvider' in your configuration. +``` + ## Embedded Bouncy Castle Library (Version 1.68) Bouncy Castle library has been updated to version `1.68` and it is now **included directly in the application bundle (\*.war)**. @@ -223,7 +243,7 @@ CREATE TABLE shedlock ( ### Oracle ```sql -CREATE TABLE "shedlock" ( +CREATE TABLE shedlock ( name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, diff --git a/docs/PowerAuth-Server-1.2.0.md b/docs/PowerAuth-Server-1.2.0.md new file mode 100644 index 000000000..b16d5e96d --- /dev/null +++ b/docs/PowerAuth-Server-1.2.0.md @@ -0,0 +1,25 @@ +# Migration from 1.1.x to 1.2.x + +This guide contains instructions for migration from PowerAuth Server version `1.1.x` to version `1.2.x`. + +## Database Changes + +The `pa_application_callback` table was updated to include request authentication. + +### Oracle + +```sql +ALTER TABLE "PA_APPLICATION_CALLBACK" ADD "AUTHENTICATION" CLOB; +``` + +### PostgreSQL + +```sql +ALTER TABLE "pa_application_callback" ADD "authentication" TEXT; +``` + +### MySQL + +```sql +ALTER TABLE `pa_application_callback` ADD `authentication` TEXT; +``` diff --git a/docs/WebServices-Methods.md b/docs/WebServices-Methods.md index 4b9df7537..9f5a8cee3 100644 --- a/docs/WebServices-Methods.md +++ b/docs/WebServices-Methods.md @@ -84,7 +84,7 @@ The following `v3` methods are published using the service: - [updateActivationFlags](#method-updateactivationflags) - [removeActivationFlags](#method-removeactivationflags) - Application Roles - - [listApplicationRoles](#method-listapplicationoles) + - [listApplicationRoles](#method-listapplicationroles) - [addApplicationRoles](#method-addapplicationroles) - [updateApplicationRoles](#method-updateapplicationroles) - [removeApplicationRoles](#method-removeapplicationroles) @@ -96,7 +96,7 @@ The following `v3` methods are published using the service: - [findAllOperationsByExternalId](#method-findalloperationsbyexternalid) - [cancelOperation](#method-canceloperation) - [approveOperation](#method-approveoperation) - - [failApprovalOperation](#method-failapprovaloperation) + - [failApprovalOperation](#method-failapproveoperation) - [rejectOperation](#method-rejectoperation) - Operation Templates - [createOperationTemplate](#method-createoperationtemplate) @@ -1275,6 +1275,7 @@ REST endpoint: `POST /rest/v3/application/callback/create` | `String` | `name` | Callback URL name, for visual identification. | | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | +| `String` | `authentication` | Callback HTTP request authentication configuration. | The `attributes` list can contain following values: - `activationId` @@ -1287,6 +1288,28 @@ The `attributes` list can contain following values: - `blockedReason` - `applicationId` +The `authentication` parameter contains a JSON-based configuration for client TLS certificate and HTTP basic authentication: +```json +{ + "certificate": { + "enabled": false, + "useCustomKeyStore": false, + "keyStoreLocation": "[keystore resource location]", + "keyStorePassword": "[keystore password]", + "keyAlias": "[key alias]", + "keyPassword": "[key password]", + "useCustomTrustStore": false, + "trustStoreLocation": "[truststore resource location]", + "trustStorePassword": "[truststore password]" + }, + "httpBasic": { + "enabled": false, + "username": "[HTTP basic authentication username]", + "password": "[HTTP basic authentication password]" + } +} +``` + #### Response `CreateCallbackUrlResponse` @@ -1298,6 +1321,7 @@ The `attributes` list can contain following values: | `String` | `name` | Callback URL name, for visual identification. | | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | +| `String` | `authentication` | Callback HTTP request authentication configuration. | ### Method 'updateCallbackUrl' @@ -1315,6 +1339,7 @@ REST endpoint: `POST /rest/v3/application/callback/update` | `String` | `name` | Callback URL name, for visual identification. | | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | +| `String` | `authentication` | Callback HTTP request authentication configuration. | The `attributes` list can contain following values: - `activationId` @@ -1327,6 +1352,29 @@ The `attributes` list can contain following values: - `blockedReason` - `applicationId` +The `authentication` parameter contains a JSON-based configuration for client TLS certificate and HTTP basic authentication: +```json +{ + "certificate": { + "enabled": false, + "useCustomKeyStore": false, + "keyStoreLocation": "[keystore resource location]", + "keyStorePassword": "[keystore password]", + "keyAlias": "[key alias]", + "keyPassword": "[key password]", + "useCustomTrustStore": false, + "trustStoreLocation": "[truststore resource location]", + "trustStorePassword": "[truststore password]" + }, + "httpBasic": { + "enabled": false, + "username": "[HTTP basic authentication username]", + "password": "[HTTP basic authentication password]" + } +} +``` + + #### Response `UpdateCallbackUrlResponse` @@ -1338,6 +1386,7 @@ The `attributes` list can contain following values: | `String` | `name` | Callback URL name, for visual identification. | | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | +| `String` | `authentication` | Callback HTTP request authentication configuration. | ### Method 'getCallbackUrlList' @@ -1370,6 +1419,7 @@ REST endpoint: `POST /rest/v3/application/callback/list` | `String` | `name` | Callback URL name, for visual identification. | | `String` | `callbackUrl` | Callback URL that should be notified about activation status updates. | | `List` | `attributes` | Attributes which should be sent with the callback. | +| `String` | `authentication` | Callback HTTP request authentication configuration. | ### Method 'removeCallbackUrl' diff --git a/docs/images/arch_db_structure.png b/docs/images/arch_db_structure.png index 9ee5c40c4..3f0fc6e20 100644 Binary files a/docs/images/arch_db_structure.png and b/docs/images/arch_db_structure.png differ diff --git a/docs/sql/mysql/create_schema.sql b/docs/sql/mysql/create_schema.sql index fd5ecdb52..aba4f7329 100644 --- a/docs/sql/mysql/create_schema.sql +++ b/docs/sql/mysql/create_schema.sql @@ -118,6 +118,7 @@ CREATE TABLE `pa_application_callback` ( `callback_url` text NOT NULL, `type` VARCHAR(64) DEFAULT 'ACTIVATION_STATUS_CHANGE' NOT NULL, `attributes` text NOT NULL, + `authentication` text, PRIMARY KEY (`id`), CONSTRAINT `FK_APPLICATION_CALLBACK` FOREIGN KEY (`application_id`) REFERENCES `pa_application` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/docs/sql/mysql/mysql-workbench-model.mwb b/docs/sql/mysql/mysql-workbench-model.mwb deleted file mode 100644 index 8de95c8b1..000000000 Binary files a/docs/sql/mysql/mysql-workbench-model.mwb and /dev/null differ diff --git a/docs/sql/oracle/create_schema.sql b/docs/sql/oracle/create_schema.sql index 360a7af23..122d2d4a2 100755 --- a/docs/sql/oracle/create_schema.sql +++ b/docs/sql/oracle/create_schema.sql @@ -124,7 +124,8 @@ CREATE TABLE "PA_APPLICATION_CALLBACK" "NAME" VARCHAR2(255 CHAR), "CALLBACK_URL" VARCHAR2(1024 CHAR), "TYPE" VARCHAR2(64 CHAR) DEFAULT 'ACTIVATION_STATUS_CHANGE' NOT NULL, - "ATTRIBUTES" VARCHAR2(1024 CHAR) + "ATTRIBUTES" VARCHAR2(1024 CHAR), + "AUTHENTICATION" CLOB ); -- diff --git a/docs/sql/postgresql/create_schema.sql b/docs/sql/postgresql/create_schema.sql index 0979f6f24..a0c77eca0 100644 --- a/docs/sql/postgresql/create_schema.sql +++ b/docs/sql/postgresql/create_schema.sql @@ -125,7 +125,8 @@ CREATE TABLE "pa_application_callback" "name" VARCHAR(255), "callback_url" VARCHAR(1024), "type" VARCHAR(64) DEFAULT 'ACTIVATION_STATUS_CHANGE' NOT NULL, - "attributes" VARCHAR(1024) + "attributes" VARCHAR(1024), + "authentication" TEXT ); -- @@ -238,7 +239,7 @@ CREATE TABLE "pa_operation_template" ( -- -- DDL for Table SHEDLOCK -- -CREATE TABLE "shedlock" ( +CREATE TABLE shedlock ( name VARCHAR(64) NOT NULL PRIMARY KEY, lock_until TIMESTAMP NOT NULL, locked_at TIMESTAMP NOT NULL, diff --git a/pom.xml b/pom.xml index ec7a5240b..ba9a8a7f9 100644 --- a/pom.xml +++ b/pom.xml @@ -26,13 +26,13 @@ io.getlime.security powerauth-server-parent - 1.1.0 + 1.2.0 pom org.springframework.boot spring-boot-starter-parent - 2.4.5 + 2.6.1 @@ -86,16 +86,16 @@ 1.8 3.2.0 3.0.0-M1 - 3.2.0 - 3.3.1 + 3.3.1 + 3.3.2 - 3.0.3 + 3.1.0 - 1.1.0 - 1.3.0 - 1.68 + 1.2.0 + 1.4.0 + 1.69 2.3.1 @@ -107,17 +107,17 @@ 1.5.3 - 1.5.8 + 1.6.1 - 4.23.0 + 4.30.0 - 5.7.2 + 5.8.2 1.4.197 - 1.7.9 + 2.13.0 1.9 @@ -188,13 +188,11 @@ - org.apache.maven.plugins - maven-gpg-plugin - 1.6 + org.kohsuke + pgp-maven-plugin + 1.1 - sign-artifacts - verify sign diff --git a/powerauth-client-model/pom.xml b/powerauth-client-model/pom.xml index 8ea9fba7c..e7f3d70a1 100644 --- a/powerauth-client-model/pom.xml +++ b/powerauth-client-model/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-client-model - 1.1.0 + 1.2.0 powerauth-client-model PowerAuth Server Client Model io.getlime.security powerauth-server-parent - 1.1.0 + 1.2.0 ../pom.xml @@ -42,13 +42,17 @@ com.fasterxml.jackson.core jackson-databind - 2.12.3 + ${jackson.version} javax.xml.bind jaxb-api ${jaxb-api.version} + + org.projectlombok + lombok + diff --git a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/PowerAuthClient.java b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/PowerAuthClient.java index a98dd44a9..327b67f2c 100644 --- a/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/PowerAuthClient.java +++ b/powerauth-client-model/src/main/java/com/wultra/security/powerauth/client/PowerAuthClient.java @@ -781,15 +781,16 @@ VaultUnlockResponse unlockVault(String activationId, String applicationKey, Stri /** * Create a new callback URL with given parameters. * - * @param applicationId Application ID. - * @param name Callback URL display name. - * @param type Callback type. - * @param callbackUrl Callback URL value. - * @param attributes Attributes to send in the callback data. + * @param applicationId Application ID. + * @param name Callback URL display name. + * @param type Callback type. + * @param callbackUrl Callback URL value. + * @param attributes Attributes to send in the callback data. + * @param authentication Callback request authentication. * @return Information about new callback URL object. * @throws PowerAuthClientException In case REST API call fails. */ - CreateCallbackUrlResponse createCallbackUrl(Long applicationId, String name, CallbackUrlType type, String callbackUrl, List attributes) throws PowerAuthClientException; + CreateCallbackUrlResponse createCallbackUrl(Long applicationId, String name, CallbackUrlType type, String callbackUrl, List attributes, HttpAuthenticationPrivate authentication) throws PowerAuthClientException; /** * Update a callback URL with given request object. @@ -803,15 +804,16 @@ VaultUnlockResponse unlockVault(String activationId, String applicationKey, Stri /** * Update a callback URL with given parameters. * - * @param id Callback URL identifier. - * @param applicationId Application ID. - * @param name Callback URL display name. - * @param callbackUrl Callback URL value. - * @param attributes Attributes to send in the callback data. + * @param id Callback URL identifier. + * @param applicationId Application ID. + * @param name Callback URL display name. + * @param callbackUrl Callback URL value. + * @param attributes Attributes to send in the callback data. + * @param authentication Callback request authentication. * @return Information about new callback URL object. * @throws PowerAuthClientException In case REST API call fails. */ - UpdateCallbackUrlResponse updateCallbackUrl(String id, long applicationId, String name, String callbackUrl, List attributes) throws PowerAuthClientException; + UpdateCallbackUrlResponse updateCallbackUrl(String id, long applicationId, String name, String callbackUrl, List attributes, HttpAuthenticationPrivate authentication) throws PowerAuthClientException; /** * Get the response with list of callback URL objects. diff --git a/powerauth-java-server/pom.xml b/powerauth-java-server/pom.xml index 6ac716f0d..3f842d73d 100644 --- a/powerauth-java-server/pom.xml +++ b/powerauth-java-server/pom.xml @@ -24,13 +24,13 @@ powerauth-java-server PowerAuth Server powerauth-java-server - 1.1.0 + 1.2.0 war io.getlime.security powerauth-server-parent - 1.1.0 + 1.2.0 ../pom.xml @@ -43,6 +43,12 @@ org.springframework.boot spring-boot-starter-web + + + log4j-to-slf4j + org.apache.logging.log4j + + org.springframework.boot @@ -106,7 +112,7 @@ io.getlime.security powerauth-client-model - 1.1.0 + 1.2.0 io.getlime.security @@ -159,6 +165,13 @@ ${schedlock.version} + + + io.micrometer + micrometer-registry-prometheus + runtime + + org.springframework.boot diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java index cc72f70f2..96098c837 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/PowerAuthServiceConfiguration.java @@ -18,8 +18,13 @@ package io.getlime.security.powerauth.app.server.configuration; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.validation.annotation.Validated; @@ -192,6 +197,21 @@ public class PowerAuthServiceConfiguration { @Value("${powerauth.service.secureVault.enableBiometricAuthentication}") private boolean secureVaultBiometricAuthenticationEnabled; + /** + * Prepare and configure object mapper. + * @return Object mapper. + */ + @Bean + public ObjectMapper objectMapper() { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + objectMapper.registerModule(new JavaTimeModule()); + return objectMapper; + } + /** * Get application name, usually used as a "unique code" for the application within * a server infrastructure. diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebApplicationConfig.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebApplicationConfig.java index 263e2f1f7..c1f98c029 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebApplicationConfig.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebApplicationConfig.java @@ -19,6 +19,7 @@ package io.getlime.security.powerauth.app.server.configuration; import io.getlime.security.powerauth.app.server.controller.RESTResponseExceptionResolver; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -37,9 +38,20 @@ @Configuration public class WebApplicationConfig implements WebMvcConfigurer { + private final RESTResponseExceptionResolver restResponseExceptionResolver; + + /** + * Configuration constructor. + * @param restResponseExceptionResolver REST response exception resolver. + */ + @Autowired + public WebApplicationConfig(RESTResponseExceptionResolver restResponseExceptionResolver) { + this.restResponseExceptionResolver = restResponseExceptionResolver; + } + @Override public void configureHandlerExceptionResolvers(List exceptionResolvers) { - exceptionResolvers.add(new RESTResponseExceptionResolver()); + exceptionResolvers.add(restResponseExceptionResolver); exceptionResolvers.add(new ExceptionHandlerExceptionResolver()); exceptionResolvers.add(new ResponseStatusExceptionResolver()); } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebSecurityConfig.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebSecurityConfig.java index cb3fa99db..7b39f5972 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebSecurityConfig.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/configuration/WebSecurityConfig.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.getlime.core.rest.model.base.response.ErrorResponse; import io.getlime.security.powerauth.app.server.integration.IntegrationUserDetailsService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; @@ -49,18 +48,20 @@ @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - private IntegrationUserDetailsService userDetailsService; + private final IntegrationUserDetailsService userDetailsService; + private final PowerAuthServiceConfiguration configuration; + private final ObjectMapper objectMapper; - private PowerAuthServiceConfiguration configuration; - - @Autowired - public void setConfiguration(PowerAuthServiceConfiguration configuration) { - this.configuration = configuration; - } - - @Autowired - public void setUserDetailsService(IntegrationUserDetailsService userDetailsService) { + /** + * Configuration constructor. + * @param userDetailsService User details service. + * @param configuration PowerAuth service configuration. + * @param objectMapper Object mapper. + */ + public WebSecurityConfig(IntegrationUserDetailsService userDetailsService, PowerAuthServiceConfiguration configuration, ObjectMapper objectMapper) { this.userDetailsService = userDetailsService; + this.configuration = configuration; + this.objectMapper = objectMapper; } @Override @@ -90,7 +91,7 @@ public AuthenticationEntryPoint authenticationEntryPoint() { httpServletResponse.setContentType("application/json"); httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - httpServletResponse.getOutputStream().println(new ObjectMapper().writeValueAsString(errorResponse)); + httpServletResponse.getOutputStream().println(objectMapper.writeValueAsString(errorResponse)); httpServletResponse.getOutputStream().flush(); }; } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTResponseExceptionResolver.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTResponseExceptionResolver.java index e9342a1ac..65d366132 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTResponseExceptionResolver.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/controller/RESTResponseExceptionResolver.java @@ -49,10 +49,14 @@ public class RESTResponseExceptionResolver extends DefaultHandlerExceptionResolv private static final Logger logger = LoggerFactory.getLogger(RESTResponseExceptionResolver.class); + private final ObjectMapper objectMapper; + /** * Default constructor. + * @param objectMapper Object mapper. */ - public RESTResponseExceptionResolver() { + public RESTResponseExceptionResolver(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; super.setOrder(Ordered.LOWEST_PRECEDENCE - 1); } @@ -90,8 +94,7 @@ protected ModelAndView doResolveException(@NonNull HttpServletRequest request, @ ObjectResponse errorResponse = new ObjectResponse<>("ERROR", error); // Write the response in JSON and send it - ObjectMapper mapper = new ObjectMapper(); - String responseString = mapper.writeValueAsString(errorResponse); + String responseString = objectMapper.writeValueAsString(errorResponse); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.setCharacterEncoding(StandardCharsets.UTF_8.name()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAttributeConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAttributeConverter.java index a5925d3dc..8d22884b1 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAttributeConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAttributeConverter.java @@ -43,7 +43,15 @@ public class CallbackAttributeConverter implements AttributeConverter attributes) { diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationConverter.java new file mode 100644 index 000000000..c7757086b --- /dev/null +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationConverter.java @@ -0,0 +1,79 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2020 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package io.getlime.security.powerauth.app.server.converter.v3; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.wultra.security.powerauth.client.v3.HttpAuthenticationPrivate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import java.io.IOException; + +/** + * Converter for callback request authentication. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +@Converter +@Component +public class CallbackAuthenticationConverter implements AttributeConverter { + + private static final Logger logger = LoggerFactory.getLogger(CallbackAuthenticationConverter.class); + + private final ObjectMapper objectMapper; + + /** + * Converter constructor. + * @param objectMapper Object mapper. + */ + public CallbackAuthenticationConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public String convertToDatabaseColumn(HttpAuthenticationPrivate authentication) { + try { + if (authentication == null) { + authentication = new HttpAuthenticationPrivate(); + } + return objectMapper.writeValueAsString(authentication); + } catch (JsonProcessingException ex) { + logger.error("Unable to serialize JSON payload", ex); + return null; + } + + } + + @Override + public HttpAuthenticationPrivate convertToEntityAttribute(String authentication) { + if (authentication == null) { + return new HttpAuthenticationPrivate(); + } + try { + return objectMapper.readValue(authentication, HttpAuthenticationPrivate.class); + } catch (IOException ex) { + logger.error("Unable to parse JSON payload", ex); + return new HttpAuthenticationPrivate(); + } + + } +} diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationPublicConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationPublicConverter.java new file mode 100644 index 000000000..054ceab3b --- /dev/null +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/CallbackAuthenticationPublicConverter.java @@ -0,0 +1,65 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2021 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package io.getlime.security.powerauth.app.server.converter.v3; + +import com.wultra.security.powerauth.client.v3.HttpAuthenticationPrivate; +import com.wultra.security.powerauth.client.v3.HttpAuthenticationPublic; + +/** + * Converter of private to public HTTP authentication. + * + * @author Roman Strobl, roman.strobl@wultra.com + */ +public class CallbackAuthenticationPublicConverter { + + /** + * Convert private HTTP authentication to public HTTP authentication. + * @param authPrivate Private HTTP authentication. + * @return Public HTTP authentication. + */ + public HttpAuthenticationPublic toPublic(HttpAuthenticationPrivate authPrivate) { + HttpAuthenticationPublic authPublic = new HttpAuthenticationPublic(); + if (authPrivate == null) { + return authPublic; + } + HttpAuthenticationPrivate.HttpBasic httpBasicPrivate = authPrivate.getHttpBasic(); + if (httpBasicPrivate != null) { + HttpAuthenticationPublic.HttpBasic httpBasicPublic = new HttpAuthenticationPublic.HttpBasic(); + httpBasicPublic.setEnabled(httpBasicPrivate.isEnabled()); + httpBasicPublic.setUsername(httpBasicPrivate.getUsername()); + httpBasicPublic.setPasswordSet(httpBasicPrivate.getPassword() != null && !httpBasicPrivate.getPassword().isEmpty()); + authPublic.setHttpBasic(httpBasicPublic); + } + HttpAuthenticationPrivate.Certificate certificatePrivate = authPrivate.getCertificate(); + if (certificatePrivate != null) { + HttpAuthenticationPublic.Certificate certificatePublic = new HttpAuthenticationPublic.Certificate(); + certificatePublic.setEnabled(certificatePrivate.isEnabled()); + certificatePublic.setUseCustomKeyStore(certificatePrivate.isUseCustomKeyStore()); + certificatePublic.setKeyStoreLocation(certificatePrivate.getKeyStoreLocation()); + certificatePublic.setKeyStorePasswordSet(certificatePrivate.getKeyStorePassword() != null && !certificatePrivate.getKeyStorePassword().isEmpty()); + certificatePublic.setKeyAlias(certificatePrivate.getKeyAlias()); + certificatePublic.setKeyPasswordSet(certificatePrivate.getKeyPassword() != null && !certificatePrivate.getKeyPassword().isEmpty()); + certificatePublic.setUseCustomTrustStore(certificatePrivate.isUseCustomTrustStore()); + certificatePublic.setTrustStoreLocation(certificatePrivate.getTrustStoreLocation()); + certificatePublic.setTrustStorePasswordSet(certificatePrivate.getTrustStorePassword() != null && !certificatePrivate.getTrustStorePassword().isEmpty()); + authPublic.setCertificate(certificatePublic); + } + return authPublic; + } + +} diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/KeyValueMapConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/KeyValueMapConverter.java index 04ea1c484..68f8d9736 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/KeyValueMapConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/converter/v3/KeyValueMapConverter.java @@ -22,6 +22,7 @@ import com.wultra.security.powerauth.client.v3.KeyValueMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import java.io.IOException; import java.util.List; @@ -31,11 +32,21 @@ * * @author Roman Strobl, roman.strobl@wultra.com */ +@Component public class KeyValueMapConverter { - private static final ObjectMapper mapper = new ObjectMapper(); private static final Logger logger = LoggerFactory.getLogger(KeyValueMapConverter.class); + private final ObjectMapper objectMapper; + + /** + * Converter constructor. + * @param objectMapper Object mapper. + */ + public KeyValueMapConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + /** * Convert {@link KeyValueMap} to {@link String}. * @param keyValueMap KeyValueMap. @@ -46,7 +57,7 @@ public String toString(KeyValueMap keyValueMap) { return null; } try { - return mapper.writeValueAsString(keyValueMap); + return objectMapper.writeValueAsString(keyValueMap); } catch (JsonProcessingException ex) { logger.error("Unable to serialize JSON payload.", ex); return null; @@ -63,7 +74,7 @@ public KeyValueMap fromString(String s) { return new KeyValueMap(); } try { - return mapper.readValue(s, KeyValueMap.class); + return objectMapper.readValue(s, KeyValueMap.class); } catch (IOException ex) { logger.error("Unable to parse JSON payload.", ex); return new KeyValueMap(); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ActivationFlagConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ActivationFlagConverter.java index 153264857..21f541dc1 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ActivationFlagConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ActivationFlagConverter.java @@ -42,7 +42,15 @@ public class ActivationFlagConverter implements AttributeConverter, private static final String EMPTY_FLAGS = "[]"; - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; + + /** + * Converter constructor. + * @param objectMapper Object mapper. + */ + public ActivationFlagConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } @Override public String convertToDatabaseColumn(List flags) { diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ApplicationRoleConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ApplicationRoleConverter.java index 7310a7eb7..4d61a5b3d 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ApplicationRoleConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/ApplicationRoleConverter.java @@ -42,7 +42,15 @@ public class ApplicationRoleConverter implements AttributeConverter private static final String EMPTY_ROLES = "[]"; - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; + + /** + * Converter constructor. + * @param objectMapper Object mapper. + */ + public ApplicationRoleConverter(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } @Override public String convertToDatabaseColumn(List roles) { diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/OperationParameterConverter.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/OperationParameterConverter.java index 48022ea2f..9a8e08efe 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/OperationParameterConverter.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/OperationParameterConverter.java @@ -44,7 +44,15 @@ public class OperationParameterConverter implements AttributeConverter parameters) { diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlEntity.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlEntity.java index d2fc2553f..920c49147 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlEntity.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/CallbackUrlEntity.java @@ -17,13 +17,16 @@ */ package io.getlime.security.powerauth.app.server.database.model.entity; +import com.wultra.security.powerauth.client.v3.HttpAuthenticationPrivate; import io.getlime.security.powerauth.app.server.converter.v3.CallbackAttributeConverter; +import io.getlime.security.powerauth.app.server.converter.v3.CallbackAuthenticationConverter; import io.getlime.security.powerauth.app.server.database.model.CallbackUrlType; import io.getlime.security.powerauth.app.server.database.model.CallbackUrlTypeConverter; import javax.persistence.*; import java.io.Serializable; import java.util.List; +import java.util.Objects; /** * Class representing a callback URL associated with given application. @@ -57,6 +60,10 @@ public class CallbackUrlEntity implements Serializable { @Convert(converter = CallbackAttributeConverter.class) private List attributes; + @Column(name = "authentication") + @Convert(converter = CallbackAuthenticationConverter.class) + private HttpAuthenticationPrivate authentication; + /** * Get the ID of an integration. * @return ID of an integration. @@ -152,4 +159,33 @@ public List getAttributes() { public void setAttributes(List attributes) { this.attributes = attributes; } + + /** + * Get callback request authentication. + * @return Callback request authentication. + */ + public HttpAuthenticationPrivate getAuthentication() { + return authentication; + } + + /** + * Set callback request authentication. + * @param authentication Callback request authentication. + */ + public void setAuthentication(HttpAuthenticationPrivate authentication) { + this.authentication = authentication; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CallbackUrlEntity)) return false; + CallbackUrlEntity that = (CallbackUrlEntity) o; + return applicationId.equals(that.applicationId) && type == that.type && callbackUrl.equals(that.callbackUrl); + } + + @Override + public int hashCode() { + return Objects.hash(applicationId, type, callbackUrl); + } } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/ServiceBehaviorCatalogue.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/ServiceBehaviorCatalogue.java index 30fda62d5..dca68f580 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/ServiceBehaviorCatalogue.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/ServiceBehaviorCatalogue.java @@ -20,6 +20,7 @@ import io.getlime.security.powerauth.app.server.service.behavior.tasks.v2.EncryptionServiceBehavior; import io.getlime.security.powerauth.app.server.service.behavior.tasks.v3.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; /** @@ -69,102 +70,102 @@ public class ServiceBehaviorCatalogue { private ServiceBehaviorCatalogueV2 serviceBehaviorCatalogueV2; @Autowired - public void setActivationServiceBehavior(ActivationServiceBehavior activationServiceBehavior) { + public void setActivationServiceBehavior(@Lazy ActivationServiceBehavior activationServiceBehavior) { this.activationServiceBehavior = activationServiceBehavior; } @Autowired - public void setActivationFlagsServiceBehavior(ActivationFlagsServiceBehavior activationFlagsServiceBehavior) { + public void setActivationFlagsServiceBehavior(@Lazy ActivationFlagsServiceBehavior activationFlagsServiceBehavior) { this.activationFlagsServiceBehavior = activationFlagsServiceBehavior; } @Autowired - public void setActivationHistoryServiceBehavior(ActivationHistoryServiceBehavior activationHistoryServiceBehavior) { + public void setActivationHistoryServiceBehavior(@Lazy ActivationHistoryServiceBehavior activationHistoryServiceBehavior) { this.activationHistoryServiceBehavior = activationHistoryServiceBehavior; } @Autowired - public void setApplicationServiceBehavior(ApplicationServiceBehavior applicationServiceBehavior) { + public void setApplicationServiceBehavior(@Lazy ApplicationServiceBehavior applicationServiceBehavior) { this.applicationServiceBehavior = applicationServiceBehavior; } @Autowired - public void setApplicationRolesServiceBehavior(ApplicationRolesServiceBehavior applicationRolesServiceBehavior) { + public void setApplicationRolesServiceBehavior(@Lazy ApplicationRolesServiceBehavior applicationRolesServiceBehavior) { this.applicationRolesServiceBehavior = applicationRolesServiceBehavior; } @Autowired - public void setAuditingServiceBehavior(AuditingServiceBehavior auditingServiceBehavior) { + public void setAuditingServiceBehavior(@Lazy AuditingServiceBehavior auditingServiceBehavior) { this.auditingServiceBehavior = auditingServiceBehavior; } @Autowired - public void setOnlineSignatureServiceBehavior(OnlineSignatureServiceBehavior onlineSignatureServiceBehavior) { + public void setOnlineSignatureServiceBehavior(@Lazy OnlineSignatureServiceBehavior onlineSignatureServiceBehavior) { this.onlineSignatureServiceBehavior = onlineSignatureServiceBehavior; } @Autowired - public void setOfflineSignatureServiceBehavior(OfflineSignatureServiceBehavior offlineSignatureServiceBehavior) { + public void setOfflineSignatureServiceBehavior(@Lazy OfflineSignatureServiceBehavior offlineSignatureServiceBehavior) { this.offlineSignatureServiceBehavior = offlineSignatureServiceBehavior; } @Autowired - public void setVaultUnlockServiceBehavior(VaultUnlockServiceBehavior vaultUnlockServiceBehavior) { + public void setVaultUnlockServiceBehavior(@Lazy VaultUnlockServiceBehavior vaultUnlockServiceBehavior) { this.vaultUnlockServiceBehavior = vaultUnlockServiceBehavior; } @Autowired - public void setIntegrationBehavior(IntegrationBehavior integrationBehavior) { + public void setIntegrationBehavior(@Lazy IntegrationBehavior integrationBehavior) { this.integrationBehavior = integrationBehavior; } @Autowired - public void setCallbackUrlBehavior(CallbackUrlBehavior callbackUrlBehavior) { + public void setCallbackUrlBehavior(@Lazy CallbackUrlBehavior callbackUrlBehavior) { this.callbackUrlBehavior = callbackUrlBehavior; } @Autowired - public void setAsymmetricSignatureServiceBehavior(AsymmetricSignatureServiceBehavior asymmetricSignatureServiceBehavior) { + public void setAsymmetricSignatureServiceBehavior(@Lazy AsymmetricSignatureServiceBehavior asymmetricSignatureServiceBehavior) { this.asymmetricSignatureServiceBehavior = asymmetricSignatureServiceBehavior; } @Autowired - public void setTokenBehavior(TokenBehavior tokenBehavior) { + public void setTokenBehavior(@Lazy TokenBehavior tokenBehavior) { this.tokenBehavior = tokenBehavior; } @Autowired - public void setEciesEncryptionBehavior(EciesEncryptionBehavior eciesEncryptionBehavior) { + public void setEciesEncryptionBehavior(@Lazy EciesEncryptionBehavior eciesEncryptionBehavior) { this.eciesEncryptionBehavior = eciesEncryptionBehavior; } @Autowired - public void setUpgradeServiceBehavior(UpgradeServiceBehavior upgradeServiceBehavior) { + public void setUpgradeServiceBehavior(@Lazy UpgradeServiceBehavior upgradeServiceBehavior) { this.upgradeServiceBehavior = upgradeServiceBehavior; } @Autowired - public void setRecoveryServiceBehavior(RecoveryServiceBehavior recoveryServiceBehavior) { + public void setRecoveryServiceBehavior(@Lazy RecoveryServiceBehavior recoveryServiceBehavior) { this.recoveryServiceBehavior = recoveryServiceBehavior; } @Autowired - public void setRecoveryServiceBehavior(OperationServiceBehavior operationServiceBehavior) { + public void setRecoveryServiceBehavior(@Lazy OperationServiceBehavior operationServiceBehavior) { this.operationServiceBehavior = operationServiceBehavior; } @Autowired - public void setOperationBehavior(OperationServiceBehavior operationServiceBehavior) { + public void setOperationBehavior(@Lazy OperationServiceBehavior operationServiceBehavior) { this.operationServiceBehavior = operationServiceBehavior; } @Autowired - public void setOperationTemplateBehavior(OperationTemplateServiceBehavior operationTemplateServiceBehavior) { + public void setOperationTemplateBehavior(@Lazy OperationTemplateServiceBehavior operationTemplateServiceBehavior) { this.operationTemplateServiceBehavior = operationTemplateServiceBehavior; } @Autowired - public void setServiceBehaviorCatalogueV2(ServiceBehaviorCatalogueV2 serviceBehaviorCatalogueV2) { + public void setServiceBehaviorCatalogueV2(@Lazy ServiceBehaviorCatalogueV2 serviceBehaviorCatalogueV2) { this.serviceBehaviorCatalogueV2 = serviceBehaviorCatalogueV2; } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v2/TokenBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v2/TokenBehavior.java index 09f16ea0a..97b02124b 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v2/TokenBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v2/TokenBehavior.java @@ -24,7 +24,6 @@ import com.wultra.security.powerauth.client.v2.CreateTokenResponse; import com.wultra.security.powerauth.client.v2.SignatureType; import io.getlime.security.powerauth.app.server.configuration.PowerAuthServiceConfiguration; -import io.getlime.security.powerauth.app.server.converter.v3.SignatureTypeConverter; import io.getlime.security.powerauth.app.server.database.RepositoryCatalogue; import io.getlime.security.powerauth.app.server.database.model.ActivationStatus; import io.getlime.security.powerauth.app.server.database.model.entity.ActivationRecordEntity; @@ -40,7 +39,6 @@ import io.getlime.security.powerauth.crypto.lib.model.exception.CryptoProviderException; import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import io.getlime.security.powerauth.crypto.server.token.ServerTokenGenerator; -import io.getlime.security.powerauth.crypto.server.token.ServerTokenVerifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -72,19 +70,18 @@ public class TokenBehavior { // Business logic implementation classes private final ServerTokenGenerator tokenGenerator = new ServerTokenGenerator(); - private final ServerTokenVerifier tokenVerifier = new ServerTokenVerifier(); - // Helper classes - private final SignatureTypeConverter signatureTypeConverter = new SignatureTypeConverter(); + private final ObjectMapper objectMapper; // Prepare logger private static final Logger logger = LoggerFactory.getLogger(TokenBehavior.class); @Autowired - public TokenBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, PowerAuthServiceConfiguration powerAuthServiceConfiguration) { + public TokenBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, PowerAuthServiceConfiguration powerAuthServiceConfiguration, ObjectMapper objectMapper) { this.repositoryCatalogue = repositoryCatalogue; this.localizationProvider = localizationProvider; this.powerAuthServiceConfiguration = powerAuthServiceConfiguration; + this.objectMapper = objectMapper; } /** @@ -182,8 +179,7 @@ private EciesCryptogram createToken(String activationId, String ephemeralPublicK tokenInfo.setTokenId(tokenId); tokenInfo.setTokenSecret(tokenSecret); - final ObjectMapper mapper = new ObjectMapper(); - final byte[] tokenBytes = mapper.writeValueAsBytes(tokenInfo); + final byte[] tokenBytes = objectMapper.writeValueAsBytes(tokenInfo); EciesCryptogram response = decryptor.encryptResponse(tokenBytes); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java index 41cd02f48..9a30f22b0 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/ActivationServiceBehavior.java @@ -107,16 +107,17 @@ public class ActivationServiceBehavior { // Helper classes private final EciesFactory eciesFactory = new EciesFactory(); - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; private final IdentifierGenerator identifierGenerator = new IdentifierGenerator(); // Prepare logger private static final Logger logger = LoggerFactory.getLogger(ActivationServiceBehavior.class); @Autowired - public ActivationServiceBehavior(RepositoryCatalogue repositoryCatalogue, PowerAuthServiceConfiguration powerAuthServiceConfiguration) { + public ActivationServiceBehavior(RepositoryCatalogue repositoryCatalogue, PowerAuthServiceConfiguration powerAuthServiceConfiguration, ObjectMapper objectMapper) { this.repositoryCatalogue = repositoryCatalogue; this.powerAuthServiceConfiguration = powerAuthServiceConfiguration; + this.objectMapper = objectMapper; } @Autowired diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/AuditingServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/AuditingServiceBehavior.java index de6f0f93b..844789085 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/AuditingServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/AuditingServiceBehavior.java @@ -49,11 +49,12 @@ public class AuditingServiceBehavior { // Prepare converters private final ActivationStatusConverter activationStatusConverter = new ActivationStatusConverter(); private final SignatureTypeConverter signatureTypeConverter = new SignatureTypeConverter(); - private final KeyValueMapConverter keyValueMapConverter = new KeyValueMapConverter(); + private final KeyValueMapConverter keyValueMapConverter; @Autowired - public AuditingServiceBehavior(SignatureAuditRepository signatureAuditRepository) { + public AuditingServiceBehavior(SignatureAuditRepository signatureAuditRepository, KeyValueMapConverter keyValueMapConverter) { this.signatureAuditRepository = signatureAuditRepository; + this.keyValueMapConverter = keyValueMapConverter; } /** diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/CallbackUrlBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/CallbackUrlBehavior.java index 6eb12b5b7..a98418142 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/CallbackUrlBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/CallbackUrlBehavior.java @@ -22,6 +22,7 @@ import com.wultra.core.rest.client.base.RestClientException; import com.wultra.security.powerauth.client.v3.*; import io.getlime.security.powerauth.app.server.configuration.PowerAuthServiceConfiguration; +import io.getlime.security.powerauth.app.server.converter.v3.CallbackAuthenticationPublicConverter; import io.getlime.security.powerauth.app.server.database.model.CallbackUrlType; import io.getlime.security.powerauth.app.server.database.model.entity.ActivationRecordEntity; import io.getlime.security.powerauth.app.server.database.model.entity.CallbackUrlEntity; @@ -54,16 +55,19 @@ public class CallbackUrlBehavior { private final CallbackUrlRepository callbackUrlRepository; - private LocalizationProvider localizationProvider; - - private RestClient restClient; - private PowerAuthServiceConfiguration configuration; + private final Map restClientCache = new HashMap<>(); + private final CallbackAuthenticationPublicConverter authenticationPublicConverter = new CallbackAuthenticationPublicConverter(); + // Prepare logger private static final Logger logger = LoggerFactory.getLogger(CallbackUrlBehavior.class); + /** + * Behavior constructor. + * @param callbackUrlRepository Callback URL repository. + */ @Autowired public CallbackUrlBehavior(CallbackUrlRepository callbackUrlRepository) { this.callbackUrlRepository = callbackUrlRepository; @@ -79,23 +83,6 @@ public void setConfiguration(PowerAuthServiceConfiguration configuration) { this.configuration = configuration; } - /** - * Initialize Rest client instance and configure it based on client configuration. - */ - private void initializeRestClient() throws RestClientException { - DefaultRestClient.Builder builder = DefaultRestClient.builder(); - if (configuration.getHttpConnectionTimeout() != null) { - builder.connectionTimeout(configuration.getHttpConnectionTimeout()); - } - if (configuration.getHttpProxyEnabled()) { - DefaultRestClient.ProxyBuilder proxyBuilder = builder.proxy().host(configuration.getHttpProxyHost()).port(configuration.getHttpProxyPort()); - if (configuration.getHttpProxyUsername() != null) { - proxyBuilder.username(configuration.getHttpProxyUsername()).password(configuration.getHttpProxyPassword()); - } - } - restClient = builder.build(); - } - /** * Creates a new callback URL record for application with given ID. * @param request Instance specifying parameters of the callback URL. @@ -120,12 +107,17 @@ public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest requ entity.setType(CallbackUrlType.valueOf(request.getType())); entity.setCallbackUrl(request.getCallbackUrl()); entity.setAttributes(request.getAttributes()); + entity.setAuthentication(request.getAuthentication()); callbackUrlRepository.save(entity); CreateCallbackUrlResponse response = new CreateCallbackUrlResponse(); response.setId(entity.getId()); response.setApplicationId(entity.getApplicationId()); response.setName(entity.getName()); response.setCallbackUrl(entity.getCallbackUrl()); + if (entity.getAttributes() != null) { + response.getAttributes().addAll(entity.getAttributes()); + } + response.setAuthentication(authenticationPublicConverter.toPublic(entity.getAuthentication())); return response; } @@ -163,6 +155,28 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ entity.setName(request.getName()); entity.setCallbackUrl(request.getCallbackUrl()); entity.setAttributes(request.getAttributes()); + // Retain existing passwords in case new password is not set + HttpAuthenticationPrivate authRequest = request.getAuthentication(); + HttpAuthenticationPrivate authExisting = entity.getAuthentication(); + if (authRequest != null) { + if (authRequest.getCertificate() != null && authExisting.getCertificate() != null) { + if (authExisting.getCertificate().getKeyStorePassword() != null && authRequest.getCertificate().getKeyStorePassword() == null) { + authRequest.getCertificate().setKeyStorePassword(authExisting.getCertificate().getKeyStorePassword()); + } + if (authExisting.getCertificate().getKeyPassword() != null && authRequest.getCertificate().getKeyPassword() == null) { + authRequest.getCertificate().setKeyPassword(authExisting.getCertificate().getKeyPassword()); + } + if (authExisting.getCertificate().getTrustStorePassword() != null && authRequest.getCertificate().getTrustStorePassword() == null) { + authRequest.getCertificate().setTrustStorePassword(authExisting.getCertificate().getTrustStorePassword()); + } + } + if (authRequest.getHttpBasic() != null && authExisting.getHttpBasic() != null) { + if (authExisting.getHttpBasic().getPassword() != null && authRequest.getHttpBasic().getPassword() == null) { + authRequest.getHttpBasic().setPassword(authExisting.getHttpBasic().getPassword()); + } + } + } + entity.setAuthentication(authRequest); callbackUrlRepository.save(entity); UpdateCallbackUrlResponse response = new UpdateCallbackUrlResponse(); response.setId(entity.getId()); @@ -170,7 +184,10 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ response.setName(entity.getName()); response.setType(entity.getType().toString()); response.setCallbackUrl(entity.getCallbackUrl()); - response.getAttributes().addAll(entity.getAttributes()); + if (entity.getAttributes() != null) { + response.getAttributes().addAll(entity.getAttributes()); + } + response.setAuthentication(authenticationPublicConverter.toPublic(entity.getAuthentication())); return response; } @@ -189,7 +206,10 @@ public GetCallbackUrlListResponse getCallbackUrlList(GetCallbackUrlListRequest r item.setName(callbackUrl.getName()); item.setType(callbackUrl.getType().toString()); item.setCallbackUrl(callbackUrl.getCallbackUrl()); - item.getAttributes().addAll(callbackUrl.getAttributes()); + if (callbackUrl.getAttributes() != null) { + item.getAttributes().addAll(callbackUrl.getAttributes()); + } + item.setAuthentication(authenticationPublicConverter.toPublic(callbackUrl.getAuthentication())); response.getCallbackUrlList().add(item); } return response; @@ -219,10 +239,6 @@ public RemoveCallbackUrlResponse removeCallbackUrl(RemoveCallbackUrlRequest requ */ public void notifyCallbackListenersOnActivationChange(ActivationRecordEntity activation) { try { - if (restClient == null) { - // Initialize Rest Client when it is used for the first time - initializeRestClient(); - } if (activation != null && activation.getApplication() != null) { final Iterable callbackUrlEntities = callbackUrlRepository.findByApplicationIdAndTypeOrderByName(activation.getApplication().getId(), CallbackUrlType.ACTIVATION_STATUS_CHANGE); for (CallbackUrlEntity callbackUrlEntity : callbackUrlEntities) { @@ -279,10 +295,6 @@ private Map prepareCallbackDataActivation(CallbackUrlEntity call */ public void notifyCallbackListenersOnOperationChange(OperationEntity operation) { try { - if (restClient == null) { - // Initialize Rest Client when it is used for the first time - initializeRestClient(); - } if (operation != null && operation.getApplication() != null) { final Iterable callbackUrlEntities = callbackUrlRepository.findByApplicationIdAndTypeOrderByName(operation.getApplication().getId(), CallbackUrlType.OPERATION_STATUS_CHANGE); for (CallbackUrlEntity callbackUrlEntity : callbackUrlEntities) { @@ -349,11 +361,74 @@ private Map prepareCallbackDataOperation(CallbackUrlEntity callb // Private methods + /** + * Notify callback URL. + * @param callbackUrlEntity Callback URL entity. + * @param callbackData Callback data. + * @throws RestClientException Thrown when HTTP request fails. + */ private void notifyCallbackUrl(CallbackUrlEntity callbackUrlEntity, Map callbackData) throws RestClientException { Consumer> onSuccess = response -> logger.debug("Callback succeeded, URL: {}", callbackUrlEntity.getCallbackUrl()); Consumer onError = error -> logger.warn("Callback failed, URL: {}, error: {}", callbackUrlEntity.getCallbackUrl(), error.getMessage()); ParameterizedTypeReference responseType = new ParameterizedTypeReference(){}; + RestClient restClient = getRestClient(callbackUrlEntity); restClient.postNonBlocking(callbackUrlEntity.getCallbackUrl(), callbackData, responseType, onSuccess, onError); } + /** + * Get a rest client for a callback URL entity. + * @param callbackUrlEntity Callback URL entity. + * @return Rest client. + * @throws RestClientException Thrown when rest client initialization fails. + */ + private synchronized RestClient getRestClient(CallbackUrlEntity callbackUrlEntity) throws RestClientException { + RestClient restClient = restClientCache.get(callbackUrlEntity); + if (restClient == null) { + restClient = initializeRestClient(callbackUrlEntity); + restClientCache.put(callbackUrlEntity, restClient); + } + return restClient; + } + + /** + * Initialize Rest client instance and configure it based on client configuration. + * @param callbackUrlEntity Callback URL entity. + */ + private RestClient initializeRestClient(CallbackUrlEntity callbackUrlEntity) throws RestClientException { + DefaultRestClient.Builder builder = DefaultRestClient.builder(); + if (configuration.getHttpConnectionTimeout() != null) { + builder.connectionTimeout(configuration.getHttpConnectionTimeout()); + } + if (configuration.getHttpProxyEnabled()) { + DefaultRestClient.ProxyBuilder proxyBuilder = builder.proxy().host(configuration.getHttpProxyHost()).port(configuration.getHttpProxyPort()); + if (configuration.getHttpProxyUsername() != null) { + proxyBuilder.username(configuration.getHttpProxyUsername()).password(configuration.getHttpProxyPassword()); + } + } + HttpAuthenticationPrivate authentication = callbackUrlEntity.getAuthentication(); + HttpAuthenticationPrivate.Certificate certificateAuth = authentication.getCertificate(); + if (certificateAuth != null && certificateAuth.isEnabled()) { + DefaultRestClient.CertificateAuthBuilder certificateAuthBuilder = builder.certificateAuth(); + if (certificateAuth.isUseCustomKeyStore()) { + certificateAuthBuilder.enableCustomKeyStore() + .keyStoreLocation(certificateAuth.getKeyStoreLocation()) + .keyStorePassword(certificateAuth.getKeyStorePassword()) + .keyAlias(certificateAuth.getKeyAlias()) + .keyPassword(certificateAuth.getKeyPassword()); + } + if (certificateAuth.isUseCustomTrustStore()) { + certificateAuthBuilder.enableCustomTruststore() + .trustStoreLocation(certificateAuth.getTrustStoreLocation()) + .trustStorePassword(certificateAuth.getTrustStorePassword()); + } + } + HttpAuthenticationPrivate.HttpBasic httpBasicAuth = authentication.getHttpBasic(); + if (httpBasicAuth != null && httpBasicAuth.isEnabled()) { + builder.httpBasicAuth() + .username(httpBasicAuth.getUsername()) + .password(httpBasicAuth.getPassword()); + } + return builder.build(); + } + } diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/RecoveryServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/RecoveryServiceBehavior.java index 3a8d7861d..727e5f1b9 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/RecoveryServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/RecoveryServiceBehavior.java @@ -92,7 +92,7 @@ public class RecoveryServiceBehavior { private final EciesFactory eciesFactory = new EciesFactory(); // Helper classes - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; private final IdentifierGenerator identifierGenerator = new IdentifierGenerator(); private final RecoveryCodeStatusConverter recoveryCodeStatusConverter = new RecoveryCodeStatusConverter(); private final RecoveryPukStatusConverter recoveryPukStatusConverter = new RecoveryPukStatusConverter(); @@ -103,12 +103,13 @@ public class RecoveryServiceBehavior { public RecoveryServiceBehavior(LocalizationProvider localizationProvider, PowerAuthServiceConfiguration powerAuthServiceConfiguration, RepositoryCatalogue repositoryCatalogue, ServerPrivateKeyConverter serverPrivateKeyConverter, ActivationServiceBehavior activationServiceBehavior, - RecoveryPrivateKeyConverter recoveryPrivateKeyConverter, RecoveryPukConverter recoveryPukConverter) { + RecoveryPrivateKeyConverter recoveryPrivateKeyConverter, ObjectMapper objectMapper, RecoveryPukConverter recoveryPukConverter) { this.localizationProvider = localizationProvider; this.powerAuthServiceConfiguration = powerAuthServiceConfiguration; this.repositoryCatalogue = repositoryCatalogue; this.serverPrivateKeyConverter = serverPrivateKeyConverter; this.recoveryPrivateKeyConverter = recoveryPrivateKeyConverter; + this.objectMapper = objectMapper; this.recoveryPukConverter = recoveryPukConverter; } @@ -377,8 +378,7 @@ public ConfirmRecoveryCodeResponse confirmRecoveryCode(ConfirmRecoveryCodeReques final ConfirmRecoveryResponsePayload responsePayload = new ConfirmRecoveryResponsePayload(alreadyConfirmed); // Convert response payload - final ObjectMapper mapper = new ObjectMapper(); - final byte[] responseBytes = mapper.writeValueAsBytes(responsePayload); + final byte[] responseBytes = objectMapper.writeValueAsBytes(responsePayload); // Encrypt response using previously created ECIES decryptor final EciesCryptogram eciesResponse = decryptor.encryptResponse(responseBytes); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java index 3baaf310a..52259ce72 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/TokenBehavior.java @@ -83,15 +83,18 @@ public class TokenBehavior { // Helper classes private final SignatureTypeConverter signatureTypeConverter = new SignatureTypeConverter(); + private final ObjectMapper objectMapper; + // Prepare logger private static final Logger logger = LoggerFactory.getLogger(TokenBehavior.class); @Autowired - public TokenBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, PowerAuthServiceConfiguration powerAuthServiceConfiguration, ServerPrivateKeyConverter serverPrivateKeyConverter) { + public TokenBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, PowerAuthServiceConfiguration powerAuthServiceConfiguration, ServerPrivateKeyConverter serverPrivateKeyConverter, ObjectMapper objectMapper) { this.repositoryCatalogue = repositoryCatalogue; this.localizationProvider = localizationProvider; this.powerAuthServiceConfiguration = powerAuthServiceConfiguration; this.serverPrivateKeyConverter = serverPrivateKeyConverter; + this.objectMapper = objectMapper; } /** @@ -206,8 +209,7 @@ private EciesCryptogram createToken(String activationId, String applicationKey, tokenInfo.setTokenId(tokenId); tokenInfo.setTokenSecret(tokenSecret); - final ObjectMapper mapper = new ObjectMapper(); - final byte[] tokenBytes = mapper.writeValueAsBytes(tokenInfo); + final byte[] tokenBytes = objectMapper.writeValueAsBytes(tokenInfo); // Encrypt response using previously created ECIES decryptor final EciesCryptogram response = decryptor.encryptResponse(tokenBytes); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/UpgradeServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/UpgradeServiceBehavior.java index 332d3e81b..cf2751545 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/UpgradeServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/UpgradeServiceBehavior.java @@ -74,16 +74,17 @@ public class UpgradeServiceBehavior { private final EciesFactory eciesFactory = new EciesFactory(); private final KeyConvertor keyConvertor = new KeyConvertor(); private final PowerAuthServerKeyFactory powerAuthServerKeyFactory = new PowerAuthServerKeyFactory(); - private final ObjectMapper mapper = new ObjectMapper(); + private final ObjectMapper objectMapper; // Prepare logger private static final Logger logger = LoggerFactory.getLogger(UpgradeServiceBehavior.class); @Autowired - public UpgradeServiceBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, ServerPrivateKeyConverter serverPrivateKeyConverter) { + public UpgradeServiceBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, ServerPrivateKeyConverter serverPrivateKeyConverter, ObjectMapper objectMapper) { this.repositoryCatalogue = repositoryCatalogue; this.localizationProvider = localizationProvider; this.serverPrivateKeyConverter = serverPrivateKeyConverter; + this.objectMapper = objectMapper; } /** @@ -188,7 +189,7 @@ public StartUpgradeResponse startUpgrade(StartUpgradeRequest request) throws Gen final UpgradeResponsePayload payload = new UpgradeResponsePayload(ctrDataBase64); // Encrypt response payload and return it - final byte[] payloadBytes = mapper.writeValueAsBytes(payload); + final byte[] payloadBytes = objectMapper.writeValueAsBytes(payload); final EciesCryptogram cryptogramResponse = decryptor.encryptResponse(payloadBytes); final StartUpgradeResponse response = new StartUpgradeResponse(); diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/VaultUnlockServiceBehavior.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/VaultUnlockServiceBehavior.java index cf7478f2e..634b5bc28 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/VaultUnlockServiceBehavior.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/v3/VaultUnlockServiceBehavior.java @@ -84,18 +84,19 @@ public class VaultUnlockServiceBehavior { // Helper classes private final EciesFactory eciesFactory = new EciesFactory(); private final PowerAuthServerVault powerAuthServerVault = new PowerAuthServerVault(); - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; private final PowerAuthServerKeyFactory powerAuthServerKeyFactory = new PowerAuthServerKeyFactory(); // Prepare logger private static final Logger logger = LoggerFactory.getLogger(VaultUnlockServiceBehavior.class); @Autowired - public VaultUnlockServiceBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, ServerPrivateKeyConverter serverPrivateKeyConverter, ServiceBehaviorCatalogue behavior) { + public VaultUnlockServiceBehavior(RepositoryCatalogue repositoryCatalogue, LocalizationProvider localizationProvider, ServerPrivateKeyConverter serverPrivateKeyConverter, ServiceBehaviorCatalogue behavior, ObjectMapper objectMapper) { this.repositoryCatalogue = repositoryCatalogue; this.localizationProvider = localizationProvider; this.serverPrivateKeyConverter = serverPrivateKeyConverter; this.behavior = behavior; + this.objectMapper = objectMapper; } /** diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/v2/PowerAuthServiceImpl.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/v2/PowerAuthServiceImpl.java index fee857e5a..e03e38cc6 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/v2/PowerAuthServiceImpl.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/service/v2/PowerAuthServiceImpl.java @@ -18,6 +18,7 @@ package io.getlime.security.powerauth.app.server.service.v2; import com.wultra.security.powerauth.client.v2.*; +import io.getlime.security.powerauth.app.server.converter.v3.KeyValueMapConverter; import io.getlime.security.powerauth.app.server.converter.v3.XMLGregorianCalendarConverter; import io.getlime.security.powerauth.app.server.database.model.AdditionalInformation; import io.getlime.security.powerauth.app.server.service.behavior.ServiceBehaviorCatalogue; @@ -28,7 +29,6 @@ import io.getlime.security.powerauth.crypto.lib.util.KeyConvertor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -52,24 +52,27 @@ @Component("powerAuthServiceImplV2") public class PowerAuthServiceImpl implements PowerAuthService { - private ServiceBehaviorCatalogue behavior; - - private LocalizationProvider localizationProvider; - // Prepare logger private static final Logger logger = LoggerFactory.getLogger(PowerAuthServiceImpl.class); - @Autowired - public void setBehavior(ServiceBehaviorCatalogue behavior) { - this.behavior = behavior; - } + private final ServiceBehaviorCatalogue behavior; + private final LocalizationProvider localizationProvider; + private final KeyValueMapConverter keyValueMapConverter; - @Autowired - public void setLocalizationProvider(LocalizationProvider localizationProvider) { + private final KeyConvertor keyConvertor = new KeyConvertor(); + + /** + * Service constructor. + * @param behavior Service behavior catalogue. + * @param localizationProvider Localization provider. + * @param keyValueMapConverter Key value map converter. + */ + public PowerAuthServiceImpl(ServiceBehaviorCatalogue behavior, LocalizationProvider localizationProvider, KeyValueMapConverter keyValueMapConverter) { + this.behavior = behavior; this.localizationProvider = localizationProvider; + this.keyValueMapConverter = keyValueMapConverter; } - private final KeyConvertor keyConvertor = new KeyConvertor(); @Override @Transactional @@ -313,7 +316,7 @@ public CreateTokenResponse createToken(CreateTokenRequest request) throws Generi private boolean verifySignatureImplNonTransaction(String activationId, String applicationKey, String dataString, String signature, SignatureType signatureType, KeyValueMap additionalInfo) throws GenericServiceException { com.wultra.security.powerauth.client.v3.SignatureType signatureTypeV3 = new io.getlime.security.powerauth.app.server.converter.v3.SignatureTypeConverter().convertFrom(signatureType); - com.wultra.security.powerauth.client.v3.KeyValueMap additionalInfoV3 = new io.getlime.security.powerauth.app.server.converter.v3.KeyValueMapConverter().fromKeyValueMap(additionalInfo); + com.wultra.security.powerauth.client.v3.KeyValueMap additionalInfoV3 = keyValueMapConverter.fromKeyValueMap(additionalInfo); return behavior.getOnlineSignatureServiceBehavior().verifySignature(activationId, signatureTypeV3, signature, "2.1", additionalInfoV3, dataString, applicationKey, null, keyConvertor).isSignatureValid(); } diff --git a/powerauth-java-server/src/main/resources/application.properties b/powerauth-java-server/src/main/resources/application.properties index 488f4afad..80230bc83 100644 --- a/powerauth-java-server/src/main/resources/application.properties +++ b/powerauth-java-server/src/main/resources/application.properties @@ -19,11 +19,12 @@ # Allow externalization of properties using application-ext.properties spring.profiles.active=ext -# Database Configuration - MySQL -spring.datasource.url=jdbc:mysql://localhost:3306/powerauth +# Database Configuration - PostgreSQL +spring.datasource.url=jdbc:postgresql://localhost:5432/powerauth spring.datasource.username=powerauth spring.datasource.password= -spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.driver-class-name=org.postgresql.Driver +spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false spring.jpa.properties.hibernate.connection.characterEncoding=utf8 spring.jpa.properties.hibernate.connection.useUnicode=true @@ -35,12 +36,11 @@ spring.jpa.properties.hibernate.connection.useUnicode=true # The following property speeds up Spring Boot startup #spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false -# Database Configuration - PostgreSQL -#spring.datasource.url=jdbc:postgresql://localhost:5432/powerauth +# Database Configuration - MySQL +#spring.datasource.url=jdbc:mysql://localhost:3306/powerauth #spring.datasource.username=powerauth #spring.datasource.password= -#spring.datasource.driver-class-name=org.postgresql.Driver -#spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false +#spring.datasource.driver-class-name=com.mysql.jdbc.Driver #spring.jpa.properties.hibernate.connection.characterEncoding=utf8 #spring.jpa.properties.hibernate.connection.useUnicode=true diff --git a/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd b/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd index 3f520ff19..ff7114dae 100644 --- a/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd +++ b/powerauth-java-server/src/main/resources/xsd/PowerAuth-3.0.xsd @@ -1067,6 +1067,7 @@ + @@ -1083,6 +1084,7 @@ + @@ -1101,6 +1103,7 @@ + @@ -1117,6 +1120,7 @@ + @@ -1149,6 +1153,7 @@ + @@ -1841,4 +1846,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml index fba087557..6632567d9 100644 --- a/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml +++ b/powerauth-java-server/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -12,7 +12,7 @@ - + diff --git a/powerauth-rest-client-spring/pom.xml b/powerauth-rest-client-spring/pom.xml index 1cc5376c2..954ccc624 100644 --- a/powerauth-rest-client-spring/pom.xml +++ b/powerauth-rest-client-spring/pom.xml @@ -22,14 +22,14 @@ 4.0.0 powerauth-rest-client-spring - 1.1.0 + 1.2.0 powerauth-rest-client-spring PowerAuth Server REST Service Client io.getlime.security powerauth-server-parent - 1.1.0 + 1.2.0 ../pom.xml @@ -38,7 +38,7 @@ io.getlime.security powerauth-client-model - 1.1.0 + 1.2.0 io.getlime.core @@ -55,6 +55,12 @@ org.springframework.boot spring-boot-starter + + + log4j-to-slf4j + org.apache.logging.log4j + + org.springframework.boot diff --git a/powerauth-rest-client-spring/src/main/java/com/wultra/security/powerauth/rest/client/PowerAuthRestClient.java b/powerauth-rest-client-spring/src/main/java/com/wultra/security/powerauth/rest/client/PowerAuthRestClient.java index 6104879c3..7c42eb38b 100644 --- a/powerauth-rest-client-spring/src/main/java/com/wultra/security/powerauth/rest/client/PowerAuthRestClient.java +++ b/powerauth-rest-client-spring/src/main/java/com/wultra/security/powerauth/rest/client/PowerAuthRestClient.java @@ -37,9 +37,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; @@ -692,7 +689,7 @@ public CreateCallbackUrlResponse createCallbackUrl(CreateCallbackUrlRequest requ } @Override - public CreateCallbackUrlResponse createCallbackUrl(Long applicationId, String name, CallbackUrlType type, String callbackUrl, List attributes) throws PowerAuthClientException { + public CreateCallbackUrlResponse createCallbackUrl(Long applicationId, String name, CallbackUrlType type, String callbackUrl, List attributes, HttpAuthenticationPrivate authentication) throws PowerAuthClientException { CreateCallbackUrlRequest request = new CreateCallbackUrlRequest(); request.setApplicationId(applicationId); request.setName(name); @@ -701,6 +698,7 @@ public CreateCallbackUrlResponse createCallbackUrl(Long applicationId, String na if (attributes != null) { request.getAttributes().addAll(attributes); } + request.setAuthentication(authentication); return this.createCallbackUrl(request); } @@ -710,7 +708,7 @@ public UpdateCallbackUrlResponse updateCallbackUrl(UpdateCallbackUrlRequest requ } @Override - public UpdateCallbackUrlResponse updateCallbackUrl(String id, long applicationId, String name, String callbackUrl, List attributes) throws PowerAuthClientException { + public UpdateCallbackUrlResponse updateCallbackUrl(String id, long applicationId, String name, String callbackUrl, List attributes, HttpAuthenticationPrivate authentication) throws PowerAuthClientException { UpdateCallbackUrlRequest request = new UpdateCallbackUrlRequest(); request.setId(id); request.setApplicationId(applicationId); @@ -719,6 +717,7 @@ public UpdateCallbackUrlResponse updateCallbackUrl(String id, long applicationId if (attributes != null) { request.getAttributes().addAll(attributes); } + request.setAuthentication(authentication); return this.updateCallbackUrl(request); }