RED-9472: seperation of system rules

added endpoints for full rule files (including system rules)

added roles
This commit is contained in:
yhampe 2024-10-18 12:37:18 +02:00
parent b54662cf5f
commit 94d38e561f
4 changed files with 89 additions and 2 deletions

View File

@ -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<DroolsValidationResponse> 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) {

View File

@ -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<DroolsValidationResponse> 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);
}

View File

@ -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";

View File

@ -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,