diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java index 6383422e3..9240293d8 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/ComponentControllerV2.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Optional; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -42,15 +43,17 @@ import lombok.experimental.FieldDefaults; @RestController @RequiredArgsConstructor @Tag(name = "4. Component endpoints", description = "Provides operations related to components") -@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) public class ComponentControllerV2 implements ComponentResource { - ComponentLogService componentLogService; - UserService userService; - StatusController statusController; - FileStatusService fileStatusService; - DossierTemplatePersistenceService dossierTemplatePersistenceService; - ComponentMapper componentMapper = ComponentMapper.INSTANCE; + private final ComponentLogService componentLogService; + private final UserService userService; + private final StatusController statusController; + private final FileStatusService fileStatusService; + private final DossierTemplatePersistenceService dossierTemplatePersistenceService; + private final ComponentMapper componentMapper = ComponentMapper.INSTANCE; + + @Value("${application.type}") + private String applicationType; @Override @@ -59,8 +62,9 @@ public class ComponentControllerV2 implements ComponentResource { @PathVariable(FILE_ID_PARAM) String fileId, @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails) { - dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); + checkApplicationType(); validateUserRoles(KeycloakSecurity.getUserId()); + dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); var componentLog = componentLogService.getComponentLog(dossierId, fileId); return componentMapper.toFileComponents(componentLog, dossierTemplateId, dossierId, fileId, fileStatusService.getFileName(fileId), includeDetails); @@ -85,6 +89,7 @@ public class ComponentControllerV2 implements ComponentResource { @PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestParam(name = INCLUDE_DETAILS_PARAM, defaultValue = "false", required = false) boolean includeDetails) { + checkApplicationType(); dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); var dossierFiles = statusController.getDossierStatus(dossierId); return new FileComponentsList(dossierFiles.stream() @@ -100,6 +105,7 @@ public class ComponentControllerV2 implements ComponentResource { @PathVariable(FILE_ID_PARAM) String fileId, @RequestBody Component override) { + checkApplicationType(); dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); componentLogService.overrideComponent(dossierId, fileId, componentMapper.toComponentLogEntry(override)); @@ -112,6 +118,7 @@ public class ComponentControllerV2 implements ComponentResource { @PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId) { + checkApplicationType(); dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); FileModel status = fileStatusService.getStatus(fileId); @@ -138,9 +145,18 @@ public class ComponentControllerV2 implements ComponentResource { @PathVariable(FILE_ID_PARAM) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest) { + checkApplicationType(); dossierTemplatePersistenceService.checkDossierTemplateExistsOrElseThrow404(dossierTemplateId); componentLogService.revertOverrides(dossierId, fileId, revertOverrideRequest); } + + private void checkApplicationType() { + + if(!applicationType.equals("DocuMine")) { + throw new NotAllowedException("Components can only be accessed in DocuMine"); + } + } + } diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java index 5a89c5332..4579b2c13 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java @@ -1,6 +1,7 @@ package com.iqser.red.persistence.service.v2.external.api.impl.controller; import java.util.List; +import java.util.Optional; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @@ -8,7 +9,11 @@ import org.springframework.web.bind.annotation.RestController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException; +import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; +import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User; import com.iqser.red.service.persistence.service.v1.api.shared.model.RemoveDownloadRequest; import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatusList; @@ -26,10 +31,13 @@ public class DownloadControllerV2 implements DownloadResource { private final DownloadController downloadController; private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final UserService userService; + @Transactional public DownloadStatusList getDownloadStatusList() { + validateUserRoles(KeycloakSecurity.getUserId()); var downloads = downloadStatusPersistenceService.getStatusesByUser(KeycloakSecurity.getUserId()); return new DownloadStatusList(downloads.stream().map( @@ -61,6 +69,7 @@ public class DownloadControllerV2 implements DownloadResource { @Transactional public DownloadStatus getDownloadStatus(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + validateUserRoles(KeycloakSecurity.getUserId()); var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); return DownloadStatus.builder() @@ -88,6 +97,7 @@ public class DownloadControllerV2 implements DownloadResource { public void deleteDownload(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + validateUserRoles(KeycloakSecurity.getUserId()); var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); downloadController.deleteDownloadStatus(new RemoveDownloadRequest(List.of(status.getStorageId()))); } @@ -95,8 +105,22 @@ public class DownloadControllerV2 implements DownloadResource { public void download(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + validateUserRoles(KeycloakSecurity.getUserId()); var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); downloadController.downloadFile(status.getStorageId()); } + + private void validateUserRoles(String userId) { + + Optional userOptional = userService.getUserById(userId); + if (userOptional.isPresent()) { + if (userOptional.get().getRoles() + .stream() + .noneMatch(ApplicationRoles.VALID_MEMBER_ROLES::contains)) { + throw new NotAllowedException("User doesn't have appropriate roles"); + } + } + } + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ApplicationRoles.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ApplicationRoles.java index b9856f9c3..05ced6d54 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ApplicationRoles.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ApplicationRoles.java @@ -53,7 +53,9 @@ public final class ApplicationRoles { DOWNLOAD_REDACTION_PREVIEW_FILE, DOWNLOAD_REPORT_TEMPLATE, EXCLUDE_INCLUDE_FILE, - EXCLUDE_INCLUDE_PAGES, GET_REPORT_TEMPLATES, GET_SIMILAR_IMAGES, + EXCLUDE_INCLUDE_PAGES, + GET_REPORT_TEMPLATES, + GET_SIMILAR_IMAGES, MANAGE_USER_PREFERENCES, MANAGE_VIEWED_PAGES, PROCESS_DOWNLOAD, @@ -105,7 +107,9 @@ public final class ApplicationRoles { DELETE_DICTIONARY_TYPE, DELETE_REPORT_TEMPLATE, DOWNLOAD_REPORT_TEMPLATE, - GET_REPORT_TEMPLATES, MANAGE_USER_PREFERENCES, GET_SIMILAR_IMAGES, + GET_REPORT_TEMPLATES, + MANAGE_USER_PREFERENCES, + GET_SIMILAR_IMAGES, READ_COLORS, READ_DICTIONARY_TYPES, READ_DIGITAL_SIGNATURE, @@ -147,7 +151,9 @@ public final class ApplicationRoles { public static final Set RED_USER_ADMIN_ACTION_ROLES = Sets.newHashSet(MANAGE_USER_PREFERENCES, READ_ALL_USERS, READ_APP_CONFIG, - READ_GENERAL_CONFIGURATION, READ_GENERAL_CONFIGURATION, GET_SIMILAR_IMAGES, + READ_GENERAL_CONFIGURATION, + READ_GENERAL_CONFIGURATION, + GET_SIMILAR_IMAGES, READ_NOTIFICATIONS, READ_USERS, UPDATE_MY_PROFILE, diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentControllerV2Test.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentControllerV2Test.java index e599aa426..46e110a4e 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentControllerV2Test.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentControllerV2Test.java @@ -1,18 +1,21 @@ package com.iqser.red.service.peristence.v1.server.integration.tests; + import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.openMocks; + +import java.util.Collections; +import java.util.Optional; +import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; -import org.mockito.MockitoAnnotations; - -import java.util.Collections; -import java.util.Optional; -import java.util.Set; +import org.springframework.test.util.ReflectionTestUtils; import com.iqser.red.persistence.service.v1.external.api.impl.controller.StatusController; import com.iqser.red.persistence.service.v2.external.api.impl.controller.ComponentControllerV2; @@ -22,17 +25,26 @@ import com.iqser.red.service.persistence.management.v1.processor.service.FileSta import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User; +import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry; +import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel; +import com.iqser.red.service.persistence.service.v2.api.external.model.Component; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; +import lombok.SneakyThrows; + public class ComponentControllerV2Test { public static final String USER_ID = "user-111"; public static final String FILE_ID = "file-789"; public static final String DOSSIER_ID = "dossier-456"; public static final String DOSSIER_TEMPLATE_ID = "template-123"; + @InjectMocks private ComponentControllerV2 componentControllerV2; + @Mock private UserService userService; @Mock @@ -43,17 +55,22 @@ public class ComponentControllerV2Test { private DossierTemplatePersistenceService dossierTemplatePersistenceService; @Mock private StatusController statusController; - @Mock private ComponentLog mockComponentLog; + @BeforeEach + @SneakyThrows void setUp() { - MockitoAnnotations.openMocks(this); + + openMocks(this); + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "DocuMine"); } + @Test - void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles() { + void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles_getComponents() { User invalidUser = new User(); invalidUser.setUserId(USER_ID); @@ -64,43 +81,129 @@ public class ComponentControllerV2Test { try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); - assertThrows(NotAllowedException.class, () -> { - componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false); - }); + assertThrows(NotAllowedException.class, () -> componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false)); } } - @Test - void shouldNotThrowNotAllowedExceptionIfUserHasValidRoles() { - + void shouldNotThrowNotAllowedExceptionIfUserHasValidRoles_getComponents() { User validUser = new User(); validUser.setUserId(USER_ID); validUser.setRoles(Set.of("RED_USER")); - User validManager = new User(); - validManager.setUserId(USER_ID); - validManager.setRoles(Set.of("RED_MANAGER")); - when(componentLogService.getComponentLog(DOSSIER_ID, FILE_ID)).thenReturn(mockComponentLog); - when(mockComponentLog.getComponentLogEntries()).thenReturn(Collections.emptyList()); - when(fileStatusService.getFileName(FILE_ID)).thenReturn("mock-file-name"); try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); - when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validUser)); - assertDoesNotThrow(() -> { - componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false); - }); - when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validManager)); - assertDoesNotThrow(() -> { - componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false); - }); + + assertDoesNotThrow(() -> componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false)); } } + + + @Test + void shouldThrowNotAllowedExceptionIfApplicationTypeIsRM_getComponents() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "RedactManager"); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(new User())); + + assertThrows(NotAllowedException.class, () -> componentControllerV2.getComponents(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, false)); + } + + + @Test + void shouldThrowNotAllowedExceptionIfApplicationTypeIsRM_getComponentsOfDossier() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "RedactManager"); + + assertThrows(NotAllowedException.class, () -> componentControllerV2.getComponentsOfDossier(DOSSIER_TEMPLATE_ID, DOSSIER_ID, false)); + } + + + @Test + void shouldNotThrowExceptionIfApplicationTypeIsValid_getComponentsOfDossier() { + + FileStatus fileStatus = FileStatus.builder().fileId(FILE_ID).build(); + when(statusController.getDossierStatus(DOSSIER_ID)).thenReturn(Collections.singletonList(fileStatus)); + + when(componentLogService.getComponentLog(DOSSIER_ID, FILE_ID)).thenReturn(mockComponentLog); + when(fileStatusService.getFileName(FILE_ID)).thenReturn("mock-file-name"); + when(mockComponentLog.getComponentLogEntries()).thenReturn(Collections.emptyList()); + + assertDoesNotThrow(() -> componentControllerV2.getComponentsOfDossier(DOSSIER_TEMPLATE_ID, DOSSIER_ID, false)); + } + + + @Test + void shouldThrowNotAllowedExceptionIfApplicationTypeIsRM_addOverride() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "RedactManager"); + + Component component = Component.builder().name("dummy").componentValues(Collections.emptyList()).build(); + + assertThrows(NotAllowedException.class, () -> componentControllerV2.addOverride(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, component)); + } + + + @Test + void shouldNotThrowException_addOverride() { + + Component component = Component.builder().name("dummy").componentValues(Collections.emptyList()).build(); + + assertDoesNotThrow(() -> componentControllerV2.addOverride(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, component)); + } + + + @Test + void shouldThrowNotAllowedExceptionIfApplicationTypeIsRM_getOverrides() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "RedactManager"); + + assertThrows(NotAllowedException.class, () -> componentControllerV2.getOverrides(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID)); + } + + + @Test + void shouldNotThrowException_getOverrides() { + + FileModel fileModel = new FileModel(); + fileModel.setId(FILE_ID); + when(fileStatusService.getStatus(FILE_ID)).thenReturn(fileModel); + + when(componentLogService.getComponentLog(DOSSIER_ID, FILE_ID)).thenReturn(mockComponentLog); + ComponentLogEntry overriddenEntry = new ComponentLogEntry(); + overriddenEntry.setName("dummy"); + overriddenEntry.setValues(Collections.emptyList()); + overriddenEntry.setOverridden(true); + when(mockComponentLog.getComponentLogEntries()).thenReturn(Collections.singletonList(overriddenEntry)); + + assertDoesNotThrow(() -> componentControllerV2.getOverrides(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID)); + } + + + @Test + void shouldThrowNotAllowedExceptionIfApplicationTypeIsRM_revertOverrides() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "RedactManager"); + + RevertOverrideRequest revertOverrideRequest = new RevertOverrideRequest(); + + assertThrows(NotAllowedException.class, () -> componentControllerV2.revertOverrides(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, revertOverrideRequest)); + } + + + @Test + void shouldNotThrowException_revertOverrides() { + + RevertOverrideRequest revertOverrideRequest = new RevertOverrideRequest(); + + assertDoesNotThrow(() -> componentControllerV2.revertOverrides(DOSSIER_TEMPLATE_ID, DOSSIER_ID, FILE_ID, revertOverrideRequest)); + } + } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentOverrideTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentOverrideTest.java index 97819563e..8e79a863f 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentOverrideTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ComponentOverrideTest.java @@ -4,28 +4,28 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.MockitoAnnotations.openMocks; import java.io.IOException; -import java.util.HashMap; +import java.lang.reflect.Field; import java.util.List; -import java.util.Map; import java.util.Set; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; +import org.springframework.test.util.ReflectionTestUtils; import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.persistence.service.v2.external.api.impl.controller.ComponentControllerV2; import com.iqser.red.service.peristence.v1.server.integration.client.ComponentClient; import com.iqser.red.service.peristence.v1.server.integration.client.DossierTemplateClient; import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; -import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.service.FileService; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog; -import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLogEntry; -import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentsOverrides; import com.iqser.red.service.persistence.service.v1.api.shared.model.component.RevertOverrideRequest; import com.iqser.red.service.persistence.service.v2.api.external.model.Component; import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentValue; @@ -54,6 +54,17 @@ public class ComponentOverrideTest extends AbstractPersistenceServerServiceTest @Autowired private FileService fileService; + @Autowired + private ComponentControllerV2 componentControllerV2; + + + @BeforeEach + @SneakyThrows + void setUp() { + + ReflectionTestUtils.setField(componentControllerV2, "applicationType", "DocuMine"); + } + @Test public void testOverrides() throws IOException { @@ -130,21 +141,19 @@ public class ComponentOverrideTest extends AbstractPersistenceServerServiceTest .get(0).isOverridden()); // add and revert override - Component componentOverrideModel3 = Component.builder() - .name("Report_Number") - .componentValues(List.of(ComponentValue.builder() - .value("WOHOO 11/111-111A") - //.originalValue("11/111-111A") - .valueDescription("First found value of type report_number or else ''") - .componentRuleId("ReportNumber.0.0") - .entityReferences(List.of(EntityReference.builder() - .id("e2a93bcc72e9740bbfc19bd9cd982e01") - .type("report_number") - .entityRuleId("DOC.2.0") - .page(1) - .build())) - .build())) - .build(); + Component componentOverrideModel3 = Component.builder().name("Report_Number").componentValues(List.of(ComponentValue.builder() + .value("WOHOO 11/111-111A") + //.originalValue("11/111-111A") + .valueDescription( + "First found value of type report_number or else ''") + .componentRuleId("ReportNumber.0.0") + .entityReferences(List.of(EntityReference.builder() + .id("e2a93bcc72e9740bbfc19bd9cd982e01") + .type("report_number") + .entityRuleId("DOC.2.0") + .page(1) + .build())) + .build())).build(); componentClient.addOverride(dossierTemplate.getId(), dossier.getId(), file.getId(), componentOverrideModel3); overrides = componentClient.getOverrides(dossierTemplate.getId(), dossier.getId(), file.getId()); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadControllerV2Test.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadControllerV2Test.java new file mode 100644 index 000000000..a94bffa1d --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadControllerV2Test.java @@ -0,0 +1,231 @@ +package com.iqser.red.service.peristence.v1.server.integration.tests; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.openMocks; + +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; + +import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController; +import com.iqser.red.persistence.service.v2.external.api.impl.controller.DownloadControllerV2; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.download.DownloadStatusEntity; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; +import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User; +import com.iqser.red.service.persistence.service.v1.api.shared.model.RemoveDownloadRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; +import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; + +public class DownloadControllerV2Test { + + public static final String USER_ID = "user-111"; + public static final String DOWNLOAD_ID = "download-123"; + + @InjectMocks + private DownloadControllerV2 downloadControllerV2; + + @Mock + private DownloadController downloadController; + @Mock + private DownloadStatusPersistenceService downloadStatusPersistenceService; + @Mock + private UserService userService; + + @Mock + private DownloadStatusEntity mockDownloadStatusEntity; + + + @BeforeEach + void setUp() { + + openMocks(this); + } + + + @Test + void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles_getDownloadStatusList() { + + User invalidUser = new User(); + invalidUser.setUserId(USER_ID); + invalidUser.setRoles(Set.of("RED_ADMIN")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(invalidUser)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertThrows(NotAllowedException.class, () -> downloadControllerV2.getDownloadStatusList()); + } + } + + + @Test + void shouldNotThrowExceptionIfUserHasValidRoles_getDownloadStatusList() { + + User validUser = new User(); + validUser.setUserId(USER_ID); + validUser.setRoles(Set.of("RED_MANAGER")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validUser)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + when(downloadStatusPersistenceService.getStatusesByUser(USER_ID)).thenReturn(Collections.emptyList()); + + assertDoesNotThrow(() -> downloadControllerV2.getDownloadStatusList()); + } + } + + + @Test + void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles_getDownloadStatus() { + + User invalidUser = new User(); + invalidUser.setUserId(USER_ID); + invalidUser.setRoles(Collections.emptySet()); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(invalidUser)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertThrows(NotAllowedException.class, () -> downloadControllerV2.getDownloadStatus(DOWNLOAD_ID)); + } + } + + + @Test + void shouldNotThrowExceptionIfUserHasValidRoles_getDownloadStatus() { + + User validUser = new User(); + validUser.setUserId(USER_ID); + validUser.setRoles(Set.of("RED_USER")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validUser)); + + when(downloadStatusPersistenceService.getStatusesByUuid(DOWNLOAD_ID)).thenReturn(mockDownloadStatusEntity); + + when(mockDownloadStatusEntity.getUuid()).thenReturn(DOWNLOAD_ID); + when(mockDownloadStatusEntity.getUserId()).thenReturn(USER_ID); + when(mockDownloadStatusEntity.getFilename()).thenReturn("dummy-file"); + when(mockDownloadStatusEntity.getMimeType()).thenReturn("application/pdf"); + when(mockDownloadStatusEntity.getErrorCause()).thenReturn(null); + when(mockDownloadStatusEntity.getStatus()).thenReturn(DownloadStatusValue.READY); + when(mockDownloadStatusEntity.getCreationDate()).thenReturn(OffsetDateTime.now()); + when(mockDownloadStatusEntity.getLastDownload()).thenReturn(OffsetDateTime.now()); + when(mockDownloadStatusEntity.getFileSize()).thenReturn(12345L); + DossierEntity dossierEntity = mock(DossierEntity.class); + when(dossierEntity.getId()).thenReturn("dossier-123"); + when(mockDownloadStatusEntity.getDossier()).thenReturn(dossierEntity); + when(mockDownloadStatusEntity.getFiles()).thenReturn(Collections.emptyList()); + when(mockDownloadStatusEntity.getDownloadFileTypes()).thenReturn(Collections.emptySet()); + when(mockDownloadStatusEntity.getReports()).thenReturn(Collections.emptyList()); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertDoesNotThrow(() -> downloadControllerV2.getDownloadStatus(DOWNLOAD_ID)); + } + } + + + @Test + void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles_deleteDownload() { + + User invalidUser = new User(); + invalidUser.setUserId(USER_ID); + invalidUser.setRoles(Set.of("RED_USER_ADMIN")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(invalidUser)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertThrows(NotAllowedException.class, () -> downloadControllerV2.deleteDownload(DOWNLOAD_ID)); + } + } + + + @Test + void shouldNotThrowExceptionIfUserHasValidRoles_deleteDownload() { + + User validUser = new User(); + validUser.setUserId(USER_ID); + validUser.setRoles(Set.of("RED_MANAGER")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validUser)); + + when(downloadStatusPersistenceService.getStatusesByUuid(DOWNLOAD_ID)).thenReturn(mockDownloadStatusEntity); + when(mockDownloadStatusEntity.getStorageId()).thenReturn("storage-123"); + + doNothing().when(downloadController).deleteDownloadStatus(any(RemoveDownloadRequest.class)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertDoesNotThrow(() -> downloadControllerV2.deleteDownload(DOWNLOAD_ID)); + + verify(downloadController).deleteDownloadStatus(any(RemoveDownloadRequest.class)); + } + } + + + @Test + void shouldThrowNotAllowedExceptionIfUserHasInvalidRoles_download() { + + User invalidUser = new User(); + invalidUser.setUserId(USER_ID); + invalidUser.setRoles(Set.of("NON_ELIGIBLE_ROLE")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(invalidUser)); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertThrows(NotAllowedException.class, () -> downloadControllerV2.download(DOWNLOAD_ID)); + } + } + + + @Test + void shouldNotThrowExceptionIfUserHasValidRoles_download() { + + User validUser = new User(); + validUser.setUserId(USER_ID); + validUser.setRoles(Set.of("RED_USER")); + + when(userService.getUserById(USER_ID)).thenReturn(Optional.of(validUser)); + + when(downloadStatusPersistenceService.getStatusesByUuid(DOWNLOAD_ID)).thenReturn(mockDownloadStatusEntity); + when(mockDownloadStatusEntity.getStorageId()).thenReturn("storage-123"); + + doNothing().when(downloadController).downloadFile("storage-123"); + + try (MockedStatic keycloakSecurityMock = mockStatic(KeycloakSecurity.class)) { + keycloakSecurityMock.when(KeycloakSecurity::getUserId).thenReturn(USER_ID); + + assertDoesNotThrow(() -> downloadControllerV2.download(DOWNLOAD_ID)); + + verify(downloadController).downloadFile("storage-123"); + } + } + +}