diff --git a/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java b/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java index 71c39bf35..6f7e10641 100644 --- a/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java +++ b/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java @@ -47,16 +47,18 @@ public interface PlanService { List assignUsers(UUID planId, List model, FieldSet fields, boolean disableDelete) throws InvalidApplicationException, IOException; Plan removeUser(PlanUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException; - ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; + ResponseEntity export(UUID id, String transformerId, String exportType, boolean isPublic) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; void inviteUserOrAssignUsers(UUID id, List users) throws InvalidApplicationException, JAXBException, IOException; void planInvitationAccept(String token) throws InvalidApplicationException, IOException; - PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException; + PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize, boolean isPublic) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException; ResponseEntity exportXml(UUID id) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException; + ResponseEntity exportPublicXml(UUID id) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException; + Plan importXml(byte[] bytes, String label, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException; Plan importJson(PlanCommonModelConfig planCommonModelConfig, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, ParserConfigurationException, TransformerException, InstantiationException, IllegalAccessException, SAXException; diff --git a/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java index 7535f128f..033c6b335 100644 --- a/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java @@ -18,7 +18,6 @@ import gr.cite.tools.validation.ValidationFailure; import gr.cite.tools.validation.ValidatorFactory; import jakarta.xml.bind.JAXBException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.Permission; import org.opencdmp.authorization.authorizationcontentresolver.AuthorizationContentResolver; @@ -72,6 +71,7 @@ import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEvent; import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import org.opencdmp.model.PlanUser; import org.opencdmp.model.PlanValidationResult; +import org.opencdmp.model.PublicPlan; import org.opencdmp.model.builder.PlanUserBuilder; import org.opencdmp.model.builder.description.DescriptionBuilder; import org.opencdmp.model.builder.plan.PlanBuilder; @@ -128,6 +128,8 @@ import java.time.Instant; import java.util.*; import java.util.stream.Collectors; +import static org.opencdmp.authorization.AuthorizationFlags.Public; + @Service public class PlanServiceImpl implements PlanService { @@ -916,10 +918,10 @@ public class PlanServiceImpl implements PlanService { } @Override - public ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { + public ResponseEntity export(UUID id, String transformerId, String exportType, boolean isPublic) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { HttpHeaders headers = new HttpHeaders(); - FileEnvelope fileEnvelope = this.fileTransformerService.exportPlan(id, transformerId, exportType); + FileEnvelope fileEnvelope = this.fileTransformerService.exportPlan(id, transformerId, exportType, isPublic); headers.add("Content-Disposition", "attachment;filename=" + fileEnvelope.getFilename()); byte[] data = fileEnvelope.getFile(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); @@ -1637,15 +1639,26 @@ public class PlanServiceImpl implements PlanService { //region Export @Override - public PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { + public PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize, boolean isPublic) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { logger.debug(new MapLogEntry("export xml").And("id", id)); if (!ignoreAuthorize) this.authorizationService.authorizeForce(Permission.ExportPlan); - PlanEntity data = this.queryFactory.query(PlanQuery.class).disableTracking().ids(id).authorize(AuthorizationFlags.All).isActive(IsActive.Active).first(); + PlanEntity data = null; + if (!isPublic) { + data = this.queryFactory.query(PlanQuery.class).disableTracking().ids(id).authorize(AuthorizationFlags.All).isActive(IsActive.Active).first(); + } else { + try { + this.entityManager.disableTenantFilters(); + data = this.queryFactory.query(PlanQuery.class).disableTracking().authorize(EnumSet.of(Public)).ids(id).isActive(IsActive.Active).statuses(PlanStatus.Finalized).accessTypes(PlanAccessType.Public).first(); + this.entityManager.reloadTenantFilters(); + } finally { + this.entityManager.reloadTenantFilters(); + } + } if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, Plan.class.getSimpleName()}, LocaleContextHolder.getLocale())); PlanPropertiesEntity definition = this.jsonHandlingService.fromJson(PlanPropertiesEntity.class, data.getProperties()); - return this.definitionXmlToExport(data, definition); + return this.definitionXmlToExport(data, definition, isPublic); } @Override @@ -1656,12 +1669,34 @@ public class PlanServiceImpl implements PlanService { PlanEntity data = this.queryFactory.query(PlanQuery.class).disableTracking().ids(id).authorize(AuthorizationFlags.All).isActive(IsActive.Active).first(); if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, Plan.class.getSimpleName()}, LocaleContextHolder.getLocale())); - String xml = this.xmlHandlingService.toXml(this.exportXmlEntity(data.getId(), false)); + String xml = this.xmlHandlingService.toXml(this.exportXmlEntity(data.getId(), false, false)); + this.accountingService.increase(UsageLimitTargetMetric.EXPORT_PLAN_XML_EXECUTION_COUNT.getValue()); + return this.responseUtilsService.buildResponseFileFromText(xml, data.getLabel() + ".xml"); + } + + @Override + public ResponseEntity exportPublicXml(UUID id) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { + logger.debug(new MapLogEntry("export public xml").And("id", id)); + + this.authorizationService.authorizeForce(Permission.ExportPlan); + + PlanEntity data = null; + try { + this.entityManager.disableTenantFilters(); + data = this.queryFactory.query(PlanQuery.class).disableTracking().authorize(EnumSet.of(Public)).ids(id).isActive(IsActive.Active).statuses(PlanStatus.Finalized).accessTypes(PlanAccessType.Public).first(); + this.entityManager.reloadTenantFilters(); + } finally { + this.entityManager.reloadTenantFilters(); + } + + if (data == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, PublicPlan.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + String xml = this.xmlHandlingService.toXml(this.exportXmlEntity(data.getId(), false, true)); this.accountingService.increase(UsageLimitTargetMetric.EXPORT_PLAN_XML_EXECUTION_COUNT.getValue()); return this.responseUtilsService.buildResponseFileFromText(xml, data.getLabel() + ".xml"); } - private PlanImportExport definitionXmlToExport(PlanEntity data, PlanPropertiesEntity propertiesEntity) throws InvalidApplicationException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + private PlanImportExport definitionXmlToExport(PlanEntity data, PlanPropertiesEntity propertiesEntity, Boolean isPublic) throws InvalidApplicationException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { PlanBlueprintEntity blueprintEntity = this.queryFactory.query(PlanBlueprintQuery.class).disableTracking().ids(data.getBlueprintId()).authorize(AuthorizationFlags.All).first(); if (blueprintEntity == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{data.getBlueprintId(), PlanBlueprint.class.getSimpleName()}, LocaleContextHolder.getLocale())); @@ -1680,17 +1715,28 @@ public class PlanServiceImpl implements PlanService { xml.setDescriptionTemplates(this.planDescriptionTemplatesToExport(data)); xml.setBlueprintValues(this.planBlueprintValuesToExport(propertiesEntity, blueprintEntity)); xml.setReferences(this.planReferencesToExport(data)); - xml.setDescriptions(this.descriptionsToExport(data)); + xml.setDescriptions(this.descriptionsToExport(data, isPublic)); return xml; } - private List descriptionsToExport(PlanEntity data) throws JAXBException, InvalidApplicationException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { - List descriptions = this.queryFactory.query(DescriptionQuery.class).disableTracking().planIds(data.getId()).authorize(AuthorizationFlags.All).planIds(data.getId()).isActive(IsActive.Active).collect(); + private List descriptionsToExport(PlanEntity data, Boolean isPublic) throws JAXBException, InvalidApplicationException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + List descriptions; + if (!isPublic) { + descriptions = this.queryFactory.query(DescriptionQuery.class).disableTracking().planIds(data.getId()).authorize(AuthorizationFlags.All).planIds(data.getId()).isActive(IsActive.Active).collect(); + } else { + try { + this.entityManager.disableTenantFilters(); + descriptions = this.queryFactory.query(DescriptionQuery.class).disableTracking().authorize(EnumSet.of(Public)).planIds(data.getId()).collect(); + this.entityManager.reloadTenantFilters(); + } finally { + this.entityManager.reloadTenantFilters(); + } + } if (!this.conventionService.isListNullOrEmpty(descriptions)) { List descriptionImportExports = new LinkedList<>(); for (DescriptionEntity description : descriptions) { - descriptionImportExports.add(this.descriptionService.exportXmlEntity(description.getId(), true)); + descriptionImportExports.add(this.descriptionService.exportXmlEntity(description.getId(), true, isPublic)); } return descriptionImportExports; }