diff --git a/persistence-service-v1/keycloak-commons/src/main/java/com/iqser/red/keycloak/commons/roles/ApplicationRoles.java b/persistence-service-v1/keycloak-commons/src/main/java/com/iqser/red/keycloak/commons/roles/ApplicationRoles.java index b2f0f4010..e07164db5 100644 --- a/persistence-service-v1/keycloak-commons/src/main/java/com/iqser/red/keycloak/commons/roles/ApplicationRoles.java +++ b/persistence-service-v1/keycloak-commons/src/main/java/com/iqser/red/keycloak/commons/roles/ApplicationRoles.java @@ -109,6 +109,8 @@ public final class ApplicationRoles { public static final String RED_ADMIN_ROLE = "RED_ADMIN"; public static final String RED_USER_ADMIN_ROLE = "RED_USER_ADMIN"; + public static final Set RED_ROLES = Sets.newHashSet(RED_USER_ROLE, RED_MANAGER_ROLE, RED_ADMIN_ROLE, RED_USER_ADMIN_ROLE); + public static final Set UNMAPPED_ACTION_ROLES = Sets.newHashSet(UNARCHIVE_DOSSIER, UPDATE_LICENSE, GET_RSS); public static final Set RED_USER_ACTION_ROLES = Sets.newHashSet(ADD_COMMENT, diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierTemplateController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierTemplateController.java index 3e620d7e6..566225450 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierTemplateController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierTemplateController.java @@ -2,6 +2,8 @@ package com.iqser.red.persistence.service.v1.external.api.impl.controller; import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_DOSSIER_TEMPLATES; import static com.iqser.red.keycloak.commons.roles.ActionRoles.WRITE_DOSSIER_TEMPLATES; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_MANAGER_ROLE; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ROLE; import static com.iqser.red.service.persistence.management.v1.processor.service.FeignExceptionHandler.processFeignException; import java.io.IOException; @@ -15,6 +17,7 @@ import java.util.stream.Collectors; import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; +import org.keycloak.representations.idm.RoleRepresentation; import org.springframework.beans.BeanUtils; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -31,6 +34,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.Confl import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateStatsService; +import com.iqser.red.service.persistence.management.v1.processor.service.UserService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.service.v1.api.external.resource.DossierTemplateResource; import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; @@ -61,6 +65,7 @@ public class DossierTemplateController implements DossierTemplateResource { private final AuditPersistenceService auditPersistenceService; private final DossierManagementService dossierManagementService; private final DossierACLService dossierACLService; + private final UserService userService; @Override @@ -113,9 +118,12 @@ public class DossierTemplateController implements DossierTemplateResource { @PreAuthorize("hasAuthority('" + READ_DOSSIER_TEMPLATES + "')") public void deleteDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { - String userId = KeycloakSecurity.getUserId(); + String userId = KeycloakSecurity.getUserId(); + if (!userService.checkUserHasAdminRole(userId)) { + throw new BadRequestException("Only admin user can delete the dossier template"); + } - List dossiers = dossierManagementService.getAllDossiers(true, false); + List dossiers = dossierManagementService.getAllDossiers(true, false); if (dossiers != null && dossiers.stream().anyMatch(dossier -> dossier.getDossierTemplateId().equals(dossierTemplateId))) { throw new ConflictException("Can not delete dossier template because there are dossiers based on it"); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/UserService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/UserService.java index a75980c6f..f993f6c9a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/UserService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/UserService.java @@ -3,6 +3,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service; import static com.iqser.red.keycloak.commons.DefaultKeyCloakCommonsConfiguration.USERS_CACHE; import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_ADMIN_ROLE; import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_MANAGER_ROLE; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_ROLES; import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ADMIN_ROLE; import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ROLE; import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.validateRoles; @@ -39,6 +40,7 @@ import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.iqser.red.keycloak.commons.KeyCloakSettings; import com.iqser.red.keycloak.commons.KeycloakSecurity; import com.iqser.red.keycloak.commons.RealmService; @@ -268,6 +270,12 @@ public class UserService { } } + public boolean checkUserHasAdminRole(String userId) { + var userResource = this.getUserResource(userId); + var userRoles = userResource.roles().realmLevel().listEffective().stream().map(RoleRepresentation::getName).collect(Collectors.toSet()); + return userRoles.contains(RED_ADMIN_ROLE); + } + private void removeUserFromDossiers(String userId, UserRemovalModel mode) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateTest.java index 6a960fbc3..200baec4e 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateTest.java @@ -1,19 +1,28 @@ package com.iqser.red.service.peristence.v1.server.integration.tests; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_MANAGER_ROLE; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_ROLES; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ADMIN_ROLE; +import static com.iqser.red.keycloak.commons.roles.ApplicationRoles.RED_USER_ROLE; import static org.assertj.core.api.Assertions.assertThat; import java.io.InputStream; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.keycloak.commons.KeycloakSecurity; +import com.iqser.red.keycloak.commons.model.User; +import com.iqser.red.persistence.service.v1.external.api.impl.controller.UserController; import com.iqser.red.service.peristence.v1.server.integration.client.DictionaryClient; import com.iqser.red.service.peristence.v1.server.integration.client.DossierAttributeConfigClient; import com.iqser.red.service.peristence.v1.server.integration.client.DossierClient; @@ -530,6 +539,36 @@ public class DossierTemplateTest extends AbstractPersistenceServerServiceTest { assertThat(existingLegalBasis.isEmpty()).isTrue(); } + @Test + public void testDeleteDossierTemplate() { + + var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); + + var allTemplates = dossierTemplateClient.getAllDossierTemplates(); + assertThat(allTemplates.size()).isEqualTo(1); + assertThat(allTemplates.get(0)).isEqualTo(dossierTemplate); + Optional optionalUser = userService.getOptionalUserByUsername(USERNAME); + if(optionalUser.isPresent()) { + String userId = optionalUser.get().getUserId(); + + userService.setRoles(userId, List.of(RED_USER_ROLE), RED_ROLES.stream().toList()); + Assertions.assertThrows(FeignException.BadRequest.class, () -> dossierTemplateClient.deleteDossierTemplate(dossierTemplate.getId())); + + userService.setRoles(userId, List.of(RED_MANAGER_ROLE), RED_ROLES.stream().toList()); + Assertions.assertThrows(FeignException.BadRequest.class, () -> dossierTemplateClient.deleteDossierTemplate(dossierTemplate.getId())); + + userService.setRoles(userId, List.of(RED_USER_ADMIN_ROLE), RED_ROLES.stream().toList()); + Assertions.assertThrows(FeignException.Forbidden.class, () -> dossierTemplateClient.deleteDossierTemplate(dossierTemplate.getId())); + + userService.setRoles(userId, List.of(RED_USER_ADMIN_ROLE, RED_USER_ROLE), RED_ROLES.stream().toList()); + Assertions.assertThrows(FeignException.BadRequest.class, () -> dossierTemplateClient.deleteDossierTemplate(dossierTemplate.getId())); + + userService.setRoles(userId, RED_ROLES.stream().toList(), RED_ROLES.stream().toList()); + dossierTemplateClient.deleteDossierTemplate(dossierTemplate.getId()); + allTemplates = dossierTemplateClient.getAllDossierTemplates(); + assertThat(allTemplates.size()).isZero(); + } + } @Test @SneakyThrows diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java index c6cb5a0ae..4db784c4e 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java @@ -108,6 +108,7 @@ import lombok.extern.slf4j.Slf4j; @ContextConfiguration(initializers = {AbstractPersistenceServerServiceTest.Initializer.class}) @SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = "spring-hibernate-query-utils.n-plus-one-queries-detection.error-level=INFO") public abstract class AbstractPersistenceServerServiceTest { + protected final String USERNAME = "manageradmin1@test.com"; @MockBean protected RabbitTemplate rabbitTemplate; @@ -203,7 +204,7 @@ public abstract class AbstractPersistenceServerServiceTest { @Autowired private ApplicationConfigService applicationConfigService; @Autowired - private UserService userService; + protected UserService userService; @Autowired private TokenService tokenService; @Autowired @@ -240,7 +241,7 @@ public abstract class AbstractPersistenceServerServiceTest { KeyCloakTestContainer.getInstance().getKeycloakAdminClient().realm("redaction").clients().create(redactionSystemClient); - tokenService.setUser("manageradmin1@test.com", "secret"); + tokenService.setUser(USERNAME, "secret"); TenantContext.clear();