diff --git a/backend/app/gzac/build.gradle b/backend/app/gzac/build.gradle index 1f04d6cc4f..959346c341 100644 --- a/backend/app/gzac/build.gradle +++ b/backend/app/gzac/build.gradle @@ -23,6 +23,8 @@ dependencies { implementation(project(":backend:process-link-url")) implementation("io.github.oshai:kotlin-logging") + implementation "org.springframework.boot:spring-boot-starter-classic" + implementation "org.springframework.boot:spring-boot-jackson2" implementation "org.springframework.boot:spring-boot-starter-webflux" implementation "org.springframework.boot:spring-boot-starter-security" diff --git a/backend/app/gzac/src/dev/kotlin/com/ritense/gzac/security/TestImplHttpSecurityConfigurer.kt b/backend/app/gzac/src/dev/kotlin/com/ritense/gzac/security/TestImplHttpSecurityConfigurer.kt index cd2e94a4a0..f30878a4c9 100644 --- a/backend/app/gzac/src/dev/kotlin/com/ritense/gzac/security/TestImplHttpSecurityConfigurer.kt +++ b/backend/app/gzac/src/dev/kotlin/com/ritense/gzac/security/TestImplHttpSecurityConfigurer.kt @@ -22,7 +22,7 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.core.annotation.Order import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern import org.springframework.stereotype.Component @Order(0) @@ -33,7 +33,7 @@ class TestImplHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(POST, "/api/test-impl/notification")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/test-impl/notification")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/audit/build.gradle b/backend/audit/build.gradle index 416d2753f5..0af32427a2 100644 --- a/backend/audit/build.gradle +++ b/backend/audit/build.gradle @@ -64,9 +64,9 @@ dependencies { implementation "org.springframework.boot:spring-boot-autoconfigure" implementation "org.liquibase:liquibase-core:${liquibaseVersion}" - implementation "org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}" + implementation "org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "org.hibernate.orm:hibernate-core:${hibernateCoreVersion}" diff --git a/backend/audit/src/main/java/com/ritense/audit/autoconfigure/AuditAutoConfiguration.java b/backend/audit/src/main/java/com/ritense/audit/autoconfigure/AuditAutoConfiguration.java index 3e8ab41f2a..5a16c578c9 100644 --- a/backend/audit/src/main/java/com/ritense/audit/autoconfigure/AuditAutoConfiguration.java +++ b/backend/audit/src/main/java/com/ritense/audit/autoconfigure/AuditAutoConfiguration.java @@ -39,7 +39,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; diff --git a/backend/audit/src/test/java/com/ritense/audit/domain/event/AuditEventJsonSerializingTest.java b/backend/audit/src/test/java/com/ritense/audit/domain/event/AuditEventJsonSerializingTest.java index 05dc19fae3..5bcac8da07 100644 --- a/backend/audit/src/test/java/com/ritense/audit/domain/event/AuditEventJsonSerializingTest.java +++ b/backend/audit/src/test/java/com/ritense/audit/domain/event/AuditEventJsonSerializingTest.java @@ -43,7 +43,7 @@ public class AuditEventJsonSerializingTest extends AbstractTestHelper { @BeforeEach public void setUp() throws IOException { - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); jsonString = TestHelper.getResourceAsString("json/event/TestEvent.json"); } diff --git a/backend/audit/src/test/java/com/ritense/audit/domain/event/TaskCompletedJsonSerializingTest.java b/backend/audit/src/test/java/com/ritense/audit/domain/event/TaskCompletedJsonSerializingTest.java index 02cea9899d..5f6a120ffa 100644 --- a/backend/audit/src/test/java/com/ritense/audit/domain/event/TaskCompletedJsonSerializingTest.java +++ b/backend/audit/src/test/java/com/ritense/audit/domain/event/TaskCompletedJsonSerializingTest.java @@ -44,7 +44,7 @@ public class TaskCompletedJsonSerializingTest extends AbstractTestHelper { @BeforeEach public void setUp() throws IOException { - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); jsonString = TestHelper.getResourceAsString("json/event/TaskCompletedEvent.json"); } diff --git a/backend/audit/src/test/resources/json/event/TaskCompletedEvent.json b/backend/audit/src/test/resources/json/event/TaskCompletedEvent.json index 4ca2b81db2..f11406e60b 100644 --- a/backend/audit/src/test/resources/json/event/TaskCompletedEvent.json +++ b/backend/audit/src/test/resources/json/event/TaskCompletedEvent.json @@ -3,10 +3,10 @@ "id": "edb1a672-4ba1-4e79-a5ee-b9658c55fe52", "businessKey": null, "origin": "somewhere", - "occurredOn": "2019-03-18T14:17:11.639Z", + "occurredOn": "2019-03-18T14:17:11.639", "user": "somebody", "assignee": "test@test.com", - "createdOn": "2019-03-18T14:17:11.639Z", + "createdOn": "2019-03-18T14:17:11.639", "taskId": "taskId", "taskName": "aTaskName", "processDefinitionId": "aProcessDefinitionId", diff --git a/backend/audit/src/test/resources/json/event/TestEvent.json b/backend/audit/src/test/resources/json/event/TestEvent.json index e92d46e539..3736d9a68b 100644 --- a/backend/audit/src/test/resources/json/event/TestEvent.json +++ b/backend/audit/src/test/resources/json/event/TestEvent.json @@ -2,7 +2,7 @@ "className": "com.ritense.audit.domain.event.TestEvent", "id": "edb1a672-4ba1-4e79-a5ee-b9658c55fe52", "origin": "somewhere", - "occurredOn": "2019-03-18T14:17:11.639Z", + "occurredOn": "2019-03-18T14:17:11.639", "user": "somebody", "name": "John Doe", "age": 21, diff --git a/backend/authorization/src/main/kotlin/com/ritense/authorization/autoconfigure/AuthorizationAutoConfiguration.kt b/backend/authorization/src/main/kotlin/com/ritense/authorization/autoconfigure/AuthorizationAutoConfiguration.kt index e6873a2eae..e2faa1f5dc 100644 --- a/backend/authorization/src/main/kotlin/com/ritense/authorization/autoconfigure/AuthorizationAutoConfiguration.kt +++ b/backend/authorization/src/main/kotlin/com/ritense/authorization/autoconfigure/AuthorizationAutoConfiguration.kt @@ -46,7 +46,7 @@ import com.ritense.valtimo.contract.authorization.UserManagementServiceHolder import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Lazy import org.springframework.core.Ordered.HIGHEST_PRECEDENCE diff --git a/backend/authorization/src/main/kotlin/com/ritense/authorization/permission/condition/PermissionCondition.kt b/backend/authorization/src/main/kotlin/com/ritense/authorization/permission/condition/PermissionCondition.kt index 2549ad1ea7..5d456d2723 100644 --- a/backend/authorization/src/main/kotlin/com/ritense/authorization/permission/condition/PermissionCondition.kt +++ b/backend/authorization/src/main/kotlin/com/ritense/authorization/permission/condition/PermissionCondition.kt @@ -17,6 +17,7 @@ package com.ritense.authorization.permission.condition import com.fasterxml.jackson.annotation.JsonPropertyOrder +import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.fasterxml.jackson.annotation.JsonView import com.ritense.authorization.permission.PermissionView @@ -34,6 +35,11 @@ import java.lang.reflect.Field property = "type", visible = true ) +@JsonSubTypes( + JsonSubTypes.Type(value = FieldPermissionCondition::class, name = "field"), + JsonSubTypes.Type(value = ContainerPermissionCondition::class, name = "container"), + JsonSubTypes.Type(value = ExpressionPermissionCondition::class, name = "expression") +) @JsonPropertyOrder("type") abstract class PermissionCondition( @field:JsonView(value = [PermissionView.RoleManagement::class, PermissionView.PermissionManagement::class]) diff --git a/backend/authorization/src/main/kotlin/com/ritense/authorization/specification/AuthorizationSpecification.kt b/backend/authorization/src/main/kotlin/com/ritense/authorization/specification/AuthorizationSpecification.kt index a930c54024..14c9df656d 100644 --- a/backend/authorization/src/main/kotlin/com/ritense/authorization/specification/AuthorizationSpecification.kt +++ b/backend/authorization/src/main/kotlin/com/ritense/authorization/specification/AuthorizationSpecification.kt @@ -252,12 +252,10 @@ abstract class AuthorizationSpecification( */ override fun toPredicate( root: Root, - query: CriteriaQuery<*>?, + query: CriteriaQuery<*>, criteriaBuilder: CriteriaBuilder ): Predicate? { - return query?.let { - toPredicate(root, it as AbstractQuery<*>, criteriaBuilder) - } + return toPredicate(root, query as AbstractQuery<*>, criteriaBuilder) } /** diff --git a/backend/authorization/src/main/kotlin/com/ritense/authorization/web/security/ValtimoAuthorizationHttpSecurityConfigurer.kt b/backend/authorization/src/main/kotlin/com/ritense/authorization/web/security/ValtimoAuthorizationHttpSecurityConfigurer.kt index 9071dba503..0d8a10bbd7 100644 --- a/backend/authorization/src/main/kotlin/com/ritense/authorization/web/security/ValtimoAuthorizationHttpSecurityConfigurer.kt +++ b/backend/authorization/src/main/kotlin/com/ritense/authorization/web/security/ValtimoAuthorizationHttpSecurityConfigurer.kt @@ -24,20 +24,20 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ValtimoAuthorizationHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, ROLES_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, ROLES_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$ROLES_URL/{oldRoleKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, ROLES_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$ROLES_URL/{roleKey}/permissions")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$ROLES_URL/{roleKey}/permissions")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/permissions/search")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/permissions")).authenticated() + requests.requestMatchers(pathPattern(GET, ROLES_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, ROLES_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$ROLES_URL/{oldRoleKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, ROLES_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$ROLES_URL/{roleKey}/permissions")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$ROLES_URL/{roleKey}/permissions")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/permissions/search")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/permissions")).authenticated() } } catch (e: Exception) { diff --git a/backend/authorization/src/test/kotlin/com/ritense/authorization/HibernateJsonMapperConfiguration.kt b/backend/authorization/src/test/kotlin/com/ritense/authorization/HibernateJsonMapperConfiguration.kt index 4290bcb5ec..3ca1d20550 100644 --- a/backend/authorization/src/test/kotlin/com/ritense/authorization/HibernateJsonMapperConfiguration.kt +++ b/backend/authorization/src/test/kotlin/com/ritense/authorization/HibernateJsonMapperConfiguration.kt @@ -19,7 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import org.hibernate.cfg.AvailableSettings import org.hibernate.type.format.jackson.JacksonJsonFormatMapper import org.springframework.boot.autoconfigure.AutoConfiguration -import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer +import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer import org.springframework.context.annotation.Bean @@ -28,7 +28,7 @@ class HibernateJsonMapperConfiguration { @Bean fun jsonFormatMapperCustomizer(objectMapper: ObjectMapper): HibernatePropertiesCustomizer { - return HibernatePropertiesCustomizer { properties: MutableMap -> + return HibernatePropertiesCustomizer { properties: MutableMap -> properties[AvailableSettings.JSON_FORMAT_MAPPER] = JacksonJsonFormatMapper(objectMapper) } } diff --git a/backend/authorization/src/test/kotlin/com/ritense/authorization/TestApplication.kt b/backend/authorization/src/test/kotlin/com/ritense/authorization/TestApplication.kt index 5150d9c4da..ca68a18fb7 100644 --- a/backend/authorization/src/test/kotlin/com/ritense/authorization/TestApplication.kt +++ b/backend/authorization/src/test/kotlin/com/ritense/authorization/TestApplication.kt @@ -23,7 +23,7 @@ import javax.sql.DataSource import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.boot.runApplication import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Import diff --git a/backend/building-block/build.gradle b/backend/building-block/build.gradle index 4ed57503e8..6d22e7bd37 100644 --- a/backend/building-block/build.gradle +++ b/backend/building-block/build.gradle @@ -80,7 +80,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-autoconfigure" implementation "org.liquibase:liquibase-core:${liquibaseVersion}" - implementation "org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}" + implementation "org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}" implementation "io.github.oshai:kotlin-logging:${kotlinLoggingVersion}" implementation "com.github.erosb:everit-json-schema:${everitJsonSchemaVersion}" @@ -88,7 +88,7 @@ dependencies { implementation "com.jayway.jsonpath:json-path:${jaywayJsonpathVersion}" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "org.hibernate.orm:hibernate-core:${hibernateCoreVersion}" implementation "org.apache.commons:commons-lang3:${commonsLangVersion}" diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/configuration/BuildingBlockAutoConfiguration.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/configuration/BuildingBlockAutoConfiguration.kt index c305962875..2e8cc3388d 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/configuration/BuildingBlockAutoConfiguration.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/configuration/BuildingBlockAutoConfiguration.kt @@ -113,7 +113,7 @@ import org.operaton.bpm.engine.RepositoryService import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.context.annotation.DependsOn diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/processlink/domain/BuildingBlockProcessLink.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/processlink/domain/BuildingBlockProcessLink.kt index 3681a55300..8ae0e37a0b 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/processlink/domain/BuildingBlockProcessLink.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/processlink/domain/BuildingBlockProcessLink.kt @@ -149,7 +149,7 @@ class BuildingBlockProcessLink( data class BuildingBlockInputMapping( val source: String, val target: String -) +) : java.io.Serializable enum class BuildingBlockSyncTiming { CONTINUOUS, @@ -160,4 +160,4 @@ data class BuildingBlockOutputMapping( val source: String, val target: String, val syncTiming: BuildingBlockSyncTiming = BuildingBlockSyncTiming.END -) +) : java.io.Serializable diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/security/config/BuildingBlockHttpSecurityConfigurer.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/security/config/BuildingBlockHttpSecurityConfigurer.kt index 68f3961a1e..a25047f248 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/security/config/BuildingBlockHttpSecurityConfigurer.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/security/config/BuildingBlockHttpSecurityConfigurer.kt @@ -24,98 +24,98 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class BuildingBlockHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, MANAGEMENT_BASE_PATH)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_BASE_PATH)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/document")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/document")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/draft")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/export")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/finalize")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/plugin")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/fields")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/process-definition/{processDefinitionId}/is-building-block")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, MANAGEMENT_BASE_PATH)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_BASE_PATH)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/document")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/document")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/draft")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/export")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/finalize")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/plugin")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/fields")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/process-definition/{processDefinitionId}/is-building-block")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition")).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition/{processDefinitionId}" ) ).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition/{processDefinitionId}" ) ).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/import")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/import")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/artwork")) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition/main/key" ) ).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition/{processDefinitionId}/main" ) ).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/process-definition/{processDefinitionId}" ) ).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "$VALUE_RESOLVER_BASE_PATH/{key}/version/{versionTag}/keys" ) ).hasAuthority(ADMIN) // Form option endpoint - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-option")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-option")) .hasAuthority(ADMIN) // Form management endpoints - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form")) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{formDefinitionId}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/name/{name}")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/name/{name}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{name}/exists")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form/{name}/exists")) .hasAuthority(ADMIN) // Form flow management endpoints - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition")) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_BASE_PATH/{key}/version/{versionTag}/form-flow-definition/{definitionKey}")) .hasAuthority(ADMIN) } } catch (e: Exception) { diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockDocumentDefinitionService.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockDocumentDefinitionService.kt index 4c7b5204d6..47148f33ca 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockDocumentDefinitionService.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockDocumentDefinitionService.kt @@ -89,7 +89,7 @@ class BuildingBlockDocumentDefinitionService( JsonSchemaDocumentDefinition::class.java, documentDefinition.id.toString(), { - definitionChecker.assertCanUpdateBuildingBlockDefinition(documentDefinition.id.buildingBlockDefinitionId()) + definitionChecker.assertCanUpdateBuildingBlockDefinition(documentDefinition.id!!.buildingBlockDefinitionId()) repository.saveAndFlush(documentDefinition) } diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockFormDefinitionService.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockFormDefinitionService.kt index 271a8d1713..6fd4b138dc 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockFormDefinitionService.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockFormDefinitionService.kt @@ -173,7 +173,7 @@ class BuildingBlockFormDefinitionService( "$sourceBuildingBlockDefinitionId to $targetBuildingBlockDefinitionId" } formDefinitionRepository.save(newForm) - mapping[oldForm.id] = newForm.id + mapping[oldForm.id!!] = newForm.id!! } return mapping } diff --git a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockJsonSchemaDocumentDefinitionExporter.kt b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockJsonSchemaDocumentDefinitionExporter.kt index e9340a0d34..a956e25857 100644 --- a/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockJsonSchemaDocumentDefinitionExporter.kt +++ b/backend/building-block/src/main/kotlin/com/ritense/buildingblock/service/BuildingBlockJsonSchemaDocumentDefinitionExporter.kt @@ -53,7 +53,7 @@ class BuildingBlockJsonSchemaDocumentDefinitionExporter( PATH.format( request.buildingBlockDefinitionId.key, formattedCaseDefinitionVersion, - documentDefinition.id.name() + documentDefinition.id!!.name() ), it.toByteArray() ) diff --git a/backend/building-block/src/test/kotlin/com/ritense/buildingblock/BaseIntegrationTest.kt b/backend/building-block/src/test/kotlin/com/ritense/buildingblock/BaseIntegrationTest.kt index d91f97f174..2927551e37 100644 --- a/backend/building-block/src/test/kotlin/com/ritense/buildingblock/BaseIntegrationTest.kt +++ b/backend/building-block/src/test/kotlin/com/ritense/buildingblock/BaseIntegrationTest.kt @@ -31,7 +31,7 @@ import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mockito.mockingDetails import org.mockito.kotlin.reset import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.ApplicationEventPublisher import org.springframework.test.context.bean.override.mockito.MockitoBean diff --git a/backend/building-block/src/test/kotlin/com/ritense/buildingblock/web/rest/BuildingBlockProcessResourceIT.kt b/backend/building-block/src/test/kotlin/com/ritense/buildingblock/web/rest/BuildingBlockProcessResourceIT.kt index 6bf9604a9f..17e86992d4 100644 --- a/backend/building-block/src/test/kotlin/com/ritense/buildingblock/web/rest/BuildingBlockProcessResourceIT.kt +++ b/backend/building-block/src/test/kotlin/com/ritense/buildingblock/web/rest/BuildingBlockProcessResourceIT.kt @@ -219,7 +219,7 @@ class BuildingBlockProcessResourceIT @Autowired constructor( eq(version), any(), any(), - eq("\"$processDefinitionId\""), + eq(processDefinitionId), eq(true), eq(false) ) diff --git a/backend/case/build.gradle b/backend/case/build.gradle index 4683cc2c88..d7c6063344 100644 --- a/backend/case/build.gradle +++ b/backend/case/build.gradle @@ -72,7 +72,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-autoconfigure" implementation "org.liquibase:liquibase-core:${liquibaseVersion}" - implementation "org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}" + implementation "org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}" implementation "io.github.oshai:kotlin-logging:${kotlinLoggingVersion}" implementation "com.github.erosb:everit-json-schema:${everitJsonSchemaVersion}" @@ -80,7 +80,7 @@ dependencies { implementation "com.jayway.jsonpath:json-path:${jaywayJsonpathVersion}" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "org.hibernate.orm:hibernate-core:${hibernateCoreVersion}" implementation "org.apache.commons:commons-lang3:${commonsLangVersion}" diff --git a/backend/case/src/main/java/com/ritense/document/autoconfigure/DocumentAutoConfiguration.java b/backend/case/src/main/java/com/ritense/document/autoconfigure/DocumentAutoConfiguration.java index 5da1db9bdd..f31fd7af0e 100644 --- a/backend/case/src/main/java/com/ritense/document/autoconfigure/DocumentAutoConfiguration.java +++ b/backend/case/src/main/java/com/ritense/document/autoconfigure/DocumentAutoConfiguration.java @@ -67,7 +67,7 @@ import javax.annotation.Nullable; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; diff --git a/backend/case/src/main/java/com/ritense/document/security/config/DocumentDefinitionHttpSecurityConfigurer.java b/backend/case/src/main/java/com/ritense/document/security/config/DocumentDefinitionHttpSecurityConfigurer.java index 5af8c761a4..35b6739d6a 100644 --- a/backend/case/src/main/java/com/ritense/document/security/config/DocumentDefinitionHttpSecurityConfigurer.java +++ b/backend/case/src/main/java/com/ritense/document/security/config/DocumentDefinitionHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -35,33 +35,33 @@ public class DocumentDefinitionHttpSecurityConfigurer implements HttpSecurityCon public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, DEFINITION_URL)) + requests.requestMatchers(pathPattern(GET, DEFINITION_URL)) .authenticated() - .requestMatchers(antMatcher(GET, DEFINITION_URL)) + .requestMatchers(pathPattern(GET, DEFINITION_URL)) .authenticated() - .requestMatchers(antMatcher(POST, "/api/management/v1/document-definition-template")) + .requestMatchers(pathPattern(POST, "/api/management/v1/document-definition-template")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, DEFINITION_URL + "/{name}")) + .requestMatchers(pathPattern(GET, DEFINITION_URL + "/{name}")) .authenticated() - .requestMatchers(antMatcher(GET, DEFINITION_URL + "/open/count")) + .requestMatchers(pathPattern(GET, DEFINITION_URL + "/open/count")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/document-definition")) + .requestMatchers(pathPattern(GET, "/api/management/v1/document-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/document-definition/{name}")) + .requestMatchers(pathPattern(GET, "/api/management/v1/document-definition/{name}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/document-definition")) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/document-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/document-definition")) + .requestMatchers(pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/document-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/document-definition/{name}/version")) + .requestMatchers(pathPattern(GET, "/api/management/v1/document-definition/{name}/version")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, DEFINITION_URL)) + .requestMatchers(pathPattern(POST, DEFINITION_URL)) .hasAuthority(ADMIN) // Deprecated since v11 - .requestMatchers(antMatcher(POST, "/api/management/v1/document-definition")) + .requestMatchers(pathPattern(POST, "/api/management/v1/document-definition")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, DEFINITION_URL + "/{name}")) + .requestMatchers(pathPattern(DELETE, DEFINITION_URL + "/{name}")) .hasAuthority(ADMIN) // Deprecated since v11 - .requestMatchers(antMatcher(DELETE, "/api/management/v1/document-definition/{name}")) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/document-definition/{name}")) .hasAuthority(ADMIN) ); } catch (Exception e) { diff --git a/backend/case/src/main/java/com/ritense/document/security/config/DocumentHttpSecurityConfigurer.java b/backend/case/src/main/java/com/ritense/document/security/config/DocumentHttpSecurityConfigurer.java index 6cedeccfe6..e381ef9eac 100644 --- a/backend/case/src/main/java/com/ritense/document/security/config/DocumentHttpSecurityConfigurer.java +++ b/backend/case/src/main/java/com/ritense/document/security/config/DocumentHttpSecurityConfigurer.java @@ -20,7 +20,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -32,18 +32,18 @@ public class DocumentHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/document/{id}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/document/{id}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/document")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document/{document-id}/resource/{resource-id}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/document/{document-id}/resource/{resource-id}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document/{documentId}/assign")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document/assign")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document/{documentId}/unassign")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{document-id}/candidate-user")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document/candidate-user")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{document-id}/candidate-team")).authenticated()); + requests.requestMatchers(pathPattern(GET, "/api/v1/document/{id}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/document/{id}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/document")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document/{document-id}/resource/{resource-id}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/document/{document-id}/resource/{resource-id}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document/{documentId}/assign")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document/assign")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document/{documentId}/unassign")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{document-id}/candidate-user")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document/candidate-user")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{document-id}/candidate-team")).authenticated()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/case/src/main/java/com/ritense/document/security/config/DocumentSearchHttpSecurityConfigurer.java b/backend/case/src/main/java/com/ritense/document/security/config/DocumentSearchHttpSecurityConfigurer.java index b46326f157..e6eeb2728a 100644 --- a/backend/case/src/main/java/com/ritense/document/security/config/DocumentSearchHttpSecurityConfigurer.java +++ b/backend/case/src/main/java/com/ritense/document/security/config/DocumentSearchHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -35,13 +35,13 @@ public class DocumentSearchHttpSecurityConfigurer implements HttpSecurityConfigu public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/document-search")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document-definition/{name}/search")).authenticated() - .requestMatchers(antMatcher(POST, FIELDS_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, FIELDS_URL)).authenticated() - .requestMatchers(antMatcher(PUT, FIELDS_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, FIELDS_URL)).hasAuthority( ADMIN) - .requestMatchers(antMatcher( + requests.requestMatchers(pathPattern(POST, "/api/v1/document-search")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/document-definition/{name}/search")).authenticated() + .requestMatchers(pathPattern(POST, FIELDS_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, FIELDS_URL)).authenticated() + .requestMatchers(pathPattern(PUT, FIELDS_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, FIELDS_URL)).hasAuthority( ADMIN) + .requestMatchers(pathPattern( GET, "/api/management/v1/document-search/{documentDefinitionName}/fields")).hasAuthority(ADMIN)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/case/src/main/java/com/ritense/document/security/config/DocumentSnapshotHttpSecurityConfigurer.java b/backend/case/src/main/java/com/ritense/document/security/config/DocumentSnapshotHttpSecurityConfigurer.java index cae06e4c46..a6fba32fee 100644 --- a/backend/case/src/main/java/com/ritense/document/security/config/DocumentSnapshotHttpSecurityConfigurer.java +++ b/backend/case/src/main/java/com/ritense/document/security/config/DocumentSnapshotHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.document.security.config; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,8 +29,8 @@ public class DocumentSnapshotHttpSecurityConfigurer implements HttpSecurityConfi public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/document-snapshot/{id}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document-snapshot")).authenticated()); + requests.requestMatchers(pathPattern(GET, "/api/v1/document-snapshot/{id}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document-snapshot")).authenticated()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/case/src/main/kotlin/com/ritense/case/configuration/CaseAutoConfiguration.kt b/backend/case/src/main/kotlin/com/ritense/case/configuration/CaseAutoConfiguration.kt index 28ebbfa7ad..4ba105cd92 100644 --- a/backend/case/src/main/kotlin/com/ritense/case/configuration/CaseAutoConfiguration.kt +++ b/backend/case/src/main/kotlin/com/ritense/case/configuration/CaseAutoConfiguration.kt @@ -81,7 +81,7 @@ import org.springframework.beans.factory.ObjectProvider import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Lazy diff --git a/backend/case/src/main/kotlin/com/ritense/case/security/config/CaseHttpSecurityConfigurer.kt b/backend/case/src/main/kotlin/com/ritense/case/security/config/CaseHttpSecurityConfigurer.kt index bb695268d0..900d03c032 100644 --- a/backend/case/src/main/kotlin/com/ritense/case/security/config/CaseHttpSecurityConfigurer.kt +++ b/backend/case/src/main/kotlin/com/ritense/case/security/config/CaseHttpSecurityConfigurer.kt @@ -26,102 +26,102 @@ import org.springframework.http.HttpMethod.PATCH import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class CaseHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, LIST_COLUMN_URL)).authenticated() - .requestMatchers(antMatcher(POST, LIST_COLUMN_URL)).hasAuthority(ADMIN) // Deprecated - .requestMatchers(antMatcher(PUT, LIST_COLUMN_URL)).hasAuthority(ADMIN) // Deprecated - .requestMatchers(antMatcher(DELETE, "$LIST_COLUMN_URL/{columnKey}")) + requests.requestMatchers(pathPattern(GET, LIST_COLUMN_URL)).authenticated() + .requestMatchers(pathPattern(POST, LIST_COLUMN_URL)).hasAuthority(ADMIN) // Deprecated + .requestMatchers(pathPattern(PUT, LIST_COLUMN_URL)).hasAuthority(ADMIN) // Deprecated + .requestMatchers(pathPattern(DELETE, "$LIST_COLUMN_URL/{columnKey}")) .hasAuthority(ADMIN) // Deprecated - .requestMatchers(antMatcher(GET, "/api/v1/case-definition")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/version")) + .requestMatchers(pathPattern(GET, "/api/v1/case-definition")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/version")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/settings")) + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/settings")) .authenticated() .requestMatchers( - antMatcher( + pathPattern( GET, "/api/v1/case-definition/{caseDefinitionkey}/version/{caseDefinitionVersionTag}/tab" ) ).authenticated() // Deprecated - .requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/tab")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/case/{caseDefinitionName}/search")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/case/{caseDefinitionKey}/stored-quick-search")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/case/{caseDefinitionKey}/stored-quick-search/{title}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case/{caseDefinitionKey}/stored-quick-search")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/case/{caseDefinitionName}/export")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case/{caseDefinitionKey}/hidden-list-column")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/case/{caseDefinitionKey}/hidden-list-column")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/configuration-issues")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/settings")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PATCH, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/settings")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/active")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PATCH, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case-definition/draft")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case-definition/{key}/version/{version}/finalize")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_CASE_LIST_COLUMN_URL/{columnKey}")) + .requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/tab")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/case/{caseDefinitionName}/search")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/case/{caseDefinitionKey}/stored-quick-search")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/case/{caseDefinitionKey}/stored-quick-search/{title}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case/{caseDefinitionKey}/stored-quick-search")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/case/{caseDefinitionName}/export")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case/{caseDefinitionKey}/hidden-list-column")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/case/{caseDefinitionKey}/hidden-list-column")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/configuration-issues")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/settings")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PATCH, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/settings")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/active")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PATCH, "/api/management/v1/case-definition/{key}/version/{version}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case-definition/draft")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case-definition/{key}/version/{version}/finalize")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, MANAGEMENT_CASE_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_CASE_LIST_COLUMN_URL/{columnKey}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, CASE_COLUMN_URL)).authenticated() - .requestMatchers(antMatcher(GET, MANAGEMENT_TASK_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_TASK_LIST_COLUMN_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_TASK_LIST_COLUMN_V2_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_TASK_LIST_COLUMN_URL/{columnKey}")) + .requestMatchers(pathPattern(GET, CASE_COLUMN_URL)).authenticated() + .requestMatchers(pathPattern(GET, MANAGEMENT_TASK_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_TASK_LIST_COLUMN_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_TASK_LIST_COLUMN_V2_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_TASK_LIST_COLUMN_URL/{columnKey}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_TASK_LIST_COLUMN_URL/{columnKey}")) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_TASK_LIST_COLUMN_URL/{columnKey}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_TAB_URL/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, MANAGEMENT_TAB_URL)).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/case/{caseDefinitionName}/version/{caseDefinitionVersion}/export" ) ).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case/import")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case/import/preview")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/check")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "$MANAGEMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}/widget/{widgetKey}")) + .requestMatchers(pathPattern(POST, "/api/management/v1/case/import")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case/import/preview")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/check")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "$MANAGEMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}/widget/{widgetKey}")) .hasAuthority(USER) - .requestMatchers(antMatcher(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(USER) - .requestMatchers(antMatcher(POST, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}/widget/{widgetKey}")) + .requestMatchers(pathPattern(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}")).hasAuthority(USER) + .requestMatchers(pathPattern(POST, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, MANAGEMENT_HEADER_WIDGET_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$DOCUMENT_WIDGET_TAB_URL/{tabKey}/widget/{widgetKey}")) .hasAuthority(USER) - .requestMatchers(antMatcher(GET, HEADER_WIDGET_URL)) + .requestMatchers(pathPattern(GET, HEADER_WIDGET_URL)) .hasAuthority(USER) - .requestMatchers(antMatcher(GET, "$HEADER_WIDGET_URL/data")).hasAuthority(USER) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{key}/version/{version}/finalizable")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, STARTABLE_ITEMS_PATH)).authenticated() - .requestMatchers(antMatcher(GET, MANAGEMENT_STARTABLE_ITEMS_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, MANAGEMENT_STARTABLE_ITEMS_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/order")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}/properties")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/properties")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$HEADER_WIDGET_URL/data")).hasAuthority(USER) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{key}/version/{version}/finalizable")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, STARTABLE_ITEMS_PATH)).authenticated() + .requestMatchers(pathPattern(GET, MANAGEMENT_STARTABLE_ITEMS_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, MANAGEMENT_STARTABLE_ITEMS_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/order")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}/properties")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/properties")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}/version/{versionTag}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "$MANAGEMENT_STARTABLE_ITEMS_URL/{itemKey}")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/case/src/main/kotlin/com/ritense/case_/configuration/CaseWidgetAutoConfiguration.kt b/backend/case/src/main/kotlin/com/ritense/case_/configuration/CaseWidgetAutoConfiguration.kt index 55ef2011bb..fb26486936 100644 --- a/backend/case/src/main/kotlin/com/ritense/case_/configuration/CaseWidgetAutoConfiguration.kt +++ b/backend/case/src/main/kotlin/com/ritense/case_/configuration/CaseWidgetAutoConfiguration.kt @@ -64,7 +64,7 @@ import com.ritense.widget.map.geojson.GeoJsonMapper import jakarta.validation.Validator import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.data.jpa.repository.config.EnableJpaRepositories diff --git a/backend/case/src/main/kotlin/com/ritense/document/exporter/JsonSchemaDocumentDefinitionExporter.kt b/backend/case/src/main/kotlin/com/ritense/document/exporter/JsonSchemaDocumentDefinitionExporter.kt index e1c6fcb571..af73bae643 100644 --- a/backend/case/src/main/kotlin/com/ritense/document/exporter/JsonSchemaDocumentDefinitionExporter.kt +++ b/backend/case/src/main/kotlin/com/ritense/document/exporter/JsonSchemaDocumentDefinitionExporter.kt @@ -66,7 +66,7 @@ class JsonSchemaDocumentDefinitionExporter( exportFile, setOf( FormDefinitionExportRequest( - documentDefinition.id.name() + ".summary", + documentDefinition.id!!.name() + ".summary", request.caseDefinitionId, false ) diff --git a/backend/case/src/main/kotlin/com/ritense/document/security/CaseTagHttpSecurityConfigurer.kt b/backend/case/src/main/kotlin/com/ritense/document/security/CaseTagHttpSecurityConfigurer.kt index 9ce7b29883..c1398294a4 100644 --- a/backend/case/src/main/kotlin/com/ritense/document/security/CaseTagHttpSecurityConfigurer.kt +++ b/backend/case/src/main/kotlin/com/ritense/document/security/CaseTagHttpSecurityConfigurer.kt @@ -29,26 +29,26 @@ class CaseTagHttpSecurityConfigurer : AuthorizeRequestsHttpSecurityConfigurer() override fun authorizeHttpRequests(requests: AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry) { requests - .antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/case-tag").authenticated() - .antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag") + .pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/case-tag").authenticated() + .pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag") .authenticated() - .antMatcher( + .pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag" ).hasAuthority(ADMIN) - .antMatcher( + .pathPattern( POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag" ).hasAuthority(ADMIN) - .antMatcher( + .pathPattern( PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag" ).hasAuthority(ADMIN) - .antMatcher( + .pathPattern( PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag/{caseTagKey}" ).hasAuthority(ADMIN) - .antMatcher( + .pathPattern( DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/case-tag/{caseTagKey}" ).hasAuthority(ADMIN) diff --git a/backend/case/src/main/kotlin/com/ritense/document/security/DocumentMigrationHttpSecurityConfigurer.kt b/backend/case/src/main/kotlin/com/ritense/document/security/DocumentMigrationHttpSecurityConfigurer.kt index 006130ce84..26858d41fc 100644 --- a/backend/case/src/main/kotlin/com/ritense/document/security/DocumentMigrationHttpSecurityConfigurer.kt +++ b/backend/case/src/main/kotlin/com/ritense/document/security/DocumentMigrationHttpSecurityConfigurer.kt @@ -26,7 +26,7 @@ class DocumentMigrationHttpSecurityConfigurer : AuthorizeRequestsHttpSecurityCon override fun authorizeHttpRequests(requests: AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry) { requests - .antMatcher(POST, "/api/management/v1/document-definition/migration/conflicts").hasAuthority(ADMIN) - .antMatcher(POST, "/api/management/v1/document-definition/migrate").hasAuthority(ADMIN) + .pathPattern(POST, "/api/management/v1/document-definition/migration/conflicts").hasAuthority(ADMIN) + .pathPattern(POST, "/api/management/v1/document-definition/migrate").hasAuthority(ADMIN) } } \ No newline at end of file diff --git a/backend/case/src/main/kotlin/com/ritense/document/security/InternalCaseHttpSecurityConfigurer.kt b/backend/case/src/main/kotlin/com/ritense/document/security/InternalCaseHttpSecurityConfigurer.kt index d63f52648b..5aa1b487ab 100644 --- a/backend/case/src/main/kotlin/com/ritense/document/security/InternalCaseHttpSecurityConfigurer.kt +++ b/backend/case/src/main/kotlin/com/ritense/document/security/InternalCaseHttpSecurityConfigurer.kt @@ -29,11 +29,11 @@ class InternalCaseHttpSecurityConfigurer : AuthorizeRequestsHttpSecurityConfigur override fun authorizeHttpRequests(requests: AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry) { requests - .antMatcher(GET, "/api/v1/case-definition/{caseDefinitionName}/internal-status").authenticated() - .antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) - .antMatcher(POST, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) - .antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) - .antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status/{internalStatusKey}").hasAuthority(ADMIN) - .antMatcher(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status/{internalStatusKey}").hasAuthority(ADMIN) + .pathPattern(GET, "/api/v1/case-definition/{caseDefinitionName}/internal-status").authenticated() + .pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) + .pathPattern(POST, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) + .pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status").hasAuthority(ADMIN) + .pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status/{internalStatusKey}").hasAuthority(ADMIN) + .pathPattern(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/internal-status/{internalStatusKey}").hasAuthority(ADMIN) } } \ No newline at end of file diff --git a/backend/case/src/main/kotlin/com/ritense/document/service/DocumentMigrationService.kt b/backend/case/src/main/kotlin/com/ritense/document/service/DocumentMigrationService.kt index dc56d8a018..d325084e82 100644 --- a/backend/case/src/main/kotlin/com/ritense/document/service/DocumentMigrationService.kt +++ b/backend/case/src/main/kotlin/com/ritense/document/service/DocumentMigrationService.kt @@ -218,7 +218,7 @@ class DocumentMigrationService( patch: DocumentMigrationPatch, sourceValue: SourceValue? = null ): MutableMap { - val contextMap: MutableMap = applicationContext.getBeansWithAnnotation(PublicBean::class.java) + val contextMap: MutableMap = applicationContext.getBeansWithAnnotation(PublicBean::class.java).toMutableMap() contextMap["source"] = source contextMap["target"] = target contextMap["builder"] = builder diff --git a/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentDefinitionIdJsonSerializingTest.java b/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentDefinitionIdJsonSerializingTest.java index c0718930ab..5fb1ee677b 100644 --- a/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentDefinitionIdJsonSerializingTest.java +++ b/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentDefinitionIdJsonSerializingTest.java @@ -40,7 +40,7 @@ class JsonSchemaDocumentDefinitionIdJsonSerializingTest { @BeforeEach void setUp() { ObjectMapper objectMapper = MapperSingleton.INSTANCE.get(); - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); } @Test diff --git a/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentIdJsonSerializingTest.java b/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentIdJsonSerializingTest.java index fd8cbfe5e9..d441f0c616 100644 --- a/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentIdJsonSerializingTest.java +++ b/backend/case/src/test/java/com/ritense/document/domain/impl/JsonSchemaDocumentIdJsonSerializingTest.java @@ -40,7 +40,7 @@ public class JsonSchemaDocumentIdJsonSerializingTest { @BeforeEach public void setUp() { ObjectMapper objectMapper = MapperSingleton.INSTANCE.get(); - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); } @Test diff --git a/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationJsonSerializingTest.java b/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationJsonSerializingTest.java index 3a8bdaae79..aa832165e3 100644 --- a/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationJsonSerializingTest.java +++ b/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationJsonSerializingTest.java @@ -41,7 +41,7 @@ public class DocumentRelationJsonSerializingTest { @BeforeEach public void setUp() { ObjectMapper objectMapper = MapperSingleton.INSTANCE.get(); - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); jsonString = """ { \t"id": "91e750e1-53ab-4922-9979-6a2dacd009cf", diff --git a/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationListJsonSerializingTest.java b/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationListJsonSerializingTest.java index 9cb2fc15c8..c4f401c0ff 100644 --- a/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationListJsonSerializingTest.java +++ b/backend/case/src/test/java/com/ritense/document/domain/impl/relation/DocumentRelationListJsonSerializingTest.java @@ -42,7 +42,7 @@ public class DocumentRelationListJsonSerializingTest { @BeforeEach public void setUp() { ObjectMapper objectMapper = MapperSingleton.INSTANCE.get(); - JacksonTester.initFields(this, objectMapper); + JacksonTester.initFields(this, tools.jackson.databind.json.JsonMapper.builder().build()); jsonString = """ [{ \t"id": "91e750e1-53ab-4922-9979-6a2dacd009cf", diff --git a/backend/case/src/test/java/com/ritense/document/domain/impl/request/ModifyJsonSchemaDocumentRequestJsonSerializingTestImpl.java b/backend/case/src/test/java/com/ritense/document/domain/impl/request/ModifyJsonSchemaDocumentRequestJsonSerializingTestImpl.java index 1fc0224a0b..ef57db62fd 100644 --- a/backend/case/src/test/java/com/ritense/document/domain/impl/request/ModifyJsonSchemaDocumentRequestJsonSerializingTestImpl.java +++ b/backend/case/src/test/java/com/ritense/document/domain/impl/request/ModifyJsonSchemaDocumentRequestJsonSerializingTestImpl.java @@ -25,21 +25,21 @@ import org.junit.jupiter.api.Test; import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; -import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.Jackson2Tester; import org.springframework.boot.test.json.JsonContent; import org.springframework.boot.test.json.ObjectContent; public class ModifyJsonSchemaDocumentRequestJsonSerializingTestImpl { private static final String UUID = "4bd8f762-0f83-42a6-8640-741b3f848752"; - private JacksonTester jacksonTester; + private Jackson2Tester jacksonTester; private String jsonString; private ObjectMapper objectMapper; @BeforeEach public void setUp() { objectMapper = MapperSingleton.INSTANCE.get(); - JacksonTester.initFields(this, objectMapper); + Jackson2Tester.initFields(this, objectMapper); jsonString = """ { \t"documentId": "4bd8f762-0f83-42a6-8640-741b3f848752", diff --git a/backend/case/src/test/java/com/ritense/document/web/rest/JsonSchemaDocumentResourceTest.java b/backend/case/src/test/java/com/ritense/document/web/rest/JsonSchemaDocumentResourceTest.java index b1fc0192cd..198b3db466 100644 --- a/backend/case/src/test/java/com/ritense/document/web/rest/JsonSchemaDocumentResourceTest.java +++ b/backend/case/src/test/java/com/ritense/document/web/rest/JsonSchemaDocumentResourceTest.java @@ -42,6 +42,7 @@ import com.ritense.document.web.rest.impl.JsonSchemaDocumentResource; import com.ritense.valtimo.contract.authentication.NamedUser; import com.ritense.valtimo.contract.authentication.Team; +import com.ritense.valtimo.contract.json.MapperSingleton; import com.ritense.valtimo.contract.utils.TestUtil; import java.util.List; import java.util.Optional; @@ -51,6 +52,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -68,6 +70,7 @@ void setUp() { mockMvc = MockMvcBuilders.standaloneSetup(documentResource) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) + .setMessageConverters(new MappingJackson2HttpMessageConverter(MapperSingleton.INSTANCE.get())) .build(); var content = new JsonDocumentContent("{\"firstName\": \"John\"}"); diff --git a/backend/case/src/test/kotlin/com/ritense/case/service/CaseDefinitionServiceTest.kt b/backend/case/src/test/kotlin/com/ritense/case/service/CaseDefinitionServiceTest.kt index 3c0414437d..076759da04 100644 --- a/backend/case/src/test/kotlin/com/ritense/case/service/CaseDefinitionServiceTest.kt +++ b/backend/case/src/test/kotlin/com/ritense/case/service/CaseDefinitionServiceTest.kt @@ -58,6 +58,7 @@ import org.springframework.beans.factory.ObjectProvider import org.springframework.data.domain.PageImpl import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort +import org.springframework.data.jpa.domain.Specification import java.util.Optional import java.util.stream.Stream import kotlin.test.assertEquals @@ -173,7 +174,7 @@ class CaseDefinitionServiceTest : BaseTest() { val spec = mock>() whenever(authorizationService.getAuthorizationSpecification(any(), eq(null))) .thenReturn(spec) - whenever(spec.and(any())).thenReturn(spec) + whenever(spec.and(any>())).thenReturn(spec) service.saveHiddenCaseListColumns( @@ -203,7 +204,7 @@ class CaseDefinitionServiceTest : BaseTest() { val spec = mock>() whenever(authorizationService.getAuthorizationSpecification(any(), eq(null))) .thenReturn(spec) - whenever(spec.and(any())).thenReturn(spec) + whenever(spec.and(any>())).thenReturn(spec) service.saveHiddenCaseListColumns( @@ -457,7 +458,7 @@ class CaseDefinitionServiceTest : BaseTest() { val spec = mock>() whenever(authorizationService.getAuthorizationSpecification(any(), eq(null))) .thenReturn(spec) - whenever(spec.and(any())).thenReturn(spec) + whenever(spec.and(any>())).thenReturn(spec) assertEquals( "Failed to delete case-definition. Case-definition with id: '$caseDefinitionId' is the global active version.", @@ -478,7 +479,7 @@ class CaseDefinitionServiceTest : BaseTest() { val spec = mock>() whenever(authorizationService.getAuthorizationSpecification(any(), eq(null))) .thenReturn(spec) - whenever(spec.and(any())).thenReturn(spec) + whenever(spec.and(any>())).thenReturn(spec) service.deleteCaseDefinition(caseDefinitionId) } @@ -488,7 +489,7 @@ class CaseDefinitionServiceTest : BaseTest() { val spec = mock>() whenever(authorizationService.getAuthorizationSpecification(any(), eq(null))) .thenReturn(spec) - whenever(spec.and(any())).thenReturn(spec) + whenever(spec.and(any>())).thenReturn(spec) val caseDefinitions = listOf( caseDefinition(name = "Alpha"), diff --git a/backend/case/src/test/kotlin/com/ritense/case/service/CaseTabServiceTest.kt b/backend/case/src/test/kotlin/com/ritense/case/service/CaseTabServiceTest.kt index 741e1f03c4..a0b6bf81f5 100644 --- a/backend/case/src/test/kotlin/com/ritense/case/service/CaseTabServiceTest.kt +++ b/backend/case/src/test/kotlin/com/ritense/case/service/CaseTabServiceTest.kt @@ -42,6 +42,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.springframework.context.ApplicationEventPublisher import org.springframework.data.domain.Sort +import org.springframework.data.jpa.domain.Specification import java.util.Optional @@ -77,7 +78,7 @@ class CaseTabServiceTest( whenever(documentDefinitionService.findByBlueprintId(caseDefinitionId)).thenReturn(Optional.of(mock())) val specMock = mock>() - whenever(specMock.and(any())).thenReturn(specMock) + whenever(specMock.and(any>())).thenReturn(specMock) whenever(authorizationService.getAuthorizationSpecification(any>(), anyOrNull())).thenReturn(specMock) whenever(caseTabRepository.findAll(any>(), any())).thenReturn(emptyList()) whenever(caseTabRepository.save(any())).thenReturn(caseTab) diff --git a/backend/case/src/test/kotlin/com/ritense/case/web/rest/CaseTabResourceIntTest.kt b/backend/case/src/test/kotlin/com/ritense/case/web/rest/CaseTabResourceIntTest.kt index 44346bf198..a2bfcf1b4c 100644 --- a/backend/case/src/test/kotlin/com/ritense/case/web/rest/CaseTabResourceIntTest.kt +++ b/backend/case/src/test/kotlin/com/ritense/case/web/rest/CaseTabResourceIntTest.kt @@ -70,7 +70,7 @@ class CaseTabResourceIntTest : BaseIntegrationTest() { val caseDefinitionName = "some-case-type" val document = createDocument(caseDefinitionName) mockMvc.perform( - get("/api/v1/document/{documentId}/tab", document.id.id) + get("/api/v1/document/{documentId}/tab", document.id!!.id) .contentType(MediaType.APPLICATION_JSON_VALUE) ).andExpect(status().isOk) .andExpect(MockMvcResultMatchers.jsonPath("$").isNotEmpty) @@ -90,7 +90,7 @@ class CaseTabResourceIntTest : BaseIntegrationTest() { val caseDefinitionName = "some-case-type" val document = createDocument(caseDefinitionName) mockMvc.perform( - get("/api/v1/document/{documentId}/tab", document.id.id) + get("/api/v1/document/{documentId}/tab", document.id!!.id) .contentType(MediaType.APPLICATION_JSON_VALUE) ).andExpect(status().isOk) .andExpect(MockMvcResultMatchers.jsonPath("$").isNotEmpty) @@ -106,7 +106,7 @@ class CaseTabResourceIntTest : BaseIntegrationTest() { val caseDefinitionName = "some-case-type" val document = createDocument(caseDefinitionName, "{\"key\": \"CONTEXT\"}") mockMvc.perform( - get("/api/v1/document/{documentId}/tab", document.id.id) + get("/api/v1/document/{documentId}/tab", document.id!!.id) .contentType(MediaType.APPLICATION_JSON_VALUE) ).andExpect(status().isOk) .andExpect(MockMvcResultMatchers.jsonPath("$").isNotEmpty) @@ -122,7 +122,7 @@ class CaseTabResourceIntTest : BaseIntegrationTest() { val caseDefinitionName = "some-case-type" val document = createDocument(caseDefinitionName) mockMvc.perform( - get("/api/v1/document/{documentId}/tab", document.id.id) + get("/api/v1/document/{documentId}/tab", document.id!!.id) .contentType(MediaType.APPLICATION_JSON_VALUE) ).andExpect(status().isOk) .andExpect(MockMvcResultMatchers.jsonPath("$").isEmpty) diff --git a/backend/case/src/test/kotlin/com/ritense/document/other/LostUpdateIntTest.kt b/backend/case/src/test/kotlin/com/ritense/document/other/LostUpdateIntTest.kt index b8be3a80fe..a780afecd9 100644 --- a/backend/case/src/test/kotlin/com/ritense/document/other/LostUpdateIntTest.kt +++ b/backend/case/src/test/kotlin/com/ritense/document/other/LostUpdateIntTest.kt @@ -64,7 +64,7 @@ internal class LostUpdateIntTest : BaseIntegrationTest() { @Test @WithMockUser(username = USERNAME, authorities = [ADMIN]) fun `should throw when Lost Update`(): Unit = runBlocking { - val documentId = createDocument("""{}""").id + val documentId = createDocument("""{}""").id!! val exceptions = (1..100).map { i -> async(Dispatchers.IO) { diff --git a/backend/case/src/test/kotlin/com/ritense/document/web/rest/DocumentDefinitionManagementResourceTest.kt b/backend/case/src/test/kotlin/com/ritense/document/web/rest/DocumentDefinitionManagementResourceTest.kt index 58cc40e519..10b660e88a 100644 --- a/backend/case/src/test/kotlin/com/ritense/document/web/rest/DocumentDefinitionManagementResourceTest.kt +++ b/backend/case/src/test/kotlin/com/ritense/document/web/rest/DocumentDefinitionManagementResourceTest.kt @@ -79,7 +79,7 @@ class DocumentDefinitionManagementResourceTest : BaseTest() { @Test fun shouldReturnSingleDefinitionRecordByNameAndVersion() { - val caseDefinitionId = definition.getId().caseDefinitionId() + val caseDefinitionId = definition.getId()!!.caseDefinitionId() whenever(documentDefinitionService.findByBlueprintId(caseDefinitionId)) .thenReturn(Optional.of(definition)) mockMvc.perform( @@ -97,7 +97,7 @@ class DocumentDefinitionManagementResourceTest : BaseTest() { @Test fun shouldReturnNoDefinitionRecordByNameAndVersion() { - val caseDefinitionId = definition.getId().caseDefinitionId() + val caseDefinitionId = definition.getId()!!.caseDefinitionId() whenever(documentDefinitionService.findByBlueprintId(caseDefinitionId)) .thenReturn(Optional.empty()) mockMvc.perform( diff --git a/backend/changelog/src/main/kotlin/com/ritense/valtimo/changelog/autoconfigure/ChangelogAutoConfiguration.kt b/backend/changelog/src/main/kotlin/com/ritense/valtimo/changelog/autoconfigure/ChangelogAutoConfiguration.kt index 9d591a345b..d8e2f1ab06 100644 --- a/backend/changelog/src/main/kotlin/com/ritense/valtimo/changelog/autoconfigure/ChangelogAutoConfiguration.kt +++ b/backend/changelog/src/main/kotlin/com/ritense/valtimo/changelog/autoconfigure/ChangelogAutoConfiguration.kt @@ -25,7 +25,7 @@ import com.ritense.valtimo.changelog.service.ChangelogService import jakarta.persistence.EntityManager import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order import org.springframework.core.env.Environment diff --git a/backend/command-handling/src/main/kotlin/com/ritense/commandhandling/SpringContextHelper.kt b/backend/command-handling/src/main/kotlin/com/ritense/commandhandling/SpringContextHelper.kt index 582bb0a9e2..f1b936529a 100644 --- a/backend/command-handling/src/main/kotlin/com/ritense/commandhandling/SpringContextHelper.kt +++ b/backend/command-handling/src/main/kotlin/com/ritense/commandhandling/SpringContextHelper.kt @@ -37,7 +37,7 @@ class SpringContextHelper : ApplicationContextAware { * @param beanClass * @return Object */ - fun getBean(beanClass: Class): T { + fun getBean(beanClass: Class): T { logger.trace { "Retrieving bean $beanClass" } return context?.getBean(beanClass) ?: throw IllegalStateException("Cannot getBean $beanClass").also { logger.error { it.message } diff --git a/backend/contract/build.gradle b/backend/contract/build.gradle index 8870bc7fd1..8648d494b4 100644 --- a/backend/contract/build.gradle +++ b/backend/contract/build.gradle @@ -41,7 +41,7 @@ dependencies { api "commons-codec:commons-codec:${commonsCodecVersion}" api "commons-validator:commons-validator:${commonsValidatorVersion}" api "com.fasterxml.jackson.module:jackson-module-kotlin" - api "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + api "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" api "org.springframework.security:spring-security-core" api "org.springframework.boot:spring-boot" @@ -56,6 +56,10 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-security" implementation "org.springframework.boot:spring-boot-starter-validation" implementation "org.springframework.boot:spring-boot-starter-oauth2-resource-server" + implementation "org.springframework.boot:spring-boot-security-oauth2-client" + api "org.springframework.boot:spring-boot-jackson2" + implementation "org.springframework.boot:spring-boot-restclient" + implementation "org.springframework.boot:spring-boot-webclient" implementation "com.fasterxml.jackson.module:jackson-module-blackbird" implementation "com.fasterxml.jackson.module:jackson-module-parameter-names" @@ -79,6 +83,7 @@ dependencies { testImplementation "org.mockito.kotlin:mockito-kotlin:${mockitoKotlinVersion}" implementation "org.liquibase:liquibase-core:${liquibaseVersion}" + implementation "org.springframework.boot:spring-boot-liquibase" } apply from: "gradle/publishing.gradle" diff --git a/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunner.java b/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunner.java index 022ef8260a..92548262fc 100644 --- a/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunner.java +++ b/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunner.java @@ -36,7 +36,7 @@ import liquibase.resource.ClassLoaderResourceAccessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties; public class LiquibaseRunner { diff --git a/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunnerAutoConfiguration.java b/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunnerAutoConfiguration.java index 5893833922..617816d077 100644 --- a/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunnerAutoConfiguration.java +++ b/backend/contract/src/main/java/com/ritense/valtimo/contract/config/LiquibaseRunnerAutoConfiguration.java @@ -21,9 +21,9 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration; +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties; +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; diff --git a/backend/contract/src/main/java/com/ritense/valtimo/contract/json/JacksonJsonSerializer.java b/backend/contract/src/main/java/com/ritense/valtimo/contract/json/JacksonJsonSerializer.java new file mode 100644 index 0000000000..e785581700 --- /dev/null +++ b/backend/contract/src/main/java/com/ritense/valtimo/contract/json/JacksonJsonSerializer.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015-2026 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ritense.valtimo.contract.json; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.hypersistence.utils.hibernate.type.util.JsonConfiguration; +import io.hypersistence.utils.hibernate.type.util.JsonSerializer; +import org.hibernate.internal.util.SerializationHelper; + +import java.io.Serializable; + +/** + * Custom Hypersistence JsonSerializer that clones JSON objects. + * Uses Java serialization when possible (preserves generic types in collections), + * falls back to Jackson for non-serializable objects. + */ +public class JacksonJsonSerializer implements JsonSerializer { + + @Override + public T clone(T object) { + if (object instanceof String) { + return object; + } + if (object instanceof JsonNode jsonNode) { + return (T) jsonNode.deepCopy(); + } + if (object instanceof Serializable) { + try { + return (T) SerializationHelper.clone((Serializable) object); + } catch (Exception e) { + // Fall back to Jackson cloning for Serializable objects that fail + } + } + ObjectMapper objectMapper = JsonConfiguration.INSTANCE.getObjectMapperWrapper().getObjectMapper(); + JsonNode tree = objectMapper.valueToTree(object); + return (T) objectMapper.convertValue(tree, object.getClass()); + } +} diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/ApacheRequestFactoryCustomizer.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/ApacheRequestFactoryCustomizer.kt index 666be95950..f8806f2563 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/ApacheRequestFactoryCustomizer.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/ApacheRequestFactoryCustomizer.kt @@ -16,7 +16,11 @@ package com.ritense.valtimo.contract.client -import org.springframework.boot.web.client.RestClientCustomizer +import org.apache.hc.client5.http.config.ConnectionConfig +import org.apache.hc.client5.http.impl.classic.HttpClients +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder +import org.apache.hc.core5.util.Timeout +import org.springframework.boot.restclient.RestClientCustomizer import org.springframework.http.client.BufferingClientHttpRequestFactory import org.springframework.http.client.HttpComponentsClientHttpRequestFactory import org.springframework.web.client.RestClient @@ -27,10 +31,17 @@ class ApacheRequestFactoryCustomizer( ) : RestClientCustomizer { override fun customize(restClientBuilder: RestClient.Builder) { - val apacheRequestFactory = HttpComponentsClientHttpRequestFactory() - valtimoHttpRestClientConfigurationProperties.connectTimeout.let { - apacheRequestFactory.setConnectTimeout(Duration.ofSeconds(it)) - } + val connectionManager = PoolingHttpClientConnectionManagerBuilder.create() + .setDefaultConnectionConfig( + ConnectionConfig.custom() + .setConnectTimeout(Timeout.ofSeconds(valtimoHttpRestClientConfigurationProperties.connectTimeout)) + .build() + ) + .build() + val httpClient = HttpClients.custom() + .setConnectionManager(connectionManager) + .build() + val apacheRequestFactory = HttpComponentsClientHttpRequestFactory(httpClient) valtimoHttpRestClientConfigurationProperties.connectionRequestTimeout.let { apacheRequestFactory.setConnectionRequestTimeout(Duration.ofSeconds(it)) } diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/HostDockerInternalRestClientCustomizer.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/HostDockerInternalRestClientCustomizer.kt index f5444a3867..ceec508918 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/HostDockerInternalRestClientCustomizer.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/HostDockerInternalRestClientCustomizer.kt @@ -18,8 +18,8 @@ package com.ritense.valtimo.contract.client import com.ritense.valtimo.contract.annotation.SkipComponentScan import com.ritense.valtimo.contract.io.FindReplaceInputStream -import org.springframework.boot.web.client.RestClientCustomizer -import org.springframework.boot.web.client.RestTemplateCustomizer +import org.springframework.boot.restclient.RestClientCustomizer +import org.springframework.boot.restclient.RestTemplateCustomizer import org.springframework.http.HttpHeaders import org.springframework.http.HttpRequest import org.springframework.http.MediaType.APPLICATION_JSON @@ -115,7 +115,7 @@ class HostDockerInternalRestClientCustomizer( override fun getHeaders(): HttpHeaders { val headers = HttpHeaders() headers.addAll(super.getHeaders()) - if (headers.contains("Content-Length")) { + if (headers.containsHeader("Content-Length")) { headers["Content-Length"] = newBody.size.toString() } return headers diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/LoggingWebClientCustomizer.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/LoggingWebClientCustomizer.kt index 1bdfc7973c..3a7d6a3f04 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/LoggingWebClientCustomizer.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/LoggingWebClientCustomizer.kt @@ -17,15 +17,15 @@ package com.ritense.valtimo.contract.client import io.netty.handler.logging.LogLevel -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer +import org.springframework.boot.webclient.WebClientCustomizer import org.springframework.http.client.reactive.ReactorClientHttpConnector import org.springframework.web.reactive.function.client.WebClient import reactor.netty.http.client.HttpClient import reactor.netty.transport.logging.AdvancedByteBufFormat class LoggingWebClientCustomizer: WebClientCustomizer { - override fun customize(webClientBuilder: WebClient.Builder?) { - webClientBuilder?.clientConnector( + override fun customize(webClientBuilder: WebClient.Builder) { + webClientBuilder.clientConnector( ReactorClientHttpConnector( HttpClient.create().wiretap( "reactor.netty.http.client.HttpClient", diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/RestClientAutoConfiguration.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/RestClientAutoConfiguration.kt index b99e58d9d2..6693598abe 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/RestClientAutoConfiguration.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/client/RestClientAutoConfiguration.kt @@ -16,18 +16,63 @@ package com.ritense.valtimo.contract.client +import com.fasterxml.jackson.databind.ObjectMapper import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.boot.restclient.RestClientCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Profile +import org.springframework.boot.autoconfigure.AutoConfigureBefore +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration +import org.springframework.http.converter.HttpMessageConverter +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer @AutoConfiguration +@AutoConfigureBefore(WebMvcAutoConfiguration::class) @EnableConfigurationProperties(ValtimoHttpRestClientConfigurationProperties::class) class RestClientAutoConfiguration { + @Bean + fun jackson2HttpMessageConverter(objectMapper: ObjectMapper): MappingJackson2HttpMessageConverter { + return MappingJackson2HttpMessageConverter(objectMapper) + } + + @Bean + fun jackson2RestClientCustomizer(jackson2HttpMessageConverter: MappingJackson2HttpMessageConverter): RestClientCustomizer { + return RestClientCustomizer { restClientBuilder -> + restClientBuilder.messageConverters { converters -> + addJackson2BeforeJackson3(converters, jackson2HttpMessageConverter) + } + } + } + + @Bean + fun jackson2WebMvcConfigurer(jackson2HttpMessageConverter: MappingJackson2HttpMessageConverter): WebMvcConfigurer { + return object : WebMvcConfigurer { + override fun extendMessageConverters(converters: MutableList>) { + addJackson2BeforeJackson3(converters, jackson2HttpMessageConverter) + } + } + } + + private fun addJackson2BeforeJackson3( + converters: MutableList>, + jackson2Converter: MappingJackson2HttpMessageConverter + ) { + val jackson3Index = converters.indexOfFirst { + it.javaClass.name == "org.springframework.http.converter.json.JacksonJsonHttpMessageConverter" + } + if (jackson3Index >= 0) { + converters.add(jackson3Index, jackson2Converter) + } else { + converters.add(jackson2Converter) + } + } + @Bean fun requestFactoryCustomizer( valtimoHttpRestClientConfigurationProperties: ValtimoHttpRestClientConfigurationProperties diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/conditions/Condition.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/conditions/Condition.kt index 9a3b397a35..d72ff36c3e 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/conditions/Condition.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/conditions/Condition.kt @@ -42,7 +42,7 @@ data class Condition>( @JsonAlias("queryValue") @JsonDeserialize(using = ComparableDeserializer::class) val value: T -) { +) : java.io.Serializable { fun isValid( expressionResolver: (String) -> Any? @@ -63,7 +63,7 @@ data class Condition>( val valueClass = if (resolvedValue != null) { resolvedValue::class.java as Class } else { - Any::class.java as Class + String::class.java as Class } val expression = pathExpressionFunction(valueClass, path, root, criteriaBuilder) diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/json/MapperSingleton.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/json/MapperSingleton.kt index 62c7ef043f..b5803916c3 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/json/MapperSingleton.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/json/MapperSingleton.kt @@ -21,7 +21,7 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer import com.ritense.valtimo.contract.json.serializer.PageSerializer import com.ritense.valtimo.contract.json.serializer.SortOrderSerializer import com.ritense.valtimo.contract.json.serializer.SortSerializer -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer +import org.springframework.boot.jackson2.autoconfigure.Jackson2ObjectMapperBuilderCustomizer import org.springframework.data.domain.Page import org.springframework.data.domain.Sort import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/AuthorizeRequestsHttpSecurityConfigurer.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/AuthorizeRequestsHttpSecurityConfigurer.kt index ab511a1673..ac3ef6d422 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/AuthorizeRequestsHttpSecurityConfigurer.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/AuthorizeRequestsHttpSecurityConfigurer.kt @@ -18,7 +18,7 @@ package com.ritense.valtimo.contract.security.config import org.springframework.http.HttpMethod import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer -import org.springframework.security.web.util.matcher.AntPathRequestMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher abstract class AuthorizeRequestsHttpSecurityConfigurer : HttpSecurityConfigurer { final override fun configure(http: HttpSecurity) { @@ -31,8 +31,8 @@ abstract class AuthorizeRequestsHttpSecurityConfigurer : HttpSecurityConfigurer abstract fun authorizeHttpRequests(requests: AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry) - fun AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry.antMatcher( + fun AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry.pathPattern( method: HttpMethod, pattern: String - ): AuthorizeHttpRequestsConfigurer.AuthorizedUrl = this.requestMatchers(AntPathRequestMatcher.antMatcher(method, pattern)) + ): AuthorizeHttpRequestsConfigurer.AuthorizedUrl = this.requestMatchers(PathPatternRequestMatcher.pathPattern(method, pattern)) } \ No newline at end of file diff --git a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/oauth2/NoOAuth2ClientsConfiguredCondition.kt b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/oauth2/NoOAuth2ClientsConfiguredCondition.kt index 15523ea07b..3546c23115 100644 --- a/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/oauth2/NoOAuth2ClientsConfiguredCondition.kt +++ b/backend/contract/src/main/kotlin/com/ritense/valtimo/contract/security/config/oauth2/NoOAuth2ClientsConfiguredCondition.kt @@ -18,14 +18,14 @@ package com.ritense.valtimo.contract.security.config.oauth2 import org.springframework.boot.autoconfigure.condition.ConditionMessage import org.springframework.boot.autoconfigure.condition.ConditionOutcome import org.springframework.boot.autoconfigure.condition.SpringBootCondition -import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties +import org.springframework.boot.security.oauth2.client.autoconfigure.OAuth2ClientProperties import org.springframework.boot.context.properties.bind.Bindable import org.springframework.boot.context.properties.bind.Binder import org.springframework.context.annotation.ConditionContext import org.springframework.core.env.Environment import org.springframework.core.type.AnnotatedTypeMetadata -// The opposite of: org.springframework.boot.autoconfigure.security.oauth2.client.ClientsConfiguredCondition +// The opposite of: org.springframework.boot.security.oauth2.client.autoconfigure.ClientsConfiguredCondition class NoOAuth2ClientsConfiguredCondition : SpringBootCondition() { override fun getMatchOutcome(context: ConditionContext, metadata: AnnotatedTypeMetadata): ConditionOutcome { val message = ConditionMessage.forCondition("No OAuth2 Clients Configured Condition") @@ -44,7 +44,7 @@ class NoOAuth2ClientsConfiguredCondition : SpringBootCondition() { private fun getRegistrations(environment: Environment): Map { return Binder.get(environment) .bind("spring.security.oauth2.client.registration", STRING_REGISTRATION_MAP) - .orElse(emptyMap()) + .orElse(emptyMap()) ?: emptyMap() } companion object { diff --git a/backend/contract/src/main/resources/hypersistence-utils.properties b/backend/contract/src/main/resources/hypersistence-utils.properties new file mode 100644 index 0000000000..b30346f56f --- /dev/null +++ b/backend/contract/src/main/resources/hypersistence-utils.properties @@ -0,0 +1 @@ +hypersistence.utils.json.serializer=com.ritense.valtimo.contract.json.JacksonJsonSerializer diff --git a/backend/core/build.gradle b/backend/core/build.gradle index 2b3f0d993b..eff90f05cb 100644 --- a/backend/core/build.gradle +++ b/backend/core/build.gradle @@ -81,6 +81,7 @@ dependencies { api ("org.operaton.bpm.springboot:operaton-bpm-spring-boot-starter-webapp:${operatonVersion}") { exclude group: "com.sun.xml.bind" } + api "org.springframework.boot:spring-boot-starter-jersey" // Operaton plugins implementation "org.operaton.bpm:operaton-engine-plugin-spin:${operatonVersion}" @@ -100,7 +101,7 @@ dependencies { implementation "com.fasterxml.jackson.datatype:jackson-datatype-json-org" implementation "com.fasterxml.jackson.datatype:jackson-datatype-hppc" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" - implementation "com.fasterxml.jackson.datatype:jackson-datatype-hibernate6" + implementation "com.fasterxml.jackson.datatype:jackson-datatype-hibernate7" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml" implementation "com.fasterxml.jackson.module:jackson-module-blackbird" implementation "com.fasterxml.jackson.module:jackson-module-parameter-names" diff --git a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ChoiceFieldAutoConfiguration.java b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ChoiceFieldAutoConfiguration.java index ca07adb485..196f48716c 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ChoiceFieldAutoConfiguration.java +++ b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ChoiceFieldAutoConfiguration.java @@ -24,7 +24,7 @@ import com.ritense.valtimo.web.rest.ChoiceFieldValueResource; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/EmailNotificationSettingsAutoConfiguration.java b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/EmailNotificationSettingsAutoConfiguration.java index 930a208b01..73647b1a68 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/EmailNotificationSettingsAutoConfiguration.java +++ b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/EmailNotificationSettingsAutoConfiguration.java @@ -22,7 +22,7 @@ import com.ritense.valtimo.emailnotificationsettings.web.rest.EmailNotificationSettingsResource; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/HttpSecurityAutoConfiguration.java b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/HttpSecurityAutoConfiguration.java index 47c445be54..17c4b425c5 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/HttpSecurityAutoConfiguration.java +++ b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/HttpSecurityAutoConfiguration.java @@ -53,7 +53,7 @@ import org.operaton.bpm.engine.IdentityService; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties; +import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointProperties; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; diff --git a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ValtimoAutoConfiguration.java b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ValtimoAutoConfiguration.java index 7770475204..0d8aaa008f 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ValtimoAutoConfiguration.java +++ b/backend/core/src/main/java/com/ritense/valtimo/autoconfigure/ValtimoAutoConfiguration.java @@ -90,7 +90,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; diff --git a/backend/core/src/main/java/com/ritense/valtimo/config/JacksonConfiguration.java b/backend/core/src/main/java/com/ritense/valtimo/config/JacksonConfiguration.java index 8d154974f0..cb5ce5fc08 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/config/JacksonConfiguration.java +++ b/backend/core/src/main/java/com/ritense/valtimo/config/JacksonConfiguration.java @@ -16,14 +16,14 @@ package com.ritense.valtimo.config; -import com.fasterxml.jackson.datatype.hibernate6.Hibernate6Module; +import com.fasterxml.jackson.datatype.hibernate7.Hibernate7Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.module.blackbird.BlackbirdModule; import com.ritense.valtimo.contract.json.MapperSingleton; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.boot.jackson2.autoconfigure.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; @AutoConfiguration @@ -54,8 +54,8 @@ public Jdk8Module jdk8Module() { * Support for Hibernate types in Jackson. */ @Bean - public Hibernate6Module hibernateModule() { - return new Hibernate6Module(); + public Hibernate7Module hibernateModule() { + return new Hibernate7Module(); } /* diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/AccountHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/AccountHttpSecurityConfigurer.java index ac78542572..5487b9c2be 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/AccountHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/AccountHttpSecurityConfigurer.java @@ -18,7 +18,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -30,10 +30,10 @@ public class AccountHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/account")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/account")).authenticated() .requestMatchers( - antMatcher(POST, "/api/v1/account/profile"), - antMatcher(POST,"/api/v1/account/change_password")).authenticated() + pathPattern(POST, "/api/v1/account/profile"), + pathPattern(POST,"/api/v1/account/change_password")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ApiLoginHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ApiLoginHttpSecurityConfigurer.java index 5f3c43dffe..b5d31cce55 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ApiLoginHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ApiLoginHttpSecurityConfigurer.java @@ -16,7 +16,7 @@ package com.ritense.valtimo.security.config; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -28,7 +28,7 @@ public class ApiLoginHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher("/api/v1/authenticate")).permitAll() + requests.requestMatchers(pathPattern("/api/v1/authenticate")).permitAll() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ChoiceFieldHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ChoiceFieldHttpSecurityConfigurer.java index 19c038b55a..a0a0509eca 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ChoiceFieldHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ChoiceFieldHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -34,24 +34,24 @@ public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests.requestMatchers( - antMatcher(GET, "/api/v1/choice-fields"), - antMatcher(GET, "/api/v1/choice-fields/{id}"), - antMatcher(GET, "/api/v1/choice-fields/name/{name}"), - antMatcher(GET, "/api/v2/choice-fields") + pathPattern(GET, "/api/v1/choice-fields"), + pathPattern(GET, "/api/v1/choice-fields/{id}"), + pathPattern(GET, "/api/v1/choice-fields/name/{name}"), + pathPattern(GET, "/api/v2/choice-fields") ).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/choice-fields")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/v1/choice-fields")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/v1/choice-fields/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/choice-fields")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/v1/choice-fields")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/v1/choice-fields/{id}")).hasAuthority(ADMIN) //choice-field-values - .requestMatchers(antMatcher(GET, "/api/v1/choice-field-values")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/choice-field-values")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/choice-field-values")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/v1/choice-field-values")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/choice-field-values/{id}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/choice-field-values/{id}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/choice-field-values/choice-field/{choicefield_name}/value/{value}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/choice-field-values/{choice_field_name}/values")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/choice-field-values/{choice_field_name}/values")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/choice-field-values")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v2/choice-field-values")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/choice-field-values")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/v1/choice-field-values")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/choice-field-values/{id}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/choice-field-values/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/choice-field-values/choice-field/{choicefield_name}/value/{value}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/choice-field-values/{choice_field_name}/values")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v2/choice-field-values/{choice_field_name}/values")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/CsrfHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/CsrfHttpSecurityConfigurer.java index c95502c370..91d5daeebb 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/CsrfHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/CsrfHttpSecurityConfigurer.java @@ -25,7 +25,7 @@ public class CsrfHttpSecurityConfigurer implements HttpSecurityConfigurer { @Override public void configure(HttpSecurity http) { try { - http.csrf().disable(); + http.csrf(csrf -> csrf.disable()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/EmailNotificationSettingsSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/EmailNotificationSettingsSecurityConfigurer.java index 2ab775be12..3cfd8deb1e 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/EmailNotificationSettingsSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/EmailNotificationSettingsSecurityConfigurer.java @@ -18,7 +18,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -30,8 +30,8 @@ public class EmailNotificationSettingsSecurityConfigurer implements HttpSecurity public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/email-notification-settings")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/email-notification-settings")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/email-notification-settings")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/email-notification-settings")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ErrorHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ErrorHttpSecurityConfigurer.java index 100e0e7b20..71e8bf19ed 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ErrorHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ErrorHttpSecurityConfigurer.java @@ -31,7 +31,7 @@ public ErrorHttpSecurityConfigurer(Http403ForbiddenEntryPoint http403ForbiddenEn @Override public void configure(HttpSecurity http) { try { - http.exceptionHandling().authenticationEntryPoint(http403ForbiddenEntryPoint); + http.exceptionHandling(ex -> ex.authenticationEntryPoint(http403ForbiddenEntryPoint)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/HeaderFrameOptionHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/HeaderFrameOptionHttpSecurityConfigurer.java index f1b8ec1cbc..01723515c1 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/HeaderFrameOptionHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/HeaderFrameOptionHttpSecurityConfigurer.java @@ -25,7 +25,7 @@ public class HeaderFrameOptionHttpSecurityConfigurer implements HttpSecurityConf @Override public void configure(HttpSecurity http) { try { - http.headers().frameOptions().disable(); + http.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable())); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/OpenApiHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/OpenApiHttpSecurityConfigurer.java index 7bf6b4d60b..e79fdd060d 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/OpenApiHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/OpenApiHttpSecurityConfigurer.java @@ -19,7 +19,7 @@ import static com.ritense.valtimo.contract.authentication.AuthoritiesConstants.ADMIN; import static com.ritense.valtimo.contract.authentication.AuthoritiesConstants.DEVELOPER; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -31,8 +31,8 @@ public class OpenApiHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/v3/api-docs")).hasAnyAuthority(ADMIN, DEVELOPER) - .requestMatchers(antMatcher(GET, "/v3/api-docs/**")).hasAnyAuthority(ADMIN, DEVELOPER) + requests.requestMatchers(pathPattern(GET, "/v3/api-docs")).hasAnyAuthority(ADMIN, DEVELOPER) + .requestMatchers(pathPattern(GET, "/v3/api-docs/**")).hasAnyAuthority(ADMIN, DEVELOPER) ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonCockpitHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonCockpitHttpSecurityConfigurer.java index 058c768d37..24554ddc5b 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonCockpitHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonCockpitHttpSecurityConfigurer.java @@ -16,7 +16,7 @@ package com.ritense.valtimo.security.config; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -46,19 +46,19 @@ public void configure(HttpSecurity http) { http.authorizeHttpRequests(requests -> requests.requestMatchers( whiteListed( - antMatcher("/operaton-welcome/**"), - antMatcher("/operaton/api/admin/**"), - antMatcher("/operaton/api/cockpit/**"), - antMatcher("/operaton/api/engine/**"), - antMatcher("/operaton/api/tasklist/**"), - antMatcher("/operaton/api/welcome/**"), - antMatcher("/operaton/app/admin/**"), - antMatcher("/operaton/app/cockpit/**"), - antMatcher("/operaton/app/tasklist/**"), - antMatcher("/operaton/app/welcome/**"), - antMatcher("/operaton/assets/**"), - antMatcher("/operaton/favicon.ico"), - antMatcher("/operaton/lib/**") + pathPattern("/operaton-welcome/**"), + pathPattern("/operaton/api/admin/**"), + pathPattern("/operaton/api/cockpit/**"), + pathPattern("/operaton/api/engine/**"), + pathPattern("/operaton/api/tasklist/**"), + pathPattern("/operaton/api/welcome/**"), + pathPattern("/operaton/app/admin/**"), + pathPattern("/operaton/app/cockpit/**"), + pathPattern("/operaton/app/tasklist/**"), + pathPattern("/operaton/app/welcome/**"), + pathPattern("/operaton/assets/**"), + pathPattern("/operaton/favicon.ico"), + pathPattern("/operaton/lib/**") ) ).permitAll() ); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonRestHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonRestHttpSecurityConfigurer.java index 4c011d7634..2469c8becf 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonRestHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/OperatonRestHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.valtimo.security.config; import static com.ritense.valtimo.contract.authentication.AuthoritiesConstants.ADMIN; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,7 +29,7 @@ public class OperatonRestHttpSecurityConfigurer implements HttpSecurityConfigure public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher("/api/operaton-rest/**")).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern("/api/operaton-rest/**")).hasAuthority(ADMIN) ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/PingHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/PingHttpSecurityConfigurer.java index f53e6b3390..ad8229a2ca 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/PingHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/PingHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.valtimo.security.config; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,7 +29,7 @@ public class PingHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/ping")).permitAll() + requests.requestMatchers(pathPattern(GET, "/api/v1/ping")).permitAll() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessHttpSecurityConfigurer.java index b52bc286ae..3024496bf2 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessHttpSecurityConfigurer.java @@ -20,7 +20,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -32,36 +32,36 @@ public class ProcessHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/process/definition")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/definition/{processDefinitionId}/count")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionId}/xml")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/process/definition/{processDefinitionId}/xml/timer")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/search-properties")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/versions")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/start-form")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/usertasks")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/heatmap/count")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{processDefinitionKey}/heatmap/duration")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/definition/{processDefinitionKey}/{businessKey}/start")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/definition/{sourceProcessDefinitionId}/{targetProcessDefinitionId}/flownodes")) + requests.requestMatchers(pathPattern(GET, "/api/v1/process/definition")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/definition/{processDefinitionId}/count")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionId}/xml")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/process/definition/{processDefinitionId}/xml/timer")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/search-properties")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/versions")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/start-form")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/usertasks")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/heatmap/count")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{processDefinitionKey}/heatmap/duration")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/definition/{processDefinitionKey}/{businessKey}/start")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/definition/{sourceProcessDefinitionId}/{targetProcessDefinitionId}/flownodes")) .authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/definition/{sourceProcessDefinitionId}/{targetProcessDefinitionId}/migrate")) + .requestMatchers(pathPattern(POST, "/api/v1/process/definition/{sourceProcessDefinitionId}/{targetProcessDefinitionId}/migrate")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/history")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/log")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/tasks")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/activetask")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/xml")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/activities")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/comments")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/{processDefinitionName}/search")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v2/process/{processDefinitionName}/search")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/{processDefinitionName}/count")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/{processInstanceId}/comment")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process/{processInstanceId}/delete")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/process/definition/deployment")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/history")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/log")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/tasks")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/activetask")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/xml")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/activities")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/comments")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/{processDefinitionName}/search")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v2/process/{processDefinitionName}/search")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/{processDefinitionName}/count")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/{processInstanceId}/comment")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process/{processInstanceId}/delete")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/process/definition/deployment")).hasAuthority(ADMIN) ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessInstanceHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessInstanceHttpSecurityConfigurer.java index b1a21778bc..420e4cd659 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessInstanceHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ProcessInstanceHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.valtimo.security.config; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,7 +29,7 @@ public class ProcessInstanceHttpSecurityConfigurer implements HttpSecurityConfig public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/process-instance/{id}/variables")).authenticated() + requests.requestMatchers(pathPattern(POST, "/api/v1/process-instance/{id}/variables")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ReportingHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ReportingHttpSecurityConfigurer.java index 7be1d039c9..2cf3505e94 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ReportingHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ReportingHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.valtimo.security.config; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,13 +29,13 @@ public class ReportingHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/reporting/instancecount")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/instancesstatistics")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/tasksAverage")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/tasksPerPerson")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/pendingTasksByRole")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/unfinishedTasksPerType")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/reporting/finishedAndUnfinishedInstances")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/reporting/instancecount")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/instancesstatistics")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/tasksAverage")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/tasksPerPerson")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/pendingTasksByRole")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/unfinishedTasksPerType")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/reporting/finishedAndUnfinishedInstances")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/StatelessHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/StatelessHttpSecurityConfigurer.java index 183e2ac3eb..a5b6170458 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/StatelessHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/StatelessHttpSecurityConfigurer.java @@ -27,7 +27,7 @@ public class StatelessHttpSecurityConfigurer implements HttpSecurityConfigurer { @Override public void configure(HttpSecurity http) { try { - http.sessionManagement().sessionCreationPolicy(STATELESS); + http.sessionManagement(sm -> sm.sessionCreationPolicy(STATELESS)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/StaticResourcesHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/StaticResourcesHttpSecurityConfigurer.java index daef8af821..753b68638b 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/StaticResourcesHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/StaticResourcesHttpSecurityConfigurer.java @@ -18,7 +18,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; -import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.boot.security.autoconfigure.web.servlet.PathRequest; import org.springframework.security.config.annotation.web.builders.HttpSecurity; public class StaticResourcesHttpSecurityConfigurer implements HttpSecurityConfigurer { diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/TaskHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/TaskHttpSecurityConfigurer.java index a80ac26f52..873d6b2fe8 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/TaskHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/TaskHttpSecurityConfigurer.java @@ -18,7 +18,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -31,19 +31,19 @@ public class TaskHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/task")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/task")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/assign/batch-assign")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/batch-complete")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/task/{taskId}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/{taskId}/assign")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/task/{taskId}/comments")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/{taskId}/complete")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/{taskId}/unassign")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/task/{taskId}/candidate-user")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/task/{taskId}/candidate-user")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/task/{taskId}/set-due-date")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/task/{taskId}/candidate-team")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/task")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v2/task")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/assign/batch-assign")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/batch-complete")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/task/{taskId}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/{taskId}/assign")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/task/{taskId}/comments")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/{taskId}/complete")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/{taskId}/unassign")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/task/{taskId}/candidate-user")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v2/task/{taskId}/candidate-user")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/task/{taskId}/set-due-date")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/task/{taskId}/candidate-team")).authenticated() ); } catch (Exception e) { diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/UserHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/UserHttpSecurityConfigurer.java index 8524a7fd0a..71f15b54ff 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/UserHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/UserHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -35,19 +35,19 @@ public class UserHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, USER_URL)).authenticated() - .requestMatchers(antMatcher(POST, USER_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, USER_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, USER_URL + "/{userId}/activate")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, USER_URL + "/{userId}/deactivate")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, USER_URL + "/email/{email}/")).authenticated() - .requestMatchers(antMatcher(GET, USER_URL + "/{userId}")).authenticated() - .requestMatchers(antMatcher(GET, USER_URL + "/authority/{authority}")).authenticated() - .requestMatchers(antMatcher(DELETE, USER_URL + "/{userId}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, USER_URL + "/send-verification-email/{userId}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/user/settings")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/user/settings")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/user/team")).authenticated() + requests.requestMatchers(pathPattern(GET, USER_URL)).authenticated() + .requestMatchers(pathPattern(POST, USER_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, USER_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, USER_URL + "/{userId}/activate")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, USER_URL + "/{userId}/deactivate")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, USER_URL + "/email/{email}/")).authenticated() + .requestMatchers(pathPattern(GET, USER_URL + "/{userId}")).authenticated() + .requestMatchers(pathPattern(GET, USER_URL + "/authority/{authority}")).authenticated() + .requestMatchers(pathPattern(DELETE, USER_URL + "/{userId}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, USER_URL + "/send-verification-email/{userId}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/user/settings")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/user/settings")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/user/team")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/java/com/ritense/valtimo/security/config/ValtimoVersionHttpSecurityConfigurer.java b/backend/core/src/main/java/com/ritense/valtimo/security/config/ValtimoVersionHttpSecurityConfigurer.java index 223259d4d6..6a89a497b4 100644 --- a/backend/core/src/main/java/com/ritense/valtimo/security/config/ValtimoVersionHttpSecurityConfigurer.java +++ b/backend/core/src/main/java/com/ritense/valtimo/security/config/ValtimoVersionHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.valtimo.security.config; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -29,7 +29,7 @@ public class ValtimoVersionHttpSecurityConfigurer implements HttpSecurityConfigu public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/valtimo/version")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/valtimo/version")).authenticated() ); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/AllowedClassesScriptEngineResolver.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/AllowedClassesScriptEngineResolver.kt index 64b2b3f10b..ed8b5876fb 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/AllowedClassesScriptEngineResolver.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/AllowedClassesScriptEngineResolver.kt @@ -40,6 +40,8 @@ class AllowedClassesScriptEngineResolver( companion object { private val ALLOWED = mutableSetOf( "java.util.ArrayList", + "java.util.HashMap", + "java.util.LinkedHashMap", "org.joda.time.DateTime", "java.util.Date", "java.lang.Math", diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregator.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregator.kt index 4d84921277..0b5b6d1fba 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregator.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregator.kt @@ -1,10 +1,10 @@ package com.ritense.valtimo.actuator.health -import org.springframework.boot.actuate.health.Status -import org.springframework.boot.actuate.health.StatusAggregator +import org.springframework.boot.health.actuate.endpoint.StatusAggregator +import org.springframework.boot.health.contributor.Status class ValtimoHealthAggregator : StatusAggregator { - override fun getAggregateStatus(statuses: MutableSet): Status { + override fun getAggregateStatus(statuses: Set): Status { if(statuses.stream().allMatch { s -> s.equals(Status.UP) }) return Status.UP if(statuses.stream().anyMatch { s -> s.equals(Status.DOWN) }) return Status.DOWN if(statuses.stream().anyMatch { s -> s.equals(Status.OUT_OF_SERVICE) }) return Status.OUT_OF_SERVICE diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/autoconfiguration/ValtimoOperatonAutoConfiguration.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/autoconfiguration/ValtimoOperatonAutoConfiguration.kt index 4fccba6a85..76f7daf58b 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/autoconfiguration/ValtimoOperatonAutoConfiguration.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/autoconfiguration/ValtimoOperatonAutoConfiguration.kt @@ -58,7 +58,7 @@ import org.operaton.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Lazy import org.springframework.core.annotation.Order diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/domain/OperatonTask.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/domain/OperatonTask.kt index ccace3879f..7d702e4a8c 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/domain/OperatonTask.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/domain/OperatonTask.kt @@ -17,6 +17,7 @@ package com.ritense.valtimo.operaton.domain import io.hypersistence.utils.hibernate.type.json.JsonType +import com.ritense.valtimo.task.domain.TaskTeam import jakarta.persistence.Column import jakarta.persistence.Entity import jakarta.persistence.EnumType @@ -26,6 +27,7 @@ import jakarta.persistence.Id import jakarta.persistence.JoinColumn import jakarta.persistence.ManyToOne import jakarta.persistence.OneToMany +import jakarta.persistence.OneToOne import jakarta.persistence.Table import jakarta.persistence.Transient import org.hibernate.annotations.Formula @@ -118,7 +120,11 @@ class OperatonTask( @Immutable @OneToMany(mappedBy = "task", fetch = FetchType.LAZY) - val variableInstances: Set + val variableInstances: Set, + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ID_", referencedColumnName = "task_id", insertable = false, updatable = false) + val taskTeam: TaskTeam? = null ): OperatonVariableScope() { diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonHealthAutoConfiguration.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonHealthAutoConfiguration.kt index f2b2df6cb1..78c5e441e6 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonHealthAutoConfiguration.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonHealthAutoConfiguration.kt @@ -18,7 +18,7 @@ package com.ritense.valtimo.operaton.health import org.operaton.bpm.engine.RuntimeService -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator +import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.context.annotation.Bean diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicator.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicator.kt index da09f9ae4e..d330d1c3c3 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicator.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicator.kt @@ -17,9 +17,9 @@ package com.ritense.valtimo.operaton.health import org.operaton.bpm.engine.RuntimeService -import org.springframework.boot.actuate.health.AbstractHealthIndicator -import org.springframework.boot.actuate.health.Health -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.AbstractHealthIndicator +import org.springframework.boot.health.contributor.Health +import org.springframework.boot.health.contributor.Status class OperatonIncidentHealthIndicator ( private val runtimeService: RuntimeService diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/repository/OperatonTaskSpecificationHelper.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/repository/OperatonTaskSpecificationHelper.kt index 63d8f02623..6bf2773773 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/repository/OperatonTaskSpecificationHelper.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/operaton/repository/OperatonTaskSpecificationHelper.kt @@ -184,45 +184,35 @@ class OperatonTaskSpecificationHelper { fun byActive() = bySuspensionState(SuspensionState.ACTIVE.stateCode) @JvmStatic - fun byTeamKeys(teamKeys: Collection) = Specification { root, query, cb -> + fun byTeamKeys(teamKeys: Collection) = Specification { root, _, cb -> if (teamKeys.isEmpty()) { cb.equal(cb.literal(0), 1) } else { - val subquery = query!!.subquery(String::class.java) - val taskTeamRoot = subquery.from(TaskTeam::class.java) - subquery.select(taskTeamRoot.get("taskId")) - subquery.where(taskTeamRoot.get("teamKey").`in`(teamKeys)) - root.get(ID).`in`(subquery) + val join = root.join("taskTeam", jakarta.persistence.criteria.JoinType.INNER) + join.get("teamKey").`in`(teamKeys) } } @JvmStatic - fun byTeamKey(teamKey: String?) = Specification { root, query, cb -> - val subquery = query!!.subquery(String::class.java) - val taskTeamRoot = subquery.from(TaskTeam::class.java) - subquery.select(taskTeamRoot.get("taskId")) + fun byTeamKey(teamKey: String?) = Specification { root, _, cb -> + val join = root.join("taskTeam", jakarta.persistence.criteria.JoinType.LEFT) if (teamKey == null) { - root.get(ID).`in`(subquery).not() + join.get("taskId").isNull } else { - subquery.where(cb.equal(taskTeamRoot.get("teamKey"), teamKey)) - root.get(ID).`in`(subquery) + cb.equal(join.get("teamKey"), teamKey) } } @JvmStatic - fun byHasTeam() = Specification { root, query, _ -> - val subquery = query!!.subquery(String::class.java) - val taskTeamRoot = subquery.from(TaskTeam::class.java) - subquery.select(taskTeamRoot.get("taskId")) - root.get(ID).`in`(subquery) + fun byHasTeam() = Specification { root, _, _ -> + val join = root.join("taskTeam", jakarta.persistence.criteria.JoinType.INNER) + join.get("taskId").isNotNull } @JvmStatic - fun byNoTeam() = Specification { root, query, _ -> - val subquery = query!!.subquery(String::class.java) - val taskTeamRoot = subquery.from(TaskTeam::class.java) - subquery.select(taskTeamRoot.get("taskId")) - root.get(ID).`in`(subquery).not() + fun byNoTeam() = Specification { root, _, _ -> + val join = root.join("taskTeam", jakarta.persistence.criteria.JoinType.LEFT) + join.get("taskId").isNull } } diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/repository/ReadOnlyJpaSpecificationRepository.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/repository/ReadOnlyJpaSpecificationRepository.kt index ff14149be7..190b63fb5f 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/repository/ReadOnlyJpaSpecificationRepository.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/repository/ReadOnlyJpaSpecificationRepository.kt @@ -29,7 +29,7 @@ import java.util.Optional import java.util.function.Function @NoRepositoryBean -interface ReadOnlyJpaSpecificationRepository : Repository, JpaSpecificationExecutor { +interface ReadOnlyJpaSpecificationRepository : Repository, JpaSpecificationExecutor { fun findAll(): List diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/security/ActuatorSecurityFilterChainFactory.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/security/ActuatorSecurityFilterChainFactory.kt index 4b8ecdd77e..dd908b38be 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/security/ActuatorSecurityFilterChainFactory.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/security/ActuatorSecurityFilterChainFactory.kt @@ -18,7 +18,7 @@ package com.ritense.valtimo.security import com.ritense.valtimo.contract.authentication.AuthoritiesConstants.ACTUATOR import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties +import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointProperties import org.springframework.boot.actuate.endpoint.Show import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST @@ -32,7 +32,7 @@ import org.springframework.security.core.userdetails.UserDetailsService import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.provisioning.InMemoryUserDetailsManager import org.springframework.security.web.SecurityFilterChain -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern import org.springframework.security.web.util.matcher.OrRequestMatcher class ActuatorSecurityFilterChainFactory { @@ -86,9 +86,8 @@ class ActuatorSecurityFilterChainFactory { password: String ): AuthenticationManager { val userDetailsService: UserDetailsService = userDetailsService(passwordEncoder, username, password) - val authenticationProvider = DaoAuthenticationProvider() + val authenticationProvider = DaoAuthenticationProvider(userDetailsService) authenticationProvider.setPasswordEncoder(passwordEncoder) - authenticationProvider.setUserDetailsService(userDetailsService) return ProviderManager(authenticationProvider) } @@ -109,20 +108,20 @@ class ActuatorSecurityFilterChainFactory { private fun getActuatorMatchers(actuatorPath: String) = arrayOf( *getPublicMatchers(actuatorPath), - antMatcher(GET, "${actuatorPath}/configprops"), - antMatcher(GET, "${actuatorPath}/env"), - antMatcher(GET, "${actuatorPath}/mappings"), - antMatcher(GET, "${actuatorPath}/logfile"), - antMatcher(GET, "${actuatorPath}/loggers"), - antMatcher(POST, "${actuatorPath}/loggers/**"), - antMatcher(GET, "${actuatorPath}/info"), + pathPattern(GET, "${actuatorPath}/configprops"), + pathPattern(GET, "${actuatorPath}/env"), + pathPattern(GET, "${actuatorPath}/mappings"), + pathPattern(GET, "${actuatorPath}/logfile"), + pathPattern(GET, "${actuatorPath}/loggers"), + pathPattern(POST, "${actuatorPath}/loggers/**"), + pathPattern(GET, "${actuatorPath}/info"), ) private fun getPublicMatchers(actuatorPath: String) = arrayOf( - antMatcher(GET, actuatorPath), - antMatcher(GET, "${actuatorPath}/health"), - antMatcher(GET, "${actuatorPath}/health/liveness"), - antMatcher(GET, "${actuatorPath}/health/readiness"), + pathPattern(GET, actuatorPath), + pathPattern(GET, "${actuatorPath}/health"), + pathPattern(GET, "${actuatorPath}/health/liveness"), + pathPattern(GET, "${actuatorPath}/health/readiness"), ) companion object { diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/security/DecisionHttpSecurityConfigurer.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/security/DecisionHttpSecurityConfigurer.kt index 2681ebfaf5..62f30e8839 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/security/DecisionHttpSecurityConfigurer.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/security/DecisionHttpSecurityConfigurer.kt @@ -23,17 +23,17 @@ import org.springframework.http.HttpMethod.DELETE import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class DecisionHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, DECISION_MANAGEMENT_URL)) + requests.requestMatchers(pathPattern(GET, DECISION_MANAGEMENT_URL)) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, DECISION_MANAGEMENT_URL)) + .requestMatchers(pathPattern(POST, DECISION_MANAGEMENT_URL)) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$DECISION_MANAGEMENT_URL/{decisionDefinitionId}")) + .requestMatchers(pathPattern(DELETE, "$DECISION_MANAGEMENT_URL/{decisionDefinitionId}")) .hasAuthority(ADMIN) } } catch (e: Exception) { diff --git a/backend/core/src/main/kotlin/com/ritense/valtimo/security/ValtimoCoreSecurityFactory.kt b/backend/core/src/main/kotlin/com/ritense/valtimo/security/ValtimoCoreSecurityFactory.kt index 97ffb68dde..e18bb819f6 100644 --- a/backend/core/src/main/kotlin/com/ritense/valtimo/security/ValtimoCoreSecurityFactory.kt +++ b/backend/core/src/main/kotlin/com/ritense/valtimo/security/ValtimoCoreSecurityFactory.kt @@ -22,7 +22,7 @@ import org.springframework.http.HttpMethod import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer import org.springframework.security.web.SecurityFilterChain -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ValtimoCoreSecurityFactory( private val httpSecurityConfigurers: List @@ -40,8 +40,8 @@ class ValtimoCoreSecurityFactory( override fun createWebSecurityCustomizer(): WebSecurityCustomizer { return WebSecurityCustomizer { web -> web.ignoring() - .requestMatchers(antMatcher(HttpMethod.OPTIONS, "/**")) - .requestMatchers(antMatcher("/content/**")) } + .requestMatchers(pathPattern(HttpMethod.OPTIONS, "/**")) + .requestMatchers(pathPattern("/content/**")) } } diff --git a/backend/core/src/test/java/com/ritense/valtimo/service/OperatonTaskServiceTest.java b/backend/core/src/test/java/com/ritense/valtimo/service/OperatonTaskServiceTest.java index 380f048caa..d9792cea19 100644 --- a/backend/core/src/test/java/com/ritense/valtimo/service/OperatonTaskServiceTest.java +++ b/backend/core/src/test/java/com/ritense/valtimo/service/OperatonTaskServiceTest.java @@ -136,7 +136,8 @@ void setUp() { null, 0, null, - Set.of() + Set.of(), + null ) ); operatonTaskService = spy( diff --git a/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldResourceTest.java b/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldResourceTest.java index 9cddc6a54c..e9023de21f 100644 --- a/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldResourceTest.java +++ b/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldResourceTest.java @@ -16,6 +16,7 @@ package com.ritense.valtimo.web.rest; +import static com.ritense.valtimo.contract.domain.ValtimoMediaType.APPLICATION_JSON_UTF8_VALUE; import com.ritense.valtimo.domain.choicefield.ChoiceField; import com.ritense.valtimo.service.ChoiceFieldService; import java.time.ZoneId; @@ -31,7 +32,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.hasSize; @@ -43,7 +44,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ExtendWith(SpringExtension.class) +@ExtendWith(MockitoExtension.class) class ChoiceFieldResourceTest { @Mock @@ -72,7 +73,7 @@ void testGetChoiceFields() throws Exception { mvc.perform(get("/api/v2/choice-fields")) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))) .andExpect(jsonPath("$.content[0].id").value(choiceField.getId().intValue())) .andExpect(jsonPath("$.content[0].title").value(choiceField.getTitle())) diff --git a/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldValueResourceTest.java b/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldValueResourceTest.java index e61232ab05..961cc9593e 100644 --- a/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldValueResourceTest.java +++ b/backend/core/src/test/java/com/ritense/valtimo/web/rest/ChoiceFieldValueResourceTest.java @@ -16,6 +16,7 @@ package com.ritense.valtimo.web.rest; +import static com.ritense.valtimo.contract.domain.ValtimoMediaType.APPLICATION_JSON_UTF8_VALUE; import com.ritense.valtimo.domain.choicefield.ChoiceField; import com.ritense.valtimo.domain.choicefield.ChoiceFieldValue; import com.ritense.valtimo.service.ChoiceFieldValueService; @@ -32,7 +33,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.hamcrest.Matchers.hasSize; @@ -45,7 +46,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ExtendWith(SpringExtension.class) +@ExtendWith(MockitoExtension.class) class ChoiceFieldValueResourceTest { @Mock @@ -74,7 +75,7 @@ void testGetChoiceFieldValues() throws Exception { mvc.perform(get("/api/v2/choice-field-values")) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))) .andExpect(jsonPath("$.content[0].id").value(choiceFieldValue.getId())) .andExpect(jsonPath("$.content[0].name").value(choiceFieldValue.getName())) @@ -103,7 +104,7 @@ void testGetChoiceFieldValuesByChoiceFieldKey() throws Exception { mvc.perform(get("/api/v2/choice-field-values/some-name/values")) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(APPLICATION_JSON_UTF8_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))) .andExpect(jsonPath("$.content[0].id").value(choiceFieldValue.getId())) .andExpect(jsonPath("$.content[0].name").value(choiceFieldValue.getName())) diff --git a/backend/core/src/test/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregatorTest.kt b/backend/core/src/test/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregatorTest.kt index 8b112ec406..825133b9af 100644 --- a/backend/core/src/test/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregatorTest.kt +++ b/backend/core/src/test/kotlin/com/ritense/valtimo/actuator/health/ValtimoHealthAggregatorTest.kt @@ -3,7 +3,7 @@ package com.ritense.valtimo.actuator.health import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.Status class ValtimoHealthAggregatorTest { lateinit var aggregator: ValtimoHealthAggregator diff --git a/backend/core/src/test/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicatorTest.kt b/backend/core/src/test/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicatorTest.kt index 05c2500454..549d0a5ce7 100644 --- a/backend/core/src/test/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicatorTest.kt +++ b/backend/core/src/test/kotlin/com/ritense/valtimo/operaton/health/OperatonIncidentHealthIndicatorTest.kt @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test import org.mockito.Mockito import org.mockito.kotlin.mock import org.mockito.kotlin.whenever -import org.springframework.boot.actuate.health.Health +import org.springframework.boot.health.contributor.Health class OperatonIncidentHealthIndicatorTest { lateinit var runtimeService: RuntimeService diff --git a/backend/core/src/test/resources/config/case/everything/1-0-0/bpmn/javascript-script-task-process-unallowed.bpmn b/backend/core/src/test/resources/config/case/everything/1-0-0/bpmn/javascript-script-task-process-unallowed.bpmn index 7fcfd0ade2..77b90b2364 100644 --- a/backend/core/src/test/resources/config/case/everything/1-0-0/bpmn/javascript-script-task-process-unallowed.bpmn +++ b/backend/core/src/test/resources/config/case/everything/1-0-0/bpmn/javascript-script-task-process-unallowed.bpmn @@ -12,9 +12,9 @@ Flow_0kymcf3 Flow_1muqoyt - const HashMap = Java.type("java.util.HashMap"); + const Runtime = Java.type("java.lang.Runtime"); -const result = new HashMap() +const result = Runtime.getRuntime() diff --git a/backend/dashboard/build.gradle b/backend/dashboard/build.gradle index afa5041209..56afb0df5d 100644 --- a/backend/dashboard/build.gradle +++ b/backend/dashboard/build.gradle @@ -39,6 +39,7 @@ dependencies { implementation(project(":backend:contract")) implementation(project(":backend:changelog")) + implementation "org.springframework.boot:spring-boot-starter-cache" implementation "org.springframework.boot:spring-boot-starter-web" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-security" diff --git a/backend/dashboard/src/main/kotlin/com/ritense/dashboard/autoconfigure/DashboardAutoConfiguration.kt b/backend/dashboard/src/main/kotlin/com/ritense/dashboard/autoconfigure/DashboardAutoConfiguration.kt index e90a3074d2..4179bbd175 100644 --- a/backend/dashboard/src/main/kotlin/com/ritense/dashboard/autoconfigure/DashboardAutoConfiguration.kt +++ b/backend/dashboard/src/main/kotlin/com/ritense/dashboard/autoconfigure/DashboardAutoConfiguration.kt @@ -34,7 +34,7 @@ import com.ritense.valtimo.contract.database.QueryDialectHelper import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.cache.annotation.EnableCaching import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean diff --git a/backend/dashboard/src/main/kotlin/com/ritense/dashboard/security/config/DashboardHttpSecurityConfigurer.kt b/backend/dashboard/src/main/kotlin/com/ritense/dashboard/security/config/DashboardHttpSecurityConfigurer.kt index 10e109d2d5..388acbe23b 100644 --- a/backend/dashboard/src/main/kotlin/com/ritense/dashboard/security/config/DashboardHttpSecurityConfigurer.kt +++ b/backend/dashboard/src/main/kotlin/com/ritense/dashboard/security/config/DashboardHttpSecurityConfigurer.kt @@ -24,28 +24,28 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class DashboardHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/dashboard")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/dashboard/{dashboardKey}/data")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/dashboard")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/dashboard/{dashboardKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/dashboard")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/dashboard")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/dashboard/{dashboard-key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/dashboard/{dashboard-key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/dashboard/widget-data-sources")).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern(GET, "/api/v1/dashboard")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/dashboard/{dashboardKey}/data")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/dashboard")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/dashboard/{dashboardKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/dashboard")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/dashboard")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/dashboard/{dashboard-key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/dashboard/{dashboard-key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/dashboard/{dashboardKey}/widget-configuration/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/dashboard/widget-data-sources")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/defaultdataproviders/autoconfigure/DefaultDataProviderAutoConfiguration.kt b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/defaultdataproviders/autoconfigure/DefaultDataProviderAutoConfiguration.kt index db5ed9e300..6871b955fa 100644 --- a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/defaultdataproviders/autoconfigure/DefaultDataProviderAutoConfiguration.kt +++ b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/defaultdataproviders/autoconfigure/DefaultDataProviderAutoConfiguration.kt @@ -25,7 +25,7 @@ import com.ritense.dataprovider.defaultdataproviders.repository.DropdownListRepo import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.AutoConfigureBefore import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.core.io.ResourceLoader import org.springframework.data.jpa.repository.config.EnableJpaRepositories diff --git a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/security/config/DataProviderHttpSecurityConfigurer.kt b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/security/config/DataProviderHttpSecurityConfigurer.kt index 18d2785cba..440ea69b06 100644 --- a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/security/config/DataProviderHttpSecurityConfigurer.kt +++ b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/security/config/DataProviderHttpSecurityConfigurer.kt @@ -23,18 +23,18 @@ import org.springframework.http.HttpMethod.DELETE import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class DataProviderHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "$DATA_URL/provider")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$DATA_URL/all")).authenticated() - .requestMatchers(antMatcher(GET, DATA_URL)).authenticated() - .requestMatchers(antMatcher(POST, DATA_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, DATA_URL)).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern(GET, "$DATA_URL/provider")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$DATA_URL/all")).authenticated() + .requestMatchers(pathPattern(GET, DATA_URL)).authenticated() + .requestMatchers(pathPattern(POST, DATA_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, DATA_URL)).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/web/rest/DataProviderResource.kt b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/web/rest/DataProviderResource.kt index 07317c666d..b51c91f4c1 100644 --- a/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/web/rest/DataProviderResource.kt +++ b/backend/data-provider/src/main/kotlin/com/ritense/dataprovider/web/rest/DataProviderResource.kt @@ -57,7 +57,7 @@ class DataProviderResource( @PathVariable category: String, @RequestParam provider: String?, @RequestParam query: Map = emptyMap() - ): ResponseEntity { + ): ResponseEntity { return ResponseEntity.ok(dataProviderService.getData(category, provider, query)) } diff --git a/backend/dependencies/valtimo-dependency-versions/build.gradle b/backend/dependencies/valtimo-dependency-versions/build.gradle index c597522bd2..961bd27ea3 100644 --- a/backend/dependencies/valtimo-dependency-versions/build.gradle +++ b/backend/dependencies/valtimo-dependency-versions/build.gradle @@ -98,7 +98,7 @@ dependencies { api("org.liquibase:liquibase-core:${liquibaseVersion}") - api("org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}") + api("org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}") api("org.hibernate.orm:hibernate-core:${hibernateCoreVersion}") //ShedLock diff --git a/backend/document-generation/smartdocuments/build.gradle b/backend/document-generation/smartdocuments/build.gradle index 8af83c0b8f..cdbe56e624 100644 --- a/backend/document-generation/smartdocuments/build.gradle +++ b/backend/document-generation/smartdocuments/build.gradle @@ -69,6 +69,7 @@ dependencies { testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.springframework.boot:spring-boot-starter-test" + testImplementation "org.springframework.boot:spring-boot-webtestclient" implementation "org.springframework.boot:spring-boot-autoconfigure" implementation "org.springframework.boot:spring-boot-starter-webflux" diff --git a/backend/document-generation/smartdocuments/src/main/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClient.kt b/backend/document-generation/smartdocuments/src/main/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClient.kt index 76cdeccd14..fc484a1c94 100644 --- a/backend/document-generation/smartdocuments/src/main/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClient.kt +++ b/backend/document-generation/smartdocuments/src/main/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClient.kt @@ -30,9 +30,10 @@ import com.ritense.smartdocuments.io.UnicodeUnescapeInputStream import com.ritense.valtimo.contract.annotation.SkipComponentScan import com.ritense.valtimo.contract.domain.ValtimoMediaType.APPLICATION_JSON_UTF8 import org.apache.commons.io.FilenameUtils -import org.springframework.core.io.Resource -import org.springframework.http.converter.ResourceHttpMessageConverter +import org.springframework.http.HttpStatusCode import org.springframework.stereotype.Component +import org.springframework.web.client.HttpClientErrorException +import org.springframework.web.client.HttpServerErrorException import org.springframework.web.client.RestClient import org.springframework.web.client.body import java.io.InputStream @@ -71,27 +72,43 @@ class SmartDocumentsClient( smartDocumentsRequest: SmartDocumentsRequest, outputFormat: DocumentFormatOption, ): FileStreamResponse { - // Stream complete response (json) to a Resource - val result = restClient(authentication) + return restClient(authentication) .post() .uri { it.pathSegment("wsxmldeposit", "deposit", "unattended").build() } .contentType(APPLICATION_JSON_UTF8) .body(fixRequest(smartDocumentsRequest)) - .retrieve() - .body()!! - - val responseResourceId = temporaryResourceStorageService.store(result.inputStream) - val parsedResponse = temporaryResourceStorageService.getResourceContentAsInputStream(responseResourceId) - .use { parseSmartDocumentsResponse(it, outputFormat) } - - val resourceIn = temporaryResourceStorageService.getResourceContentAsInputStream(responseResourceId) - val documentDataIn = toDocumentDataInputStream(resourceIn, parsedResponse) - - return FileStreamResponse( - parsedResponse.fileName, - FilenameUtils.getExtension(parsedResponse.fileName), - documentDataIn - ) + .exchange { _, response -> + if (response.statusCode.is4xxClientError) { + throw HttpClientErrorException.create( + response.statusCode as HttpStatusCode, + response.statusText, + response.headers, + response.body.readBytes(), + null + ) + } + if (response.statusCode.is5xxServerError) { + throw HttpServerErrorException.create( + response.statusCode as HttpStatusCode, + response.statusText, + response.headers, + response.body.readBytes(), + null + ) + } + val responseResourceId = temporaryResourceStorageService.store(response.body) + val parsedResponse = temporaryResourceStorageService.getResourceContentAsInputStream(responseResourceId) + .use { parseSmartDocumentsResponse(it, outputFormat) } + + val resourceIn = temporaryResourceStorageService.getResourceContentAsInputStream(responseResourceId) + val documentDataIn = toDocumentDataInputStream(resourceIn, parsedResponse) + + FileStreamResponse( + parsedResponse.fileName, + FilenameUtils.getExtension(parsedResponse.fileName), + documentDataIn + ) + } } private fun fixRequest(smartDocumentsRequest: SmartDocumentsRequest): SmartDocumentsRequest { @@ -116,9 +133,6 @@ class SmartDocumentsClient( authentication.password ) } - .messageConverters { - it + ResourceHttpMessageConverter(true) // Enables streaming - } .build() } diff --git a/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClientTest.kt b/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClientTest.kt index 8fabc60c55..418e70bd6f 100644 --- a/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClientTest.kt +++ b/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/client/SmartDocumentsClientTest.kt @@ -24,6 +24,7 @@ import com.ritense.smartdocuments.domain.DocumentFormatOption import com.ritense.smartdocuments.domain.SmartDocumentsRequest import com.ritense.smartdocuments.domain.SmartDocumentsTemplateData import com.ritense.temporaryresource.repository.ResourceStorageMetadataRepository +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import com.ritense.valtimo.contract.upload.ValtimoUploadProperties import okhttp3.mockwebserver.MockResponse @@ -45,7 +46,6 @@ import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.springframework.http.HttpStatus import org.springframework.web.client.HttpClientErrorException -import org.springframework.web.client.RestClient @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class SmartDocumentsClientTest : BaseTest() { @@ -80,7 +80,7 @@ internal class SmartDocumentsClientTest : BaseTest() { client = spy( SmartDocumentsClient( - RestClient.builder(), + Jackson2TestUtils.restClientBuilder(), 5, temporaryResourceStorageService, ) diff --git a/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/plugin/SmartDocumentsPluginIntegrationTest.kt b/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/plugin/SmartDocumentsPluginIntegrationTest.kt index 8b2b20bbf4..78c0719305 100644 --- a/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/plugin/SmartDocumentsPluginIntegrationTest.kt +++ b/backend/document-generation/smartdocuments/src/test/kotlin/com/ritense/smartdocuments/plugin/SmartDocumentsPluginIntegrationTest.kt @@ -38,7 +38,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.operaton.bpm.engine.RuntimeService import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient import org.springframework.http.HttpMethod import org.springframework.transaction.annotation.Transactional import java.util.UUID diff --git a/backend/exact-plugin/build.gradle b/backend/exact-plugin/build.gradle index d92f54a84c..1ebf47dd1f 100644 --- a/backend/exact-plugin/build.gradle +++ b/backend/exact-plugin/build.gradle @@ -36,6 +36,7 @@ dependencies { implementation "net.javacrumbs.shedlock:shedlock-spring:${shedlockVersion}" implementation "net.javacrumbs.shedlock:shedlock-provider-jdbc-template:${shedlockVersion}" + testImplementation project(':backend:test-utils-common') testImplementation "org.springframework.security:spring-security-test" testImplementation "org.mockito.kotlin:mockito-kotlin:${mockitoKotlinVersion}" testImplementation "org.jetbrains.kotlin:kotlin-test" diff --git a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PostEndpoint.kt b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PostEndpoint.kt index cec010a3a4..d72a446527 100644 --- a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PostEndpoint.kt +++ b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PostEndpoint.kt @@ -3,6 +3,7 @@ package com.ritense.exact.client.endpoints import com.fasterxml.jackson.databind.JsonNode import com.ritense.exact.client.endpoints.structs.AuthorizedExactEndpoint import org.springframework.http.MediaType +import org.springframework.http.StreamingHttpOutputMessage import org.springframework.web.client.RestClient class PostEndpoint( @@ -15,6 +16,8 @@ class PostEndpoint( .post() .uri(uri) .contentType(MediaType.APPLICATION_JSON) - .body(content) + .body(StreamingHttpOutputMessage.Body { outputStream -> + outputStream.write(content.toByteArray(Charsets.UTF_8)) + }) } } \ No newline at end of file diff --git a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PutEndpoint.kt b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PutEndpoint.kt index 13bc748f51..b14e1cb0c1 100644 --- a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PutEndpoint.kt +++ b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/PutEndpoint.kt @@ -2,6 +2,8 @@ package com.ritense.exact.client.endpoints import com.fasterxml.jackson.databind.JsonNode import com.ritense.exact.client.endpoints.structs.AuthorizedExactEndpoint +import org.springframework.http.MediaType +import org.springframework.http.StreamingHttpOutputMessage import org.springframework.web.client.RestClient class PutEndpoint( @@ -13,6 +15,9 @@ class PutEndpoint( return client .put() .uri(uri) - .body(content) + .contentType(MediaType.APPLICATION_JSON) + .body(StreamingHttpOutputMessage.Body { outputStream -> + outputStream.write(content.toByteArray(Charsets.UTF_8)) + }) } } \ No newline at end of file diff --git a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/AuthorizedExactEndpoint.kt b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/AuthorizedExactEndpoint.kt index 5e7dd0b8af..6188cb3aee 100644 --- a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/AuthorizedExactEndpoint.kt +++ b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/AuthorizedExactEndpoint.kt @@ -4,7 +4,7 @@ import org.springframework.web.client.HttpClientErrorException import org.springframework.web.client.RestClient import org.springframework.web.client.RestClientResponseException -abstract class AuthorizedExactEndpoint( +abstract class AuthorizedExactEndpoint( type: Class, private val accessToken: String ) : ExactEndpoint(type) { diff --git a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/ExactEndpoint.kt b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/ExactEndpoint.kt index ef257c6945..b80e14476d 100644 --- a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/ExactEndpoint.kt +++ b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/client/endpoints/structs/ExactEndpoint.kt @@ -4,7 +4,7 @@ import org.springframework.web.client.HttpClientErrorException import org.springframework.web.client.RestClient import org.springframework.web.client.RestClientResponseException -abstract class ExactEndpoint(val type: Class) { +abstract class ExactEndpoint(val type: Class) { open fun call(client: RestClient): Response { try { diff --git a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/security/ExactPluginSecurityConfigurer.kt b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/security/ExactPluginSecurityConfigurer.kt index a9a1b1a086..19c6077c57 100644 --- a/backend/exact-plugin/src/main/kotlin/com/ritense/exact/security/ExactPluginSecurityConfigurer.kt +++ b/backend/exact-plugin/src/main/kotlin/com/ritense/exact/security/ExactPluginSecurityConfigurer.kt @@ -5,13 +5,13 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ExactPluginSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/plugin/exact/exchange")).hasAuthority(AuthoritiesConstants.ADMIN) + requests.requestMatchers(pathPattern(POST, "/api/v1/plugin/exact/exchange")).hasAuthority(AuthoritiesConstants.ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/exact-plugin/src/test/kotlin/com/ritense/exact/plugin/ExactPluginTest.kt b/backend/exact-plugin/src/test/kotlin/com/ritense/exact/plugin/ExactPluginTest.kt index 4db4cdd662..f1529e6b52 100644 --- a/backend/exact-plugin/src/test/kotlin/com/ritense/exact/plugin/ExactPluginTest.kt +++ b/backend/exact-plugin/src/test/kotlin/com/ritense/exact/plugin/ExactPluginTest.kt @@ -26,6 +26,7 @@ import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever +import com.ritense.valtimo.Jackson2TestUtils import org.springframework.context.ApplicationContext import org.springframework.web.client.RestClient @@ -53,7 +54,10 @@ internal class ExactPluginTest { fun setUpEach() { exactService = mock() context = mock() - exactClient = ExactPluginAutoConfiguration().exactClient("http://localhost:${mockWebServer.port}") + exactClient = Jackson2TestUtils.restClientBuilder() + .baseUrl("http://localhost:${mockWebServer.port}") + .defaultHeader("Accept", "application/json") + .build() exactPlugin = ExactPlugin(exactService, exactClient, context) } diff --git a/backend/form-flow/build.gradle b/backend/form-flow/build.gradle index 24d9b60e3e..d1cbae4078 100644 --- a/backend/form-flow/build.gradle +++ b/backend/form-flow/build.gradle @@ -61,8 +61,8 @@ dependencies { implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" - implementation "org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "org.jetbrains.kotlin:kotlin-reflect" implementation "io.github.oshai:kotlin-logging:${kotlinLoggingVersion}" implementation "com.github.erosb:everit-json-schema:${everitJsonSchemaVersion}" diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/autoconfigure/FormFlowAutoConfiguration.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/autoconfigure/FormFlowAutoConfiguration.kt index f2c1b5c506..35c0586a8d 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/autoconfigure/FormFlowAutoConfiguration.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/autoconfigure/FormFlowAutoConfiguration.kt @@ -67,7 +67,7 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationContext import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/domain/instance/FormFlowStepInstance.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/domain/instance/FormFlowStepInstance.kt index 88d5dc49ff..c4c8725414 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/domain/instance/FormFlowStepInstance.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/domain/instance/FormFlowStepInstance.kt @@ -122,7 +122,7 @@ data class FormFlowStepInstance( ?.first } - private fun processExpressions(expressions: List): List { + private fun processExpressions(expressions: List): List { return ExpressionProcessorFactoryHolder.getInstance().let { factory -> val variables = createVarMap() val expressionProcessor = factory.create(variables) diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/ExpressionProcessor.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/ExpressionProcessor.kt index e8ad0ff026..60f6e354b1 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/ExpressionProcessor.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/ExpressionProcessor.kt @@ -17,6 +17,6 @@ package com.ritense.formflow.expression interface ExpressionProcessor { - fun process(expression: String, resultType: Class? = null): T? + fun process(expression: String, resultType: Class? = null): T? fun validate(expression: String) } \ No newline at end of file diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/spel/SpelExpressionProcessor.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/spel/SpelExpressionProcessor.kt index f50cac8761..1f1e533a73 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/spel/SpelExpressionProcessor.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/expression/spel/SpelExpressionProcessor.kt @@ -33,7 +33,7 @@ class SpelExpressionProcessor( private val contextMap: Map = mapOf() ) : ExpressionProcessor { - override fun process(expression: String, resultType: Class?): T? { + override fun process(expression: String, resultType: Class?): T? { val spelExpression = parseSpelExpression(expression) return if (spelExpression != null) { diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/json/MapperSingleton.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/json/MapperSingleton.kt index 79276017ac..1e30e544fa 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/json/MapperSingleton.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/json/MapperSingleton.kt @@ -18,7 +18,7 @@ package com.ritense.formflow.json import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer +import org.springframework.boot.jackson2.autoconfigure.Jackson2ObjectMapperBuilderCustomizer import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder import java.time.format.DateTimeFormatter diff --git a/backend/form-flow/src/main/kotlin/com/ritense/formflow/security/ValtimoFormFlowHttpSecurityConfigurer.kt b/backend/form-flow/src/main/kotlin/com/ritense/formflow/security/ValtimoFormFlowHttpSecurityConfigurer.kt index 37bb300069..a23c7606d1 100644 --- a/backend/form-flow/src/main/kotlin/com/ritense/formflow/security/ValtimoFormFlowHttpSecurityConfigurer.kt +++ b/backend/form-flow/src/main/kotlin/com/ritense/formflow/security/ValtimoFormFlowHttpSecurityConfigurer.kt @@ -24,29 +24,29 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ValtimoFormFlowHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/form-flow/{formFlowInstanceId}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/{formFlowId}/step/{stepInstanceId}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/{formFlowId}/back")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/{formFlowId}/save")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-link/form-flow-definition")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/form-flow/instance/{formFlowInstanceId}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/instance/{formFlowId}/step/instance/{stepInstanceId}")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/instance/{formFlowId}/back")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/instance/{formFlowId}/save")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/form-flow/instance/{formFlowId}/step/instance/{stepInstanceId}/to/step/instance/{targetStepInstanceId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/form-flow/instance/{formFlowId}/breadcrumbs")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/process-link-option")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern(GET, "/api/v1/form-flow/{formFlowInstanceId}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/{formFlowId}/step/{stepInstanceId}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/{formFlowId}/back")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/{formFlowId}/save")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process-link/form-flow-definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/form-flow/instance/{formFlowInstanceId}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/instance/{formFlowId}/step/instance/{stepInstanceId}")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/instance/{formFlowId}/back")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/instance/{formFlowId}/save")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/form-flow/instance/{formFlowId}/step/instance/{stepInstanceId}/to/step/instance/{targetStepInstanceId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/form-flow/instance/{formFlowId}/breadcrumbs")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/process-link-option")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-flow-definition/{definitionKey}")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/form-flow/src/test/kotlin/com/ritense/formflow/rest/FormFlowResourceTest.kt b/backend/form-flow/src/test/kotlin/com/ritense/formflow/rest/FormFlowResourceTest.kt index 8eab80fd05..10c8ed32a5 100644 --- a/backend/form-flow/src/test/kotlin/com/ritense/formflow/rest/FormFlowResourceTest.kt +++ b/backend/form-flow/src/test/kotlin/com/ritense/formflow/rest/FormFlowResourceTest.kt @@ -47,6 +47,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.springframework.test.web.servlet.setup.MockMvcBuilders +import com.ritense.valtimo.Jackson2TestUtils class FormFlowResourceTest : BaseTest() { lateinit var mockMvc: MockMvc @@ -90,7 +91,9 @@ class FormFlowResourceTest : BaseTest() { whenever(stepInstance.id).thenReturn(stepInstanceId) whenever(stepInstance.definition).thenReturn(step1) - mockMvc = MockMvcBuilders.standaloneSetup(formFlowResource).build() + mockMvc = MockMvcBuilders.standaloneSetup(formFlowResource) + .setMessageConverters(Jackson2TestUtils.jackson2Converter()) + .build() } @Test diff --git a/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/security/config/FormViewModelHttpSecurityConfigurerKotlin.kt b/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/security/config/FormViewModelHttpSecurityConfigurerKotlin.kt index 0fdebfe848..075264cbef 100644 --- a/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/security/config/FormViewModelHttpSecurityConfigurerKotlin.kt +++ b/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/security/config/FormViewModelHttpSecurityConfigurerKotlin.kt @@ -21,19 +21,19 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class FormViewModelHttpSecurityConfigurerKotlin : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> requests.requestMatchers( - antMatcher(POST, "$BASE_URL/$START_FORM"), - antMatcher(POST, "$BASE_URL/$USER_TASK"), - antMatcher(GET, "$BASE_URL/$START_FORM"), - antMatcher(GET, "$BASE_URL/$USER_TASK"), - antMatcher(POST, "$BASE_URL/submit/$START_FORM"), - antMatcher(POST, "$BASE_URL/submit/$USER_TASK") + pathPattern(POST, "$BASE_URL/$START_FORM"), + pathPattern(POST, "$BASE_URL/$USER_TASK"), + pathPattern(GET, "$BASE_URL/$START_FORM"), + pathPattern(GET, "$BASE_URL/$USER_TASK"), + pathPattern(POST, "$BASE_URL/submit/$START_FORM"), + pathPattern(POST, "$BASE_URL/submit/$USER_TASK") ).authenticated() } } catch (e: Exception) { diff --git a/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResource.kt b/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResource.kt index 62ee3fd628..8928c3a840 100644 --- a/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResource.kt +++ b/backend/form-view-model/src/main/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResource.kt @@ -46,7 +46,7 @@ class FormViewModelResource( fun getStartFormViewModel( @RequestParam processDefinitionKey: String, @RequestParam(required = false) documentId: UUID? - ): ResponseEntity { + ): ResponseEntity { val viewModel = formViewModelService.getStartFormViewModel( processDefinitionKey = processDefinitionKey, documentId = documentId @@ -54,19 +54,19 @@ class FormViewModelResource( return if (viewModel != null) { ResponseEntity.ok(viewModel) } else { - ResponseEntity.notFound().build() + ResponseEntity.notFound().build() } } @GetMapping("/user-task") fun getUserTaskFormViewModel( @RequestParam taskInstanceId: String - ): ResponseEntity { + ): ResponseEntity { return formViewModelService.getUserTaskFormViewModel( taskInstanceId = taskInstanceId, )?.let { ResponseEntity.ok(it) - } ?: ResponseEntity.notFound().build() + } ?: ResponseEntity.notFound().build() } @PostMapping("/start-form") @@ -83,7 +83,7 @@ class FormViewModelResource( documentId = documentId, )?.let { ResponseEntity.ok(it) - } ?: ResponseEntity.notFound().build() + } ?: ResponseEntity.notFound().build() } @PostMapping("/user-task") @@ -98,7 +98,7 @@ class FormViewModelResource( submission = submission )?.let { ResponseEntity.ok(it) - } ?: ResponseEntity.notFound().build() + } ?: ResponseEntity.notFound().build() } @PostMapping("/submit/user-task") diff --git a/backend/form-view-model/src/test/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResourceIntTest.kt b/backend/form-view-model/src/test/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResourceIntTest.kt index e64b5014b3..14d7b24ca6 100644 --- a/backend/form-view-model/src/test/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResourceIntTest.kt +++ b/backend/form-view-model/src/test/kotlin/com/ritense/formviewmodel/web/rest/FormViewModelResourceIntTest.kt @@ -52,6 +52,7 @@ class FormViewModelResourceIntTest @Autowired constructor( internal fun init() { mockMvc = MockMvcBuilders.standaloneSetup(formViewModelResource) .setCustomArgumentResolvers(PageableHandlerMethodArgumentResolver()) + .setMessageConverters(com.ritense.valtimo.Jackson2TestUtils.jackson2Converter()) .build() } diff --git a/backend/form/src/main/java/com/ritense/form/autoconfigure/FormAutoConfiguration.java b/backend/form/src/main/java/com/ritense/form/autoconfigure/FormAutoConfiguration.java index 7e7dc1227c..e8e9faf0f8 100644 --- a/backend/form/src/main/java/com/ritense/form/autoconfigure/FormAutoConfiguration.java +++ b/backend/form/src/main/java/com/ritense/form/autoconfigure/FormAutoConfiguration.java @@ -44,7 +44,7 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ResourceLoader; diff --git a/backend/form/src/main/java/com/ritense/form/security/config/FormFileHttpSecurityConfigurer.java b/backend/form/src/main/java/com/ritense/form/security/config/FormFileHttpSecurityConfigurer.java index 8ee6c98ff3..03f4f10c8b 100644 --- a/backend/form/src/main/java/com/ritense/form/security/config/FormFileHttpSecurityConfigurer.java +++ b/backend/form/src/main/java/com/ritense/form/security/config/FormFileHttpSecurityConfigurer.java @@ -19,7 +19,7 @@ import static org.springframework.http.HttpMethod.DELETE; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -35,9 +35,9 @@ public FormFileHttpSecurityConfigurer() { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/form-file")).permitAll() - .requestMatchers(antMatcher(POST, "/api/v1/form-file/upload")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/form-file")).authenticated()); + requests.requestMatchers(pathPattern(GET, "/api/v1/form-file")).permitAll() + .requestMatchers(pathPattern(POST, "/api/v1/form-file/upload")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/form-file")).authenticated()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/form/src/main/java/com/ritense/form/security/config/FormHttpSecurityConfigurer.java b/backend/form/src/main/java/com/ritense/form/security/config/FormHttpSecurityConfigurer.java index b1910a0d4c..88c9484e58 100644 --- a/backend/form/src/main/java/com/ritense/form/security/config/FormHttpSecurityConfigurer.java +++ b/backend/form/src/main/java/com/ritense/form/security/config/FormHttpSecurityConfigurer.java @@ -17,7 +17,7 @@ package com.ritense.form.security.config; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -33,9 +33,9 @@ public FormHttpSecurityConfigurer() { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/form")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/form/{formDefinitionName}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/form/{formDefinitionName}/document/{documentId}")).authenticated()); + .requestMatchers(pathPattern(GET, "/api/v1/form")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/form/{formDefinitionName}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/form/{formDefinitionName}/document/{documentId}")).authenticated()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/form/src/main/kotlin/com/ritense/form/mapper/FormProcessLinkMapper.kt b/backend/form/src/main/kotlin/com/ritense/form/mapper/FormProcessLinkMapper.kt index 1d630d1d79..d2062ae5b1 100644 --- a/backend/form/src/main/kotlin/com/ritense/form/mapper/FormProcessLinkMapper.kt +++ b/backend/form/src/main/kotlin/com/ritense/form/mapper/FormProcessLinkMapper.kt @@ -81,7 +81,7 @@ class FormProcessLinkMapper( processDefinitionId = deployDto.processDefinitionId, activityId = deployDto.activityId, activityType = deployDto.activityType, - formDefinitionId = formDefinition.id, + formDefinitionId = formDefinition.id!!, viewModelEnabled = deployDto.viewModelEnabled, formDisplayType = deployDto.formDisplayType, formSize = deployDto.formSize, @@ -100,7 +100,7 @@ class FormProcessLinkMapper( return FormProcessLinkUpdateRequestDto( id = existingProcessLinkId, - formDefinitionId = formDefinition.id, + formDefinitionId = formDefinition.id!!, viewModelEnabled = deployDto.viewModelEnabled, formDisplayType = deployDto.formDisplayType, formSize = deployDto.formSize, diff --git a/backend/form/src/main/kotlin/com/ritense/form/security/config/FormHttpSecurityConfigurerKotlin.kt b/backend/form/src/main/kotlin/com/ritense/form/security/config/FormHttpSecurityConfigurerKotlin.kt index 26a13266a3..fe697df902 100644 --- a/backend/form/src/main/kotlin/com/ritense/form/security/config/FormHttpSecurityConfigurerKotlin.kt +++ b/backend/form/src/main/kotlin/com/ritense/form/security/config/FormHttpSecurityConfigurerKotlin.kt @@ -23,7 +23,7 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class FormHttpSecurityConfigurerKotlin : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { @@ -31,45 +31,45 @@ class FormHttpSecurityConfigurerKotlin : HttpSecurityConfigurer { http.authorizeHttpRequests { requests -> requests .requestMatchers( - antMatcher(POST, "$PROCESS_LINK_BASE_URL/{processLinkId}/form/submission"), - antMatcher(GET, "$PROCESS_LINK_BASE_URL/form-definition/{formKey}"), - antMatcher(GET, INTERMEDIATE_BASE_URL), - antMatcher(POST, INTERMEDIATE_BASE_URL), - antMatcher(DELETE, INTERMEDIATE_BASE_URL) + pathPattern(POST, "$PROCESS_LINK_BASE_URL/{processLinkId}/form/submission"), + pathPattern(GET, "$PROCESS_LINK_BASE_URL/form-definition/{formKey}"), + pathPattern(GET, INTERMEDIATE_BASE_URL), + pathPattern(POST, INTERMEDIATE_BASE_URL), + pathPattern(DELETE, INTERMEDIATE_BASE_URL) ).authenticated() .requestMatchers( - antMatcher(GET, "/api/management/v1/form-option"), - antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-option"), - antMatcher( + pathPattern(GET, "/api/management/v1/form-option"), + pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form-option"), + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form" ), - antMatcher( + pathPattern( POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form" ), - antMatcher( + pathPattern( PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form" ), - antMatcher( + pathPattern( DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form/{formDefinitionId}" ), - antMatcher( + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form/{formDefinitionId}" ), - antMatcher( + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/form/{name}/exists" ), - antMatcher(GET, "/api/management/v1/form"), - antMatcher(GET, "/api/management/v1/form/{formDefinitionId}"), - antMatcher(POST, "/api/management/v1/form"), - antMatcher(PUT, "/api/management/v1/form"), - antMatcher(DELETE, "/api/management/v1/form/{formDefinitionId}"), - antMatcher(GET, "/api/management/v1/form/exists/{name}") + pathPattern(GET, "/api/management/v1/form"), + pathPattern(GET, "/api/management/v1/form/{formDefinitionId}"), + pathPattern(POST, "/api/management/v1/form"), + pathPattern(PUT, "/api/management/v1/form"), + pathPattern(DELETE, "/api/management/v1/form/{formDefinitionId}"), + pathPattern(GET, "/api/management/v1/form/exists/{name}") ).hasAuthority(ADMIN) } } catch (e: Exception) { diff --git a/backend/form/src/main/kotlin/com/ritense/form/service/impl/DefaultFormSubmissionService.kt b/backend/form/src/main/kotlin/com/ritense/form/service/impl/DefaultFormSubmissionService.kt index c58a786db9..2762158c00 100644 --- a/backend/form/src/main/kotlin/com/ritense/form/service/impl/DefaultFormSubmissionService.kt +++ b/backend/form/src/main/kotlin/com/ritense/form/service/impl/DefaultFormSubmissionService.kt @@ -536,7 +536,7 @@ class DefaultFormSubmissionService( withLoggingContext(JsonSchemaDocument::class, document.id()) { formFields.forEach { it.postProcess(document) } publishExternalDataSubmittedEvent(externalFormData, documentDefinitionName, document) - valueResolverService.handleValues(document.id.id, remainingValueResolverValues) + valueResolverService.handleValues(document.id!!.id, remainingValueResolverValues) } } ) diff --git a/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormManagementResource.kt b/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormManagementResource.kt index 96434a6751..9cf0a06ed0 100644 --- a/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormManagementResource.kt +++ b/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormManagementResource.kt @@ -137,7 +137,7 @@ class FormManagementResource( fun getFormDefinitions( @RequestParam(required = false) searchTerm: String?, @PageableDefault(sort = ["name"], direction = ASC) pageable: Pageable? - ): ResponseEntity> { + ): ResponseEntity> { return if (searchTerm.isNullOrEmpty()) { ResponseEntity.ok(formDefinitionService.getAll(pageable)) } else { diff --git a/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormResource.kt b/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormResource.kt index 0e4f95e755..281a5e0f0b 100644 --- a/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormResource.kt +++ b/backend/form/src/main/kotlin/com/ritense/form/web/rest/FormResource.kt @@ -93,8 +93,8 @@ class FormResource( return ResponseEntity.ok(prefilledForm) } - fun applyResult(result: T): ResponseEntity { - val httpStatus = if (result!!.errors().isEmpty()) HttpStatus.OK else HttpStatus.BAD_REQUEST + fun applyResult(result: T): ResponseEntity { + val httpStatus = if (result.errors().isEmpty()) HttpStatus.OK else HttpStatus.BAD_REQUEST return ResponseEntity.status(httpStatus).body(result) } } diff --git a/backend/form/src/test/kotlin/com/ritense/form/mapper/FormProcessLinkMapperTest.kt b/backend/form/src/test/kotlin/com/ritense/form/mapper/FormProcessLinkMapperTest.kt index cd4b69ee3c..ac8580e173 100644 --- a/backend/form/src/test/kotlin/com/ritense/form/mapper/FormProcessLinkMapperTest.kt +++ b/backend/form/src/test/kotlin/com/ritense/form/mapper/FormProcessLinkMapperTest.kt @@ -205,7 +205,7 @@ internal class FormProcessLinkMapperTest { processDefinitionId = "processDefinitionId", activityId = "activityId", activityType = USER_TASK_CREATE, - formDefinitionId = formDefinition.id, + formDefinitionId = formDefinition.id!!, viewModelEnabled = false ) diff --git a/backend/form/src/test/kotlin/com/ritense/form/service/DefaultFormSubmissionServiceIntTest.kt b/backend/form/src/test/kotlin/com/ritense/form/service/DefaultFormSubmissionServiceIntTest.kt index 8cca58d68e..6419b1bf2e 100644 --- a/backend/form/src/test/kotlin/com/ritense/form/service/DefaultFormSubmissionServiceIntTest.kt +++ b/backend/form/src/test/kotlin/com/ritense/form/service/DefaultFormSubmissionServiceIntTest.kt @@ -82,7 +82,7 @@ class DefaultFormSubmissionServiceIntTest @Autowired constructor( } val document = runWithoutAuthorization { documentService.get(submissionResult.documentId()) } - val businessKey = document.id.id.toString() + val businessKey = document.id!!.id.toString() val json = objectMapper.writeValueAsString(document.content().asJson()) assertThat(json, hasJsonPath("""${'$'}.personalInformation.firstName""", equalTo("John"))) assertThat(json, hasJsonPath("""${'$'}.fruitTypes[0].apples""", equalTo(3))) diff --git a/backend/form/src/test/kotlin/com/ritense/form/service/PrefillFormServiceTest.kt b/backend/form/src/test/kotlin/com/ritense/form/service/PrefillFormServiceTest.kt index a72d947170..2e25a1b9af 100644 --- a/backend/form/src/test/kotlin/com/ritense/form/service/PrefillFormServiceTest.kt +++ b/backend/form/src/test/kotlin/com/ritense/form/service/PrefillFormServiceTest.kt @@ -111,7 +111,7 @@ class PrefillFormServiceTest : BaseTest() { requestedValues.associateWith(dataMap::get) } - val prefilledFormDefinition = prefillFormService.getPrefilledFormDefinition(formDefinition.id!!, document.id.id) + val prefilledFormDefinition = prefillFormService.getPrefilledFormDefinition(formDefinition.id!!, document.id!!.id) assertThat(prefilledFormDefinition).isNotNull val inputFields = prefilledFormDefinition.inputFields diff --git a/backend/form/src/test/kotlin/com/ritense/form/web/rest/FormManagementResourceIntTest.kt b/backend/form/src/test/kotlin/com/ritense/form/web/rest/FormManagementResourceIntTest.kt index a61efa62a3..2ccc58987c 100644 --- a/backend/form/src/test/kotlin/com/ritense/form/web/rest/FormManagementResourceIntTest.kt +++ b/backend/form/src/test/kotlin/com/ritense/form/web/rest/FormManagementResourceIntTest.kt @@ -182,13 +182,13 @@ class FormManagementResourceIntTest : BaseIntegrationTest() { fun `should delete form for case definition`() { val savedFormDefinition = formDefinitionRepository.save(formDefinition()) - Assertions.assertThat(formDefinitionRepository.existsById(savedFormDefinition.id)).isTrue() + Assertions.assertThat(formDefinitionRepository.existsById(savedFormDefinition.id!!)).isTrue() mockMvc.perform( MockMvcRequestBuilders.delete("$BASE_URL/{formDefinitionId}", "person", "1.0.0", - savedFormDefinition.id + savedFormDefinition.id!! ).contentType(MediaType.APPLICATION_JSON_VALUE) ) .andDo(MockMvcResultHandlers.print()) @@ -196,7 +196,7 @@ class FormManagementResourceIntTest : BaseIntegrationTest() { formDefinitionRepository.flush() - Assertions.assertThat(formDefinitionRepository.existsById(savedFormDefinition.id)).isFalse() + Assertions.assertThat(formDefinitionRepository.existsById(savedFormDefinition.id!!)).isFalse() } companion object { diff --git a/backend/form/src/test/kotlin/com/ritense/form/web/rest/IntermediateSubmissionResourceIntTest.kt b/backend/form/src/test/kotlin/com/ritense/form/web/rest/IntermediateSubmissionResourceIntTest.kt index cfeb853f27..22b68405d6 100644 --- a/backend/form/src/test/kotlin/com/ritense/form/web/rest/IntermediateSubmissionResourceIntTest.kt +++ b/backend/form/src/test/kotlin/com/ritense/form/web/rest/IntermediateSubmissionResourceIntTest.kt @@ -49,6 +49,7 @@ class IntermediateSubmissionResourceIntTest : BaseIntegrationTest() { internal fun init() { mockMvc = MockMvcBuilders.standaloneSetup(intermediateSubmissionResource) .setCustomArgumentResolvers(PageableHandlerMethodArgumentResolver()) + .setMessageConverters(com.ritense.valtimo.Jackson2TestUtils.jackson2Converter()) .alwaysDo(MockMvcResultHandlers.print()) .build() val task: OperatonTask = mock() diff --git a/backend/gradle/test.gradle b/backend/gradle/test.gradle index fc702ce0d2..87ca2ab157 100644 --- a/backend/gradle/test.gradle +++ b/backend/gradle/test.gradle @@ -42,6 +42,7 @@ tasks.register("integrationTesting") { tasks.register("integrationTestingPostgresql", Test) { group = 'verification' + maxHeapSize = '1g' systemProperty("spring.profiles.include", "inttest,postgresql") testLogging { events("passed", "skipped", "failed", "standardError") diff --git a/backend/iko/build.gradle b/backend/iko/build.gradle index 083161f445..768a6a4ed4 100644 --- a/backend/iko/build.gradle +++ b/backend/iko/build.gradle @@ -58,8 +58,8 @@ dependencies { implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" - implementation "org.liquibase.ext:liquibase-hibernate6:${liquibaseVersion}" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "org.liquibase.ext:liquibase-hibernate7:${liquibaseHibernateVersion}" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "org.jetbrains.kotlin:kotlin-reflect" implementation "io.github.oshai:kotlin-logging:${kotlinLoggingVersion}" implementation "com.github.erosb:everit-json-schema:${everitJsonSchemaVersion}" diff --git a/backend/iko/src/main/kotlin/com/ritense/iko/autoconfigure/IkoAutoConfiguration.kt b/backend/iko/src/main/kotlin/com/ritense/iko/autoconfigure/IkoAutoConfiguration.kt index faed11f833..d123d0fb9d 100644 --- a/backend/iko/src/main/kotlin/com/ritense/iko/autoconfigure/IkoAutoConfiguration.kt +++ b/backend/iko/src/main/kotlin/com/ritense/iko/autoconfigure/IkoAutoConfiguration.kt @@ -76,7 +76,7 @@ import com.ritense.valtimo.contract.iko.IkoRepository import com.ritense.widget.service.WidgetService import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/iko/src/main/kotlin/com/ritense/iko/security/config/IkoHttpSecurityConfigurer.kt b/backend/iko/src/main/kotlin/com/ritense/iko/security/config/IkoHttpSecurityConfigurer.kt index 00a4d6fa13..9dcc782881 100644 --- a/backend/iko/src/main/kotlin/com/ritense/iko/security/config/IkoHttpSecurityConfigurer.kt +++ b/backend/iko/src/main/kotlin/com/ritense/iko/security/config/IkoHttpSecurityConfigurer.kt @@ -24,7 +24,7 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class IkoHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -32,65 +32,65 @@ class IkoHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-types")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-property-fields/{type}/repository-config")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/iko/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/iko/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-types")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-property-fields/{type}/repository-config")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko/{ikoKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/iko/{ikoKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko/{ikoKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/iko/{ikoKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/iko-view")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-property-fields/{type}/view")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/iko-view/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko-view/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/iko-view/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}/export")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/iko-view/import")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/iko-view")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-property-fields/{type}/view")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/iko-view/{viewKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko-view/{viewKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/iko-view/{viewKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}/export")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/iko-view/import")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/iko-view/{key}/search-action")).authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/iko-view/{key}/search-action/{key}/search")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-property-fields/{type}/search-action")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}/search-action")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}/search-action/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/iko-view/{key}/search-action/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko-view/{key}/search-action/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko-view/{key}/search-action")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/iko-view/{key}/search-action/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/iko-view/{viewKey}/search-action")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/iko-view/{viewKey}/search-action/{actionKey}/search")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-property-fields/{type}/search-action")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}/search-action")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko-view/{viewKey}/search-action")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/iko-view/{key}/tab")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-property-fields/{type}/tab")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}/tab")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/iko-view/{key}/tab/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/iko-view/{key}/tab/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko-view/{key}/tab/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/iko-view/{key}/tab")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/iko-view/{key}/tab/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/iko-view/{viewKey}/tab")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-property-fields/{type}/tab")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}/tab")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/iko-view/{viewKey}/tab/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/iko-view/{viewKey}/tab/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko-view/{viewKey}/tab/{tabKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/iko-view/{viewKey}/tab")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/iko-view/{viewKey}/tab/{tabKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/v1/iko-view/{key}/tab/{key}/widget")).authenticated() - .requestMatchers(antMatcher(GET,"/api/v1/iko-view/{key}/tab/{key}/widget/{key}/data")).authenticated() - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/tab/{key}/widget")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/tab/{key}/widget/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST,"/api/management/v1/iko-view/{key}/tab/{key}/widget/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/tab/{key}/widget/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/tab/{key}/widget")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE,"/api/management/v1/iko-view/{key}/tab/{key}/widget/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/v1/iko-view/{viewKey}/tab/{tabKey}/widget")).authenticated() + .requestMatchers(pathPattern(GET,"/api/v1/iko-view/{viewKey}/tab/{tabKey}/widget/{widgetKey}/data")).authenticated() + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget/{widgetKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE,"/api/management/v1/iko-view/{viewKey}/tab/{tabKey}/widget/{widgetKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/column")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/column/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST,"/api/management/v1/iko-view/{key}/column/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/column/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/column")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE,"/api/management/v1/iko-view/{key}/column/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/column")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/column/{columnKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST,"/api/management/v1/iko-view/{viewKey}/column/{columnKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/column/{columnKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/column")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE,"/api/management/v1/iko-view/{viewKey}/column/{columnKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE,"/api/management/v1/iko-view/{key}/search-action/{key}/search-field/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field/{fieldKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field/{fieldKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field/{fieldKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE,"/api/management/v1/iko-view/{viewKey}/search-action/{actionKey}/search-field/{fieldKey}")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/iko/src/main/kotlin/com/ritense/iko/service/IkoSearchActionService.kt b/backend/iko/src/main/kotlin/com/ritense/iko/service/IkoSearchActionService.kt index ff69e624dd..cd45ead274 100644 --- a/backend/iko/src/main/kotlin/com/ritense/iko/service/IkoSearchActionService.kt +++ b/backend/iko/src/main/kotlin/com/ritense/iko/service/IkoSearchActionService.kt @@ -118,12 +118,8 @@ class IkoSearchActionService( applicationEventPublisher.publishEvent( IkoSearchActionPreDeleteEvent(ikoViewKey, key) ) - ikoSearchActionRepository.delete( - getSpecification( - key = key, - ikoViewKey = ikoViewKey, - ) - ) + val entities = ikoSearchActionRepository.findAll(getSpecification(key = key, ikoViewKey = ikoViewKey)) + ikoSearchActionRepository.deleteAll(entities) } private fun getSpecification( diff --git a/backend/iko/src/main/kotlin/com/ritense/iko/web/rest/IkoWidgetResource.kt b/backend/iko/src/main/kotlin/com/ritense/iko/web/rest/IkoWidgetResource.kt index e8c84d85a8..19ccfaabd7 100644 --- a/backend/iko/src/main/kotlin/com/ritense/iko/web/rest/IkoWidgetResource.kt +++ b/backend/iko/src/main/kotlin/com/ritense/iko/web/rest/IkoWidgetResource.kt @@ -60,7 +60,7 @@ class IkoWidgetResource( @RequestParam properties: LinkedMultiValueMap>, @PageableDefault pageable: Pageable, request: HttpServletRequest, - ): ResponseEntity { + ): ResponseEntity { val pageSize = request.parameterMap["size"]?.firstOrNull()?.toIntOrNull() val collapsedValuesPropertiesMap = properties diff --git a/backend/iko/src/test/kotlin/com/ritense/iko/client/IkoClientTest.kt b/backend/iko/src/test/kotlin/com/ritense/iko/client/IkoClientTest.kt index 0f57ee76c0..57b699f5a4 100644 --- a/backend/iko/src/test/kotlin/com/ritense/iko/client/IkoClientTest.kt +++ b/backend/iko/src/test/kotlin/com/ritense/iko/client/IkoClientTest.kt @@ -16,6 +16,7 @@ package com.ritense.iko.client +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -24,7 +25,6 @@ import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance -import org.springframework.web.client.RestClient import java.net.URI @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -44,7 +44,7 @@ class IkoClientTest { @Test fun `should get iko JSON by id`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = IkoClient(restClientBuilder, MapperSingleton.get()) val responseBody = """ @@ -114,7 +114,7 @@ class IkoClientTest { @Test fun `should send create besluit request and parse response when vervalreden is null`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = IkoClient(restClientBuilder, MapperSingleton.get()) val responseBody = """ diff --git a/backend/keycloak-iam/build.gradle b/backend/keycloak-iam/build.gradle index 902b43e75b..bf12edf967 100644 --- a/backend/keycloak-iam/build.gradle +++ b/backend/keycloak-iam/build.gradle @@ -38,6 +38,7 @@ dependencies { api "org.springframework.data:spring-data-commons" implementation "org.springframework.boot:spring-boot-starter" + implementation "org.springframework.boot:spring-boot-starter-cache" implementation "org.springframework.boot:spring-boot-starter-web" implementation "org.springframework.boot:spring-boot-starter-actuator" implementation "org.springframework.boot:spring-boot-starter-data-jpa" diff --git a/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/autoconfigure/KeycloakAutoConfiguration.java b/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/autoconfigure/KeycloakAutoConfiguration.java index f42a021489..b09c3e3125 100644 --- a/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/autoconfigure/KeycloakAutoConfiguration.java +++ b/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/autoconfigure/KeycloakAutoConfiguration.java @@ -36,7 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.security.oauth2.client.ClientsConfiguredCondition; +import org.springframework.boot.security.oauth2.client.autoconfigure.ConditionalOnOAuth2ClientRegistrationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; @@ -111,7 +111,7 @@ public KeycloakService keycloakService( @Bean @Order(465) @ConditionalOnMissingBean(KeycloakOAuth2HttpSecurityConfigurer.class) - @Conditional(ClientsConfiguredCondition.class) + @ConditionalOnOAuth2ClientRegistrationProperties public KeycloakOAuth2HttpSecurityConfigurer keycloakOAuth2HttpSecurityConfigurer( KeycloakService keycloakService ) { diff --git a/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/liquibase/changelog/AbstractMigrateWithKeycloakChangeLog.kt b/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/liquibase/changelog/AbstractMigrateWithKeycloakChangeLog.kt index da32e21a45..4af42ef411 100644 --- a/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/liquibase/changelog/AbstractMigrateWithKeycloakChangeLog.kt +++ b/backend/keycloak-iam/src/main/java/com/valtimo/keycloak/liquibase/changelog/AbstractMigrateWithKeycloakChangeLog.kt @@ -47,7 +47,7 @@ abstract class AbstractMigrateWithKeycloakChangeLog : EnvironmentPostProcessor { override fun postProcessEnvironment(environment: ConfigurableEnvironment, application: SpringApplication) { Companion.environment = environment Companion.userCache = - ConcurrentLruCache(DEFAULT_BUFFER_SIZE, ::getKeycloakUserFromKeycloak) + ConcurrentLruCache(DEFAULT_BUFFER_SIZE, ::getKeycloakUserFromKeycloak) } protected fun checkTableExists(connection: JdbcConnection, tableName: String): Boolean { @@ -118,10 +118,8 @@ abstract class AbstractMigrateWithKeycloakChangeLog : EnvironmentPostProcessor { } } - protected fun getKeycloakUserFromKeycloak(emailOrUsernameOrUserId: String?): AbstractUserRepresentation? { - if (emailOrUsernameOrUserId == null) { - return null - } else if (emailOrUsernameOrUserId == SYSTEM_ACCOUNT) { + protected fun getKeycloakUserFromKeycloak(emailOrUsernameOrUserId: String): AbstractUserRepresentation { + if (emailOrUsernameOrUserId == SYSTEM_ACCOUNT) { val systemUser = UserRepresentation() systemUser.id = SYSTEM_ACCOUNT systemUser.username = SYSTEM_ACCOUNT @@ -237,7 +235,7 @@ abstract class AbstractMigrateWithKeycloakChangeLog : EnvironmentPostProcessor { protected lateinit var environment: Environment - protected lateinit var userCache: ConcurrentLruCache + protected lateinit var userCache: ConcurrentLruCache private val logger = KotlinLogging.logger {} } } diff --git a/backend/keycloak-iam/src/main/kotlin/com/valtimo/keycloak/security/config/ExternalRoleSecurityConfigurer.kt b/backend/keycloak-iam/src/main/kotlin/com/valtimo/keycloak/security/config/ExternalRoleSecurityConfigurer.kt index 23e3a66e58..c64dd6834d 100644 --- a/backend/keycloak-iam/src/main/kotlin/com/valtimo/keycloak/security/config/ExternalRoleSecurityConfigurer.kt +++ b/backend/keycloak-iam/src/main/kotlin/com/valtimo/keycloak/security/config/ExternalRoleSecurityConfigurer.kt @@ -22,7 +22,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ExternalRoleSecurityConfigurer: HttpSecurityConfigurer { @@ -30,7 +30,7 @@ class ExternalRoleSecurityConfigurer: HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/external-role")).hasAnyAuthority(USER, ADMIN) + requests.requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/external-role")).hasAnyAuthority(USER, ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/localization/build.gradle b/backend/localization/build.gradle index 08762e2b4a..b2bbe27025 100644 --- a/backend/localization/build.gradle +++ b/backend/localization/build.gradle @@ -38,6 +38,7 @@ dependencies { implementation(project(":backend:contract")) implementation(project(":backend:changelog")) + implementation "org.springframework.boot:spring-boot-starter-cache" implementation "org.springframework.boot:spring-boot-starter-web" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-security" diff --git a/backend/localization/src/main/kotlin/com/ritense/localization/autoconfigure/LocalizationAutoConfiguration.kt b/backend/localization/src/main/kotlin/com/ritense/localization/autoconfigure/LocalizationAutoConfiguration.kt index 27160854ae..717ef5ab2f 100644 --- a/backend/localization/src/main/kotlin/com/ritense/localization/autoconfigure/LocalizationAutoConfiguration.kt +++ b/backend/localization/src/main/kotlin/com/ritense/localization/autoconfigure/LocalizationAutoConfiguration.kt @@ -24,7 +24,7 @@ import com.ritense.localization.web.rest.AdminLocalizationResource import com.ritense.localization.web.rest.LocalizationResource import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.cache.annotation.EnableCaching import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/localization/src/main/kotlin/com/ritense/localization/security/config/LocalizationHttpSecurityConfigurer.kt b/backend/localization/src/main/kotlin/com/ritense/localization/security/config/LocalizationHttpSecurityConfigurer.kt index af8abd27fd..cffa35276a 100644 --- a/backend/localization/src/main/kotlin/com/ritense/localization/security/config/LocalizationHttpSecurityConfigurer.kt +++ b/backend/localization/src/main/kotlin/com/ritense/localization/security/config/LocalizationHttpSecurityConfigurer.kt @@ -22,17 +22,17 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class LocalizationHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/localization")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/localization/{languageKey}")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/management/v1/localization/{languageKey}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/localization")).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern(GET, "/api/v1/localization")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/localization/{languageKey}")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/management/v1/localization/{languageKey}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/localization")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/logging/build.gradle b/backend/logging/build.gradle index f706e94a19..c6396d73ea 100644 --- a/backend/logging/build.gradle +++ b/backend/logging/build.gradle @@ -39,7 +39,7 @@ dependencies { implementation "org.springframework.boot:spring-boot" implementation "org.springframework.boot:spring-boot-starter" - implementation "org.springframework.boot:spring-boot-starter-aop" + implementation "org.springframework.boot:spring-boot-starter-aspectj" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-security" implementation "com.fasterxml.jackson.core:jackson-databind" diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/LoggingAutoConfiguration.kt b/backend/logging/src/main/kotlin/com/ritense/logging/LoggingAutoConfiguration.kt index a3232d2cf7..a2063d8ab5 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/LoggingAutoConfiguration.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/LoggingAutoConfiguration.kt @@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.core.Ordered.LOWEST_PRECEDENCE import org.springframework.core.annotation.Order diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/LoggingContextExceptionReporter.kt b/backend/logging/src/main/kotlin/com/ritense/logging/LoggingContextExceptionReporter.kt index 64b0f83457..6ac842c46d 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/LoggingContextExceptionReporter.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/LoggingContextExceptionReporter.kt @@ -20,7 +20,7 @@ import org.springframework.boot.SpringBootExceptionReporter class LoggingContextExceptionReporter : SpringBootExceptionReporter { - override fun reportException(failure: Throwable?): Boolean { + override fun reportException(failure: Throwable): Boolean { setErrorLoggingContext() return false } diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventExceptionSpecificationHelper.kt b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventExceptionSpecificationHelper.kt index c7c6550731..866a8d53fa 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventExceptionSpecificationHelper.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventExceptionSpecificationHelper.kt @@ -18,6 +18,7 @@ package com.ritense.logging.repository import com.ritense.logging.domain.LoggingEventException import com.ritense.logging.repository.LoggingEventSpecificationHelper.Companion.TIMESTAMP +import org.springframework.data.jpa.domain.DeleteSpecification import org.springframework.data.jpa.domain.Specification import java.time.LocalDateTime import java.time.ZoneId @@ -33,5 +34,11 @@ class LoggingEventExceptionSpecificationHelper { val timestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() cb.lessThan(root.join(EVENT)[TIMESTAMP], timestamp) } + + @JvmStatic + fun deleteOlderThan(localDateTime: LocalDateTime) = DeleteSpecification { root, _, cb -> + val timestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() + cb.lessThan(root.join(EVENT)[TIMESTAMP], timestamp) + } } } \ No newline at end of file diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventPropertySpecificationHelper.kt b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventPropertySpecificationHelper.kt index 70d76bbae0..70753b599b 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventPropertySpecificationHelper.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventPropertySpecificationHelper.kt @@ -18,6 +18,7 @@ package com.ritense.logging.repository import com.ritense.logging.domain.LoggingEventProperty import com.ritense.logging.repository.LoggingEventSpecificationHelper.Companion.TIMESTAMP +import org.springframework.data.jpa.domain.DeleteSpecification import org.springframework.data.jpa.domain.Specification import java.time.LocalDateTime import java.time.ZoneId @@ -37,6 +38,12 @@ class LoggingEventPropertySpecificationHelper { cb.lessThan(root.join(EVENT)[TIMESTAMP], timestamp) } + @JvmStatic + fun deleteOlderThan(localDateTime: LocalDateTime) = DeleteSpecification { root, _, cb -> + val timestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() + cb.lessThan(root.join(EVENT)[TIMESTAMP], timestamp) + } + @JvmStatic fun byKeyValue(key: String, value: String) = Specification { root, _, cb -> cb.and( diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventSpecificationHelper.kt b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventSpecificationHelper.kt index 4a927edcc3..c7600c37ee 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventSpecificationHelper.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/repository/LoggingEventSpecificationHelper.kt @@ -20,6 +20,7 @@ import com.ritense.logging.domain.LoggingEvent import com.ritense.logging.repository.LoggingEventPropertySpecificationHelper.Companion.ID import com.ritense.logging.repository.LoggingEventPropertySpecificationHelper.Companion.KEY import com.ritense.logging.repository.LoggingEventPropertySpecificationHelper.Companion.VALUE +import org.springframework.data.jpa.domain.DeleteSpecification import org.springframework.data.jpa.domain.Specification import java.time.LocalDateTime import java.time.ZoneId @@ -78,6 +79,12 @@ class LoggingEventSpecificationHelper { cb.lessThan(root[TIMESTAMP], timestamp) } + @JvmStatic + fun deleteOlderThan(localDateTime: LocalDateTime) = DeleteSpecification { root, _, cb -> + val timestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() + cb.lessThan(root[TIMESTAMP], timestamp) + } + @JvmStatic fun byProperty(key: String, value: String) = Specification { root, _, cb -> val properties = root.join(PROPERTIES) diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/security/config/LoggingHttpSecurityConfigurer.kt b/backend/logging/src/main/kotlin/com/ritense/logging/security/config/LoggingHttpSecurityConfigurer.kt index f68615a13f..aa1cbb4270 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/security/config/LoggingHttpSecurityConfigurer.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/security/config/LoggingHttpSecurityConfigurer.kt @@ -21,7 +21,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class LoggingHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -29,7 +29,7 @@ class LoggingHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(POST, "/api/management/v1/logging")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/logging")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/logging/src/main/kotlin/com/ritense/logging/service/LoggingEventDeletionService.kt b/backend/logging/src/main/kotlin/com/ritense/logging/service/LoggingEventDeletionService.kt index 8a5e27c7dc..31269376f2 100644 --- a/backend/logging/src/main/kotlin/com/ritense/logging/service/LoggingEventDeletionService.kt +++ b/backend/logging/src/main/kotlin/com/ritense/logging/service/LoggingEventDeletionService.kt @@ -23,6 +23,7 @@ import com.ritense.logging.repository.LoggingEventPropertySpecificationHelper import com.ritense.logging.repository.LoggingEventRepository import com.ritense.logging.repository.LoggingEventSpecificationHelper import com.ritense.valtimo.contract.annotation.SkipComponentScan +import org.springframework.data.jpa.domain.DeleteSpecification import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -44,8 +45,8 @@ class LoggingEventDeletionService( ) fun deleteOldLoggingEvents() { val retentionDateTime = LocalDateTime.now() - Duration.ofMinutes(retentionInMinutes) - loggingEventPropertyRepository.delete(LoggingEventPropertySpecificationHelper.byOlderThan(retentionDateTime)) - loggingEventExceptionRepository.delete(LoggingEventExceptionSpecificationHelper.byOlderThan(retentionDateTime)) - loggingEventRepository.delete(LoggingEventSpecificationHelper.byOlderThan(retentionDateTime)) + loggingEventPropertyRepository.delete(LoggingEventPropertySpecificationHelper.deleteOlderThan(retentionDateTime)) + loggingEventExceptionRepository.delete(LoggingEventExceptionSpecificationHelper.deleteOlderThan(retentionDateTime)) + loggingEventRepository.delete(LoggingEventSpecificationHelper.deleteOlderThan(retentionDateTime)) } } diff --git a/backend/logging/src/main/resources/config/logging/logback/valtimo-defaults.xml b/backend/logging/src/main/resources/config/logging/logback/valtimo-defaults.xml index 670fa81fd8..61c4244e71 100644 --- a/backend/logging/src/main/resources/config/logging/logback/valtimo-defaults.xml +++ b/backend/logging/src/main/resources/config/logging/logback/valtimo-defaults.xml @@ -16,12 +16,12 @@ --> - + - + diff --git a/backend/mail/flowmailer/build.gradle b/backend/mail/flowmailer/build.gradle index d9bb8fa1d6..dc2a5a9fd4 100644 --- a/backend/mail/flowmailer/build.gradle +++ b/backend/mail/flowmailer/build.gradle @@ -61,7 +61,8 @@ dependencies { testImplementation "org.springframework.boot:spring-boot-starter-test" implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:${hypersistenceUtilsVersion}" + implementation "org.springframework.boot:spring-boot-restclient" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:${hypersistenceUtilsVersion}" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "org.apache.tika:tika-core:${apacheTikaVersion}" diff --git a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/autoconfigure/FlowmailerAutoConfiguration.kt b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/autoconfigure/FlowmailerAutoConfiguration.kt index 3673d802be..eda82324ed 100644 --- a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/autoconfigure/FlowmailerAutoConfiguration.kt +++ b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/autoconfigure/FlowmailerAutoConfiguration.kt @@ -24,7 +24,7 @@ import com.ritense.mail.flowmailer.service.FlowmailerTokenService import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.boot.restclient.RestTemplateBuilder import org.springframework.context.annotation.Bean import org.springframework.web.client.RestTemplate diff --git a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerDispatcher.kt b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerDispatcher.kt index 6955b8c873..6c2137a6ed 100644 --- a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerDispatcher.kt +++ b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerDispatcher.kt @@ -66,7 +66,7 @@ class FlowmailerMailDispatcher( val httpEntity = HttpEntity(objectMapper.writeValueAsString(submitMessage), getHttpHeaders(token)) val response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String::class.java) - if (httpEntity.body.encodeToByteArray().size > MAX_SIZE_EMAIL_BODY_IN_BYTES) { + if (httpEntity.body!!.encodeToByteArray().size > MAX_SIZE_EMAIL_BODY_IN_BYTES) { throw IllegalStateException("Email exceeds max size of 25 mb") } return MailMessageStatus.with( @@ -74,7 +74,7 @@ class FlowmailerMailDispatcher( "SENT", // Get id from header "location": // "https://api.flowmailer.net/520/messages/202106110944460bfd0ca81fd281ef9e" - response.headers.location.path.split("/").last() + response.headers.location!!.path.split("/").last() ).build() } catch (e: HttpStatusCodeException) { if (e.statusCode.is4xxClientError) { diff --git a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenService.kt b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenService.kt index ce6e467c22..e2cea8a5e5 100644 --- a/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenService.kt +++ b/backend/mail/flowmailer/src/main/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenService.kt @@ -55,13 +55,13 @@ class FlowmailerTokenService( httpEntity, getType(OauthTokenResponse::class.java) ) - return response.body.accessToken + return response.body!!.accessToken } catch (e: HttpStatusCodeException) { throw HttpClientErrorException(e.statusCode, "No token received") } } - fun getType(responseClass: Class): ParameterizedTypeReference { + fun getType(responseClass: Class): ParameterizedTypeReference { val type: ParameterizedTypeReference = ParameterizedTypeReference.forType( ResolvableType.forClass(responseClass).type ) diff --git a/backend/mail/flowmailer/src/test/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenServiceTest.kt b/backend/mail/flowmailer/src/test/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenServiceTest.kt index 138adabd25..64f421ba00 100644 --- a/backend/mail/flowmailer/src/test/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenServiceTest.kt +++ b/backend/mail/flowmailer/src/test/kotlin/com/ritense/mail/flowmailer/service/FlowmailerTokenServiceTest.kt @@ -74,7 +74,7 @@ class FlowmailerTokenServiceTest : BaseTest() { scope = "api", tokenType = "testToken" ) - val responseEntity = ResponseEntity(response, null, status) + val responseEntity = ResponseEntity.status(status).body(response) `when`(flowmailerProperties.clientId).thenReturn("clientId") `when`(flowmailerProperties.clientSecret).thenReturn("clientSecret") `when`( diff --git a/backend/mail/mandrill/src/main/java/com/ritense/mail/autoconfigure/MandrillMailAutoConfiguration.java b/backend/mail/mandrill/src/main/java/com/ritense/mail/autoconfigure/MandrillMailAutoConfiguration.java index 46b27ccb9f..a60b11f633 100644 --- a/backend/mail/mandrill/src/main/java/com/ritense/mail/autoconfigure/MandrillMailAutoConfiguration.java +++ b/backend/mail/mandrill/src/main/java/com/ritense/mail/autoconfigure/MandrillMailAutoConfiguration.java @@ -27,7 +27,7 @@ import com.ritense.mail.web.rest.WebhookResource; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/backend/mail/mandrill/src/main/java/com/ritense/mail/security/config/WebhookHttpSecurityConfigurer.java b/backend/mail/mandrill/src/main/java/com/ritense/mail/security/config/WebhookHttpSecurityConfigurer.java index 10f4c10006..88e644966e 100644 --- a/backend/mail/mandrill/src/main/java/com/ritense/mail/security/config/WebhookHttpSecurityConfigurer.java +++ b/backend/mail/mandrill/src/main/java/com/ritense/mail/security/config/WebhookHttpSecurityConfigurer.java @@ -18,7 +18,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -30,8 +30,8 @@ public class WebhookHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/mandrill/webhook")).permitAll() - .requestMatchers(antMatcher(POST, "/api/v1/mandrill/webhook")).permitAll()); + .requestMatchers(pathPattern(GET, "/api/v1/mandrill/webhook")).permitAll() + .requestMatchers(pathPattern(POST, "/api/v1/mandrill/webhook")).permitAll()); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/mail/mandrill/src/main/java/com/ritense/mail/service/MandrillHealthIndicator.java b/backend/mail/mandrill/src/main/java/com/ritense/mail/service/MandrillHealthIndicator.java index 2d67f622a0..6a97335b85 100644 --- a/backend/mail/mandrill/src/main/java/com/ritense/mail/service/MandrillHealthIndicator.java +++ b/backend/mail/mandrill/src/main/java/com/ritense/mail/service/MandrillHealthIndicator.java @@ -21,8 +21,8 @@ import com.ritense.mail.config.MandrillProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.health.contributor.AbstractHealthIndicator; +import org.springframework.boot.health.contributor.Health; public class MandrillHealthIndicator extends AbstractHealthIndicator { diff --git a/backend/mail/mandrill/src/test/java/com/ritense/mail/MandrillHealthIndicatorTest.java b/backend/mail/mandrill/src/test/java/com/ritense/mail/MandrillHealthIndicatorTest.java index 663c3b1c3c..023b5a09aa 100644 --- a/backend/mail/mandrill/src/test/java/com/ritense/mail/MandrillHealthIndicatorTest.java +++ b/backend/mail/mandrill/src/test/java/com/ritense/mail/MandrillHealthIndicatorTest.java @@ -29,7 +29,7 @@ import com.ritense.mail.service.MandrillHealthIndicator; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.health.contributor.Health; public class MandrillHealthIndicatorTest { diff --git a/backend/mail/src/main/kotlin/com/ritense/mail/autoconfigure/MailAutoConfiguration.kt b/backend/mail/src/main/kotlin/com/ritense/mail/autoconfigure/MailAutoConfiguration.kt index e40e9e376f..cfb5ffa910 100644 --- a/backend/mail/src/main/kotlin/com/ritense/mail/autoconfigure/MailAutoConfiguration.kt +++ b/backend/mail/src/main/kotlin/com/ritense/mail/autoconfigure/MailAutoConfiguration.kt @@ -30,7 +30,7 @@ import com.ritense.valtimo.contract.mail.MailFilter import com.ritense.valtimo.contract.mail.MailSender import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.data.jpa.repository.config.EnableJpaRepositories diff --git a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/autoconfigure/MilestonesAutoConfiguration.java b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/autoconfigure/MilestonesAutoConfiguration.java index a8e0c802ac..d2384bec92 100644 --- a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/autoconfigure/MilestonesAutoConfiguration.java +++ b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/autoconfigure/MilestonesAutoConfiguration.java @@ -33,7 +33,7 @@ import org.mapstruct.factory.Mappers; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneHttpSecurityConfigurer.java b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneHttpSecurityConfigurer.java index 48e234c246..5a5c8c7cee 100644 --- a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneHttpSecurityConfigurer.java +++ b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneHttpSecurityConfigurer.java @@ -20,7 +20,7 @@ import static org.springframework.http.HttpMethod.DELETE; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -32,10 +32,10 @@ public class MilestoneHttpSecurityConfigurer implements HttpSecurityConfigurer { public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/milestones/{id}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/milestones")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/milestones")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/v1/milestones/{id}")).hasAuthority(ADMIN)); + requests.requestMatchers(pathPattern(GET, "/api/v1/milestones/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/milestones")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/milestones")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/v1/milestones/{id}")).hasAuthority(ADMIN)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneInstanceHttpSecurityConfigurer.java b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneInstanceHttpSecurityConfigurer.java index 04bd71bb90..f026a76ac1 100644 --- a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneInstanceHttpSecurityConfigurer.java +++ b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneInstanceHttpSecurityConfigurer.java @@ -18,7 +18,7 @@ import static com.ritense.valtimo.contract.authentication.AuthoritiesConstants.ADMIN; import static org.springframework.http.HttpMethod.GET; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -30,8 +30,8 @@ public class MilestoneInstanceHttpSecurityConfigurer implements HttpSecurityConf public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/milestone-instances")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/milestones/{processDefinitionId}/flownodes")).hasAuthority(ADMIN)); + .requestMatchers(pathPattern(GET, "/api/v1/milestone-instances")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/milestones/{processDefinitionId}/flownodes")).hasAuthority(ADMIN)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneSetHttpSecurityConfigurer.java b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneSetHttpSecurityConfigurer.java index 31e8f8a927..b9201a650e 100644 --- a/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneSetHttpSecurityConfigurer.java +++ b/backend/milestones/src/main/java/com/ritense/valtimo/milestones/security/config/MilestoneSetHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.DELETE; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -33,10 +33,10 @@ public class MilestoneSetHttpSecurityConfigurer implements HttpSecurityConfigure public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/milestone-sets/{id}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/milestone-sets")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/milestone-sets")).hasAuthority(DEVELOPER) - .requestMatchers(antMatcher(DELETE, "/api/v1/milestone-sets/{id}")).hasAuthority(DEVELOPER)); + .requestMatchers(pathPattern(GET, "/api/v1/milestone-sets/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/milestone-sets")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/milestone-sets")).hasAuthority(DEVELOPER) + .requestMatchers(pathPattern(DELETE, "/api/v1/milestone-sets/{id}")).hasAuthority(DEVELOPER)); } catch (Exception e) { throw new HttpConfigurerConfigurationException(e); } diff --git a/backend/notes/src/main/kotlin/com/ritense/note/autoconfigure/NoteAutoConfiguration.kt b/backend/notes/src/main/kotlin/com/ritense/note/autoconfigure/NoteAutoConfiguration.kt index dccfbcc5ea..528f249d67 100644 --- a/backend/notes/src/main/kotlin/com/ritense/note/autoconfigure/NoteAutoConfiguration.kt +++ b/backend/notes/src/main/kotlin/com/ritense/note/autoconfigure/NoteAutoConfiguration.kt @@ -31,7 +31,7 @@ import com.ritense.valtimo.contract.authentication.UserManagementService import com.ritense.valtimo.contract.database.QueryDialectHelper import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/notes/src/main/kotlin/com/ritense/note/security/config/NoteHttpSecurityConfigurer.kt b/backend/notes/src/main/kotlin/com/ritense/note/security/config/NoteHttpSecurityConfigurer.kt index 920b48084b..f1f0823d12 100644 --- a/backend/notes/src/main/kotlin/com/ritense/note/security/config/NoteHttpSecurityConfigurer.kt +++ b/backend/notes/src/main/kotlin/com/ritense/note/security/config/NoteHttpSecurityConfigurer.kt @@ -23,17 +23,17 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class NoteHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/document/{document-id}/note")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{document-id}/note")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/note/{note-id}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/note/{note-id}")).authenticated() + requests.requestMatchers(pathPattern(POST, "/api/v1/document/{document-id}/note")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{document-id}/note")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/note/{note-id}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/note/{note-id}")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/outbox/build.gradle b/backend/outbox/build.gradle index 1607374a33..e6c1dea329 100644 --- a/backend/outbox/build.gradle +++ b/backend/outbox/build.gradle @@ -40,8 +40,9 @@ dependencies { implementation("org.springframework.security:spring-security-core") implementation "org.liquibase:liquibase-core:${liquibaseVersion}" - implementation "org.liquibase.ext:liquibase-hibernate6:$liquibaseVersion" - implementation "io.hypersistence:hypersistence-utils-hibernate-62:$hypersistenceUtilsVersion" + implementation "org.springframework.boot:spring-boot-liquibase" + implementation "org.liquibase.ext:liquibase-hibernate7:$liquibaseHibernateVersion" + implementation "io.hypersistence:hypersistence-utils-hibernate-71:$hypersistenceUtilsVersion" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" implementation "io.github.oshai:kotlin-logging:$kotlinLoggingVersion" diff --git a/backend/outbox/outbox-rabbitmq/src/test/kotlin/com/ritense/outbox/rabbitmq/RabbitMessagePublisherTest.kt b/backend/outbox/outbox-rabbitmq/src/test/kotlin/com/ritense/outbox/rabbitmq/RabbitMessagePublisherTest.kt index 8fe15d8739..539a9356fc 100644 --- a/backend/outbox/outbox-rabbitmq/src/test/kotlin/com/ritense/outbox/rabbitmq/RabbitMessagePublisherTest.kt +++ b/backend/outbox/outbox-rabbitmq/src/test/kotlin/com/ritense/outbox/rabbitmq/RabbitMessagePublisherTest.kt @@ -92,8 +92,8 @@ class RabbitMessagePublisherTest { whenever(rabbitTemplate.convertAndSend(any(), eq("test"), any(), any())).thenAnswer { answer -> val message = MessageBuilder.withBody(answer.getArgument(2, String::class.java).toByteArray()).build() val correlationData = answer.getArgument(3, CorrelationData::class.java) - correlationData.returned = ReturnedMessage( - message, 0, "returned_message_not_null", "", "") + correlationData.setReturned(ReturnedMessage( + message, 0, "returned_message_not_null", "", "")) correlationData.future.complete(CorrelationData.Confirm(true, "reasons")) } @@ -182,7 +182,7 @@ class RabbitMessagePublisherTest { val message = MessageBuilder.withBody(answer.getArgument(2, String::class.java).toByteArray()).build() val correlationData = answer.getArgument(3, CorrelationData::class.java) if (callCount == 1) { - correlationData.returned = ReturnedMessage(message, 312, "NO_ROUTE", "", "") + correlationData.setReturned(ReturnedMessage(message, 312, "NO_ROUTE", "", "")) } correlationData.future.complete(CorrelationData.Confirm(true, null)) } diff --git a/backend/outbox/src/main/kotlin/com/ritense/outbox/OutboxLiquibaseRunner.kt b/backend/outbox/src/main/kotlin/com/ritense/outbox/OutboxLiquibaseRunner.kt index 2232f1759e..91b5a8100e 100644 --- a/backend/outbox/src/main/kotlin/com/ritense/outbox/OutboxLiquibaseRunner.kt +++ b/backend/outbox/src/main/kotlin/com/ritense/outbox/OutboxLiquibaseRunner.kt @@ -25,7 +25,7 @@ import liquibase.exception.DatabaseException import liquibase.exception.LiquibaseException import liquibase.resource.ClassLoaderResourceAccessor import org.springframework.beans.factory.InitializingBean -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties import java.sql.SQLException import javax.sql.DataSource @@ -33,7 +33,7 @@ class OutboxLiquibaseRunner( liquibaseProperties: LiquibaseProperties, private val datasource: DataSource, ) : InitializingBean { - private val context: Contexts = Contexts(liquibaseProperties.contexts) + private val context: Contexts = Contexts(liquibaseProperties.contexts?.joinToString(",") ?: "") @Throws(SQLException::class, DatabaseException::class) override fun afterPropertiesSet() { diff --git a/backend/outbox/src/main/kotlin/com/ritense/outbox/UserProvider.kt b/backend/outbox/src/main/kotlin/com/ritense/outbox/UserProvider.kt index 053f30dad9..146f70f980 100644 --- a/backend/outbox/src/main/kotlin/com/ritense/outbox/UserProvider.kt +++ b/backend/outbox/src/main/kotlin/com/ritense/outbox/UserProvider.kt @@ -31,6 +31,6 @@ open class UserProvider { open fun getCurrentUserRoles(): List = SecurityContextHolder.getContext().authentication ?.authorities - ?.map { it.authority } + ?.mapNotNull { it.authority } ?: emptyList() } \ No newline at end of file diff --git a/backend/outbox/src/main/kotlin/com/ritense/outbox/config/OutboxAutoConfiguration.kt b/backend/outbox/src/main/kotlin/com/ritense/outbox/config/OutboxAutoConfiguration.kt index d88a00fcf8..6c9afb8a57 100644 --- a/backend/outbox/src/main/kotlin/com/ritense/outbox/config/OutboxAutoConfiguration.kt +++ b/backend/outbox/src/main/kotlin/com/ritense/outbox/config/OutboxAutoConfiguration.kt @@ -38,10 +38,10 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.boot.autoconfigure.domain.EntityScan -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties -import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration +import org.springframework.boot.persistence.autoconfigure.EntityScan +import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration +import org.springframework.boot.liquibase.autoconfigure.LiquibaseProperties +import org.springframework.boot.hibernate.autoconfigure.HibernateJpaAutoConfiguration import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -128,7 +128,7 @@ class OutboxAutoConfiguration { } @Configuration - @ConditionalOnClass(name = ["org.springframework.boot.actuate.health.AbstractHealthIndicator"]) + @ConditionalOnClass(name = ["org.springframework.boot.health.contributor.AbstractHealthIndicator"]) class OutboxHealthIndicatorConfiguration { @Bean @ConditionalOnMissingBean(name = ["outboxPublisherHealthIndicator"]) diff --git a/backend/outbox/src/main/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicator.kt b/backend/outbox/src/main/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicator.kt index 499a5bb26c..ad068a4717 100644 --- a/backend/outbox/src/main/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicator.kt +++ b/backend/outbox/src/main/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicator.kt @@ -17,8 +17,8 @@ package com.ritense.outbox.health import io.github.resilience4j.circuitbreaker.CircuitBreaker -import org.springframework.boot.actuate.health.AbstractHealthIndicator -import org.springframework.boot.actuate.health.Health +import org.springframework.boot.health.contributor.AbstractHealthIndicator +import org.springframework.boot.health.contributor.Health /** * Exposes the outbox publisher circuit breaker state via the /actuator/health endpoint. diff --git a/backend/outbox/src/test/kotlin/com/ritense/outbox/UserProviderTest.kt b/backend/outbox/src/test/kotlin/com/ritense/outbox/UserProviderTest.kt index 4ad9b2b9bd..891961d4db 100644 --- a/backend/outbox/src/test/kotlin/com/ritense/outbox/UserProviderTest.kt +++ b/backend/outbox/src/test/kotlin/com/ritense/outbox/UserProviderTest.kt @@ -35,7 +35,7 @@ class UserProviderTest { @Test fun `getCurrentUserLogin should return username when authenticated`() { SecurityContextHolder.getContext().authentication = - TestingAuthenticationToken("john@example.com", null) + TestingAuthenticationToken("john@example.com", "credentials") assertThat(userProvider.getCurrentUserLogin()).isEqualTo("john@example.com") } @@ -48,7 +48,7 @@ class UserProviderTest { @Test fun `getCurrentUserRoles should return authorities when authenticated`() { SecurityContextHolder.getContext().authentication = - TestingAuthenticationToken("user", null, listOf( + TestingAuthenticationToken("user", "credentials", listOf( SimpleGrantedAuthority("ROLE_ADMIN"), SimpleGrantedAuthority("ROLE_USER") )) @@ -65,7 +65,7 @@ class UserProviderTest { @Test fun `getCurrentUserRoles should return empty list when no authorities`() { SecurityContextHolder.getContext().authentication = - TestingAuthenticationToken("user", null, emptyList()) + TestingAuthenticationToken("user", "credentials", emptyList()) assertThat(userProvider.getCurrentUserRoles()).isEmpty() } diff --git a/backend/outbox/src/test/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicatorTest.kt b/backend/outbox/src/test/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicatorTest.kt index e7056f7f9b..696b52b688 100644 --- a/backend/outbox/src/test/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicatorTest.kt +++ b/backend/outbox/src/test/kotlin/com/ritense/outbox/health/OutboxPublisherHealthIndicatorTest.kt @@ -20,8 +20,8 @@ import io.github.resilience4j.circuitbreaker.CircuitBreaker import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import org.springframework.boot.actuate.health.Health -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.Health +import org.springframework.boot.health.contributor.Status import java.time.Duration class OutboxPublisherHealthIndicatorTest { diff --git a/backend/plugin-authentication/openklant-authentication/src/test/kotlin/com/ritense/openklantauthentication/OpenKlantTokenAuthenticationPluginTest.kt b/backend/plugin-authentication/openklant-authentication/src/test/kotlin/com/ritense/openklantauthentication/OpenKlantTokenAuthenticationPluginTest.kt index a12bdb7246..a99e40d6ad 100644 --- a/backend/plugin-authentication/openklant-authentication/src/test/kotlin/com/ritense/openklantauthentication/OpenKlantTokenAuthenticationPluginTest.kt +++ b/backend/plugin-authentication/openklant-authentication/src/test/kotlin/com/ritense/openklantauthentication/OpenKlantTokenAuthenticationPluginTest.kt @@ -16,9 +16,9 @@ package com.ritense.openklantauthentication +import com.ritense.valtimo.Jackson2TestUtils import org.junit.jupiter.api.Test import org.springframework.http.HttpHeaders -import org.springframework.web.client.RestClient import kotlin.test.assertEquals internal class OpenKlantTokenAuthenticationPluginTest { @@ -26,7 +26,7 @@ internal class OpenKlantTokenAuthenticationPluginTest { fun `should add header to request`() { val plugin = OpenKlantTokenAuthenticationPlugin() plugin.token = "my-token" - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() plugin.applyAuth(restClientBuilder) diff --git a/backend/plugin/src/main/kotlin/com/ritense/plugin/configuration/PluginAutoConfiguration.kt b/backend/plugin/src/main/kotlin/com/ritense/plugin/configuration/PluginAutoConfiguration.kt index aa8588f3ef..3988a8833e 100644 --- a/backend/plugin/src/main/kotlin/com/ritense/plugin/configuration/PluginAutoConfiguration.kt +++ b/backend/plugin/src/main/kotlin/com/ritense/plugin/configuration/PluginAutoConfiguration.kt @@ -46,7 +46,7 @@ import jakarta.validation.Validator import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationContext import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean diff --git a/backend/plugin/src/main/kotlin/com/ritense/plugin/security/config/PluginHttpSecurityConfigurer.kt b/backend/plugin/src/main/kotlin/com/ritense/plugin/security/config/PluginHttpSecurityConfigurer.kt index 7dbfda2ebe..3167fe8f3a 100644 --- a/backend/plugin/src/main/kotlin/com/ritense/plugin/security/config/PluginHttpSecurityConfigurer.kt +++ b/backend/plugin/src/main/kotlin/com/ritense/plugin/security/config/PluginHttpSecurityConfigurer.kt @@ -24,20 +24,20 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class PluginHttpSecurityConfigurer: HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/plugin/definition")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/plugin/configuration")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/plugin/configuration")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/v1/plugin/configuration/{pluginConfigurationId}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/v1/plugin/configuration/{pluginConfigurationId}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/plugin/definition/{pluginDefinitionKey}/action")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v1/plugin/configuration/export")).hasAuthority(ADMIN) + requests.requestMatchers(pathPattern(GET, "/api/v1/plugin/definition")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/plugin/configuration")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/plugin/configuration")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/v1/plugin/configuration/{pluginConfigurationId}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/v1/plugin/configuration/{pluginConfigurationId}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/plugin/definition/{pluginDefinitionKey}/action")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/plugin/configuration/export")).hasAuthority(ADMIN) } } catch(e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/plugin/src/test/kotlin/com/ritense/plugin/web/rest/PluginConfigurationResourceTest.kt b/backend/plugin/src/test/kotlin/com/ritense/plugin/web/rest/PluginConfigurationResourceTest.kt index 192edcd1be..7c495864cc 100644 --- a/backend/plugin/src/test/kotlin/com/ritense/plugin/web/rest/PluginConfigurationResourceTest.kt +++ b/backend/plugin/src/test/kotlin/com/ritense/plugin/web/rest/PluginConfigurationResourceTest.kt @@ -44,6 +44,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status import org.springframework.test.web.servlet.setup.MockMvcBuilders +import com.ritense.valtimo.Jackson2TestUtils import java.nio.charset.StandardCharsets import java.util.UUID @@ -64,6 +65,7 @@ internal class PluginConfigurationResourceTest { mockMvc = MockMvcBuilders .standaloneSetup(pluginConfigurationResource) .setConversionService(formattingConversionService) + .setMessageConverters(Jackson2TestUtils.jackson2Converter()) .build() } diff --git a/backend/process-document/src/main/java/com/ritense/processdocument/autoconfigure/ProcessDocumentAutoConfiguration.java b/backend/process-document/src/main/java/com/ritense/processdocument/autoconfigure/ProcessDocumentAutoConfiguration.java index 5e7f99019d..47ce8d66fb 100644 --- a/backend/process-document/src/main/java/com/ritense/processdocument/autoconfigure/ProcessDocumentAutoConfiguration.java +++ b/backend/process-document/src/main/java/com/ritense/processdocument/autoconfigure/ProcessDocumentAutoConfiguration.java @@ -53,7 +53,7 @@ import org.operaton.bpm.engine.RuntimeService; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.persistence.autoconfigure.EntityScan; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; diff --git a/backend/process-document/src/main/java/com/ritense/processdocument/security/config/ProcessDocumentHttpSecurityConfigurer.java b/backend/process-document/src/main/java/com/ritense/processdocument/security/config/ProcessDocumentHttpSecurityConfigurer.java index 9508480691..0c4c3ff4e3 100644 --- a/backend/process-document/src/main/java/com/ritense/processdocument/security/config/ProcessDocumentHttpSecurityConfigurer.java +++ b/backend/process-document/src/main/java/com/ritense/processdocument/security/config/ProcessDocumentHttpSecurityConfigurer.java @@ -21,7 +21,7 @@ import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; -import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; +import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern; import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationException; import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer; @@ -36,42 +36,42 @@ public class ProcessDocumentHttpSecurityConfigurer implements HttpSecurityConfig public void configure(HttpSecurity http) { try { http.authorizeHttpRequests(requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/case-process-link")) + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/case-process-link")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document-instance/{documentId}/case-process-link")) + .requestMatchers(pathPattern(GET, "/api/v1/document-instance/{documentId}/case-process-link")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-instance/{processInstanceId}/case-process-link")) + .requestMatchers(pathPattern(GET, "/api/v1/process-instance/{processInstanceId}/case-process-link")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-document/instance/document/{document-id}")) + .requestMatchers(pathPattern(GET, "/api/v1/process-document/instance/document/{document-id}")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/process-document/instance/document/{document-id}")) + .requestMatchers(pathPattern(GET, "/api/v2/process-document/instance/document/{document-id}")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-document/instance/document/{document-id}/audit")) + .requestMatchers(pathPattern(GET, "/api/v1/process-document/instance/document/{document-id}/audit")) .authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/process-document/operation/new-document-and-start-process")) + .requestMatchers(pathPattern(POST, "/api/v1/process-document/operation/new-document-and-start-process")) .authenticated() - .requestMatchers(antMatcher( + .requestMatchers(pathPattern( POST, "/api/v1/process-document/operation/modify-document-and-complete-task" )) .authenticated() - .requestMatchers(antMatcher( + .requestMatchers(pathPattern( POST, "/api/v1/process-document/operation/modify-document-and-start-process" )) .authenticated() - .requestMatchers(antMatcher(POST, "/api/v3/task")) + .requestMatchers(pathPattern(POST, "/api/v3/task")) .authenticated() - .requestMatchers(antMatcher(POST, "/api/v1/document-definition/{caseDefinitionName}/task/search")) + .requestMatchers(pathPattern(POST, "/api/v1/document-definition/{caseDefinitionName}/task/search")) .authenticated() //admin endpoints - .requestMatchers(antMatcher(GET, FEATURE_PROCESS_URL + "/{type}")) + .requestMatchers(pathPattern(GET, FEATURE_PROCESS_URL + "/{type}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, FEATURE_PROCESS_URL)) + .requestMatchers(pathPattern(PUT, FEATURE_PROCESS_URL)) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, FEATURE_PROCESS_URL + "/{type}")) + .requestMatchers(pathPattern(DELETE, FEATURE_PROCESS_URL + "/{type}")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher( + .requestMatchers(pathPattern( PUT, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{caseDefinitionVersionTag}/process/{processDefinitionId}/properties" )).hasAuthority(ADMIN) diff --git a/backend/process-document/src/main/kotlin/com/ritense/processdocument/resolver/CaseDocumentJsonValueResolverFactory.kt b/backend/process-document/src/main/kotlin/com/ritense/processdocument/resolver/CaseDocumentJsonValueResolverFactory.kt index a4bd5a81d6..32f90ce254 100644 --- a/backend/process-document/src/main/kotlin/com/ritense/processdocument/resolver/CaseDocumentJsonValueResolverFactory.kt +++ b/backend/process-document/src/main/kotlin/com/ritense/processdocument/resolver/CaseDocumentJsonValueResolverFactory.kt @@ -276,7 +276,7 @@ class CaseDocumentJsonValueResolverFactory( private fun validateJsonPointer(documentDefinition: JsonSchemaDocumentDefinition, jsonPointer: String) { if (!documentDefinition.schema.schema.definesProperty(jsonPointer)) { throw ValueResolverValidationException( - "JsonPointer '$jsonPointer' doesn't point to any property inside document definition '${documentDefinition.id.name()}'" + "JsonPointer '$jsonPointer' doesn't point to any property inside document definition '${documentDefinition.id!!.name()}'" ) } } @@ -287,13 +287,13 @@ class CaseDocumentJsonValueResolverFactory( PathCompiler.compile(jsonPath) } catch (e: InvalidPathException) { throw ValueResolverValidationException( - "Failed to compile JsonPath '$jsonPath' for document definition '${documentDefinition.id.name()}'", + "Failed to compile JsonPath '$jsonPath' for document definition '${documentDefinition.id!!.name()}'", e ) } if (!documentDefinitionService.isValidJsonPath(documentDefinition, jsonPath)) { throw ValueResolverValidationException( - "JsonPath '$jsonPath' doesn't point to any property inside document definition '${documentDefinition.id.name()}'" + "JsonPath '$jsonPath' doesn't point to any property inside document definition '${documentDefinition.id!!.name()}'" ) } } @@ -315,7 +315,7 @@ class CaseDocumentJsonValueResolverFactory( return if (node == null || node.isMissingNode || node.isNull) { null } else if (node.isValueNode || node.isArray || node.isObject) { - objectMapper.treeToValue(node, Object::class.java) + PLAIN_MAPPER.treeToValue(node, Object::class.java) } else { node.asText() } @@ -393,6 +393,7 @@ class CaseDocumentJsonValueResolverFactory( companion object { const val PREFIX = "doc" + private val PLAIN_MAPPER = ObjectMapper() } } diff --git a/backend/process-document/src/main/kotlin/com/ritense/processdocument/service/CaseTaskListSearchService.kt b/backend/process-document/src/main/kotlin/com/ritense/processdocument/service/CaseTaskListSearchService.kt index 18b0f8e684..189e3d72a2 100644 --- a/backend/process-document/src/main/kotlin/com/ritense/processdocument/service/CaseTaskListSearchService.kt +++ b/backend/process-document/src/main/kotlin/com/ritense/processdocument/service/CaseTaskListSearchService.kt @@ -194,7 +194,7 @@ class CaseTaskListSearchService( taskRoot.get(CaseTaskProperties.DUE_DATE.propertyName), taskRoot.get("processInstance").get("id"), documentRoot.get("id").get("id"), - taskTeamSubquery(query, taskRoot, "teamTitle") + taskTeamJoin(taskRoot, "teamTitle") ) query.select( @@ -299,6 +299,7 @@ class CaseTaskListSearchService( val username = userManagementService.currentUser.username val teamKeys = teamManagement.findTeamKeysByUsername(username) byTeamKeys(teamKeys).toPredicate(taskRoot, query, cb) + ?: cb.equal(cb.literal(1), 1) } } return assignmentFilterPredicate @@ -463,17 +464,14 @@ class CaseTaskListSearchService( val taskColumnName = searchCriteria.path.substring(TASK_PREFIX.length) if (taskColumnName == CaseTaskProperties.ASSIGNED_TEAM_TITLE.propertyName) { @Suppress("UNCHECKED_CAST") - return taskTeamSubquery(query, taskRoot, "teamTitle") as Expression> + return taskTeamJoin(taskRoot, "teamTitle") as Expression> } return taskRoot.get(taskColumnName).`as`(searchCriteria.getDataType()) } - private fun taskTeamSubquery(query: AbstractQuery<*>, taskRoot: Root, column: String): Expression { - val subquery = query.subquery(String::class.java) - val taskTeamRoot = subquery.from(TaskTeam::class.java) - subquery.select(taskTeamRoot.get(column)) - subquery.where(entityManager.criteriaBuilder.equal(taskTeamRoot.get("taskId"), taskRoot.get("id"))) - return subquery.selection + private fun taskTeamJoin(taskRoot: Root, column: String): Expression { + val join = taskRoot.join("taskTeam", jakarta.persistence.criteria.JoinType.LEFT) + return join.get(column) } private fun getValueExpressionForCasePrefix( @@ -649,7 +647,7 @@ class CaseTaskListSearchService( property.startsWith(TASK_PREFIX) -> { val taskColumnName = property.substring(TASK_PREFIX.length) expression = if (taskColumnName == CaseTaskProperties.ASSIGNED_TEAM_TITLE.propertyName) { - taskTeamSubquery(query, taskRoot, "teamTitle") + taskTeamJoin(taskRoot, "teamTitle") } else { taskRoot.get(taskColumnName) } @@ -660,9 +658,7 @@ class CaseTaskListSearchService( if (property.startsWith(CASE_PREFIX)) property.substring( CASE_PREFIX.length ) else property - if (DOCUMENT_FIELD_MAP.containsKey(docProperty)) { - docProperty = DOCUMENT_FIELD_MAP[docProperty] - } + DOCUMENT_FIELD_MAP[docProperty]?.let { docProperty = it } val parent: Path<*> if (docProperty == INTERNAL_STATUS_ORDER) { diff --git a/backend/process-document/src/test/kotlin/com/ritense/processdocument/other/DeadlockIntTest.kt b/backend/process-document/src/test/kotlin/com/ritense/processdocument/other/DeadlockIntTest.kt index 478c0c2b3c..f2db2376f3 100644 --- a/backend/process-document/src/test/kotlin/com/ritense/processdocument/other/DeadlockIntTest.kt +++ b/backend/process-document/src/test/kotlin/com/ritense/processdocument/other/DeadlockIntTest.kt @@ -84,8 +84,8 @@ internal class DeadlockIntTest : BaseIntegrationTest() { documentService.createDocument( NewDocumentRequest( definition().id().name(), - definition().id.caseDefinitionId().key, - definition().id.caseDefinitionId().versionTag.version, + definition().id!!.caseDefinitionId().key, + definition().id!!.caseDefinitionId().versionTag.version, JsonDocumentContent(content).asJson() ) ) diff --git a/backend/process-document/src/test/kotlin/com/ritense/processdocument/service/CaseTaskListSearchServiceIntTest.kt b/backend/process-document/src/test/kotlin/com/ritense/processdocument/service/CaseTaskListSearchServiceIntTest.kt index c5e1c18ffb..d6903e9a5d 100644 --- a/backend/process-document/src/test/kotlin/com/ritense/processdocument/service/CaseTaskListSearchServiceIntTest.kt +++ b/backend/process-document/src/test/kotlin/com/ritense/processdocument/service/CaseTaskListSearchServiceIntTest.kt @@ -87,8 +87,8 @@ class CaseTaskListSearchServiceIntTest : BaseIntegrationTest() { val result: CreateDocumentResult = documentService.createDocument( NewDocumentRequest( definition!!.id().name(), - definition!!.id.caseDefinitionId().key, - definition!!.id.caseDefinitionId().versionTag.version, + definition!!.id!!.caseDefinitionId().key, + definition!!.id!!.caseDefinitionId().versionTag.version, content.asJson() ) ) @@ -101,8 +101,8 @@ class CaseTaskListSearchServiceIntTest : BaseIntegrationTest() { val result: CreateDocumentResult = documentService.createDocument( NewDocumentRequest( definition!!.id().name(), - definition!!.id.caseDefinitionId().key, - definition!!.id.caseDefinitionId().versionTag.version, + definition!!.id!!.caseDefinitionId().key, + definition!!.id!!.caseDefinitionId().versionTag.version, content2.asJson() ) ) @@ -297,8 +297,8 @@ class CaseTaskListSearchServiceIntTest : BaseIntegrationTest() { val result: CreateDocumentResult = documentService.createDocument( NewDocumentRequest( museumDefinition!!.id().name(), - museumDefinition!!.id.caseDefinitionId().key, - museumDefinition!!.id.caseDefinitionId().versionTag.version, + museumDefinition!!.id!!.caseDefinitionId().key, + museumDefinition!!.id!!.caseDefinitionId().versionTag.version, content.asJson() ) ) diff --git a/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/autoconfigure/ProcessLinkUrlAutoConfiguration.kt b/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/autoconfigure/ProcessLinkUrlAutoConfiguration.kt index 128929c87b..96f437d6fc 100644 --- a/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/autoconfigure/ProcessLinkUrlAutoConfiguration.kt +++ b/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/autoconfigure/ProcessLinkUrlAutoConfiguration.kt @@ -33,7 +33,7 @@ import com.ritense.processlink.url.web.rest.URLProcessLinkResource import com.ritense.valtimo.operaton.service.OperatonRepositoryService import com.ritense.valtimo.service.OperatonTaskService import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.annotation.Order diff --git a/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/configuration/URLProcessLinkSecurityConfigurer.kt b/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/configuration/URLProcessLinkSecurityConfigurer.kt index 5018647973..86e3dbfbe4 100644 --- a/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/configuration/URLProcessLinkSecurityConfigurer.kt +++ b/backend/process-link-url/src/main/kotlin/com/ritense/processlink/url/configuration/URLProcessLinkSecurityConfigurer.kt @@ -20,15 +20,15 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class URLProcessLinkSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(POST, "/api/v1/process-link/url/{processLinkId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-link/url/variables")).authenticated() + .requestMatchers(pathPattern(POST, "/api/v1/process-link/url/{processLinkId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process-link/url/variables")).authenticated() } } diff --git a/backend/process-link/src/main/kotlin/com/ritense/processlink/configuration/ProcessLinkAutoConfiguration.kt b/backend/process-link/src/main/kotlin/com/ritense/processlink/configuration/ProcessLinkAutoConfiguration.kt index 6cf81ad912..e8633723ef 100644 --- a/backend/process-link/src/main/kotlin/com/ritense/processlink/configuration/ProcessLinkAutoConfiguration.kt +++ b/backend/process-link/src/main/kotlin/com/ritense/processlink/configuration/ProcessLinkAutoConfiguration.kt @@ -50,7 +50,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/process-link/src/main/kotlin/com/ritense/processlink/security/config/ProcessLinkHttpSecurityConfigurer.kt b/backend/process-link/src/main/kotlin/com/ritense/processlink/security/config/ProcessLinkHttpSecurityConfigurer.kt index 8d2083b5f5..0776d8e8d4 100644 --- a/backend/process-link/src/main/kotlin/com/ritense/processlink/security/config/ProcessLinkHttpSecurityConfigurer.kt +++ b/backend/process-link/src/main/kotlin/com/ritense/processlink/security/config/ProcessLinkHttpSecurityConfigurer.kt @@ -24,84 +24,84 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ProcessLinkHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, PROCESS_LINK_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$PROCESS_LINK_URL/types")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, PROCESS_LINK_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, PROCESS_LINK_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$PROCESS_LINK_URL/export")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$PROCESS_LINK_URL/{processLinkId}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/v1/process/definition/deployment/process-link")) + requests.requestMatchers(pathPattern(GET, PROCESS_LINK_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$PROCESS_LINK_URL/types")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, PROCESS_LINK_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, PROCESS_LINK_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$PROCESS_LINK_URL/export")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$PROCESS_LINK_URL/{processLinkId}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/v1/process/definition/deployment/process-link")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/v2/process-link/task/{taskId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process-definition/{processDefinitionId}/start-form")) + .requestMatchers(pathPattern(GET, "/api/v2/process-link/task/{taskId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/process-definition/{processDefinitionId}/start-form")) .authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/process/{processInstanceId}/tasks/process-link")) + .requestMatchers(pathPattern(GET, "/api/v1/process/{processInstanceId}/tasks/process-link")) .authenticated() .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/process-definition" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/process-definition" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/process-definition/key/{processDefinitionKey}" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/process-definition/key/{processDefinitionKey}" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/process-definition" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/process-definition/{processDefinitionId}" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "/api/management/v1/process-definition" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( DELETE, "/api/management/v1/process-definition/key/{processDefinitionKey}" ) ) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/process-definition/key/{processDefinitionKey}" ) diff --git a/backend/process-link/src/main/kotlin/com/ritense/processlink/uicomponent/autoconfigure/UIComponentProcessLinkAutoConfiguration.kt b/backend/process-link/src/main/kotlin/com/ritense/processlink/uicomponent/autoconfigure/UIComponentProcessLinkAutoConfiguration.kt index ee93bfc96d..2a64d4eafd 100644 --- a/backend/process-link/src/main/kotlin/com/ritense/processlink/uicomponent/autoconfigure/UIComponentProcessLinkAutoConfiguration.kt +++ b/backend/process-link/src/main/kotlin/com/ritense/processlink/uicomponent/autoconfigure/UIComponentProcessLinkAutoConfiguration.kt @@ -24,7 +24,7 @@ import com.ritense.processlink.uicomponent.service.UIComponentSupportedProcessLi import com.ritense.valtimo.operaton.domain.OperatonTask import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.core.annotation.Order diff --git a/backend/resource/local-resource/src/main/kotlin/com/ritense/resource/security/LocalResourceHttpSecurityConfigurer.kt b/backend/resource/local-resource/src/main/kotlin/com/ritense/resource/security/LocalResourceHttpSecurityConfigurer.kt index ab97c56f9a..571c4a1bd9 100644 --- a/backend/resource/local-resource/src/main/kotlin/com/ritense/resource/security/LocalResourceHttpSecurityConfigurer.kt +++ b/backend/resource/local-resource/src/main/kotlin/com/ritense/resource/security/LocalResourceHttpSecurityConfigurer.kt @@ -22,17 +22,17 @@ import org.springframework.http.HttpMethod.DELETE import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class LocalResourceHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/resource/pre-signed-url/{fileName}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/resource/{resourceId}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/resource/{resourceId}")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/resource")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/resource/pre-signed-url/{fileName}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/resource/{resourceId}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/resource/{resourceId}")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/resource")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/autoconfigure/TemporaryResourceStorageAutoConfiguration.kt b/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/autoconfigure/TemporaryResourceStorageAutoConfiguration.kt index 9dee0a69c7..03a97bd104 100644 --- a/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/autoconfigure/TemporaryResourceStorageAutoConfiguration.kt +++ b/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/autoconfigure/TemporaryResourceStorageAutoConfiguration.kt @@ -30,7 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/security/config/TemporaryResourceStorageHttpSecurityConfigurer.kt b/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/security/config/TemporaryResourceStorageHttpSecurityConfigurer.kt index 149df56531..451baa05d3 100644 --- a/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/security/config/TemporaryResourceStorageHttpSecurityConfigurer.kt +++ b/backend/resource/temporary-resource-storage/src/main/kotlin/com/ritense/resource/security/config/TemporaryResourceStorageHttpSecurityConfigurer.kt @@ -21,15 +21,15 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class TemporaryResourceStorageHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/resource/temp")).authenticated() - requests.requestMatchers(antMatcher(GET, "/api/v1/resource-storage/{resourceStorageFieldId}/metadata/{metadataKey}")).authenticated() + requests.requestMatchers(pathPattern(POST, "/api/v1/resource/temp")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/resource-storage/{resourceStorageFieldId}/metadata/{metadataKey}")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/service/TemporaryResourceStorageServiceIntegrationTest.kt b/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/service/TemporaryResourceStorageServiceIntegrationTest.kt index cd391120a9..9b54e9b824 100644 --- a/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/service/TemporaryResourceStorageServiceIntegrationTest.kt +++ b/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/service/TemporaryResourceStorageServiceIntegrationTest.kt @@ -27,7 +27,11 @@ import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.quality.Strictness import org.mockito.Mockito import org.mockito.Mockito.`when` import org.springframework.beans.factory.annotation.Autowired @@ -38,6 +42,8 @@ import java.util.UUID import kotlin.io.path.Path @TestInstance(TestInstance.Lifecycle.PER_CLASS) +@ExtendWith(MockitoExtension::class) +@MockitoSettings(strictness = Strictness.LENIENT) class TemporaryResourceStorageServiceIntegrationTest : BaseIntegrationTest() { @Autowired diff --git a/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/web/rest/TemporaryResourceStorageResourceIT.kt b/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/web/rest/TemporaryResourceStorageResourceIT.kt index c7cbe8a09d..9adcb372aa 100644 --- a/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/web/rest/TemporaryResourceStorageResourceIT.kt +++ b/backend/resource/temporary-resource-storage/src/test/kotlin/com/ritense/resource/web/rest/TemporaryResourceStorageResourceIT.kt @@ -31,7 +31,7 @@ import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.verify import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.context.event.EventListener import org.springframework.http.MediaType import org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE diff --git a/backend/search/src/main/kotlin/com/ritense/search/autoconfigure/SearchAutoConfiguration.kt b/backend/search/src/main/kotlin/com/ritense/search/autoconfigure/SearchAutoConfiguration.kt index 79eae14698..3268c1b3d4 100644 --- a/backend/search/src/main/kotlin/com/ritense/search/autoconfigure/SearchAutoConfiguration.kt +++ b/backend/search/src/main/kotlin/com/ritense/search/autoconfigure/SearchAutoConfiguration.kt @@ -34,7 +34,7 @@ import com.ritense.search.web.rest.SearchFieldV2Resource import com.ritense.search.web.rest.SearchListColumnResource import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/search/src/main/kotlin/com/ritense/search/autodeployment/SearchListColumnDefinitionDeploymentService.kt b/backend/search/src/main/kotlin/com/ritense/search/autodeployment/SearchListColumnDefinitionDeploymentService.kt index 95e0bc96c4..565dfd88b0 100644 --- a/backend/search/src/main/kotlin/com/ritense/search/autodeployment/SearchListColumnDefinitionDeploymentService.kt +++ b/backend/search/src/main/kotlin/com/ritense/search/autodeployment/SearchListColumnDefinitionDeploymentService.kt @@ -73,7 +73,7 @@ class SearchListColumnDefinitionDeploymentService( ) } - private fun loadResources(): Array { + private fun loadResources(): Array { return try { ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources(PATH) } catch (ioe: IOException) { diff --git a/backend/search/src/main/kotlin/com/ritense/search/security/config/SearchHttpSecurityConfigurer.kt b/backend/search/src/main/kotlin/com/ritense/search/security/config/SearchHttpSecurityConfigurer.kt index 41ecaa2873..80703e2bb5 100644 --- a/backend/search/src/main/kotlin/com/ritense/search/security/config/SearchHttpSecurityConfigurer.kt +++ b/backend/search/src/main/kotlin/com/ritense/search/security/config/SearchHttpSecurityConfigurer.kt @@ -21,25 +21,25 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class SearchHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(HttpMethod.POST, "/api/v1/search/list-column/{ownerId}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/search/list-column/{ownerId}")).authenticated() - .requestMatchers(antMatcher(HttpMethod.PUT, "/api/v1/search/list-column/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.PUT, "/api/v1/search/list-column/{ownerId}/search-list-columns")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.DELETE, "/api/v1/search/list-column/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.POST, "/api/v1/search/field/{ownerId}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/search/field/{ownerId}")).authenticated() - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/search/field/{ownerType}/{ownerId}")).authenticated() - .requestMatchers(antMatcher(HttpMethod.PUT, "/api/v1/search/field/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.PUT, "/api/v1/search/field/{ownerId}/fields")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.DELETE, "/api/v1/search/field/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) - .requestMatchers(antMatcher(HttpMethod.DELETE, "/api/v1/search/field/{ownerType}/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) + requests.requestMatchers(pathPattern(HttpMethod.POST, "/api/v1/search/list-column/{ownerId}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/search/list-column/{ownerId}")).authenticated() + .requestMatchers(pathPattern(HttpMethod.PUT, "/api/v1/search/list-column/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.PUT, "/api/v1/search/list-column/{ownerId}/search-list-columns")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.DELETE, "/api/v1/search/list-column/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.POST, "/api/v1/search/field/{ownerId}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/search/field/{ownerId}")).authenticated() + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/search/field/{ownerType}/{ownerId}")).authenticated() + .requestMatchers(pathPattern(HttpMethod.PUT, "/api/v1/search/field/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.PUT, "/api/v1/search/field/{ownerId}/fields")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.DELETE, "/api/v1/search/field/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) + .requestMatchers(pathPattern(HttpMethod.DELETE, "/api/v1/search/field/{ownerType}/{ownerId}/{key}")).hasAuthority(AuthoritiesConstants.ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/team/src/main/kotlin/com/ritense/team/autoconfigure/TeamAutoConfiguration.kt b/backend/team/src/main/kotlin/com/ritense/team/autoconfigure/TeamAutoConfiguration.kt index ed7d01f3b2..fa47174f6a 100644 --- a/backend/team/src/main/kotlin/com/ritense/team/autoconfigure/TeamAutoConfiguration.kt +++ b/backend/team/src/main/kotlin/com/ritense/team/autoconfigure/TeamAutoConfiguration.kt @@ -31,7 +31,7 @@ import com.ritense.valtimo.contract.authentication.TeamManagementService import com.ritense.valtimo.contract.authentication.UserManagementService import com.ritense.valtimo.contract.database.QueryDialectHelper import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration diff --git a/backend/team/src/main/kotlin/com/ritense/team/security/config/TeamHttpSecurityConfigurer.kt b/backend/team/src/main/kotlin/com/ritense/team/security/config/TeamHttpSecurityConfigurer.kt index 046ed6d949..c56571f615 100644 --- a/backend/team/src/main/kotlin/com/ritense/team/security/config/TeamHttpSecurityConfigurer.kt +++ b/backend/team/src/main/kotlin/com/ritense/team/security/config/TeamHttpSecurityConfigurer.kt @@ -20,26 +20,26 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class TeamHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/team")).authenticated() - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/team/{id}")).authenticated() - .requestMatchers(antMatcher(HttpMethod.POST, "/api/v1/team")) + requests.requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/team")).authenticated() + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/team/{id}")).authenticated() + .requestMatchers(pathPattern(HttpMethod.POST, "/api/v1/team")) .authenticated() - .requestMatchers(antMatcher(HttpMethod.PUT, "/api/v1/team/{id}")) + .requestMatchers(pathPattern(HttpMethod.PUT, "/api/v1/team/{id}")) .authenticated() - .requestMatchers(antMatcher(HttpMethod.DELETE, "/api/v1/team/{id}")) + .requestMatchers(pathPattern(HttpMethod.DELETE, "/api/v1/team/{id}")) .authenticated() - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/team/{teamKey}/user")).authenticated() - .requestMatchers(antMatcher(HttpMethod.POST, "/api/v1/team/{teamKey}/user")).authenticated() - .requestMatchers(antMatcher(HttpMethod.DELETE, "/api/v1/team/{teamKey}/user/{userId}")) + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/team/{teamKey}/user")).authenticated() + .requestMatchers(pathPattern(HttpMethod.POST, "/api/v1/team/{teamKey}/user")).authenticated() + .requestMatchers(pathPattern(HttpMethod.DELETE, "/api/v1/team/{teamKey}/user/{userId}")) .authenticated() - .requestMatchers(antMatcher(HttpMethod.GET, "/api/v1/team/{teamKey}/candidate-user")) + .requestMatchers(pathPattern(HttpMethod.GET, "/api/v1/team/{teamKey}/candidate-user")) .authenticated() } } catch (e: Exception) { diff --git a/backend/test-utils-common/build.gradle b/backend/test-utils-common/build.gradle index e8cc9149de..630ee8744d 100644 --- a/backend/test-utils-common/build.gradle +++ b/backend/test-utils-common/build.gradle @@ -45,6 +45,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-test" implementation "org.junit.jupiter:junit-jupiter" implementation "org.springframework.boot:spring-boot-starter-test" + api "org.springframework.boot:spring-boot-webmvc-test" implementation "org.liquibase:liquibase-core:${liquibaseVersion}" diff --git a/backend/test-utils-common/src/main/java/com/ritense/valtimo/web/rest/SecuritySpecificEndpointIntegrationTest.java b/backend/test-utils-common/src/main/java/com/ritense/valtimo/web/rest/SecuritySpecificEndpointIntegrationTest.java index e5be32047a..0fbcaf89ff 100644 --- a/backend/test-utils-common/src/main/java/com/ritense/valtimo/web/rest/SecuritySpecificEndpointIntegrationTest.java +++ b/backend/test-utils-common/src/main/java/com/ritense/valtimo/web/rest/SecuritySpecificEndpointIntegrationTest.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; diff --git a/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/Jackson2TestUtils.kt b/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/Jackson2TestUtils.kt new file mode 100644 index 0000000000..4c87e19d42 --- /dev/null +++ b/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/Jackson2TestUtils.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2015-2026 Ritense BV, the Netherlands. + * + * Licensed under EUPL, Version 1.2 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ritense.valtimo + +import com.ritense.valtimo.contract.json.MapperSingleton +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter +import org.springframework.web.client.RestClient + +object Jackson2TestUtils { + + private val jackson2Converter = MappingJackson2HttpMessageConverter(MapperSingleton.get()) + + fun restClientBuilder(): RestClient.Builder = + RestClient.builder().messageConverters { converters -> + converters.addFirst(jackson2Converter) + } + + fun jackson2Converter(): MappingJackson2HttpMessageConverter = jackson2Converter +} diff --git a/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/web/rest/SecuritySmokeIntegrationTest.kt b/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/web/rest/SecuritySmokeIntegrationTest.kt index 34efbbe283..48c63ef1ce 100644 --- a/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/web/rest/SecuritySmokeIntegrationTest.kt +++ b/backend/test-utils-common/src/main/kotlin/com/ritense/valtimo/web/rest/SecuritySmokeIntegrationTest.kt @@ -24,7 +24,7 @@ import org.junit.jupiter.api.TestFactory import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpMethod import org.springframework.mock.web.MockHttpServletRequest diff --git a/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverFactory.kt b/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverFactory.kt index 8ebf8fa4ea..f31ae70efb 100644 --- a/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverFactory.kt +++ b/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverFactory.kt @@ -19,7 +19,6 @@ package com.ritense.valueresolver import com.fasterxml.jackson.core.JsonPointer import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.treeToValue import com.flipkart.zjsonpatch.JsonPatch import com.ritense.valtimo.contract.json.patch.JsonPatchBuilder import io.github.oshai.kotlinlogging.KotlinLogging @@ -109,7 +108,8 @@ class ProcessVariableValueResolverFactory( val root = objectMapper.valueToTree(existingValues) buildJsonPatch(root, values) - val newValues = objectMapper.treeToValue>(root) + @Suppress("UNCHECKED_CAST") + val newValues = PLAIN_MAPPER.treeToValue(root, LinkedHashMap::class.java) as Map runtimeService.setVariables(processInstanceId, newValues) } @@ -117,7 +117,8 @@ class ProcessVariableValueResolverFactory( override fun preProcessValuesForNewCase(values: Map): Map { val jsonNode = objectMapper.createObjectNode() buildJsonPatch(jsonNode, values) - return objectMapper.treeToValue(jsonNode) + @Suppress("UNCHECKED_CAST") + return PLAIN_MAPPER.treeToValue(jsonNode, LinkedHashMap::class.java) as Map } private fun buildJsonPatch(jsonNode: JsonNode, values: Map) { @@ -134,7 +135,7 @@ class ProcessVariableValueResolverFactory( return if (valueNode.isMissingNode) { null } else { - objectMapper.treeToValue(valueNode) + PLAIN_MAPPER.treeToValue(valueNode, Object::class.java) } } @@ -153,5 +154,6 @@ class ProcessVariableValueResolverFactory( companion object { const val PREFIX = "pv" private val logger = KotlinLogging.logger {} + private val PLAIN_MAPPER = ObjectMapper() } } diff --git a/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/config/ValueResolverHttpSecurityConfigurer.kt b/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/config/ValueResolverHttpSecurityConfigurer.kt index ae3145435d..986aa8ea6c 100644 --- a/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/config/ValueResolverHttpSecurityConfigurer.kt +++ b/backend/value-resolver/src/main/kotlin/com/ritense/valueresolver/config/ValueResolverHttpSecurityConfigurer.kt @@ -22,7 +22,7 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ValueResolverHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -30,9 +30,9 @@ class ValueResolverHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/management/v1/value-resolver")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/value-resolver/case-definition/{caseDefinitionKey}/keys")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/value-resolver/case-definition/{caseDefinitionKey}/version/{versionTag}/keys")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/value-resolver")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/value-resolver/case-definition/{caseDefinitionKey}/keys")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/value-resolver/case-definition/{caseDefinitionKey}/version/{versionTag}/keys")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/value-resolver/src/test/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverTest.kt b/backend/value-resolver/src/test/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverTest.kt index 6377870613..644b70fe3d 100644 --- a/backend/value-resolver/src/test/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverTest.kt +++ b/backend/value-resolver/src/test/kotlin/com/ritense/valueresolver/ProcessVariableValueResolverTest.kt @@ -17,7 +17,7 @@ package com.ritense.valueresolver import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.module.kotlin.convertValue +import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.ritense.valtimo.contract.json.MapperSingleton import org.assertj.core.api.Assertions @@ -121,7 +121,7 @@ internal class ProcessVariableValueResolverTest { Assertions.assertThat(resolver.apply("/person/location/streetName")).isEqualTo("Funenpark") Assertions.assertThat(resolver.apply("/person/location/streetNumber")).isEqualTo(1) Assertions.assertThat(resolver.apply("/person/location")).isEqualTo(mapOf("streetName" to "Funenpark", "streetNumber" to 1)) - Assertions.assertThat(resolver.apply("/person")).isEqualTo(objectMapper.convertValue>(personVariable)) + Assertions.assertThat(resolver.apply("/person")).isEqualTo(PLAIN_MAPPER.convertValue(personVariable, LinkedHashMap::class.java)) Assertions.assertThat(resolver.apply("person.firstName")).isEqualTo("John") Assertions.assertThat(resolver.apply("person.birthDate")).isEqualTo("2000-01-01") Assertions.assertThat(resolver.apply("person.verified")).isEqualTo(true) @@ -221,14 +221,14 @@ internal class ProcessVariableValueResolverTest { Assertions.assertThat(resolver.apply("/person/location/streetName")).isEqualTo("Funenpark") Assertions.assertThat(resolver.apply("/person/location/streetNumber")).isEqualTo(1) Assertions.assertThat(resolver.apply("/person/location")).isEqualTo(mapOf("streetName" to "Funenpark", "streetNumber" to 1)) - Assertions.assertThat(resolver.apply("/person")).isEqualTo(objectMapper.convertValue>(personVariable)) + Assertions.assertThat(resolver.apply("/person")).isEqualTo(PLAIN_MAPPER.convertValue(personVariable, LinkedHashMap::class.java)) Assertions.assertThat(resolver.apply("person.firstName")).isEqualTo("John") Assertions.assertThat(resolver.apply("person.birthDate")).isEqualTo("2000-01-01") Assertions.assertThat(resolver.apply("person.verified")).isEqualTo(true) Assertions.assertThat(resolver.apply("person.location.streetName")).isEqualTo("Funenpark") Assertions.assertThat(resolver.apply("person.location.streetNumber")).isEqualTo(1) Assertions.assertThat(resolver.apply("person.location")).isEqualTo(mapOf("streetName" to "Funenpark", "streetNumber" to 1)) - Assertions.assertThat(resolver.apply("person")).isEqualTo(objectMapper.convertValue>(personVariable)) + Assertions.assertThat(resolver.apply("person")).isEqualTo(PLAIN_MAPPER.convertValue(personVariable, LinkedHashMap::class.java)) } @Test @@ -319,6 +319,10 @@ internal class ProcessVariableValueResolverTest { ) } + companion object { + private val PLAIN_MAPPER = ObjectMapper() + } + private fun mockTaskWithVariables(map: Map): DelegateTask { val delegateTask: DelegateTask = mock() whenever(delegateTask.variables).thenReturn(map) diff --git a/backend/web/build.gradle b/backend/web/build.gradle index 53c29a2845..068a65617b 100644 --- a/backend/web/build.gradle +++ b/backend/web/build.gradle @@ -30,6 +30,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-security" implementation "org.springframework.boot:spring-boot-starter-validation" + implementation "org.springframework.boot:spring-boot-restclient" implementation "com.fasterxml.jackson.module:jackson-module-kotlin" implementation "com.fasterxml.jackson.module:jackson-module-blackbird" diff --git a/backend/web/src/main/kotlin/com/ritense/valtimo/web/logging/LoggingRestClientCustomizer.kt b/backend/web/src/main/kotlin/com/ritense/valtimo/web/logging/LoggingRestClientCustomizer.kt index a9cc66b669..d273b417fa 100644 --- a/backend/web/src/main/kotlin/com/ritense/valtimo/web/logging/LoggingRestClientCustomizer.kt +++ b/backend/web/src/main/kotlin/com/ritense/valtimo/web/logging/LoggingRestClientCustomizer.kt @@ -18,7 +18,7 @@ package com.ritense.valtimo.web.logging import com.ritense.valtimo.contract.annotation.SkipComponentScan import io.github.oshai.kotlinlogging.KotlinLogging -import org.springframework.boot.web.client.RestClientCustomizer +import org.springframework.boot.restclient.RestClientCustomizer import org.springframework.http.HttpRequest import org.springframework.http.MediaType import org.springframework.http.client.ClientHttpRequestExecution @@ -70,7 +70,7 @@ class LoggingRestClientCustomizer : RestClientCustomizer, ClientHttpRequestInter |Request: |HTTP Method = ${request.method} |Request URI = ${request.uri} - |Header names = ${request.headers.keys} + |Header names = ${request.headers.headerNames()} |Body = ${getFormattedBody(requestBody, request.headers.contentType)} |--------------------------------------- |Response: diff --git a/backend/web/src/main/kotlin/com/ritense/valtimo/web/sse/security/config/SseHttpSecurityConfigurer.kt b/backend/web/src/main/kotlin/com/ritense/valtimo/web/sse/security/config/SseHttpSecurityConfigurer.kt index 5998a65a77..99634795c7 100644 --- a/backend/web/src/main/kotlin/com/ritense/valtimo/web/sse/security/config/SseHttpSecurityConfigurer.kt +++ b/backend/web/src/main/kotlin/com/ritense/valtimo/web/sse/security/config/SseHttpSecurityConfigurer.kt @@ -20,7 +20,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class SseHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -28,8 +28,8 @@ class SseHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/sse")).anonymous() - .requestMatchers(antMatcher(GET, "/api/v1/sse/{subscriptionId}")).anonymous() + .requestMatchers(pathPattern(GET, "/api/v1/sse")).anonymous() + .requestMatchers(pathPattern(GET, "/api/v1/sse/{subscriptionId}")).anonymous() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/widget/build.gradle b/backend/widget/build.gradle index 4f0b09dab6..010d2ce0e9 100644 --- a/backend/widget/build.gradle +++ b/backend/widget/build.gradle @@ -44,7 +44,7 @@ dependencies { implementation "org.springframework.boot:spring-boot" implementation "org.springframework.boot:spring-boot-starter" - implementation "org.springframework.boot:spring-boot-starter-aop" + implementation "org.springframework.boot:spring-boot-starter-aspectj" implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "org.springframework.boot:spring-boot-starter-security" diff --git a/backend/widget/src/main/kotlin/com/ritense/tab/TabAutoConfiguration.kt b/backend/widget/src/main/kotlin/com/ritense/tab/TabAutoConfiguration.kt index c45dfd76e1..077b280e9e 100644 --- a/backend/widget/src/main/kotlin/com/ritense/tab/TabAutoConfiguration.kt +++ b/backend/widget/src/main/kotlin/com/ritense/tab/TabAutoConfiguration.kt @@ -23,7 +23,7 @@ import com.ritense.tab.service.TabService import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order import org.springframework.data.jpa.repository.config.EnableJpaRepositories diff --git a/backend/widget/src/main/kotlin/com/ritense/tab/security/TabHttpSecurityConfigurer.kt b/backend/widget/src/main/kotlin/com/ritense/tab/security/TabHttpSecurityConfigurer.kt index 0a065c4365..ce18feb3f3 100644 --- a/backend/widget/src/main/kotlin/com/ritense/tab/security/TabHttpSecurityConfigurer.kt +++ b/backend/widget/src/main/kotlin/com/ritense/tab/security/TabHttpSecurityConfigurer.kt @@ -20,7 +20,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class TabHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -28,7 +28,7 @@ class TabHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/tab/{ownerType}/{ownerId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/tab/{ownerType}/{ownerId}")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/widget/src/main/kotlin/com/ritense/widget/WidgetAutoConfiguration.kt b/backend/widget/src/main/kotlin/com/ritense/widget/WidgetAutoConfiguration.kt index 86e13e1af2..cf83af63bd 100644 --- a/backend/widget/src/main/kotlin/com/ritense/widget/WidgetAutoConfiguration.kt +++ b/backend/widget/src/main/kotlin/com/ritense/widget/WidgetAutoConfiguration.kt @@ -47,7 +47,7 @@ import com.ritense.widget.table.TableWidgetDataProvider import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnClass import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/widget/src/main/kotlin/com/ritense/widget/page/ResolvedPage.kt b/backend/widget/src/main/kotlin/com/ritense/widget/page/ResolvedPage.kt index 2cc90bc2c6..de0ff7cbab 100644 --- a/backend/widget/src/main/kotlin/com/ritense/widget/page/ResolvedPage.kt +++ b/backend/widget/src/main/kotlin/com/ritense/widget/page/ResolvedPage.kt @@ -21,7 +21,7 @@ import org.springframework.data.domain.PageImpl import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort -class ResolvedPage( +class ResolvedPage( val content: List, val first: Boolean, val last: Boolean, diff --git a/backend/zgw/besluiten-api/src/test/kotlin/com/ritense/besluitenapi/client/BesluitenApiClientTest.kt b/backend/zgw/besluiten-api/src/test/kotlin/com/ritense/besluitenapi/client/BesluitenApiClientTest.kt index 373db4996f..c20d302a1e 100644 --- a/backend/zgw/besluiten-api/src/test/kotlin/com/ritense/besluitenapi/client/BesluitenApiClientTest.kt +++ b/backend/zgw/besluiten-api/src/test/kotlin/com/ritense/besluitenapi/client/BesluitenApiClientTest.kt @@ -19,6 +19,7 @@ package com.ritense.besluitenapi.client import com.jayway.jsonpath.matchers.JsonPathMatchers import com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath import com.ritense.besluitenapi.BesluitenApiAuthentication +import com.ritense.valtimo.Jackson2TestUtils import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.hamcrest.CoreMatchers @@ -55,7 +56,7 @@ class BesluitenApiClientTest { @Test fun `should send create besluit request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = BesluitenApiClient(restClientBuilder) val responseBody = """ @@ -138,7 +139,7 @@ class BesluitenApiClientTest { @Test fun `should send create besluit request and parse response when vervalreden is null`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = BesluitenApiClient(restClientBuilder) val responseBody = """ @@ -220,7 +221,7 @@ class BesluitenApiClientTest { @Test fun `should send patch besluit request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = BesluitenApiClient(restClientBuilder) val responseBody = """ diff --git a/backend/zgw/catalogi-api/build.gradle b/backend/zgw/catalogi-api/build.gradle index 26b5e9c539..7588ec5ea1 100644 --- a/backend/zgw/catalogi-api/build.gradle +++ b/backend/zgw/catalogi-api/build.gradle @@ -23,9 +23,11 @@ dependencies { implementation project(':backend:zgw') implementation "io.github.oshai:kotlin-logging:${kotlinLoggingVersion}" + implementation "org.springframework.boot:spring-boot-starter-cache" implementation "org.springframework.boot:spring-boot-starter-webflux" implementation "org.springframework.boot:spring-boot-starter-security" + testImplementation project(':backend:test-utils-common') testImplementation "org.springframework.boot:spring-boot-starter-data-jpa" testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.junit.jupiter:junit-jupiter" diff --git a/backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi/security/CatalogiApiHttpSecurityConfigurer.kt b/backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi/security/CatalogiApiHttpSecurityConfigurer.kt index 05a95ba9f1..e625f62f6f 100644 --- a/backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi/security/CatalogiApiHttpSecurityConfigurer.kt +++ b/backend/zgw/catalogi-api/src/main/kotlin/com/ritense/catalogiapi/security/CatalogiApiHttpSecurityConfigurer.kt @@ -21,22 +21,22 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class CatalogiApiHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/documenttype")).authenticated() - requests.requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/zaaktype/documenttype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/zaaktype/roltype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/statustype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/resultaattype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/besluittype")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/documenttype")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/zaaktype/documenttype")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/zaaktype/roltype")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/statustype")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/resultaattype")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaaktype/besluittype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/zgw/zaaktype")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/catalogi-eigenschappen")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/zgw/zaaktype")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/catalogi-eigenschappen")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/client/CatalogiApiClientTest.kt b/backend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/client/CatalogiApiClientTest.kt index 4455e0e57c..98fadd2639 100644 --- a/backend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/client/CatalogiApiClientTest.kt +++ b/backend/zgw/catalogi-api/src/test/kotlin/com/ritense/catalogiapi/client/CatalogiApiClientTest.kt @@ -18,6 +18,7 @@ package com.ritense.catalogiapi.client import com.ritense.catalogiapi.CatalogiApiAuthentication import com.ritense.catalogiapi.client.CatalogiApiClient.Companion.INFORMATIEOBJECTTYPECACHE_KEY +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.catalogiapi.domain.InformatieobjecttypeRichting import com.ritense.catalogiapi.domain.InformatieobjecttypeVertrouwelijkheid import okhttp3.mockwebserver.MockResponse @@ -95,7 +96,7 @@ internal class CatalogiApiClientTest { @Test fun `should send get informatieobjecttype request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val responseBody = """ @@ -135,7 +136,7 @@ internal class CatalogiApiClientTest { @Test fun `should not send get informatieobjecttype request when url and baseUrl dont match`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = "http://example.com" @@ -157,7 +158,7 @@ internal class CatalogiApiClientTest { @Test fun `should send get roltypen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val zaakTypeUrl = "$baseUrl/zaaktypen/${UUID.randomUUID()}" @@ -200,7 +201,7 @@ internal class CatalogiApiClientTest { @Test fun `should get statustypen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val zaakTypeUrl = "$baseUrl/zaaktypen/${UUID.randomUUID()}" @@ -250,7 +251,7 @@ internal class CatalogiApiClientTest { @Test fun `should get resultaattypen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val zaakTypeUrl = "$baseUrl/zaaktypen/${UUID.randomUUID()}" @@ -311,7 +312,7 @@ internal class CatalogiApiClientTest { @Test fun `should get beluittypen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val zaakTypeUrl = "$baseUrl/zaaktypen/${UUID.randomUUID()}" @@ -369,7 +370,7 @@ internal class CatalogiApiClientTest { @Test fun `prefillCache should prefill the cache`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val cache = mock() @@ -407,7 +408,7 @@ internal class CatalogiApiClientTest { private fun sendGetZaaktypeInformatieobjecttypeRequest( request: ZaaktypeInformatieobjecttypeRequest ): RecordedRequest { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val responseBody = """ @@ -469,7 +470,7 @@ internal class CatalogiApiClientTest { @Test fun `should get zaaktypen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val responseBody = """ @@ -554,7 +555,7 @@ internal class CatalogiApiClientTest { @Test fun `should get eigenschappen request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = CatalogiApiClient(restClientBuilder, cacheManager) val baseUrl = mockApi.url("api").toString() val responseBody = """ diff --git a/backend/zgw/documenten-api-preview/src/main/kotlin/com/ritense/documentenapipreview/security/DocumentenApiPreviewHttpSecurityConfigurer.kt b/backend/zgw/documenten-api-preview/src/main/kotlin/com/ritense/documentenapipreview/security/DocumentenApiPreviewHttpSecurityConfigurer.kt index 55f18b1e82..2a357763c2 100644 --- a/backend/zgw/documenten-api-preview/src/main/kotlin/com/ritense/documentenapipreview/security/DocumentenApiPreviewHttpSecurityConfigurer.kt +++ b/backend/zgw/documenten-api-preview/src/main/kotlin/com/ritense/documentenapipreview/security/DocumentenApiPreviewHttpSecurityConfigurer.kt @@ -20,7 +20,7 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class DocumentenApiPreviewHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -28,7 +28,7 @@ class DocumentenApiPreviewHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/documenten-api-preview/*/preview/*")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/documenten-api-preview/*/preview/*")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/DocumentenApiAutoConfiguration.kt b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/DocumentenApiAutoConfiguration.kt index 6087ce1001..4150d93155 100644 --- a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/DocumentenApiAutoConfiguration.kt +++ b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/DocumentenApiAutoConfiguration.kt @@ -51,7 +51,7 @@ import com.ritense.valtimo.processlink.service.PluginProcessLinkService import com.ritense.valueresolver.ValueResolverService import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.beans.factory.annotation.Value import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean diff --git a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/ZgwDocumentTrefwoordAutoConfiguration.kt b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/ZgwDocumentTrefwoordAutoConfiguration.kt index 33a84c06fe..2d0556ec31 100644 --- a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/ZgwDocumentTrefwoordAutoConfiguration.kt +++ b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/ZgwDocumentTrefwoordAutoConfiguration.kt @@ -24,7 +24,7 @@ import com.ritense.documentenapi.service.ZgwDocumentTrefwoordService import com.ritense.documentenapi.web.rest.ZgwDocumentTrefwoordResource import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.annotation.Bean @AutoConfiguration diff --git a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/security/DocumentenApiHttpSecurityConfigurer.kt b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/security/DocumentenApiHttpSecurityConfigurer.kt index 25e4dee7df..800c9cb48a 100644 --- a/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/security/DocumentenApiHttpSecurityConfigurer.kt +++ b/backend/zgw/documenten-api/src/main/kotlin/com/ritense/documentenapi/security/DocumentenApiHttpSecurityConfigurer.kt @@ -24,7 +24,7 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class DocumentenApiHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -32,32 +32,32 @@ class DocumentenApiHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}/download")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}/download")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/documenten-api/{pluginConfigurationId}/files/{documentId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionName}/zgw-document-column")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionName}/documenten-api/version")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/zgw-document/upload-field")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionName}/zgw-document-column")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionName}/documenten-api/version")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/zgw-document/upload-field")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord/{trefwoord}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord/{trefwoord}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(POST, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord/{trefwoord}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord/{trefwoord}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/trefwoord")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column-key")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column-key")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column/{key}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document-column/{key}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/documenten-api/version")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/version/{caseDefinitionVersionTag}/documenten-api/version")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/documenten-api/versions")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/documenten-api/version")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/version/{caseDefinitionVersionTag}/documenten-api/version")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/documenten-api/versions")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/upload-field")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/upload-field")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/upload-field")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, "/api/management/v1/case-definition/{caseDefinitionName}/zgw-document/upload-field")).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/documenten-api/src/test/kotlin/com/ritense/documentenapi/client/DocumentenApiClientTest.kt b/backend/zgw/documenten-api/src/test/kotlin/com/ritense/documentenapi/client/DocumentenApiClientTest.kt index 6001f71029..696ab25373 100644 --- a/backend/zgw/documenten-api/src/test/kotlin/com/ritense/documentenapi/client/DocumentenApiClientTest.kt +++ b/backend/zgw/documenten-api/src/test/kotlin/com/ritense/documentenapi/client/DocumentenApiClientTest.kt @@ -29,6 +29,7 @@ import com.ritense.documentenapi.event.DocumentUpdated import com.ritense.documentenapi.web.rest.dto.DocumentSearchRequest import com.ritense.outbox.OutboxService import com.ritense.outbox.domain.BaseEvent +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import com.ritense.zgw.Rsin import com.ritense.zgw.domain.Vertrouwelijkheid @@ -53,6 +54,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.springframework.data.domain.Page import org.springframework.data.domain.PageRequest +import org.springframework.transaction.PlatformTransactionManager import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.http.HttpHeaders.CONTENT_TYPE @@ -84,6 +86,8 @@ internal class DocumentenApiClientTest { lateinit var authorizationService: AuthorizationService + lateinit var platformTransactionManager: PlatformTransactionManager + @BeforeAll fun setUp() { mockDocumentenApi = MockWebServer() @@ -91,7 +95,9 @@ internal class DocumentenApiClientTest { objectMapper = MapperSingleton.get() outboxService = mock() authorizationService = mock() + platformTransactionManager = mock() whenever(authorizationService.hasPermission(any())).thenReturn(true) + whenever(platformTransactionManager.getTransaction(any())).thenReturn(mock()) } @BeforeEach @@ -106,8 +112,8 @@ internal class DocumentenApiClientTest { @Test fun `should send request and parse response`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val responseBody = """ { "url": "http://example.com", @@ -174,8 +180,8 @@ internal class DocumentenApiClientTest { @Test fun `should make put call for bestanddelen`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val request = BestandsdelenRequest( inhoud = InputStream.nullInputStream() @@ -229,8 +235,8 @@ internal class DocumentenApiClientTest { @Test fun `should send outbox message on saving document`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val documentURL = "http://example.com" val responseBody = """ @@ -307,8 +313,8 @@ internal class DocumentenApiClientTest { @Test fun `should not send outbox message on error when saving document`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) mockDocumentenApi.enqueue(mockResponse("").setResponseCode(400)) @@ -342,8 +348,8 @@ internal class DocumentenApiClientTest { @Test fun `should send get document request and parse response`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val responseBody = """ { @@ -416,8 +422,8 @@ internal class DocumentenApiClientTest { @Test fun `should send outbox message on retrieving document informatieobject`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val documentInformatieObjectUrl = "http://example.com/informatie-object/123" val responseBody = """ { @@ -479,8 +485,8 @@ internal class DocumentenApiClientTest { @Test fun `should not send outbox message on error retrieving document informatieobject`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) mockDocumentenApi.enqueue(mockResponse("").setResponseCode(400)) @@ -501,8 +507,8 @@ internal class DocumentenApiClientTest { @Test fun `should send outbox message on download document informatieobject content`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val documentInformatieObjectId = "123" val buffer = Buffer() @@ -533,8 +539,8 @@ internal class DocumentenApiClientTest { @Test fun `should not send outbox message on error download document informatieobject content`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val documentInformatieObjectId = "123" mockDocumentenApi.enqueue(mockResponse("").setResponseCode(400)) @@ -557,8 +563,8 @@ internal class DocumentenApiClientTest { @Test fun `should send delete document request and send event`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val eventCapture = argumentCaptor>() mockDocumentenApi.enqueue(MockResponse().setResponseCode(204)) @@ -586,8 +592,8 @@ internal class DocumentenApiClientTest { @Test fun `should not send outbox message on error deleting document informatieobject`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) mockDocumentenApi.enqueue(mockResponse("{}").setResponseCode(400)) @@ -608,9 +614,9 @@ internal class DocumentenApiClientTest { @Test fun `should send patch document object request and send event`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() .defaultHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val eventCapture = argumentCaptor>() val documentInformatieObjectUrl = mockDocumentenApi.url("/informatie-object/123").toUri() @@ -704,8 +710,8 @@ internal class DocumentenApiClientTest { @Test fun `should not send outbox message on error updating document informatieobject`() { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) mockDocumentenApi.enqueue(mockResponse("{}").setResponseCode(400)) @@ -994,8 +1000,8 @@ internal class DocumentenApiClientTest { documentSearchRequest: DocumentSearchRequest, expectException: Boolean = false ): DocumentSearchResult { - val restClientBuilder = RestClient.builder() - val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, mock(), authorizationService) + val restClientBuilder = Jackson2TestUtils.restClientBuilder() + val client = DocumentenApiClient(restClientBuilder, outboxService, objectMapper, platformTransactionManager, authorizationService) val eventCapture = argumentCaptor>() // prevent queuing of response when exception is expected to avoid other tests breaking with old data in the queue diff --git a/backend/zgw/klantinteracties-api/src/test/kotlin/com/ritense/klantinteractiesapi/client/KlantinteractiesApiClientTest.kt b/backend/zgw/klantinteracties-api/src/test/kotlin/com/ritense/klantinteractiesapi/client/KlantinteractiesApiClientTest.kt index 0b1c931f9f..bc0af9367c 100644 --- a/backend/zgw/klantinteracties-api/src/test/kotlin/com/ritense/klantinteractiesapi/client/KlantinteractiesApiClientTest.kt +++ b/backend/zgw/klantinteracties-api/src/test/kotlin/com/ritense/klantinteractiesapi/client/KlantinteractiesApiClientTest.kt @@ -29,6 +29,7 @@ import com.ritense.klantinteractiesapi.domain.PartijIdentificator import com.ritense.klantinteractiesapi.domain.PartijSoort import com.ritense.klantinteractiesapi.domain.PersoonPartijIndentificatie import com.ritense.klantinteractiesapi.domain.SoortObject +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -55,7 +56,7 @@ class KlantinteractiesApiClientTest { this.registerSubtypes(NamedType(PersoonPartijIndentificatie::class.java)) } - restClientBuilder = RestClient.builder().messageConverters { converters -> + restClientBuilder = Jackson2TestUtils.restClientBuilder().messageConverters { converters -> converters.forEach { converter -> if (converter is MappingJackson2HttpMessageConverter) { converter.setObjectMapper(objectMapper) diff --git a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/autoconfigure/NotificatiesApiAutoConfiguration.kt b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/autoconfigure/NotificatiesApiAutoConfiguration.kt index abb7b9ffda..5f4444d421 100644 --- a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/autoconfigure/NotificatiesApiAutoConfiguration.kt +++ b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/autoconfigure/NotificatiesApiAutoConfiguration.kt @@ -38,7 +38,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean @@ -150,7 +150,7 @@ class NotificatiesApiAutoConfiguration { @Bean("notificatiesApiTaskExecutor") fun notificatiesApiTaskExecutor(processingProperties: NotificatiesApiProcessingProperties): TaskExecutor { return ThreadPoolTaskExecutor().apply { - threadNamePrefix = "notificaties-api-task-" + setThreadNamePrefix("notificaties-api-task-") corePoolSize = processingProperties.executorCorePoolSize maxPoolSize = processingProperties.executorMaxPoolSize setQueueCapacity(processingProperties.executorQueueCapacity) diff --git a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicator.kt b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicator.kt index 2e11c0343a..f816ac0d88 100644 --- a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicator.kt +++ b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicator.kt @@ -19,9 +19,9 @@ package com.ritense.notificatiesapi.health import com.ritense.notificatiesapi.config.NotificatiesApiProcessingProperties import com.ritense.notificatiesapi.domain.NotificatiesApiInboundEventStatus import com.ritense.notificatiesapi.repository.NotificatiesApiInboundEventRepository -import org.springframework.boot.actuate.health.AbstractHealthIndicator -import org.springframework.boot.actuate.health.Health -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.AbstractHealthIndicator +import org.springframework.boot.health.contributor.Health +import org.springframework.boot.health.contributor.Status class NotificatiesApiInboundEventHealthIndicator( private val inboundEventRepository: NotificatiesApiInboundEventRepository, diff --git a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/security/config/NotificatiesApiHttpSecurityConfigurer.kt b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/security/config/NotificatiesApiHttpSecurityConfigurer.kt index bc60796991..d6af8a496a 100644 --- a/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/security/config/NotificatiesApiHttpSecurityConfigurer.kt +++ b/backend/zgw/notificaties-api/src/main/kotlin/com/ritense/notificatiesapi/security/config/NotificatiesApiHttpSecurityConfigurer.kt @@ -22,18 +22,18 @@ import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class NotificatiesApiHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(POST, "/api/v1/notificatiesapi/callback")).permitAll() - .requestMatchers(antMatcher(GET, "/api/management/v1/notificatiesapi/inbound-events/failed")) + requests.requestMatchers(pathPattern(POST, "/api/v1/notificatiesapi/callback")).permitAll() + .requestMatchers(pathPattern(GET, "/api/management/v1/notificatiesapi/inbound-events/failed")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/notificatiesapi/inbound-events/failed/count")) + .requestMatchers(pathPattern(GET, "/api/management/v1/notificatiesapi/inbound-events/failed/count")) .hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/notificatiesapi/inbound-events/*/retry")) + .requestMatchers(pathPattern(POST, "/api/management/v1/notificatiesapi/inbound-events/*/retry")) .hasAuthority(ADMIN) } } catch (e: Exception) { diff --git a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/BaseIntegrationTest.kt b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/BaseIntegrationTest.kt index 7594c75de1..0180530e23 100644 --- a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/BaseIntegrationTest.kt +++ b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/BaseIntegrationTest.kt @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Tag import org.junit.jupiter.api.extension.ExtendWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.bean.override.mockito.MockitoBean import org.springframework.context.ApplicationEventPublisher import org.springframework.test.context.junit.jupiter.SpringExtension @@ -31,10 +31,10 @@ import org.springframework.test.context.junit.jupiter.SpringExtension @Tag("integration") abstract class BaseIntegrationTest { - @MockBean + @MockitoBean lateinit var mailSender: MailSender - @MockBean + @MockitoBean lateinit var userManagementService: UserManagementService @Autowired diff --git a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/client/NotificatiesApiClientTest.kt b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/client/NotificatiesApiClientTest.kt index 2455e50572..69b8c9f682 100644 --- a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/client/NotificatiesApiClientTest.kt +++ b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/client/NotificatiesApiClientTest.kt @@ -17,11 +17,11 @@ package com.ritense.notificatiesapi.client import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import com.ritense.notificatiesapi.NotificatiesApiAuthentication import com.ritense.notificatiesapi.domain.Abonnement import com.ritense.notificatiesapi.domain.Kanaal import com.ritense.plugin.domain.PluginConfigurationId +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -49,7 +49,7 @@ class NotificatiesApiClientTest { fun setup() { mockNotificatiesApi = MockWebServer() mockNotificatiesApi.start() - restClientBuilder = RestClient.builder() + restClientBuilder = Jackson2TestUtils.restClientBuilder() objectMapper = MapperSingleton.get() client = NotificatiesApiClient(restClientBuilder, objectMapper) } @@ -84,9 +84,11 @@ class NotificatiesApiClientTest { kanaal = Kanaal(naam = "Test Kanaal") ) val recordedRequest = mockNotificatiesApi.takeRequest() - val requestBody = MapperSingleton.get().readValue>( - recordedRequest.body.readUtf8() - ) + @Suppress("UNCHECKED_CAST") + val requestBody: Map = PLAIN_MAPPER.readValue( + recordedRequest.body.readUtf8(), + LinkedHashMap::class.java + ) as Map assertEquals("Bearer test", recordedRequest.getHeader("Authorization")) assertEquals("/kanaal", recordedRequest.path) @@ -195,9 +197,11 @@ class NotificatiesApiClientTest { ) ) val recordedRequest = mockNotificatiesApi.takeRequest() - val requestBody = MapperSingleton.get().readValue>( - recordedRequest.body.readUtf8() - ) + @Suppress("UNCHECKED_CAST") + val requestBody: Map = PLAIN_MAPPER.readValue( + recordedRequest.body.readUtf8(), + LinkedHashMap::class.java + ) as Map assertEquals("Bearer test", recordedRequest.getHeader("Authorization")) assertEquals("/abonnement", recordedRequest.path) @@ -255,6 +259,10 @@ class NotificatiesApiClientTest { .setBody(body) } + companion object { + private val PLAIN_MAPPER = ObjectMapper() + } + class TestAuthentication() : NotificatiesApiAuthentication { override val configurationId: PluginConfigurationId get() = PluginConfigurationId.newId() diff --git a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicatorTest.kt b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicatorTest.kt index 681bb036a9..3dcbfa9af2 100644 --- a/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicatorTest.kt +++ b/backend/zgw/notificaties-api/src/test/kotlin/com/ritense/notificatiesapi/health/NotificatiesApiInboundEventHealthIndicatorTest.kt @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.whenever -import org.springframework.boot.actuate.health.Status +import org.springframework.boot.health.contributor.Status import kotlin.test.assertEquals class NotificatiesApiInboundEventHealthIndicatorTest { diff --git a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autoconfigure/ObjectManagementAutoConfiguration.kt b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autoconfigure/ObjectManagementAutoConfiguration.kt index 32e95094f2..25b2e85046 100644 --- a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autoconfigure/ObjectManagementAutoConfiguration.kt +++ b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autoconfigure/ObjectManagementAutoConfiguration.kt @@ -30,7 +30,7 @@ import com.ritense.search.service.SearchFieldV2Service import com.ritense.search.service.SearchListColumnService import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autodeployment/ObjectManagementDefinitionDeploymentService.kt b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autodeployment/ObjectManagementDefinitionDeploymentService.kt index 7843ee6831..b93b76d864 100644 --- a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autodeployment/ObjectManagementDefinitionDeploymentService.kt +++ b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/autodeployment/ObjectManagementDefinitionDeploymentService.kt @@ -93,7 +93,7 @@ class ObjectManagementDefinitionDeploymentService( ) } - private fun loadResources(): Array { + private fun loadResources(): Array { return try { ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources(PATH) } catch (ioe: IOException) { diff --git a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/security/config/ObjectManagementHttpSecurityConfigurer.kt b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/security/config/ObjectManagementHttpSecurityConfigurer.kt index 60ed8c857a..d1bb1ea505 100644 --- a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/security/config/ObjectManagementHttpSecurityConfigurer.kt +++ b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/security/config/ObjectManagementHttpSecurityConfigurer.kt @@ -24,22 +24,22 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ObjectManagementHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(POST, CONFIGURATION_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$CONFIGURATION_URL/{id}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, CONFIGURATION_URL)).authenticated() - .requestMatchers(antMatcher(PUT, CONFIGURATION_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "$CONFIGURATION_URL/{id}")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "$CONFIGURATION_URL/{id}/object")).authenticated() - .requestMatchers(antMatcher(POST, "$CONFIGURATION_URL/{id}/object")).authenticated() + requests.requestMatchers(pathPattern(POST, CONFIGURATION_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$CONFIGURATION_URL/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, CONFIGURATION_URL)).authenticated() + .requestMatchers(pathPattern(PUT, CONFIGURATION_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "$CONFIGURATION_URL/{id}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "$CONFIGURATION_URL/{id}/object")).authenticated() + .requestMatchers(pathPattern(POST, "$CONFIGURATION_URL/{id}/object")).authenticated() - .requestMatchers(antMatcher(GET, CONFIGURATION_MANAGEMENT_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, CONFIGURATION_MANAGEMENT_URL)).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/web/rest/ObjectManagementResource.kt b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/web/rest/ObjectManagementResource.kt index 793097207d..46227dede7 100644 --- a/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/web/rest/ObjectManagementResource.kt +++ b/backend/zgw/object-management/src/main/kotlin/com/ritense/objectmanagement/web/rest/ObjectManagementResource.kt @@ -53,7 +53,7 @@ class ObjectManagementResource( ResponseEntity.ok(objectManagementService.update(objectManagement)) @GetMapping("/{id}") - fun getById(@PathVariable id: UUID): ResponseEntity = + fun getById(@PathVariable id: UUID): ResponseEntity = ResponseEntity.ok(objectManagementService.getById(id)) @GetMapping diff --git a/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/security/ObjectenApiHttpSecurityConfigurer.kt b/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/security/ObjectenApiHttpSecurityConfigurer.kt index e7f7bde728..bb1e94bea5 100644 --- a/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/security/ObjectenApiHttpSecurityConfigurer.kt +++ b/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/security/ObjectenApiHttpSecurityConfigurer.kt @@ -24,22 +24,22 @@ import org.springframework.http.HttpMethod.PATCH import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ObjectenApiHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/zaak/objecttype")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/zaak/object")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/document/{documentId}/zaak/object/form")).authenticated() - .requestMatchers(antMatcher(POST, OBJECT_URL)).authenticated() - .requestMatchers(antMatcher(PUT, OBJECT_URL)).authenticated() - .requestMatchers(antMatcher(DELETE, OBJECT_URL)).authenticated() - .requestMatchers(antMatcher(GET, "$OBJECT_URL/form")).authenticated() - .requestMatchers(antMatcher(PATCH, OBJECT_URL)).authenticated() - .requestMatchers(antMatcher(GET, OBJECT_URL)).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/zaak/objecttype")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/zaak/object")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/document/{documentId}/zaak/object/form")).authenticated() + .requestMatchers(pathPattern(POST, OBJECT_URL)).authenticated() + .requestMatchers(pathPattern(PUT, OBJECT_URL)).authenticated() + .requestMatchers(pathPattern(DELETE, OBJECT_URL)).authenticated() + .requestMatchers(pathPattern(GET, "$OBJECT_URL/form")).authenticated() + .requestMatchers(pathPattern(PATCH, OBJECT_URL)).authenticated() + .requestMatchers(pathPattern(GET, OBJECT_URL)).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/web/rest/ObjectResource.kt b/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/web/rest/ObjectResource.kt index 5f234c9c24..a26ad12506 100644 --- a/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/web/rest/ObjectResource.kt +++ b/backend/zgw/objecten-api/src/main/kotlin/com/ritense/objectenapi/web/rest/ObjectResource.kt @@ -62,7 +62,7 @@ class ObjectResource( @GetMapping fun getObjectByUrl( - @RequestParam(name = "objectUrl") objectUrl: URI): ResponseEntity = + @RequestParam(name = "objectUrl") objectUrl: URI): ResponseEntity = ResponseEntity.ok(zaakObjectService.getObjectByObjectUrl(objectUrl)) } diff --git a/backend/zgw/objecten-api/src/test/kotlin/com/ritense/objectenapi/client/ObjectenApiClientTest.kt b/backend/zgw/objecten-api/src/test/kotlin/com/ritense/objectenapi/client/ObjectenApiClientTest.kt index 1ebadd6eec..a9b1bba1aa 100644 --- a/backend/zgw/objecten-api/src/test/kotlin/com/ritense/objectenapi/client/ObjectenApiClientTest.kt +++ b/backend/zgw/objecten-api/src/test/kotlin/com/ritense/objectenapi/client/ObjectenApiClientTest.kt @@ -32,6 +32,7 @@ import com.ritense.objectenapi.event.ObjectViewed import com.ritense.objectenapi.event.ObjectsListed import com.ritense.outbox.OutboxService import com.ritense.outbox.domain.BaseEvent +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer @@ -85,7 +86,7 @@ internal class ObjectenApiClientTest { mockApi.start() objectMapper = MapperSingleton.get() outboxService = mock() - restClientBuilder = RestClient.builder() + restClientBuilder = Jackson2TestUtils.restClientBuilder() .defaultHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) authorizationService = mock() } diff --git a/backend/zgw/objecttypen-api/src/test/kotlin/com/ritense/objecttypenapi/client/ObjecttypenApiClientTest.kt b/backend/zgw/objecttypen-api/src/test/kotlin/com/ritense/objecttypenapi/client/ObjecttypenApiClientTest.kt index 37f51e57fc..e6b5e2944c 100644 --- a/backend/zgw/objecttypen-api/src/test/kotlin/com/ritense/objecttypenapi/client/ObjecttypenApiClientTest.kt +++ b/backend/zgw/objecttypen-api/src/test/kotlin/com/ritense/objecttypenapi/client/ObjecttypenApiClientTest.kt @@ -17,6 +17,7 @@ package com.ritense.objecttypenapi.client import com.ritense.objecttypenapi.ObjecttypenApiAuthentication +import com.ritense.valtimo.Jackson2TestUtils import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.jupiter.api.AfterAll @@ -51,7 +52,7 @@ internal class ObjecttypenApiClientTest { @Test fun `should send get single objecttype request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = ObjecttypenApiClient(restClientBuilder) val responseBody = """ @@ -122,7 +123,7 @@ internal class ObjecttypenApiClientTest { @Test fun `should send get multiple objecttypes request and parse response`() { - val restClientBuilder = RestClient.builder() + val restClientBuilder = Jackson2TestUtils.restClientBuilder() val client = ObjecttypenApiClient(restClientBuilder) val responseBody = """ diff --git a/backend/zgw/src/test/kotlin/com/ritense/zgw/ClientToolsTest.kt b/backend/zgw/src/test/kotlin/com/ritense/zgw/ClientToolsTest.kt index 7c81182088..b2a4d237fd 100644 --- a/backend/zgw/src/test/kotlin/com/ritense/zgw/ClientToolsTest.kt +++ b/backend/zgw/src/test/kotlin/com/ritense/zgw/ClientToolsTest.kt @@ -123,7 +123,7 @@ class ClientToolsTest { fun `optionalQueryParam should not add param when null`() { val builder = mock() val result = builder.optionalQueryParam("test", null) - verify(builder, never()).queryParam(any(), any()) + verify(builder, never()).queryParam(any(), any()) assertEquals(result, builder) } } \ No newline at end of file diff --git a/backend/zgw/verzoek/src/main/kotlin/com/ritense/verzoek/VerzoekPlugin.kt b/backend/zgw/verzoek/src/main/kotlin/com/ritense/verzoek/VerzoekPlugin.kt index fc61984ffb..b7510f4726 100644 --- a/backend/zgw/verzoek/src/main/kotlin/com/ritense/verzoek/VerzoekPlugin.kt +++ b/backend/zgw/verzoek/src/main/kotlin/com/ritense/verzoek/VerzoekPlugin.kt @@ -97,7 +97,7 @@ class VerzoekPlugin( val documentPath = it.target.substringAfter(delimiter = ":") runWithoutAuthorization { documentDefinitionService.validateJsonPointer( - documentDefinition.id.name(), + documentDefinition.id!!.name(), documentPath ) } diff --git a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/ZaakDetailsAutoConfiguration.kt b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/ZaakDetailsAutoConfiguration.kt index 955954620c..066ea20eb7 100644 --- a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/ZaakDetailsAutoConfiguration.kt +++ b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/ZaakDetailsAutoConfiguration.kt @@ -37,7 +37,7 @@ import com.ritense.zakenapi.ZaakUrlProvider import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.core.annotation.Order diff --git a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/documentobjectenapisync/DocumentObjectenApiSyncManagementResource.kt b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/documentobjectenapisync/DocumentObjectenApiSyncManagementResource.kt index f30beaffaf..74d46d1766 100644 --- a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/documentobjectenapisync/DocumentObjectenApiSyncManagementResource.kt +++ b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/documentobjectenapisync/DocumentObjectenApiSyncManagementResource.kt @@ -41,13 +41,13 @@ class DocumentObjectenApiSyncManagementResource( fun getSyncConfiguration( @PathVariable(name = "caseDefinitionKey") caseDefinitionKey: String, @PathVariable(name = "caseDefinitionVersionTag") caseDefinitionVersionTag: String, - ): ResponseEntity { + ): ResponseEntity { val caseDefinitionId = CaseDefinitionId(caseDefinitionKey, caseDefinitionVersionTag) val syncConfiguration = documentObjectenApiSyncManagementService.getSyncConfiguration(caseDefinitionId) - ?: return ResponseEntity.ok(null) + ?: return ResponseEntity.noContent().build() val objectManagementConfigurationId = syncConfiguration.objectManagementConfigurationId - ?: return ResponseEntity.ok(null) + ?: return ResponseEntity.noContent().build() val objectManagementConfiguration = objectManagementInfoProvider.getObjectManagementInfo(objectManagementConfigurationId) return ResponseEntity.ok( diff --git a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/security/ZaakDetailsHttpSecurityConfigurer.kt b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/security/ZaakDetailsHttpSecurityConfigurer.kt index ed00fb356c..9c9d512156 100644 --- a/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/security/ZaakDetailsHttpSecurityConfigurer.kt +++ b/backend/zgw/zaakdetails/src/main/kotlin/com/ritense/zaakdetails/security/ZaakDetailsHttpSecurityConfigurer.kt @@ -23,7 +23,7 @@ import org.springframework.http.HttpMethod.DELETE import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ZaakDetailsHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -31,9 +31,9 @@ class ZaakDetailsHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(PUT, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(PUT, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, SYNC_MANAGEMENT_URL)).hasAuthority(ADMIN) } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/ZakenApiPlugin.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/ZakenApiPlugin.kt index b5219e29bd..a902dd0faf 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/ZakenApiPlugin.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/ZakenApiPlugin.kt @@ -245,8 +245,9 @@ class ZakenApiPlugin( ) { val relatedFiles = zaakDocumentService.getInformatieObjectenAsRelatedFiles(documentId) relatedFiles.let { relatedFile -> + val jsonNode = objectMapper.valueToTree(relatedFile) execution.setVariable(resultProcessVariable, - objectMapper.convertValue(relatedFile) + ObjectMapper().convertValue(jsonNode, Object::class.java) ) } diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/config/ZakenApiAutoConfiguration.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/config/ZakenApiAutoConfiguration.kt index 98669a1bb2..78ca0c2035 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/config/ZakenApiAutoConfiguration.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/config/ZakenApiAutoConfiguration.kt @@ -72,7 +72,7 @@ import com.ritense.zakenapi.web.rest.ZaakDocumentResource import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.persistence.autoconfigure.EntityScan import org.springframework.context.ApplicationEventPublisher import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Primary diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/security/ZakenApiHttpSecurityConfigurer.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/security/ZakenApiHttpSecurityConfigurer.kt index f53f697d5c..6ad1a69601 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/security/ZakenApiHttpSecurityConfigurer.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/security/ZakenApiHttpSecurityConfigurer.kt @@ -24,7 +24,7 @@ import org.springframework.http.HttpMethod.GET import org.springframework.http.HttpMethod.POST import org.springframework.http.HttpMethod.PUT import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class ZakenApiHttpSecurityConfigurer : HttpSecurityConfigurer { @@ -32,38 +32,38 @@ class ZakenApiHttpSecurityConfigurer : HttpSecurityConfigurer { try { http.authorizeHttpRequests { requests -> requests - .requestMatchers(antMatcher(GET, "/api/v1/zaken-api/document/{documentId}/files")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v2/zaken-api/document/{documentId}/files")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/zaken-api/document/{documentId}/zaak")).authenticated() - .requestMatchers(antMatcher(PUT, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}")).authenticated() - .requestMatchers(antMatcher(DELETE, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}")).authenticated() - .requestMatchers(antMatcher(GET, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}/download")).authenticated() - .requestMatchers(antMatcher(GET, "/api/management/v1/zaak-type-link/{documentDefinitionName}")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(GET, "/api/v1/zaken-api/document/{documentId}/files")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v2/zaken-api/document/{documentId}/files")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/zaken-api/document/{documentId}/zaak")).authenticated() + .requestMatchers(pathPattern(PUT, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}")).authenticated() + .requestMatchers(pathPattern(DELETE, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}")).authenticated() + .requestMatchers(pathPattern(GET, "/api/v1/zaken-api/{pluginConfigurationId}/case-document/{caseDocumentId}/files/{documentId}/download")).authenticated() + .requestMatchers(pathPattern(GET, "/api/management/v1/zaak-type-link/{documentDefinitionName}")).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/zaak-type-link/process/{processDefinitionKey}" ) ).hasAuthority(ADMIN) - .requestMatchers(antMatcher(POST, "/api/management/v1/zaak-type-link")).hasAuthority(ADMIN) - .requestMatchers(antMatcher(DELETE, "/api/management/v1/zaak-type-link/{documentDefinitionName}")) + .requestMatchers(pathPattern(POST, "/api/management/v1/zaak-type-link")).hasAuthority(ADMIN) + .requestMatchers(pathPattern(DELETE, "/api/management/v1/zaak-type-link/{documentDefinitionName}")) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( GET, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaak-type-link" ) ).hasAuthority(ADMIN) - .requestMatchers(antMatcher(GET, "/api/management/v1/zaak-type-link/process/{processDefinitionId}")) + .requestMatchers(pathPattern(GET, "/api/management/v1/zaak-type-link/process/{processDefinitionId}")) .hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( POST, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaak-type-link" ) ).hasAuthority(ADMIN) .requestMatchers( - antMatcher( + pathPattern( DELETE, "/api/management/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaak-type-link" ) diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/service/ZaakDocumentService.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/service/ZaakDocumentService.kt index 2e0b5d4a78..37a00597ee 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/service/ZaakDocumentService.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/service/ZaakDocumentService.kt @@ -170,7 +170,7 @@ class ZaakDocumentService( } } - private fun toPage(list: List, pageable: Pageable): Page { + private fun toPage(list: List, pageable: Pageable): Page { val startIndex = pageable.offset.toInt() val endIndex = min(startIndex + pageable.pageSize, list.size) return PageImpl(list.subList(startIndex, endIndex), pageable, list.size.toLong()) diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/uploadprocess/UploadProcessResourceHttpSecurityConfigurer.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/uploadprocess/UploadProcessResourceHttpSecurityConfigurer.kt index 793cd32d3c..13e5d07af2 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/uploadprocess/UploadProcessResourceHttpSecurityConfigurer.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/uploadprocess/UploadProcessResourceHttpSecurityConfigurer.kt @@ -20,14 +20,14 @@ import com.ritense.valtimo.contract.security.config.HttpConfigurerConfigurationE import com.ritense.valtimo.contract.security.config.HttpSecurityConfigurer import org.springframework.http.HttpMethod.GET import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern class UploadProcessResourceHttpSecurityConfigurer : HttpSecurityConfigurer { override fun configure(http: HttpSecurity) { try { http.authorizeHttpRequests { requests -> - requests.requestMatchers(antMatcher(GET, "/api/v1/uploadprocess/case/{caseDefinitionKey}/check-link")).authenticated() + requests.requestMatchers(pathPattern(GET, "/api/v1/uploadprocess/case/{caseDefinitionKey}/check-link")).authenticated() } } catch (e: Exception) { throw HttpConfigurerConfigurationException(e) diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/DefaultZaakTypeLinkResource.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/DefaultZaakTypeLinkResource.kt index f397cba723..dd8b023e81 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/DefaultZaakTypeLinkResource.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/DefaultZaakTypeLinkResource.kt @@ -32,7 +32,7 @@ class DefaultZaakTypeLinkResource( override fun get( @LoggableResource("caseDefinitionKey") caseDefinitionKey: String, @LoggableResource("versionTag") versionTag: String, - ): ResponseEntity { + ): ResponseEntity { return when (val zaakTypeLink = zaakTypeLinkService.get(CaseDefinitionId(caseDefinitionKey, versionTag))) { null -> noContent().build() else -> ok(zaakTypeLink) @@ -41,7 +41,7 @@ class DefaultZaakTypeLinkResource( override fun getByProcess( @LoggableResource("processDefinitionKey") processDefinitionKey: String - ): ResponseEntity { + ): ResponseEntity { return ok(zaakTypeLinkService.getByProcess(processDefinitionKey)) } diff --git a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/ZaakTypeLinkResource.kt b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/ZaakTypeLinkResource.kt index 1c490a8e16..4554e0efc4 100644 --- a/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/ZaakTypeLinkResource.kt +++ b/backend/zgw/zaken-api/src/main/kotlin/com/ritense/zakenapi/web/rest/ZaakTypeLinkResource.kt @@ -39,10 +39,10 @@ interface ZaakTypeLinkResource { fun get( @PathVariable(name = "caseDefinitionKey") caseDefinitionKey: String, @PathVariable(name = "versionTag") versionTag: String - ): ResponseEntity + ): ResponseEntity @GetMapping("/v1/zaak-type-link/process/{processDefinitionId}") - fun getByProcess(@PathVariable(name = "processDefinitionId") processDefinitionId: String): ResponseEntity + fun getByProcess(@PathVariable(name = "processDefinitionId") processDefinitionId: String): ResponseEntity @PostMapping("/v1/case-definition/{caseDefinitionKey}/version/{versionTag}/zaak-type-link") fun create( diff --git a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/ZakenApiPluginTest.kt b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/ZakenApiPluginTest.kt index b2de53f08a..0adf9fd9be 100644 --- a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/ZakenApiPluginTest.kt +++ b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/ZakenApiPluginTest.kt @@ -16,7 +16,6 @@ package com.ritense.zakenapi -import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper import com.ritense.documentenapi.web.rest.dto.RelatedFileDto import com.ritense.plugin.service.PluginService @@ -83,6 +82,7 @@ import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever import org.operaton.bpm.engine.delegate.DelegateExecution import org.springframework.transaction.PlatformTransactionManager +import org.springframework.transaction.TransactionStatus import java.net.URI import java.time.LocalDate import java.util.UUID @@ -1400,8 +1400,9 @@ internal class ZakenApiPluginTest { val captor = argumentCaptor() verify(executionMock).setVariable(eq(resultProcessVariable), captor.capture()) - val expected: List> = - objectMapper.convertValue(relatedFiles, object : TypeReference>>() {}) + val plainMapper = ObjectMapper() + val jsonNode = objectMapper.valueToTree(relatedFiles) + val expected = plainMapper.convertValue(jsonNode, Object::class.java) assertEquals(expected, captor.firstValue) } @@ -1798,7 +1799,9 @@ internal class ZakenApiPluginTest { pluginService: PluginService = mock(), zaakHersteltermijnRepository: ZaakHersteltermijnRepository = mock(), zaakDocumentService: ZaakDocumentService = mock(), - platformTransactionManager: PlatformTransactionManager = mock(), + platformTransactionManager: PlatformTransactionManager = mock { + on { getTransaction(any()) } doReturn mock() + }, authenticationMock: ZakenApiAuthentication = mock(), valueResolverService: ValueResolverService = mock(), objectMapper: ObjectMapper = mock(), diff --git a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/client/ZakenApiClientTest.kt b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/client/ZakenApiClientTest.kt index f0bd48fd20..04307fb3a2 100644 --- a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/client/ZakenApiClientTest.kt +++ b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/client/ZakenApiClientTest.kt @@ -21,6 +21,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import com.ritense.authorization.AuthorizationService import com.ritense.outbox.OutboxService import com.ritense.outbox.domain.BaseEvent +import com.ritense.valtimo.Jackson2TestUtils import com.ritense.valtimo.contract.json.MapperSingleton import com.ritense.zakenapi.ZakenApiAuthentication import com.ritense.zakenapi.domain.* @@ -64,7 +65,7 @@ import kotlin.test.assertNull internal class ZakenApiClientTest { private val objectMapper: ObjectMapper = MapperSingleton.get() - private val restClientBuilder: RestClient.Builder = RestClient.builder() + private val restClientBuilder: RestClient.Builder = Jackson2TestUtils.restClientBuilder() private lateinit var mockApi: MockWebServer private lateinit var outboxService: OutboxService diff --git a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakResultaatValueResolverValueIT.kt b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakResultaatValueResolverValueIT.kt index d7e58e8724..b76d21ac7a 100644 --- a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakResultaatValueResolverValueIT.kt +++ b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakResultaatValueResolverValueIT.kt @@ -70,7 +70,7 @@ class ZaakResultaatValueResolverValueIT @Autowired constructor( "1.0.0", objectMapper.createObjectNode() ) - ).resultingDocument().get().id.id + ).resultingDocument().get().id!!.id // Create zaak instance link so the resolver can find the zaak URL zaakInstanceLinkService.createZaakInstanceLink( diff --git a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakStatusValueResolverValueIT.kt b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakStatusValueResolverValueIT.kt index d994efb2e7..458f38275d 100644 --- a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakStatusValueResolverValueIT.kt +++ b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakStatusValueResolverValueIT.kt @@ -70,7 +70,7 @@ class ZaakStatusValueResolverValueIT @Autowired constructor( "1.0.0", objectMapper.createObjectNode() ) - ).resultingDocument().get().id.id + ).resultingDocument().get().id!!.id // Create zaak instance link so the resolver can find the zaak URL zaakInstanceLinkService.createZaakInstanceLink( diff --git a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakValueResolverValueIT.kt b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakValueResolverValueIT.kt index 65371766b9..c230b1bb5a 100644 --- a/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakValueResolverValueIT.kt +++ b/backend/zgw/zaken-api/src/test/kotlin/com/ritense/zakenapi/resolver/ZaakValueResolverValueIT.kt @@ -78,7 +78,7 @@ class ZaakValueResolverValueIT @Autowired constructor( "1.0.0", objectMapper.createObjectNode() ) - ).resultingDocument().get().id.id + ).resultingDocument().get().id!!.id // Create zaak instance link so the resolver can find the zaak URL zaakInstanceLinkService.createZaakInstanceLink( diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4ac279b29a..8883c265e7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -187,124 +187,616 @@ } }, "dist/valtimo/access-control": { - "dev": true + "name": "@valtimo/access-control", + "version": "13.0.1", + "dev": true, + "dependencies": { + "jwt-decode": "4.0.0", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/access-control-management": { - "dev": true + "name": "@valtimo/access-control-management", + "version": "13.0.1", + "dev": true, + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/account": { - "dev": true + "name": "@valtimo/account", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "moment": "2.30.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/analyse": { - "dev": true + "name": "@valtimo/analyse", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/bootstrap": { - "dev": true + "name": "@valtimo/bootstrap", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/building-block-management": { - "dev": true + "name": "@valtimo/building-block-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "ajv": "8.17.1", + "tslib": "2.8.1", + "vanilla-jsoneditor": "3.10.0" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/case": { - "dev": true + "name": "@valtimo/case", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@ngx-translate/core": "16.0.4", + "@ngx-translate/http-loader": "16.0.1", + "angular-split": "19.0.0", + "moment": "2.30.1", + "muuri": "0.9.5", + "ngx-csv": "0.3.2", + "tslib": "2.8.1", + "uuid": "11.1.0" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/case-management": { - "dev": true + "name": "@valtimo/case-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/case-migration": { - "dev": true + "name": "@valtimo/case-migration", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/choice-field": { - "dev": true + "name": "@valtimo/choice-field", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/components": { - "dev": true + "name": "@valtimo/components", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@carbon/charts-angular": "1.23.6", + "@carbon/grid": "11.35.0", + "@carbon/icons": "11.59.0", + "@carbon/styles": "1.80.0", + "@carbon/themes": "11.51.0", + "@floating-ui/dom": "1.7.4", + "@formio/angular": "7.0.0", + "@foxythemes/bootstrap-datetime-picker-bs4": "2.3.5", + "@mdi/font": "7.4.47", + "@ng-bootstrap/ng-bootstrap": "11.0.1", + "@ngx-translate/core": "16.0.4", + "@ngx-translate/http-loader": "16.0.1", + "@tadashi/currency": "3.4.0", + "@types/topojson": "3.2.6", + "ajv": "8.17.1", + "bpmn-js": "18.6.1", + "carbon-components-angular": "5.57.6", + "deepmerge-ts": "7.1.5", + "flatpickr": "4.6.13", + "formiojs": "4.19.5", + "heatmap.js-fixed": "2.0.2", + "jquery": "3.7.1", + "jwt-decode": "4.0.0", + "lodash": "4.17.21", + "moment": "2.30.1", + "monaco-editor": "0.50.0", + "muuri": "0.9.5", + "ng-multiselect-dropdown": "1.0.0-beta.19", + "ngx-skeleton-loader": "11.0.0", + "ngx-spinner": "19.0.0", + "semver": "7.7.1", + "tslib": "2.8.1", + "uuid": "11.1.0", + "vanilla-jsoneditor": "3.10.0" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20", + "@angular/elements": "19.2.20" + } }, "dist/valtimo/dashboard": { - "dev": true + "name": "@valtimo/dashboard", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@carbon/charts-angular": "1.23.6", + "@ngx-translate/core": "16.0.4", + "@ngx-translate/http-loader": "16.0.1", + "@types/topojson": "3.2.6", + "d3": "7.9.0", + "d3-cloud": "1.2.7", + "d3-sankey": "0.12.3", + "d3-shape": "3.2.0", + "moment": "2.30.1", + "muuri": "0.9.5", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/dashboard-management": { - "dev": true + "name": "@valtimo/dashboard-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/decision": { - "dev": true + "name": "@valtimo/decision", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@bpmn-io/dmn-migrate": "0.5.0", + "dmn-js": "17.2.0", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/document": { - "dev": true + "name": "@valtimo/document", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/form-flow-management": { - "dev": true + "name": "@valtimo/form-flow-management", + "version": "13.0.1", + "dev": true, + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/form-management": { - "dev": true + "name": "@valtimo/form-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/form-view-model": { - "dev": true + "name": "@valtimo/form-view-model", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@formio/angular": "7.0.0", + "formiojs": "4.19.5", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/iko": { - "dev": true + "name": "@valtimo/iko", + "version": "13.0.0", + "dev": true, + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/keycloak": { - "dev": true + "name": "@valtimo/keycloak", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "jwt-decode": "4.0.0", + "keycloak-angular": "19.0.2", + "keycloak-js": "26.1.5", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/layout": { - "dev": true + "name": "@valtimo/layout", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@foxythemes/bootstrap-datetime-picker-bs4": "2.3.5", + "bootstrap": "4.6.2", + "components-jqueryui": "1.12.1", + "csp-header": "6.1.0", + "jquery": "3.7.1", + "lodash": "4.17.21", + "moment": "2.30.1", + "ol": "10.7.0", + "perfect-scrollbar": "1.5.6", + "popper.js": "1.16.1", + "select2": "4.1.0-rc.0", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/logging": { - "dev": true + "name": "@valtimo/logging", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/migration": { - "dev": true + "name": "@valtimo/migration", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "bpmn-js": "18.6.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/milestone": { - "dev": true + "name": "@valtimo/milestone", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "ngx-color-picker": "17.0.0", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/object": { - "dev": true + "name": "@valtimo/object", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/object-management": { - "dev": true + "name": "@valtimo/object-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/plugin": { - "dev": true + "name": "@valtimo/plugin", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/plugin-management": { - "dev": true + "name": "@valtimo/plugin-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/process": { - "dev": true + "name": "@valtimo/process", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "bpmn-js": "18.6.1", + "heatmap.js-fixed": "2.0.2", + "jquery": "3.7.1", + "moment": "2.30.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/process-link": { - "dev": true + "name": "@valtimo/process-link", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/process-management": { - "dev": true + "name": "@valtimo/process-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@bpmn-io/properties-panel": "3.26.4", + "bpmn-js": "18.6.1", + "bpmn-js-properties-panel": "5.35.0", + "camunda-bpmn-js-behaviors": "1.10.0", + "camunda-bpmn-moddle": "7.0.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/resource": { - "dev": true + "name": "@valtimo/resource", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/security": { - "dev": true + "name": "@valtimo/security", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "csp-header": "6.1.0", + "moment": "2.30.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/shared": { - "dev": true + "name": "@valtimo/shared", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "csp-header": "6.1.0", + "deepmerge-ts": "7.1.5", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/sse": { - "dev": true + "name": "@valtimo/sse", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/swagger": { - "dev": true + "name": "@valtimo/swagger", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "immutable": "4.3.7", + "swagger-ui": "5.21.0", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/task": { - "dev": true + "name": "@valtimo/task", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "lodash": "4.17.21", + "moment": "2.30.1", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/task-management": { - "dev": true + "name": "@valtimo/task-management", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "lodash": "4.17.21", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/teams": { - "dev": true + "name": "@valtimo/teams", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "dist/valtimo/zgw": { - "dev": true + "name": "@valtimo/zgw", + "version": "13.0.1", + "dev": true, + "license": "EUPL-1.2", + "dependencies": { + "@angular/forms": "19.2.20", + "@ngx-translate/core": "16.0.4", + "carbon-components-angular": "5.57.6", + "tslib": "2.8.1" + }, + "peerDependencies": { + "@angular/common": "19.2.20", + "@angular/core": "19.2.20" + } }, "node_modules/@adobe/css-tools": { "version": "4.3.3", diff --git a/gradle.properties b/gradle.properties index e9b6c984c4..ab2b6ef261 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,21 +26,22 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true # dependency versions -kotlinVersion=2.1.20 +kotlinVersion=2.2.21 kotlinCoroutinesVersion=1.10.2 kotlinLoggingVersion=7.0.7 mockitoKotlinVersion=5.4.0 -operatonVersion=1.0.3 -mybatisSpringBootStarterVersion=3.0.4 +operatonVersion=2.0.0 +mybatisSpringBootStarterVersion=4.0.1 -springBootVersion=3.5.13 -springBootAdminStarterClientVersion=3.4.5 +springBootVersion=4.0.5 +springBootAdminStarterClientVersion=4.0.3 springDependencyManagementVersion=1.1.7 -springCloudStreamVersion=4.2.1 +springCloudStreamVersion=5.0.1 springRetryVersion=2.0.12 -liquibaseVersion=4.31.1 +liquibaseVersion=5.0.2 +liquibaseHibernateVersion=5.0.2-rc1 commonsLangVersion=3.20.0 commonsIoVersion=2.21.0 @@ -60,7 +61,7 @@ amqpCLientVersion=5.29.0 jaxbApiVersion=4.0.5 jjwtVersion=0.13.0 graalvmJsVersion=25.0.2 -hypersistenceUtilsVersion=3.9.4 +hypersistenceUtilsVersion=3.15.2 problemSpringWebVersion=0.29.1 jacksonDatatypeProblemVersion=0.27.1 okhttpVersion=4.12.0 @@ -73,16 +74,16 @@ apacheTikaVersion=3.3.0 mandrillLutungClientVersion=0.0.8 classgraphVersion=4.8.184 guavaVersion=33.5.0-jre -springDocVersion=2.8.6 +springDocVersion=3.0.3 awssdkVersion=2.42.29 jacksonVersion=2.21.2 -junitVersion=5.12.2 +junitVersion=6.0.3 postgresqlDriverVersion=42.7.10 mysqlDriverVersion=9.6.0 -hibernateCoreVersion=6.6.13.Final +hibernateCoreVersion=7.2.7.Final mapstructVersion=1.6.3 kotestVersion=5.9.1 -shedlockVersion=6.4.0 +shedlockVersion=7.7.0 jsonassertVersion=1.5.3 cloudEventsCoreVersion=4.0.1 resilience4jVersion=2.4.0 diff --git a/org/springframework/boot/logging/logback/defaults.xml b/org/springframework/boot/logging/logback/defaults.xml new file mode 100644 index 0000000000..f94006b14f --- /dev/null +++ b/org/springframework/boot/logging/logback/defaults.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +