From 94d38e561f0e9f86bc68e094b8ea6272e5427411 Mon Sep 17 00:00:00 2001 From: yhampe Date: Fri, 18 Oct 2024 12:37:18 +0200 Subject: [PATCH] RED-9472: seperation of system rules added endpoints for full rule files (including system rules) added roles --- .../api/impl/controller/RulesController.java | 66 +++++++++++++++++++ .../api/external/resource/RulesResource.java | 19 ++++++ .../v1/processor/roles/ActionRoles.java | 2 + .../v1/processor/roles/ApplicationRoles.java | 4 +- 4 files changed, 89 insertions(+), 2 deletions(-) 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/RulesController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java index b52e23f30..95dff33f3 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/RulesController.java @@ -1,7 +1,9 @@ package com.iqser.red.persistence.service.v1.external.api.impl.controller; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_RULES; +import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_SYSTEM_RULES; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_RULES; +import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_SYSTEM_RULES; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -28,6 +30,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.NotFo import com.iqser.red.service.persistence.management.v1.processor.service.RulesValidationService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; 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.service.v1.api.external.resource.RulesResource; import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; @@ -104,6 +107,47 @@ public class RulesController implements RulesResource { } + @Override + @PreAuthorize("hasAuthority('" + WRITE_SYSTEM_RULES + "')") + public ResponseEntity uploadFullFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, + @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType, + @RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun, + @RequestPart(name = "file") MultipartFile file) { + + try { + String rules = new String(file.getBytes(), StandardCharsets.UTF_8); + DroolsValidationResponse droolsValidationResponse = new DroolsValidationResponse(); + + try { + var droolsValidation = rulesValidationService.validateRules(ruleFileType, rules); + droolsValidationResponse = RulesValidationMapper.createFromDroolsValidation(droolsValidation); + if (!droolsValidation.isCompiled()) { + + return new ResponseEntity<>(droolsValidationResponse, !dryRun ? HttpStatus.UNPROCESSABLE_ENTITY : HttpStatus.OK); + } + } catch (FeignException e) { + if (e.status() == HttpStatus.BAD_REQUEST.value()) { + throw new BadRequestException("The provided rule string is not a valid drools rule file!"); + } + } + if (!dryRun) { + rulesPersistenceService.setRules(rules, dossierTemplateId, ruleFileType); + } + + auditPersistenceService.audit(AuditRequest.builder() + .userId(KeycloakSecurity.getUserId()) + .objectId(dossierTemplateId) + .category(AuditCategory.DOSSIER_TEMPLATE.name()) + .message(String.format("%s Rules have been updated", ruleFileType)) + .build()); + + return new ResponseEntity<>(droolsValidationResponse, HttpStatus.OK); + } catch (IOException e) { + throw new FileUploadException("Could not upload file.", e); + } + } + + @Override @PreAuthorize("hasAuthority('" + READ_RULES + "')") public RulesResponse download(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType) { @@ -147,6 +191,28 @@ public class RulesController implements RulesResource { } + @Override + @PreAuthorize("hasAuthority('" + READ_SYSTEM_RULES + "')") + public ResponseEntity downloadFullFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, + @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType) { + + var ruleEntityOptional = rulesPersistenceService.getRules(dossierTemplateId, ruleFileType); + if (ruleEntityOptional.isEmpty()) { + throw new NotFoundException(String.format("No rule file of type %s found for dossierTemplateId %s", ruleFileType, dossierTemplateId)); + } + RulesResponse rulesResponse = new RulesResponse(ruleEntityOptional.get().getValue(), dossierTemplateId, ruleEntityOptional.get().isTimeoutDetected()); + byte[] data = rulesResponse.getRules().getBytes(StandardCharsets.UTF_8); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.TEXT_PLAIN); + + httpHeaders.add("Content-Disposition", "attachment; filename*=utf-8''" + ruleFileType.name() + "_" + DOWNLOAD_FILE_NAME); + InputStream is = new ByteArrayInputStream(data); + + return new ResponseEntity<>(new InputStreamResource(is), httpHeaders, HttpStatus.OK); + + } + + @Override @PreAuthorize("hasAuthority('" + READ_RULES + "')") public ResponseEntity downloadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { diff --git a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java index db614e5a0..5fafa8563 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/RulesResource.java @@ -90,6 +90,16 @@ public interface RulesResource { @Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file); + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful or rules validation done"), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified."), @ApiResponse(responseCode = "422", description = "Uploaded rules could not be compiled.")}) + ResponseEntity uploadFullFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, + @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType, + @RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun, + @Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file); + + @ResponseBody @ResponseStatus(value = HttpStatus.OK) @Operation(summary = "Returns file containing the currently used Drools rules.") @@ -105,4 +115,13 @@ public interface RulesResource { @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + DOWNLOAD_PATH) ResponseEntity downloadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @Operation(summary = "Returns file containing the currently used Drools rules.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) + @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + DOWNLOAD_PATH) + ResponseEntity downloadFullFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, + @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType); + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ActionRoles.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ActionRoles.java index 6c17e7741..4dfa5e8b4 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ActionRoles.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/roles/ActionRoles.java @@ -49,7 +49,9 @@ public final class ActionRoles { // Rules public static final String READ_RULES = "red-read-rules"; + public static final String READ_SYSTEM_RULES = "red-read-system-rules"; public static final String WRITE_RULES = "red-write-rules"; + public static final String WRITE_SYSTEM_RULES = "red-write-system-rules"; // Data formats public static final String READ_DATA_FORMATS = "red-read-data-formats"; 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 05ced6d54..a86335fc9 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 @@ -120,7 +120,7 @@ public final class ApplicationRoles { READ_LEGAL_BASIS, READ_LICENSE_REPORT, READ_NOTIFICATIONS, - READ_RULES, + READ_RULES, READ_SYSTEM_RULES, READ_DATA_FORMATS, READ_SMTP_CONFIGURATION, READ_VERSIONS, @@ -136,7 +136,7 @@ public final class ApplicationRoles { WRITE_FILE_ATTRIBUTES_CONFIG, WRITE_GENERAL_CONFIGURATION, WRITE_LEGAL_BASIS, - WRITE_RULES, + WRITE_RULES, WRITE_SYSTEM_RULES, WRITE_DATA_FORMATS, WRITE_SMTP_CONFIGURATION, WRITE_WATERMARK,