Resolve RED-9225 "Findings2 fp" #528

Merged
dominique.eiflaender1 merged 2 commits from RED-9225-findings2-fp into master 2024-06-06 15:21:00 +02:00
11 changed files with 114 additions and 13 deletions

View File

@ -3,8 +3,10 @@ package com.iqser.red.persistence.service.v2.external.api.impl.controller;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES;
import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@ -12,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Sets;
import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierController;
import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController;
import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController;
@ -29,8 +32,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.Audit
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttribute;
import com.iqser.red.service.persistence.service.v2.api.external.model.DocuMineDossierRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributes;
import com.iqser.red.service.persistence.service.v2.api.external.model.DocuMineDossierRequest;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList;
import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadRequest;
import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus;
@ -55,6 +58,9 @@ public class DossierControllerV2 implements DossierResource {
private final StatusController statusController;
private final DownloadStatusPersistenceService downloadStatusPersistenceService;
@Value("${application.type}")
private String applicationType;
public DossierList getDossiers(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
@RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
@ -95,11 +101,16 @@ public class DossierControllerV2 implements DossierResource {
public void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId) {
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
@RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently) {
dossierTemplateController.getDossierTemplate(dossierTemplateId);
dossierController.deleteDossier(dossierId);
if (deletePermanently) {
dossierController.hardDeleteDossiers(Sets.newHashSet(dossierId));
} else {
dossierController.deleteDossier(dossierId);
}
}
@ -169,7 +180,7 @@ public class DossierControllerV2 implements DossierResource {
}
private static DossierRequest mapToDossierRequest(String dossierTemplateId, DocuMineDossierRequest dossier) {
private DossierRequest mapToDossierRequest(String dossierTemplateId, DocuMineDossierRequest dossier) {
return DossierRequest.builder()
.dossierId(dossier.getId())
@ -178,7 +189,7 @@ public class DossierControllerV2 implements DossierResource {
.description(dossier.getDescription())
.ownerId(dossier.getOwnerId())
.memberIds(dossier.getMemberIds())
.approverIds(dossier.getMemberIds()) // for DocuMine, the members are always set as approvers
.approverIds(applicationType.equals("DocuMine") ? dossier.getMemberIds() : dossier.getApproverIds()) // for DocuMine, the members are always set as approvers
.downloadFileTypes(Set.of(DownloadFileType.ORIGINAL))
.reportTemplateIds(dossier.getReportTemplateIds())
.watermarkId(null)

View File

@ -1,6 +1,7 @@
package com.iqser.red.persistence.service.v2.external.api.impl.controller;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.EXPERIMENTAL;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.GET_REPORT_TEMPLATES;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES_CONFIG;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_STATUS;
import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_FILE_ATTRIBUTES_CONFIG;
@ -45,6 +46,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierStatusPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.RulesValidationMapper;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
@ -65,6 +67,8 @@ import com.iqser.red.service.persistence.service.v2.api.external.model.DossierSt
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinition;
import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.ReportTemplate;
import com.iqser.red.service.persistence.service.v2.api.external.model.ReportTemplateList;
import com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource;
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
@ -96,6 +100,7 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
DossierStatusPersistenceService dossierStatusPersistenceService;
DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService;
ComponentDefinitionService componentDefinitionService;
ReportTemplatePersistenceService reportTemplatePersistenceService;
public List<DossierTemplateModel> getAllDossierTemplates() {
@ -322,6 +327,23 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
}
@PreAuthorize("hasAuthority('" + GET_REPORT_TEMPLATES + "')")
public ReportTemplateList getReportTemplates(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId) {
getDossierTemplate(dossierTemplateId);
var templates = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId);
return new ReportTemplateList(templates.stream()
.map(t -> ReportTemplate.builder()
.id(t.getTemplateId())
.name(t.getFileName())
.createdOn(t.getUploadDate())
.multiFile(t.isMultiFileReport())
.preSelect(t.isActiveByDefault())
.build())
.toList());
}
@Override
public List<ComponentDefinition> createComponents(String dossierTemplateId, List<ComponentDefinitionAddRequest> componentDefinitionAddRequests) {

View File

@ -44,7 +44,7 @@ public class DownloadControllerV2 implements DownloadResource {
.creationDate(status.getCreationDate())
.lastDownload(status.getLastDownload())
.fileSize(status.getFileSize())
.dossierId(status.getDossier().getId())
.dossierId(status.getDossier() != null ? status.getDossier().getId() : null)
.fileIds(status.getFiles()
.stream()
.map(FileEntity::getId)

View File

@ -41,6 +41,10 @@ public class DocuMineDossierRequest {
@Schema(description = "The id(s) of members associated to this dossier.")
private Set<String> memberIds = new HashSet<>();
@Builder.Default
@Schema(description = "The id(s) of approvers associated to this dossier.")
private Set<String> approverIds = new HashSet<>();
@Builder.Default
@Schema(description = "Id(s) of the word report templates used to generate downloads")
private Set<String> reportTemplateIds = new HashSet<>();

View File

@ -0,0 +1,22 @@
package com.iqser.red.service.persistence.service.v2.api.external.model;
import java.time.OffsetDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReportTemplate {
private String id;
private String name;
private OffsetDateTime createdOn;
private boolean multiFile;
private boolean preSelect;
}

View File

@ -0,0 +1,20 @@
package com.iqser.red.service.persistence.service.v2.api.external.model;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReportTemplateList {
@Builder.Default
private List<ReportTemplate> reportTemplates = new ArrayList<>();
}

View File

@ -42,6 +42,8 @@ public interface DossierResource {
String INCLUDE_ARCHIVED_PARAM = "includeArchived";
String INCLUDE_SOFT_DELETED_PARAM = "includeSoftDeleted";
String DELETE_PERMANENTLY_PARAM = "deletePermanently";
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
@ -77,7 +79,8 @@ public interface DossierResource {
@Operation(summary = "Deletes an existing dossier.", description = "Dossiers get soft-deleted unless specified other. A soft-deleted dossier can be restored during a retention period that is configured in the application settings. The default retention period is 96h.")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Successfully deleted the dossier."), @ApiResponse(responseCode = "404", description = "Not found")})
void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId);
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
@Parameter(name = DELETE_PERMANENTLY_PARAM, description = "A toggle to determine the deletion mode for a dossier: `true`: The dossier will be permanently deleted and can't be restored. `false` (default): Soft-delete, allowing restoration within the application-configured retention period.") @RequestParam(name = DELETE_PERMANENTLY_PARAM, defaultValue = "false", required = false) boolean deletePermanently);
@ResponseStatus(value = HttpStatus.NO_CONTENT)

View File

@ -1,6 +1,11 @@
package com.iqser.red.service.persistence.service.v2.api.external.resource;
import java.util.List;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierAttributeDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.ReportTemplateList;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@ -17,16 +22,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentDefinition;
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentDefinitionAddRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentDefinitionUpdateRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.DroolsValidationResponse;
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingMetadataModel;
import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingSummary;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierAttributeDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinitionList;
import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@ -51,6 +52,7 @@ public interface DossierTemplateResource {
String FILE_ATTRIBUTE_DEFINITIONS_PATH = "/file-attribute-definitions";
String DOSSIER_TEMPLATE_ID_PARAM = "dossierTemplateId";
String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID_PARAM + "}";
String REPORT_TEMPLATES_PATH = "/report-templates";
String COMPONENT_MAPPING_ID_PARAM = "componentMappingId";
String COMPONENT_MAPPING_ID_PATH_VARIABLE = "/{" + COMPONENT_MAPPING_ID_PARAM + "}";
@ -240,4 +242,10 @@ public interface DossierTemplateResource {
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + COMPONENT_PATH + REORDER_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
List<ComponentDefinition> reorderComponents(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @RequestParam(name = COMPONENT_IDS) List<String> componentIds);
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + REPORT_TEMPLATES_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Returns the list of all available report templates", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully returned the report templates for the specified dossier template."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
ReportTemplateList getReportTemplates(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
}

View File

@ -50,7 +50,7 @@ public interface DownloadResource {
@ResponseStatus(value = HttpStatus.OK)
@Operation(summary = "Download the download package.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully downloaded the requested file."), @ApiResponse(responseCode = "404", description = "Download not found. This happens if the requested download does not exist for the current user.")})
@GetMapping(value = PATH + DOWNLOAD_ID_PATH_PARAM + DOWNLOAD_PATH)
@GetMapping(value = PATH + DOWNLOAD_ID_PATH_PARAM + DOWNLOAD_PATH, produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_OCTET_STREAM_VALUE})
void download(@Parameter(name = DOWNLOAD_ID_PARAM, description = "The identifier for the file to download.", required = true) @PathVariable(DOWNLOAD_ID_PARAM) String downloadId);
}

View File

@ -149,7 +149,7 @@ public class DossierTemplateExportService {
objectMapper.writeValueAsBytes(convert(colors, Colors.class))));
// add dossier statuses
var dossierStatusList = dossierStatusPersistenceService.getAllDossierStatusForTemplate(dossierTemplateId);
var dossierStatusList = dossierStatusPersistenceService.getAllDossierStatusForTemplateWithoutSecurity(dossierTemplateId);
fileSystemBackedArchiver.addEntries(new FileSystemBackedArchiver.ArchiveModel(null,
getFilename(ExportFilename.DOSSIER_STATUS, JSON_EXT),
objectMapper.writeValueAsBytes(convert(dossierStatusList, DossierStatusInfo.class))));

View File

@ -104,6 +104,17 @@ public class DossierStatusPersistenceService {
}
@Transactional
public List<DossierStatusInfo> getAllDossierStatusForTemplateWithoutSecurity(String dossierTemplateId) {
return dossierStatusRepository.findByDossierTemplateIdIn(Collections.singletonList(dossierTemplateId))
.stream()
.map(d -> MagicConverter.convert(d, DossierStatusInfo.class))
.collect(Collectors.toList());
}
@Transactional
public List<DossierStatusInfo> getAllDossierStatuses(List<String> dossierTemplateIds) {