Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -43,7 +47,9 @@ public ProcessRoleService processRoleService(ProcessRoleRepository processRoleRe
securityContextService,
groupService,
realmService,
paginationProperties
paginationProperties,
workflowService,
taskService
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -56,4 +57,15 @@ public interface PetriNetRepository extends MongoRepository<PetriNet, String>, 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<PetriNet> findAllByRoleId(String roleId, Pageable pageable);
Comment thread
renczesstefan marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ public PetriNetImportReference getNetFromCase(String caseId) {
return pn;
}

@Override
public Page<PetriNet> findAllByRoleId(String roleId, Pageable pageable) {
Page<PetriNet> nets = repository.findAllByRoleId(roleId, pageable);
nets.forEach(PetriNet::initializeArcs);
return nets;
}

@Override
public Page<PetriNet> getAll(Pageable pageable) {
Page<PetriNet> nets = repository.findAll(pageable);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
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.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;
Expand All @@ -12,6 +15,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;
Expand All @@ -22,6 +27,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;
Expand All @@ -40,6 +48,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;
Expand All @@ -48,7 +57,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;
Expand All @@ -57,7 +71,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;
Expand All @@ -68,6 +82,8 @@ public ProcessRoleService(ProcessRoleRepository processRoleRepository,
this.groupService = groupService;
this.realmService = realmService;
this.paginationProperties = paginationProperties;
this.workflowService = workflowService;
this.taskService = taskService;
}

@Override
Expand Down Expand Up @@ -145,7 +161,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);
Expand Down Expand Up @@ -439,11 +455,67 @@ 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) {
throw new RoleNotFoundException("Role with id [%s] not found.".formatted(roleId));
}
if (!processRole.isGlobal()) {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
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.");
}
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<Realm> realms;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
do {
realms = realmService.getSmallRealm(realmPageable);
realms.forEach(realm -> {
Pageable usersPageable = PageRequest.of(0, paginationProperties.getBackendPageSize());
Page<AbstractUser> 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());
this.processRoleRepository.delete(processRole);
}
Comment thread
renczesstefan marked this conversation as resolved.

Comment thread
renczesstefan marked this conversation as resolved.
protected boolean isRoleReferenced(ProcessRole processRole) {
Pageable pageable = PageRequest.of(0, paginationProperties.getBackendPageSize());
Page<PetriNet> petriNetPage = petriNetService.findAllByRoleId(processRole.getStringId(), pageable);
return petriNetPage.getTotalElements() > 0;
}

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<ProcessResourceId> newRoles = user.getProcessRoles().stream()
.filter(role -> !role.getStringId().equals(processRole.getStringId()))
.map(ProcessRole::get_id)
.collect(Collectors.toSet());
this.assignRolesToUser(user, newRoles, loggedUser);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

private ObjectId extractObjectId(String caseId) {
String[] parts = caseId.split("-");
if (parts.length < 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<PetriNet> findAllByRoleId(String roleId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
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.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;
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;
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.access.prepost.PreAuthorize;
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;

import java.util.Map;
Comment thread
machacjozef marked this conversation as resolved.

@Slf4j
@RestController
@RequiredArgsConstructor
@Tag(name = "ProcessRoles")
@RequestMapping("/api/roles")
public class ProcessRoleController {

private final ProcessRoleService processRoleService;

@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"),
@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")
})
Comment thread
coderabbitai[bot] marked this conversation as resolved.
@DeleteMapping(value = "/{id}",produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseMessage> deleteGlobalRole(@PathVariable("id") String id, Authentication auth) {
try {
LoggedUser user = (LoggedUser) auth.getPrincipal();
processRoleService.deleteGlobalRole(id, user);
Comment thread
renczesstefan marked this conversation as resolved.
} 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 (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);
return ResponseEntity.badRequest().body(ResponseMessage.createErrorMessage(e.getMessage()));
}
return ResponseEntity.ok(ResponseMessage.createSuccessMessage("Global role was deleted successfully"));
}
Comment thread
renczesstefan marked this conversation as resolved.

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class PetriNetSearch {

private ActorRef author;

private List<String> roles;

Comment thread
machacjozef marked this conversation as resolved.
private List<String> negativeViewRoles;

private Map<String, String> tags;
Expand Down
4 changes: 2 additions & 2 deletions nae-object-library/src/main/resources/petriflow_schema.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.1.0">
<xs:include schemaLocation="https://petriflow.com/petriflow.schema.xsd"/>
<xs:include schemaLocation="https://petriflow.org/petriflow.schema.xsd"/>
Comment thread
machacjozef marked this conversation as resolved.

</xs:schema>
</xs:schema>
Original file line number Diff line number Diff line change
@@ -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);
}
}
Comment thread
renczesstefan marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -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);
}
}
Comment thread
renczesstefan marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ public interface ProcessRoleService {
Page<ProcessRole> findAllGlobalRoles(Pageable pageable);
void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser);
void clearCache();
void deleteGlobalRole(String roleId, LoggedUser loggedUser);
}
Loading