From f9a0f2dc1a9196cfc72e8332866bee19195e2175 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 22 Sep 2025 10:22:55 +0200 Subject: [PATCH 01/15] [NAE-2213] Delete global role Introduced a new process for deleting global roles, including updates to `ProcessRoleService` and a new `ProcessRoleController`. Added exceptions for role handling and enhanced `PetriNetRepository` to support role-specific queries. This allows streamlined management and cleanup of global roles across users, cases, and tasks. --- .../engine/importer/service/Importer.java | 1 - .../config/ProcessBeansConfiguration.java | 10 +- .../repositories/PetriNetRepository.java | 12 +++ .../petrinet/service/PetriNetService.java | 5 + .../petrinet/service/ProcessRoleService.java | 102 +++++++++++++++++- .../service/interfaces/IPetriNetService.java | 10 ++ .../petrinet/web/ProcessRoleController.java | 52 +++++++++ .../domain/roles/RoleNotFoundException.java | 7 ++ .../domain/roles/RoleNotGlobalException.java | 7 ++ .../petrinet/service/ProcessRoleService.java | 1 + 10 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotFoundException.java create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotGlobalException.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java index 9b7c2bb0c98..b52ee3581b4 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java @@ -1091,7 +1091,6 @@ protected ProcessRole initRole(Role importRole) { role.setName(toI18NString(importRole.getName())); } if (importRole.isGlobal() != null && importRole.isGlobal()) { - role.set_id(new ProcessResourceId(new ObjectId())); role.setGlobal(importRole.isGlobal()); } else { role.set_id(new ProcessResourceId(new ObjectId(net.getStringId()))); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/config/ProcessBeansConfiguration.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/config/ProcessBeansConfiguration.java index bd7f49907b1..3952d3b72db 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/config/ProcessBeansConfiguration.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/config/ProcessBeansConfiguration.java @@ -11,6 +11,8 @@ import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.security.service.ISecurityContextService; import com.netgrif.application.engine.auth.service.UserService; +import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; +import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; @@ -31,7 +33,9 @@ public ProcessRoleService processRoleService(ProcessRoleRepository processRoleRe ISecurityContextService securityContextService, @Lazy GroupService groupService, @Lazy RealmService realmService, - @Lazy PaginationProperties paginationProperties + @Lazy PaginationProperties paginationProperties, + @Lazy IWorkflowService workflowService, + @Lazy ITaskService taskService ) { return new com.netgrif.application.engine.petrinet.service.ProcessRoleService( processRoleRepository, @@ -43,7 +47,9 @@ public ProcessRoleService processRoleService(ProcessRoleRepository processRoleRe securityContextService, groupService, realmService, - paginationProperties + paginationProperties, + workflowService, + taskService ); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java index 641a0c50af1..a8dd005b207 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/domain/repositories/PetriNetRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; import org.springframework.data.querydsl.QuerydslPredicateExecutor; /** @@ -56,4 +57,15 @@ public interface PetriNetRepository extends MongoRepository, Q * @param id the unique ID of the PetriNet to delete. */ void deleteBy_id(ObjectId id); + + + /** + * Finds a paginated list of {@link PetriNet} entities associated with a specific role ID. + * + * @param roleId the ID of the role to filter PetriNets by + * @param pageable the pagination details + * @return a {@link Page} of {@link PetriNet} entities matching the specified role ID + */ + @Query("{ 'roles.?0' : { $exists: true } }") + Page findAllByRoleId(String roleId, Pageable pageable); } \ No newline at end of file diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index 18d214f0ce7..3ce9699db16 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -329,6 +329,11 @@ public PetriNetImportReference getNetFromCase(String caseId) { return pn; } + @Override + public Page findAllByRoleId(String roleId, Pageable pageable) { + return repository.findAllByRoleId(roleId, pageable); + } + @Override public Page getAll(Pageable pageable) { Page nets = repository.findAll(pageable); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index e4f3fd4b35f..41bae96c6ef 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -12,6 +12,8 @@ import com.netgrif.application.engine.objects.importer.model.EventPhaseType; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.QCase; import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.context.RoleContext; import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.runner.RoleActionsRunner; import com.netgrif.application.engine.objects.petrinet.domain.events.Event; @@ -22,6 +24,9 @@ import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.security.service.ISecurityContextService; import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId; +import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; +import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; +import lombok.Getter; import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +45,7 @@ public class ProcessRoleService implements com.netgrif.application.engine.adapte private static final Logger log = LoggerFactory.getLogger(ProcessRoleService.class); private final UserService userService; + @Getter private final ProcessRoleRepository processRoleRepository; private final PetriNetRepository netRepository; private final ApplicationEventPublisher publisher; @@ -48,7 +54,12 @@ public class ProcessRoleService implements com.netgrif.application.engine.adapte private final ISecurityContextService securityContextService; private final GroupService groupService; private final RealmService realmService; + @Getter private final PaginationProperties paginationProperties; + @Getter + private final IWorkflowService workflowService; + @Getter + private final ITaskService taskService; private ProcessRole defaultRole; private ProcessRole anonymousRole; @@ -57,7 +68,7 @@ public ProcessRoleService(ProcessRoleRepository processRoleRepository, PetriNetRepository netRepository, ApplicationEventPublisher publisher, RoleActionsRunner roleActionsRunner, @Lazy IPetriNetService petriNetService, @Lazy UserService userService, ISecurityContextService securityContextService, @Lazy GroupService groupService, - @Lazy RealmService realmService, @Lazy PaginationProperties paginationProperties) { + @Lazy RealmService realmService, @Lazy PaginationProperties paginationProperties, @Lazy IWorkflowService workflowService, @Lazy ITaskService taskService) { this.processRoleRepository = processRoleRepository; this.netRepository = netRepository; this.publisher = publisher; @@ -68,6 +79,8 @@ public ProcessRoleService(ProcessRoleRepository processRoleRepository, this.groupService = groupService; this.realmService = realmService; this.paginationProperties = paginationProperties; + this.workflowService = workflowService; + this.taskService = taskService; } @Override @@ -145,7 +158,7 @@ protected void saveUserAndReloadContext(AbstractUser user, LoggedUser loggedUser String userId = user.getStringId(); securityContextService.saveToken(userId); - if (Objects.equals(userId, loggedUser.getId())) { + if (Objects.equals(userId, loggedUser.getStringId())) { loggedUser.getProcessRoles().clear(); loggedUser.setProcessRoles(user.getProcessRoles()); securityContextService.reloadSecurityContext(loggedUser); @@ -439,11 +452,96 @@ public void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser) { this.processRoleRepository.deleteAllBy_idIn(deletedRoleIds); } + @Override public void clearCache() { this.defaultRole = null; this.anonymousRole = null; } + @Override + public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { + ProcessRole processRole = this.findById(roleId); + if (processRole == null) { + log.info("No role with id [{}] found", roleId); + return; + } + log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); + Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); + Page realms; + do { + realms = realmService.getSmallRealm(realmPageable); + realms.forEach(realm -> { + Pageable usersPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); + Page users; + do { + users = this.userService.findAllByProcessRoles(Set.of(processRole.get_id()), realm.getName(), usersPageable); + for (AbstractUser user : users) { + removeRoleFromUser(user, processRole, loggedUser); + } + usersPageable = usersPageable.next(); + } while (users.hasNext()); + }); + realmPageable = realmPageable.next(); + } while (realms.hasNext()); + log.info("Deleting global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); + removeRoleFromProcesses(processRole); + this.processRoleRepository.delete(processRole); + } + + protected void removeRoleFromProcesses(ProcessRole processRole) { + Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); + Page petriNetPage; + do { + petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); + petriNetPage.forEach(petriNet -> { + petriNet.getTransitions().values().forEach(transition -> { + transition.getRoles().remove(processRole.getStringId()); + }); + petriNet.getRoles().remove(processRole.getStringId()); + removeRoleFromCases(petriNet.getStringId(), processRole); + petriNetService.save(petriNet); + }); + pageable = pageable.next(); + } while (petriNetPage.hasNext()); + } + + protected void removeRoleFromCases(String petriNetId, ProcessRole processRole) { + Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); + Page casePage; + do { + casePage = workflowService.search(QCase.case$.petriNetObjectId.eq(new ObjectId(petriNetId)), pageable); + casePage.forEach(useCase -> { + useCase.getEnabledRoles().remove(processRole.getStringId()); + useCase.getPermissions().remove(processRole.getStringId()); + useCase.getViewRoles().remove(processRole.getStringId()); + useCase.getNegativeViewRoles().remove(processRole.getStringId()); + removeRoleFromTasks(useCase.getStringId(), processRole); + workflowService.save(useCase); + }); + } while (casePage.hasNext()); + } + + protected void removeRoleFromTasks(String caseId, ProcessRole processRole) { + taskService.findAllByCase(caseId).forEach(task -> { + task.getRoles().remove(processRole.getStringId()); + task.getViewRoles().remove(processRole.getStringId()); + task.getNegativeViewRoles().remove(processRole.getStringId()); + taskService.save(task); + }); + } + + private void removeRoleFromUser(AbstractUser user, ProcessRole processRole, LoggedUser loggedUser) { + log.info("Removing global role with import ID [{}] and object ID [{}] from user [{}] with id [{}]", processRole.getImportId(), processRole.getStringId(), user.getFullName(), user.getStringId()); + if (user.getProcessRoles().isEmpty()) { + return; + } + Set newRoles = user.getProcessRoles().stream() + .filter(role -> !role.getStringId().equals(processRole.getStringId()) && !role.isGlobal()) + .map(ProcessRole::get_id) + .collect(Collectors.toSet()); + this.assignRolesToUser(user, newRoles, loggedUser); + } + private ObjectId extractObjectId(String caseId) { String[] parts = caseId.split("-"); if (parts.length < 2) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java index 9bd338b60b5..c6fd966cb51 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/interfaces/IPetriNetService.java @@ -344,4 +344,14 @@ static DataFieldReference transformToReference(PetriNet net, Transition transiti * @return a {@link PetriNetImportReference} linking the PetriNet */ PetriNetImportReference getNetFromCase(String caseId); + + + /** + * Retrieves a paginated list of {@link PetriNet} objects associated with a specific role ID. + * + * @param roleId the ID of the role to filter the PetriNets by + * @param pageable the pagination information + * @return a {@link Page} of {@link PetriNet} objects matching the role ID + */ + Page findAllByRoleId(String roleId, Pageable pageable); } \ No newline at end of file diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java new file mode 100644 index 00000000000..3aa7752f1bb --- /dev/null +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -0,0 +1,52 @@ +package com.netgrif.application.engine.petrinet.web; + +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotFoundException; +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; +import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@Tag(name = "ProcessRoles") +@RequestMapping("/api/roles") +public class ProcessRoleController { + + private final ProcessRoleService processRoleService; + + @Operation(summary = "Delete global role", + security = {@SecurityRequirement(name = "X-Auth-Token")}) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Global role was deleted successfully"), + @ApiResponse(responseCode = "400", description = "Invalid role id"), + @ApiResponse(responseCode = "403", description = "Caller doesn't fulfill the authorisation requirements"), + @ApiResponse(responseCode = "500", description = "Internal server error") + }) + @DeleteMapping(value = "/{id}",produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity deleteGlobalRole(@PathVariable("id") String id, Authentication auth) { + try { + LoggedUser user = (LoggedUser) auth.getPrincipal(); + processRoleService.deleteGlobalRole(id, user); + } catch (RoleNotGlobalException | RoleNotFoundException e) { + String message = "Error when deleting global role [%s]".formatted(id); + log.error(message, e); + return ResponseEntity.badRequest().body(e.getMessage()); + } + return ResponseEntity.ok("Global role was deleted successfully"); + } + +} diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotFoundException.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotFoundException.java new file mode 100644 index 00000000000..3de7181e433 --- /dev/null +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotFoundException.java @@ -0,0 +1,7 @@ +package com.netgrif.application.engine.adapter.spring.petrinet.domain.roles; + +public class RoleNotFoundException extends RuntimeException { + public RoleNotFoundException(String message) { + super(message); + } +} diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotGlobalException.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotGlobalException.java new file mode 100644 index 00000000000..a2276689e93 --- /dev/null +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleNotGlobalException.java @@ -0,0 +1,7 @@ +package com.netgrif.application.engine.adapter.spring.petrinet.domain.roles; + +public class RoleNotGlobalException extends RuntimeException { + public RoleNotGlobalException(String message) { + super(message); + } +} diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java index 11d3de47058..77869a0093f 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/service/ProcessRoleService.java @@ -37,4 +37,5 @@ public interface ProcessRoleService { Page findAllGlobalRoles(Pageable pageable); void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser); void clearCache(); + void deleteGlobalRole(String roleId, LoggedUser loggedUser); } From 1c1b5c027b86d8a3c825b6c5b19e76bb0b6b0e0f Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 22 Sep 2025 10:24:51 +0200 Subject: [PATCH 02/15] =?UTF-8?q?[NAE-2213]=20Delete=20global=20role=CB=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - added check for non global role --- .../engine/petrinet/service/ProcessRoleService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 41bae96c6ef..d390196c445 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -465,6 +465,10 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { log.info("No role with id [{}] found", roleId); return; } + if (!processRole.isGlobal()) { + log.warn("Role with id [{}] is not global, skipping deletion", roleId); + return; + } log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); Page realms; From daad4ce6f489d52d078e9906c00d41e2532dbb49 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 22 Sep 2025 10:25:37 +0200 Subject: [PATCH 03/15] =?UTF-8?q?[NAE-2213]=20Delete=20global=20role=CB=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - replaced warn to exception --- .../engine/petrinet/service/ProcessRoleService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index d390196c445..6509b8a6c18 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -1,5 +1,6 @@ package com.netgrif.application.engine.petrinet.service; +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; import com.netgrif.application.engine.adapter.spring.utils.PaginationProperties; import com.netgrif.application.engine.auth.service.GroupService; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; @@ -466,8 +467,7 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { return; } if (!processRole.isGlobal()) { - log.warn("Role with id [{}] is not global, skipping deletion", roleId); - return; + throw new RoleNotGlobalException("Role with id [%s] is not global.".formatted(roleId)); } log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); From d331122cc9fb8a10b6a78729e778c084e6513bb8 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:07:35 +0200 Subject: [PATCH 04/15] [NAE-2213] Delete global role Updated the `findAllByRoleId` method to ensure PetriNet arcs are initialized after retrieval. This change prevents potential uninitialized arc issues and ensures consistency when accessing PetriNet objects. --- .../application/engine/petrinet/service/PetriNetService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java index 3ce9699db16..a4684616368 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/PetriNetService.java @@ -331,7 +331,9 @@ public PetriNetImportReference getNetFromCase(String caseId) { @Override public Page findAllByRoleId(String roleId, Pageable pageable) { - return repository.findAllByRoleId(roleId, pageable); + Page nets = repository.findAllByRoleId(roleId, pageable); + nets.forEach(PetriNet::initializeArcs); + return nets; } @Override From 7fae89372fe7dcdc72cfb62e738a622e38efb0d8 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:08:46 +0200 Subject: [PATCH 05/15] [NAE-2213] Delete global role Replaced logging and silent return with a `RoleNotFoundException` to ensure proper error handling during global role deletion. This change improves robustness and clarity by enforcing explicit feedback when a role is missing. --- .../engine/petrinet/service/ProcessRoleService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 6509b8a6c18..5b9fc707a1a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -1,5 +1,6 @@ package com.netgrif.application.engine.petrinet.service; +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotFoundException; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; import com.netgrif.application.engine.adapter.spring.utils.PaginationProperties; import com.netgrif.application.engine.auth.service.GroupService; @@ -463,8 +464,7 @@ public void clearCache() { public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { ProcessRole processRole = this.findById(roleId); if (processRole == null) { - log.info("No role with id [{}] found", roleId); - return; + throw new RoleNotFoundException("Role with id [%s] not found.".formatted(roleId)); } if (!processRole.isGlobal()) { throw new RoleNotGlobalException("Role with id [%s] is not global.".formatted(roleId)); From d1c8f9561374d5d1db82574aa3bde5347a7f9feb Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:10:00 +0200 Subject: [PATCH 06/15] [NAE-2213] Delete global role Added a validation to block attempts to delete core roles (DEFAULT and ANONYMOUS) in the ProcessRoleService. This change ensures critical roles remain intact and avoids potential application issues caused by their removal. --- .../engine/petrinet/service/ProcessRoleService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 5b9fc707a1a..cf0ba776285 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -469,6 +469,9 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { if (!processRole.isGlobal()) { throw new RoleNotGlobalException("Role with id [%s] is not global.".formatted(roleId)); } + if (ProcessRole.DEFAULT_ROLE.equals(processRole.getImportId()) || ProcessRole.ANONYMOUS_ROLE.equals(processRole.getImportId())) { + throw new IllegalArgumentException("Deleting core roles (DEFAULT/ANONYMOUS) is forbidden."); + } log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); Page realms; From dada5a31440b7bf07849d60d0a378aeadb010b05 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:11:36 +0200 Subject: [PATCH 07/15] [NAE-2213] Delete global role Introduced @PreAuthorize annotation to restrict access to the deleteGlobalRole endpoint to administrators only. Added IllegalArgumentException to the exception handling to improve error coverage during role deletion. These changes enhance security and robustness. --- .../engine/petrinet/web/ProcessRoleController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java index 3aa7752f1bb..1280c4edc26 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -28,6 +29,7 @@ public class ProcessRoleController { private final ProcessRoleService processRoleService; + @PreAuthorize("@authorizationService.hasAuthority('ADMIN')") @Operation(summary = "Delete global role", security = {@SecurityRequirement(name = "X-Auth-Token")}) @ApiResponses(value = { @@ -41,7 +43,7 @@ public ResponseEntity deleteGlobalRole(@PathVariable("id") String id, Au try { LoggedUser user = (LoggedUser) auth.getPrincipal(); processRoleService.deleteGlobalRole(id, user); - } catch (RoleNotGlobalException | RoleNotFoundException e) { + } catch (RoleNotGlobalException | RoleNotFoundException | IllegalArgumentException e) { String message = "Error when deleting global role [%s]".formatted(id); log.error(message, e); return ResponseEntity.badRequest().body(e.getMessage()); From ab3677f0a5e327f9cb96180256a9f05cfd7cda1b Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:15:52 +0200 Subject: [PATCH 08/15] [NAE-2213] Delete global role Ensure the `pageable` object advances in each iteration of the role removal loop to correctly process paginated cases. This fixes potential issues with infinite loops or incomplete processing of data. --- .../application/engine/petrinet/service/ProcessRoleService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index cf0ba776285..cba8d4dfa01 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -525,6 +525,7 @@ protected void removeRoleFromCases(String petriNetId, ProcessRole processRole) { removeRoleFromTasks(useCase.getStringId(), processRole); workflowService.save(useCase); }); + pageable = pageable.next(); } while (casePage.hasNext()); } From c57829fd79491c8c4dde5b3fa15d00c10f83f763 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 12:21:08 +0200 Subject: [PATCH 09/15] [NAE-2213] Delete global role Simplify the removal of process roles from transitions and refine the filtering of user roles by eliminating redundant conditions. These changes enhance code readability and maintainability. --- .../engine/petrinet/service/ProcessRoleService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index cba8d4dfa01..1cf8f71e0a1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -501,9 +501,7 @@ protected void removeRoleFromProcesses(ProcessRole processRole) { do { petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); petriNetPage.forEach(petriNet -> { - petriNet.getTransitions().values().forEach(transition -> { - transition.getRoles().remove(processRole.getStringId()); - }); + petriNet.getTransitions().values().forEach(transition -> transition.getRoles().remove(processRole.getStringId())); petriNet.getRoles().remove(processRole.getStringId()); removeRoleFromCases(petriNet.getStringId(), processRole); petriNetService.save(petriNet); @@ -544,7 +542,7 @@ private void removeRoleFromUser(AbstractUser user, ProcessRole processRole, Logg return; } Set newRoles = user.getProcessRoles().stream() - .filter(role -> !role.getStringId().equals(processRole.getStringId()) && !role.isGlobal()) + .filter(role -> !role.getStringId().equals(processRole.getStringId())) .map(ProcessRole::get_id) .collect(Collectors.toSet()); this.assignRolesToUser(user, newRoles, loggedUser); From 56a0b3ac2a43fc80c98deb09c7b30fd82a021498 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Mon, 29 Sep 2025 14:55:22 +0200 Subject: [PATCH 10/15] Update schema URL in petriflow_schema.xsd Replaced the schemaLocation URL to point to the updated GitHub-hosted location. This ensures compatibility with the latest schema version and resolves potential issues with the old URL. --- nae-object-library/src/main/resources/petriflow_schema.xsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/resources/petriflow_schema.xsd b/nae-object-library/src/main/resources/petriflow_schema.xsd index 28e88a26d6f..14cd2084848 100644 --- a/nae-object-library/src/main/resources/petriflow_schema.xsd +++ b/nae-object-library/src/main/resources/petriflow_schema.xsd @@ -3,6 +3,6 @@ - + \ No newline at end of file From 375590e0cc4fc88ed4f6f9dd55d36f25d4cb3733 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Tue, 30 Sep 2025 12:39:36 +0200 Subject: [PATCH 11/15] Add Swagger @Parameter annotation to delete global role endpoint The @Parameter annotation provides additional details for the "id" parameter in the delete global role endpoint. This enhancement improves API documentation by specifying the parameter's purpose, requirement status, and an example value. --- .../application/engine/petrinet/web/ProcessRoleController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java index 1280c4edc26..69ef13bbec3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -5,6 +5,7 @@ import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -32,6 +33,7 @@ public class ProcessRoleController { @PreAuthorize("@authorizationService.hasAuthority('ADMIN')") @Operation(summary = "Delete global role", security = {@SecurityRequirement(name = "X-Auth-Token")}) + @Parameter(name = "id", description = "Id of the global role to be deleted", required = true, example = "GcdIZcAPUc6jh7i2-68d683f80dc9384aa6791a64") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Global role was deleted successfully"), @ApiResponse(responseCode = "400", description = "Invalid role id"), From 279c662da1b67151a44c32cf13864db4cefe7e3c Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Tue, 30 Sep 2025 13:19:22 +0200 Subject: [PATCH 12/15] Refactor deleteGlobalRole to return detailed error responses Updated the deleteGlobalRole endpoint to use ResponseMessage for consistent error handling. Added specific responses for RoleNotFoundException (404) and RoleNotGlobalException (409) with detailed logging. --- .../petrinet/web/ProcessRoleController.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java index 69ef13bbec3..0c653e2a625 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -1,5 +1,6 @@ package com.netgrif.application.engine.petrinet.web; +import com.netgrif.application.engine.adapter.spring.common.web.responsebodies.ResponseMessage; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotFoundException; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; @@ -21,6 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Map; + @Slf4j @RestController @RequiredArgsConstructor @@ -38,19 +41,29 @@ public class ProcessRoleController { @ApiResponse(responseCode = "200", description = "Global role was deleted successfully"), @ApiResponse(responseCode = "400", description = "Invalid role id"), @ApiResponse(responseCode = "403", description = "Caller doesn't fulfill the authorisation requirements"), + @ApiResponse(responseCode = "404", description = "Role not found"), + @ApiResponse(responseCode = "409", description = "Role is not global"), @ApiResponse(responseCode = "500", description = "Internal server error") }) @DeleteMapping(value = "/{id}",produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity deleteGlobalRole(@PathVariable("id") String id, Authentication auth) { + public ResponseEntity deleteGlobalRole(@PathVariable("id") String id, Authentication auth) { try { LoggedUser user = (LoggedUser) auth.getPrincipal(); processRoleService.deleteGlobalRole(id, user); - } catch (RoleNotGlobalException | RoleNotFoundException | IllegalArgumentException e) { + } catch (RoleNotFoundException e) { + String message = "Error when deleting global role [%s]".formatted(id); + log.error(message, e); + return ResponseEntity.status(404).body(ResponseMessage.createErrorMessage(e.getMessage())); + } catch (RoleNotGlobalException e) { + String message = "Error when deleting global role [%s]".formatted(id); + log.error(message, e); + return ResponseEntity.status(409).body(ResponseMessage.createErrorMessage(e.getMessage())); + } catch (IllegalArgumentException e) { String message = "Error when deleting global role [%s]".formatted(id); log.error(message, e); - return ResponseEntity.badRequest().body(e.getMessage()); + return ResponseEntity.badRequest().body(ResponseMessage.createErrorMessage(e.getMessage())); } - return ResponseEntity.ok("Global role was deleted successfully"); + return ResponseEntity.ok(ResponseMessage.createErrorMessage("Global role was deleted successfully")); } } From e771098196753052f80f2288954b22d3f54efc48 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Tue, 30 Sep 2025 15:49:11 +0200 Subject: [PATCH 13/15] Add roles field to PetriNetSearch class Introduced a new `roles` field to the `PetriNetSearch` class to store a list of role identifiers. This change enhances the class by enabling role-specific functionality and broadening its applicability in access control scenarios. --- .../engine/objects/petrinet/domain/PetriNetSearch.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNetSearch.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNetSearch.java index f39ec3dc0fe..3db8891f7c4 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNetSearch.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNetSearch.java @@ -28,6 +28,8 @@ public class PetriNetSearch { private ActorRef author; + private List roles; + private List negativeViewRoles; private Map tags; From e8465266716b7cf2aa596c699e8780c0dd230a87 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Tue, 30 Sep 2025 16:19:45 +0200 Subject: [PATCH 14/15] Add validation for referenced roles during deletion Introduced a check to prevent deletion of roles referenced by other processes. Added a `RoleReferencedException` to handle this scenario, ensuring proper error responses and maintaining process integrity. Modified related methods and controller to support the new exception. --- .../petrinet/service/ProcessRoleService.java | 46 +++---------------- .../petrinet/web/ProcessRoleController.java | 5 ++ .../domain/roles/RoleReferencedException.java | 7 +++ 3 files changed, 19 insertions(+), 39 deletions(-) create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleReferencedException.java diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java index 1cf8f71e0a1..1c94340d3a8 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/service/ProcessRoleService.java @@ -2,6 +2,7 @@ import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotFoundException; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleReferencedException; import com.netgrif.application.engine.adapter.spring.utils.PaginationProperties; import com.netgrif.application.engine.auth.service.GroupService; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; @@ -472,6 +473,9 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { if (ProcessRole.DEFAULT_ROLE.equals(processRole.getImportId()) || ProcessRole.ANONYMOUS_ROLE.equals(processRole.getImportId())) { throw new IllegalArgumentException("Deleting core roles (DEFAULT/ANONYMOUS) is forbidden."); } + if (isRoleReferenced(processRole)) { + throw new RoleReferencedException("Role with id [%s] is referenced by other processes. Please delete or update the process before deleting.".formatted(roleId)); + } log.info("Initiating deletion of global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); Pageable realmPageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); Page realms; @@ -491,49 +495,13 @@ public void deleteGlobalRole(String roleId, LoggedUser loggedUser) { realmPageable = realmPageable.next(); } while (realms.hasNext()); log.info("Deleting global role with import ID [{}] and object ID [{}]", processRole.getImportId(), processRole.getStringId()); - removeRoleFromProcesses(processRole); this.processRoleRepository.delete(processRole); } - protected void removeRoleFromProcesses(ProcessRole processRole) { - Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); - Page petriNetPage; - do { - petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); - petriNetPage.forEach(petriNet -> { - petriNet.getTransitions().values().forEach(transition -> transition.getRoles().remove(processRole.getStringId())); - petriNet.getRoles().remove(processRole.getStringId()); - removeRoleFromCases(petriNet.getStringId(), processRole); - petriNetService.save(petriNet); - }); - pageable = pageable.next(); - } while (petriNetPage.hasNext()); - } - - protected void removeRoleFromCases(String petriNetId, ProcessRole processRole) { + protected boolean isRoleReferenced(ProcessRole processRole) { Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize()); - Page casePage; - do { - casePage = workflowService.search(QCase.case$.petriNetObjectId.eq(new ObjectId(petriNetId)), pageable); - casePage.forEach(useCase -> { - useCase.getEnabledRoles().remove(processRole.getStringId()); - useCase.getPermissions().remove(processRole.getStringId()); - useCase.getViewRoles().remove(processRole.getStringId()); - useCase.getNegativeViewRoles().remove(processRole.getStringId()); - removeRoleFromTasks(useCase.getStringId(), processRole); - workflowService.save(useCase); - }); - pageable = pageable.next(); - } while (casePage.hasNext()); - } - - protected void removeRoleFromTasks(String caseId, ProcessRole processRole) { - taskService.findAllByCase(caseId).forEach(task -> { - task.getRoles().remove(processRole.getStringId()); - task.getViewRoles().remove(processRole.getStringId()); - task.getNegativeViewRoles().remove(processRole.getStringId()); - taskService.save(task); - }); + Page petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable); + return petriNetPage.getTotalElements() > 0; } private void removeRoleFromUser(AbstractUser user, ProcessRole processRole, LoggedUser loggedUser) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java index 0c653e2a625..951edecbf77 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -3,6 +3,7 @@ import com.netgrif.application.engine.adapter.spring.common.web.responsebodies.ResponseMessage; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotFoundException; import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleNotGlobalException; +import com.netgrif.application.engine.adapter.spring.petrinet.domain.roles.RoleReferencedException; import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import io.swagger.v3.oas.annotations.Operation; @@ -58,6 +59,10 @@ public ResponseEntity deleteGlobalRole(@PathVariable("id") Stri String message = "Error when deleting global role [%s]".formatted(id); log.error(message, e); return ResponseEntity.status(409).body(ResponseMessage.createErrorMessage(e.getMessage())); + } catch (RoleReferencedException e) { + String message = "Error when deleting global role [%s]".formatted(id); + log.error(message, e); + return ResponseEntity.status(400).body(ResponseMessage.createErrorMessage(e.getMessage())); } catch (IllegalArgumentException e) { String message = "Error when deleting global role [%s]".formatted(id); log.error(message, e); diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleReferencedException.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleReferencedException.java new file mode 100644 index 00000000000..4ad962e40d4 --- /dev/null +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/petrinet/domain/roles/RoleReferencedException.java @@ -0,0 +1,7 @@ +package com.netgrif.application.engine.adapter.spring.petrinet.domain.roles; + +public class RoleReferencedException extends RuntimeException { + public RoleReferencedException(String message) { + super(message); + } +} From 894f208a371da532ca5905f8c7c6d76e2329fee8 Mon Sep 17 00:00:00 2001 From: Milan Mladoniczky <6153201+tuplle@users.noreply.github.com> Date: Tue, 30 Sep 2025 21:04:23 +0200 Subject: [PATCH 15/15] [NAE-2213] Delete global role - Replaced the schema location URL in `petriflow_schema.xsd` for consistency with the new domain. - Corrected the message type in `ProcessRoleController` to indicate a successful operation. --- .../engine/petrinet/web/ProcessRoleController.java | 2 +- nae-object-library/src/main/resources/petriflow_schema.xsd | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java index 951edecbf77..77cac9d06fd 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/ProcessRoleController.java @@ -68,7 +68,7 @@ public ResponseEntity deleteGlobalRole(@PathVariable("id") Stri log.error(message, e); return ResponseEntity.badRequest().body(ResponseMessage.createErrorMessage(e.getMessage())); } - return ResponseEntity.ok(ResponseMessage.createErrorMessage("Global role was deleted successfully")); + return ResponseEntity.ok(ResponseMessage.createSuccessMessage("Global role was deleted successfully")); } } diff --git a/nae-object-library/src/main/resources/petriflow_schema.xsd b/nae-object-library/src/main/resources/petriflow_schema.xsd index 14cd2084848..0bbd2530d69 100644 --- a/nae-object-library/src/main/resources/petriflow_schema.xsd +++ b/nae-object-library/src/main/resources/petriflow_schema.xsd @@ -3,6 +3,6 @@ - + - \ No newline at end of file +