From 3dd6ed90092c1c30a1581168210d79056c423261 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 12:45:36 +0100 Subject: [PATCH 1/7] fix: datetime type mapping for tenantService reference --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 7a5830e6..66f90f58 100644 --- a/pom.xml +++ b/pom.xml @@ -491,6 +491,12 @@ ${project.groupId}.${project.artifactId}.tenantservice.generated.web.model + + OffsetDateTime=LocalDateTime + + + java.time.OffsetDateTime=java.time.LocalDateTime + From bde4973f8f335005ca26b144d369d32c55098645 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:12:48 +0100 Subject: [PATCH 2/7] fix: include proper migrations --- src/main/resources/db/changelog/agencyservice-dev-master.xml | 1 + src/main/resources/db/changelog/agencyservice-local-master.xml | 1 + src/main/resources/db/changelog/agencyservice-prod-master.xml | 1 + src/main/resources/db/changelog/agencyservice-staging-master.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/src/main/resources/db/changelog/agencyservice-dev-master.xml b/src/main/resources/db/changelog/agencyservice-dev-master.xml index 9108a650..159bc005 100644 --- a/src/main/resources/db/changelog/agencyservice-dev-master.xml +++ b/src/main/resources/db/changelog/agencyservice-dev-master.xml @@ -23,4 +23,5 @@ --> + diff --git a/src/main/resources/db/changelog/agencyservice-local-master.xml b/src/main/resources/db/changelog/agencyservice-local-master.xml index 787f4ecd..8e06fc5b 100644 --- a/src/main/resources/db/changelog/agencyservice-local-master.xml +++ b/src/main/resources/db/changelog/agencyservice-local-master.xml @@ -22,4 +22,5 @@ + diff --git a/src/main/resources/db/changelog/agencyservice-prod-master.xml b/src/main/resources/db/changelog/agencyservice-prod-master.xml index 6374e10f..e0758e35 100644 --- a/src/main/resources/db/changelog/agencyservice-prod-master.xml +++ b/src/main/resources/db/changelog/agencyservice-prod-master.xml @@ -19,4 +19,5 @@ + diff --git a/src/main/resources/db/changelog/agencyservice-staging-master.xml b/src/main/resources/db/changelog/agencyservice-staging-master.xml index c9c9268d..c84782e1 100644 --- a/src/main/resources/db/changelog/agencyservice-staging-master.xml +++ b/src/main/resources/db/changelog/agencyservice-staging-master.xml @@ -19,4 +19,5 @@ + From 6a762717c752331fff90275f2889d9a28163be14 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:42:01 +0100 Subject: [PATCH 3/7] fix: fix migration script --- .../addDataProtectionAttributes-rollback.sql | 6 ++++++ .../addDataProtectionAttributes.sql | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql index e322ee1d..9c284b97 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql @@ -1,2 +1,8 @@ ALTER TABLE `agencyservice`.`agency` DROP COLUMN data_protection_officer_contact longtext; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_alternative_contact longtext; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_agency_contact longtext; \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql index f3ad82f9..a158cd8a 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql @@ -2,7 +2,7 @@ ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_responsible_entity varchar(100) NULL AFTER `counselling_relations`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_responsible_contact longtext NULL AFTER `data_protection_responsible_entity`; +ADD COLUMN data_protection_alternative_contact longtext NULL AFTER `data_protection_responsible_entity`; ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_responsible_contact`; From c5f22355f74c60c30371d87377d3f45ee2d3e599 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:49:14 +0100 Subject: [PATCH 4/7] fix: fix rollback script --- .../addDataProtectionAttributes-rollback.sql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql index 9c284b97..6ea803e2 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes-rollback.sql @@ -1,8 +1,11 @@ ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_officer_contact longtext; +DROP COLUMN data_protection_responsible_entity; ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_alternative_contact longtext; +DROP COLUMN data_protection_officer_contact; ALTER TABLE `agencyservice`.`agency` -DROP COLUMN data_protection_agency_contact longtext; \ No newline at end of file +DROP COLUMN data_protection_alternative_contact; + +ALTER TABLE `agencyservice`.`agency` +DROP COLUMN data_protection_agency_contact; \ No newline at end of file From 50fa7f8fbf9050a322eb26522ed9175a57cbad43 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 9 Nov 2023 13:56:17 +0100 Subject: [PATCH 5/7] fix: fix SQL script --- .../addDataProtectionAttributes.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql index a158cd8a..7ec8a7c9 100644 --- a/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql +++ b/src/main/resources/db/changelog/changeset/0016_add_data_protection_attributes/addDataProtectionAttributes.sql @@ -5,7 +5,7 @@ ALTER TABLE `agencyservice`.`agency` ADD COLUMN data_protection_alternative_contact longtext NULL AFTER `data_protection_responsible_entity`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_responsible_contact`; +ADD COLUMN data_protection_officer_contact longtext NULL AFTER `data_protection_alternative_contact`; ALTER TABLE `agencyservice`.`agency` -ADD COLUMN data_protection_agency_contact longtext NULL AFTER `data_protection_officer_contact`; +ADD COLUMN data_protection_agency_contact longtext NULL AFTER `data_protection_officer_contact`; \ No newline at end of file From 86456ed7e5322dcd876e46e4eaaf173ffc274acb Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 14 Nov 2023 10:04:15 +0100 Subject: [PATCH 6/7] add test to cover testcase of privacy without placeholders --- ...tralDataProtectionTemplateServiceTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java index bbb2fe21..fc4c5511 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/service/CentralDataProtectionTemplateServiceTest.java @@ -70,6 +70,39 @@ void renderDataProtectionPrivacy_shouldProperlyRenderPrivacy_When_PlaceholdersAr "Privacy template with placeholders: Data protection officer contact name: Max Mustermann, Data protection responsible contact name: Max Mustermann,"); } + @Test + void renderDataProtectionPrivacy_shouldReturnPrivacyAsItIs_When_PlaceholdersAreNotIncludedInPrivacy() { + + // given + when(tenantService.getRestrictedTenantDataByTenantId(anyLong())).thenReturn( + new RestrictedTenantDTO() + .content( + new Content().dataProtectionContactTemplate(getDataProtectionContactTemplate()) + .privacy( + "Privacy template without placeholders"))); + DataProtectionContactDTO dataProtectionContactDTO = new DataProtectionContactDTO() + .nameAndLegalForm("Max Mustermann"); + + Agency agency = Agency.builder() + .id(1000L) + .tenantId(1L) + .consultingTypeId(1) + .name("agencyName") + .dataProtectionResponsibleEntity(DataProtectionResponsibleEntity.DATA_PROTECTION_OFFICER) + .dataProtectionOfficerContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .dataProtectionAgencyResponsibleContactData(JsonConverter.convertToJson(dataProtectionContactDTO)) + .build(); + + // when + var renderedPrivacy = centralDataProtectionTemplateService.renderPrivacyTemplateWithRenderedPlaceholderValues( + agency); + + // then + assertThat( + renderedPrivacy).isEqualTo( + "Privacy template without placeholders"); + } + @Test void renderDataProtectionTemplatePlaceholders_shouldProperlyRenderPlaceholders_If_SomeVariableDataIsMissing() { From e319cc6ff02cfecfc0b675972e96f687b615004b Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Tue, 14 Nov 2023 23:22:27 +0100 Subject: [PATCH 7/7] fix: priviliges model, add separate authority to search agencies --- .../api/authorization/Authority.java | 37 ++++++++++++++----- .../RoleAuthorizationAuthorityMapper.java | 3 +- .../agencyservice/config/SecurityConfig.java | 14 +++---- .../api/authorization/AuthorityTest.java | 16 ++++---- .../RoleAuthorizationAuthorityMapperTest.java | 36 +++++++++++++----- 5 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java b/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java index 4eb6b9bf..fb11c718 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/authorization/Authority.java @@ -1,24 +1,35 @@ package de.caritas.cob.agencyservice.api.authorization; +import com.google.common.collect.Lists; +import java.util.List; import java.util.stream.Stream; +import lombok.Getter; /** * * Definition of all authorities and of the role-authority-mapping. * */ +@Getter public enum Authority { - AGENCY_ADMIN("agency-admin", "AUTHORIZATION_AGENCY_ADMIN"), - TENANT_ADMIN("tenant-admin", "AUTHORIZATION_TENANT_ADMIN"), - RESTRICTED_AGENCY_ADMIN("restricted-agency-admin", "AUTHORIZATION_RESTRICTED_AGENCY_ADMIN"); + AGENCY_ADMIN("agency-admin", AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES), + TENANT_ADMIN("tenant-admin", AuthorityValue.TENANT_ADMIN), + RESTRICTED_AGENCY_ADMIN("restricted-agency-admin", AuthorityValue.RESTRICTED_AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES), + + RESTRICTED_CONSULTANT_ADMIN("restricted-consultant-admin", AuthorityValue.SEARCH_AGENCIES); private final String roleName; - private final String authorityName; + private final List authorities; Authority(final String roleName, final String authorityName) { this.roleName = roleName; - this.authorityName = authorityName; + this.authorities = Lists.newArrayList(authorityName); + } + + Authority(final String roleName, final String... authorities) { + this.roleName = roleName; + this.authorities = Lists.newArrayList(authorities); } /** @@ -34,12 +45,18 @@ public static Authority fromRoleName(String roleName) { .orElse(null); } - public String getAuthority() { - return this.authorityName; - } - public String getRoleName() { - return this.roleName; + public static class AuthorityValue { + + private AuthorityValue() {} + + public static final String PREFIX = "AUTHORIZATION_"; + public static final String AGENCY_ADMIN = PREFIX + "AGENCY_ADMIN"; + public static final String SEARCH_AGENCIES = PREFIX + "SEARCH_AGENCIES"; + public static final String TENANT_ADMIN = PREFIX + "TENANT_ADMIN"; + public static final String RESTRICTED_AGENCY_ADMIN = PREFIX + "RESTRICTED_AGENCY_ADMIN"; + } + } diff --git a/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java b/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java index fc99d604..5df9c9b4 100644 --- a/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java +++ b/src/main/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapper.java @@ -30,7 +30,8 @@ public Set mapAuthorities(Set roleNames) { return roleNames.stream() .map(Authority::fromRoleName) .filter(Objects::nonNull) - .map(Authority::getAuthority) + .map(Authority::getAuthorities) + .flatMap(Collection::parallelStream) .map(SimpleGrantedAuthority::new) .collect(Collectors.toSet()); } diff --git a/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java b/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java index c5feba44..c5b0e17e 100644 --- a/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java +++ b/src/main/java/de/caritas/cob/agencyservice/config/SecurityConfig.java @@ -1,9 +1,6 @@ package de.caritas.cob.agencyservice.config; -import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; -import static de.caritas.cob.agencyservice.api.authorization.Authority.RESTRICTED_AGENCY_ADMIN; -import static de.caritas.cob.agencyservice.api.authorization.Authority.TENANT_ADMIN; - +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; import de.caritas.cob.agencyservice.config.security.AuthorisationService; import de.caritas.cob.agencyservice.config.security.JwtAuthConverter; import de.caritas.cob.agencyservice.config.security.JwtAuthConverterProperties; @@ -16,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; +import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -84,11 +82,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/agencies/**").permitAll() .requestMatchers(WHITE_LIST).permitAll() .requestMatchers("/agencies").permitAll() + .requestMatchers(HttpMethod.GET, "/agencyadmin/agencies") + .hasAuthority(AuthorityValue.SEARCH_AGENCIES) .requestMatchers("/agencyadmin/agencies/tenant/*") - .access("hasAuthority('" + AGENCY_ADMIN.getAuthority() - + "') and hasAuthority('" + TENANT_ADMIN.getAuthority() + "')") + .access("hasAuthority('" + AuthorityValue.AGENCY_ADMIN + + "') and hasAuthority('" + AuthorityValue.TENANT_ADMIN + "')") .requestMatchers("/agencyadmin", "/agencyadmin/", "/agencyadmin/**") - .hasAnyAuthority(AGENCY_ADMIN.getAuthority(), RESTRICTED_AGENCY_ADMIN.getAuthority()) + .hasAnyAuthority(AuthorityValue.AGENCY_ADMIN, AuthorityValue.RESTRICTED_AGENCY_ADMIN) .anyRequest().denyAll(); diff --git a/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java b/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java index 0a31a827..46fa0154 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/authorization/AuthorityTest.java @@ -2,40 +2,40 @@ import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; import static de.caritas.cob.agencyservice.api.authorization.Authority.fromRoleName; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; +import static org.assertj.core.api.Assertions.assertThat; +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; +import java.util.List; import org.junit.Test; public class AuthorityTest { @Test public void getAuthority_Should_returnExpectedAuthority_When_authorityIsAgencyAdmin() { - String authority = AGENCY_ADMIN.getAuthority(); + List authorities = AGENCY_ADMIN.getAuthorities(); - assertThat(authority, is("AUTHORIZATION_AGENCY_ADMIN")); + assertThat(authorities).containsOnly(AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES); } @Test public void fromRoleName_Should_returnNull_When_roleNameIsNull() { Authority authority = fromRoleName(null); - assertThat(authority, nullValue()); + assertThat(authority).isNull(); } @Test public void fromRoleName_Should_returnNull_When_roleNameDoesNotExist() { Authority authority = fromRoleName("not existing"); - assertThat(authority, nullValue()); + assertThat(authority).isNull(); } @Test public void fromRoleName_Should_returnAgencyAdmin_When_roleNameIsAgencyAdmin() { Authority authority = fromRoleName("agency-admin"); - assertThat(authority, is(AGENCY_ADMIN)); + assertThat(authority.getAuthorities()).containsOnly(AuthorityValue.AGENCY_ADMIN, AuthorityValue.SEARCH_AGENCIES); } } diff --git a/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java b/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java index 1afd2238..e7af266b 100644 --- a/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java +++ b/src/test/java/de/caritas/cob/agencyservice/api/authorization/RoleAuthorizationAuthorityMapperTest.java @@ -2,10 +2,8 @@ import static de.caritas.cob.agencyservice.api.authorization.Authority.AGENCY_ADMIN; import static java.util.Collections.emptyList; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; - +import static org.assertj.core.api.Assertions.assertThat; +import de.caritas.cob.agencyservice.api.authorization.Authority.AuthorityValue; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -28,8 +26,10 @@ public void mapAuthorities_Should_returnGrantedAgencyAdminAuthority_When_authori Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(1)); - assertThat(mappedAuthorities.iterator().next().getAuthority(), is(AGENCY_ADMIN.getAuthority())); + assertThat(mappedAuthorities).hasSize(2); + List authorities = mappedAuthorities.stream() + .map(grantedAuthority -> grantedAuthority.getAuthority()).toList(); + assertThat(authorities).containsAll(AGENCY_ADMIN.getAuthorities()); } @Test @@ -41,8 +41,24 @@ public void mapAuthorities_Should_returnGrantedAgencyAdminAuthority_When_authori Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(1)); - assertThat(mappedAuthorities.iterator().next().getAuthority(), is(AGENCY_ADMIN.getAuthority())); + assertThat(mappedAuthorities).hasSize(2); + List authorities = mappedAuthorities.stream() + .map(grantedAuthority -> grantedAuthority.getAuthority()).toList(); + assertThat(authorities).containsAll(AGENCY_ADMIN.getAuthorities()); + + } + + @Test + public void mapAuthorities_Should_returnGrantedAgencySearchAuthority_When_authoritiesRestrictedConsultantAdmin() { + List grantedAuthorities = Stream.of("a", "v", "restricted-consultant-admin", "c") + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper + .mapAuthorities(grantedAuthorities); + + assertThat(mappedAuthorities).hasSize(1); + assertThat(mappedAuthorities.iterator().next().getAuthority()).isEqualTo(AuthorityValue.SEARCH_AGENCIES); } @Test @@ -50,7 +66,7 @@ public void mapAuthorities_Should_returnEmptyCollection_When_authorityIsEmpty() Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(emptyList()); - assertThat(mappedAuthorities, hasSize(0)); + assertThat(mappedAuthorities).isEmpty(); } @Test @@ -62,7 +78,7 @@ public void mapAuthorities_Should_returnEmptyCollection_When_authoritiesAreNotPr Collection mappedAuthorities = this.roleAuthorizationAuthorityMapper .mapAuthorities(grantedAuthorities); - assertThat(mappedAuthorities, hasSize(0)); + assertThat(mappedAuthorities).isEmpty(); } }