From 1766b9258af7585b84ea19593417be07bce3e1fb Mon Sep 17 00:00:00 2001 From: Jozef Daxner Date: Tue, 17 Feb 2026 12:26:23 +0100 Subject: [PATCH 1/4] [NAE-2273] Implement User Impersonation - implement user impersonation - user impersonation is no longer supported in community edition - user impersonation is no longer managed by petrinets - logged user has information about impersonated user --- .../engine/migration/ActionMigration.groovy | 13 +- .../logic/action/ActionDelegate.groovy | 45 ++- .../auth/service/AuthorizationService.java | 2 - .../service/UserResourceHelperService.java | 57 --- .../IUserResourceHelperService.java | 16 - .../auth/web/AuthenticationController.java | 18 +- .../engine/auth/web/UserController.java | 6 +- .../NaeSecurityConfiguration.java | 11 +- .../SessionRegistryConfiguration.java | 2 +- .../security/AuthenticationService.java | 24 +- .../security/ImpersonationRequestFilter.java | 39 +- .../elastic/service/ElasticCaseService.java | 61 ++- .../service/ElasticPetriNetService.java | 34 +- .../elastic/service/ElasticTaskService.java | 53 ++- .../engine/elastic/web/ElasticController.java | 9 +- .../engine/export/service/ExportService.java | 11 +- .../IllegalImpersonationAttemptException.java | 14 - .../ImpersonatedUserHasSessionException.java | 15 - .../ImpersonationAuthorizationService.java | 207 ---------- .../service/ImpersonationService.java | 195 ---------- .../service/ImpersonationSessionService.java | 49 --- .../IImpersonationAuthorizationService.java | 36 -- .../interfaces/IImpersonationService.java | 33 -- .../IImpersonationSessionService.java | 7 - .../web/ImpersonationController.java | 107 ------ .../web/ImpersonationControllerAdvice.java | 30 -- .../web/requestbodies/SearchRequest.java | 18 - .../ImpersonationNotAvailableResponse.java | 15 - .../services/DashboardItemServiceImpl.java | 10 +- .../DashboardManagementServiceImpl.java | 8 +- .../engine/menu/services/MenuItemService.java | 24 +- .../petrinet/service/PetriNetService.java | 71 ++-- .../petrinet/service/ProcessRoleService.java | 14 +- .../petrinet/web/PetriNetController.java | 8 +- .../web/PublicPetriNetController.java | 11 +- .../startup/runner/DefaultFiltersRunner.java | 17 +- .../startup/runner/ImpersonationRunner.java | 56 --- .../repositories/CaseRepositoryImpl.java | 6 +- .../service/AbstractAuthorizationService.java | 6 +- .../workflow/service/CaseSearchService.java | 39 +- .../service/ConfigurableMenuService.java | 25 +- .../service/FilterImportExportService.java | 27 +- .../service/MenuImportExportService.java | 23 +- .../service/TaskAuthorizationService.java | 116 +++--- .../workflow/service/TaskSearchService.java | 39 +- .../engine/workflow/service/TaskService.java | 151 ++++---- .../service/UserFilterSearchService.java | 5 +- .../service/WorkflowAuthorizationService.java | 33 +- .../workflow/service/WorkflowService.java | 31 +- .../interfaces/ITaskAuthorizationService.java | 16 +- .../IWorkflowAuthorizationService.java | 5 +- .../workflow/web/AbstractTaskController.java | 6 +- .../workflow/web/PublicTaskController.java | 9 +- .../web/PublicWorkflowController.java | 5 +- .../workflow/web/WorkflowController.java | 3 +- .../workflow/web/responsebodies/Task.java | 4 + .../application/engine/TestHelper.groovy | 10 +- .../ImpersonationServiceTest.groovy | 354 ------------------ .../AbstractAuthorizationServiceTest.java | 8 +- .../security/ImpersonationRequestFilter.html | 4 +- .../impersonation/domain/Impersonator.html | 4 +- .../domain/class-use/Impersonator.html | 8 +- .../class-use/ImpersonatorRepository.html | 8 +- .../service/ImpersonationSessionService.html | 4 +- docs/javadoc/serialized-form.html | 4 +- .../objects/auth/domain/AbstractUser.java | 8 + .../objects/auth/domain/Impersonation.java | 126 +++++++ .../objects/auth/domain/LoggedUser.java | 125 +++++-- .../objects/elastic/domain/ElasticTask.java | 11 +- .../impersonation/domain/Impersonator.java | 25 -- .../web/requestbodies/SearchRequest.java | 18 - .../ImpersonationNotAvailableResponse.java | 15 - .../engine/objects/workflow/domain/Task.java | 13 + .../ImpersonationConfigurationProperties.java | 10 +- .../spring/elastic/domain/ElasticTask.java | 6 + .../adapter/spring/workflow/domain/Task.java | 8 +- .../engine/auth}/domain/Impersonator.java | 7 +- .../repository/ImpersonatorRepository.java | 4 +- .../service/ImpersonationServiceImpl.java | 93 +++++ .../engine/auth/service/UserServiceImpl.java | 33 +- .../auth/service/ImpersonationService.java | 38 ++ .../engine/auth/service/UserService.java | 85 ++--- 82 files changed, 1035 insertions(+), 1889 deletions(-) delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/auth/service/UserResourceHelperService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserResourceHelperService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/IllegalImpersonationAttemptException.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/ImpersonatedUserHasSessionException.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationAuthorizationService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationSessionService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationAuthorizationService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationSessionService.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationController.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationControllerAdvice.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/requestbodies/SearchRequest.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/responsebodies/ImpersonationNotAvailableResponse.java delete mode 100644 application-engine/src/main/java/com/netgrif/application/engine/startup/runner/ImpersonationRunner.java delete mode 100644 application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/Impersonation.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/impersonation/domain/Impersonator.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/impersonation/web/requestbodies/SearchRequest.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/impersonation/web/responsebodies/ImpersonationNotAvailableResponse.java rename {application-engine/src/main/java/com/netgrif/application/engine/configuration/properties => nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/configuration}/ImpersonationConfigurationProperties.java (74%) rename {application-engine/src/main/java/com/netgrif/application/engine/impersonation => nae-user-ce/src/main/java/com/netgrif/application/engine/auth}/domain/Impersonator.java (77%) rename {application-engine/src/main/java/com/netgrif/application/engine/impersonation/domain => nae-user-ce/src/main/java/com/netgrif/application/engine/auth}/repository/ImpersonatorRepository.java (68%) create mode 100644 nae-user-ce/src/main/java/com/netgrif/application/engine/auth/service/ImpersonationServiceImpl.java create mode 100644 nae-user-common/src/main/java/com/netgrif/application/engine/auth/service/ImpersonationService.java diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy index 941a9547363..cf26c23ed70 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ActionMigration.groovy @@ -1,11 +1,10 @@ package com.netgrif.application.engine.migration import com.netgrif.application.engine.auth.service.UserService -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.VersionType -import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import groovy.util.logging.Slf4j import org.springframework.beans.factory.annotation.Autowired import org.springframework.core.io.ClassPathResource @@ -26,25 +25,25 @@ class ActionMigration { void migrateActions(String petriNetPath, Pageable pageable = Pageable.unpaged()) { InputStream netStream = new ClassPathResource(petriNetPath).inputStream - ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(netStream, VersionType.MAJOR, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem())) + ImportPetriNetEventOutcome newPetriNet = petriNetService.importPetriNet(netStream, VersionType.MAJOR, userService.getLoggedOrSystem()) List oldPetriNets - if(newPetriNet.getNet() != null) { + if (newPetriNet.getNet() != null) { String message = "Petri net from file [" + petriNetPath + "] was not imported" log.error(message) throw new IllegalArgumentException(message) } else { oldPetriNets = petriNetService.getByIdentifier(newPetriNet.getNet().importId, pageable) - .stream().filter({ net -> (net.version != newPetriNet.getNet().version)}) + .stream().filter({ net -> (net.version != newPetriNet.getNet().version) }) .collect(Collectors.toList()) } - if(oldPetriNets.size() == 0){ + if (oldPetriNets.size() == 0) { String message = "Older version of Petri net with ID [" + newPetriNet.getNet().importId + "] is not present in MongoDB." log.error(message) throw new IllegalArgumentException(message) } else { - oldPetriNets.each {net -> + oldPetriNets.each { net -> migrateDataSetActions(newPetriNet.getNet(), net) migrateDataRefActions(newPetriNet.getNet(), net) petriNetService.save(net) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy index 2dd1827222b..7d0a5d2d011 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy @@ -5,6 +5,7 @@ import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRol import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask import com.netgrif.application.engine.auth.service.GroupService +import com.netgrif.application.engine.auth.service.ImpersonationService import com.netgrif.application.engine.auth.service.UserDetailsServiceImpl import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.auth.service.interfaces.IRegistrationService @@ -22,17 +23,16 @@ import com.netgrif.application.engine.export.domain.ExportDataConfig import com.netgrif.application.engine.export.service.interfaces.IExportService import com.netgrif.application.engine.files.IStorageResolverService import com.netgrif.application.engine.files.interfaces.IStorageService -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService import com.netgrif.application.engine.importer.service.FieldFactory import com.netgrif.application.engine.integration.modules.ModuleHolder import com.netgrif.application.engine.mail.domain.MailDraft import com.netgrif.application.engine.mail.interfaces.IMailAttemptService import com.netgrif.application.engine.mail.interfaces.IMailService -import com.netgrif.application.engine.objects.auth.domain.AbstractUser -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.menu.services.interfaces.DashboardItemService import com.netgrif.application.engine.menu.services.interfaces.DashboardManagementService import com.netgrif.application.engine.menu.services.interfaces.IMenuItemService +import com.netgrif.application.engine.objects.auth.domain.AbstractUser +import com.netgrif.application.engine.objects.auth.domain.ActorTransformer import com.netgrif.application.engine.objects.auth.domain.LoggedUser import com.netgrif.application.engine.objects.petrinet.domain.I18nString import com.netgrif.application.engine.objects.petrinet.domain.PetriNet @@ -46,6 +46,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.vali import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole import com.netgrif.application.engine.objects.petrinet.domain.version.Version import com.netgrif.application.engine.objects.utils.MenuItemUtils +import com.netgrif.application.engine.objects.utils.Nullable import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.Task import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome @@ -90,7 +91,6 @@ import org.springframework.core.io.FileSystemResource import org.springframework.data.domain.Page import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable -import com.netgrif.application.engine.objects.utils.Nullable import java.time.ZoneId import java.util.stream.Collectors @@ -132,6 +132,9 @@ class ActionDelegate { @Autowired UserService userService + @Autowired + ImpersonationService impersonationService + @Autowired IPetriNetService petriNetService @@ -192,9 +195,6 @@ class ActionDelegate { @Autowired ExportConfiguration exportConfiguration - @Autowired - IImpersonationService impersonationService - @Autowired SecurityConfigurationProperties.WebProperties webProperties @@ -938,18 +938,21 @@ class ActionDelegate { } Case createCase(String identifier, String title = null, String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { - return workflowService.createCaseByIdentifier(identifier, title, color, ActorTransformer.toLoggedUser(author), locale, params).getCase() + LoggedUser loggedUser = author instanceof LoggedUser ? (LoggedUser) author : ActorTransformer.toLoggedUser(author) + return workflowService.createCaseByIdentifier(identifier, title, color, loggedUser, locale, params).getCase() } Case createCase(PetriNet net, String title = net.defaultCaseName.getTranslation(locale), String color = "", AbstractUser author = userService.loggedOrSystem, Locale locale = LocaleContextHolder.getLocale(), Map params = [:]) { - CreateCaseEventOutcome outcome = workflowService.createCase(net.stringId, title, color, ActorTransformer.toLoggedUser(author), params) + LoggedUser loggedUser = author instanceof LoggedUser ? (LoggedUser) author : ActorTransformer.toLoggedUser(author) + CreateCaseEventOutcome outcome = workflowService.createCase(net.stringId, title, color, loggedUser, params) this.outcomes.add(outcome) return outcome.getCase() } Task assignTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - AssignTaskEventOutcome outcome = taskService.assignTask(ActorTransformer.toLoggedUser(user), taskId, params) + LoggedUser loggedUser = user instanceof LoggedUser ? (LoggedUser) user : ActorTransformer.toLoggedUser(user) + AssignTaskEventOutcome outcome = taskService.assignTask(loggedUser, taskId, params) this.outcomes.add(outcome) return outcome.getTask() } @@ -964,7 +967,8 @@ class ActionDelegate { Task cancelTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - return addTaskOutcomeAndReturnTask(taskService.cancelTask(ActorTransformer.toLoggedUser(user), taskId, params)) + LoggedUser loggedUser = user instanceof LoggedUser ? (LoggedUser) user : ActorTransformer.toLoggedUser(user) + return addTaskOutcomeAndReturnTask(taskService.cancelTask(loggedUser, taskId, params)) } Task cancelTask(Task task, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { @@ -982,7 +986,8 @@ class ActionDelegate { void finishTask(String transitionId, Case aCase = useCase, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { String taskId = getTaskId(transitionId, aCase) - addTaskOutcomeAndReturnTask(taskService.finishTask(ActorTransformer.toLoggedUser(user), taskId, params)) + LoggedUser loggedUser = user instanceof LoggedUser ? (LoggedUser) user : ActorTransformer.toLoggedUser(user) + addTaskOutcomeAndReturnTask(taskService.finishTask(loggedUser, taskId, params)) } void finishTask(Task task, AbstractUser user = userService.loggedOrSystem, Map params = [:]) { @@ -1450,7 +1455,7 @@ class ActionDelegate { } File exportCasesToFile(List requests, String pathName, ExportDataConfig config = null, - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + LoggedUser user = userService.getLoggedOrSystem(), int pageSize = exportConfiguration.getMongoPageSize(), Locale locale = LocaleContextHolder.getLocale(), Boolean isIntersection = false) { @@ -1461,7 +1466,7 @@ class ActionDelegate { } OutputStream exportCases(List requests, File outFile, ExportDataConfig config = null, - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + LoggedUser user = userService.getLoggedOrSystem(), int pageSize = exportConfiguration.getMongoPageSize(), Locale locale = LocaleContextHolder.getLocale(), Boolean isIntersection = false) { @@ -1481,7 +1486,7 @@ class ActionDelegate { } File exportTasksToFile(List requests, String pathName, ExportDataConfig config = null, - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + LoggedUser user = userService.getLoggedOrSystem(), int pageSize = exportConfiguration.getMongoPageSize(), Locale locale = LocaleContextHolder.getLocale(), Boolean isIntersection = false) { @@ -1492,7 +1497,7 @@ class ActionDelegate { } OutputStream exportTasks(List requests, File outFile, ExportDataConfig config = null, - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + LoggedUser user = userService.getLoggedOrSystem(), int pageSize = exportConfiguration.getMongoPageSize(), Locale locale = LocaleContextHolder.getLocale(), Boolean isIntersection = false) { @@ -1513,7 +1518,7 @@ class ActionDelegate { * @param isIntersection to decide null query handling * @return page of cases * */ - Page findCasesElastic(List requests, LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + Page findCasesElastic(List requests, LoggedUser loggedUser = userService.getLoggedOrSystem(), int page = 1, int pageSize = 25, Locale locale = Locale.default, boolean isIntersection = false) { return elasticCaseService.search(requests, loggedUser, PageRequest.of(page, pageSize), locale, isIntersection) } @@ -1528,7 +1533,7 @@ class ActionDelegate { * @param isIntersection to decide null query handling * @return page of cases * */ - Page findCasesElastic(Map request, LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + Page findCasesElastic(Map request, LoggedUser loggedUser = userService.getLoggedOrSystem(), int page = 1, int pageSize = 25, Locale locale = Locale.default, boolean isIntersection = false) { List requests = Collections.singletonList(new CaseSearchRequest(request)) return findCasesElastic(requests, loggedUser, page, pageSize, locale, isIntersection) @@ -1544,7 +1549,7 @@ class ActionDelegate { * @param isIntersection to decide null query handling * @return page of cases * */ - Page findTasks(List requests, LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + Page findTasks(List requests, LoggedUser loggedUser = userService.getLoggedOrSystem(), int page = 1, int pageSize = 25, Locale locale = Locale.default, boolean isIntersection = false) { return elasticTaskService.search(requests, loggedUser, PageRequest.of(page, pageSize), locale, isIntersection) } @@ -1559,7 +1564,7 @@ class ActionDelegate { * @param isIntersection to decide null query handling * @return page of cases * */ - Page findTasks(Map request, LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + Page findTasks(Map request, LoggedUser loggedUser = userService.getLoggedOrSystem(), int page = 1, int pageSize = 25, Locale locale = Locale.default, boolean isIntersection = false) { List requests = Collections.singletonList(new ElasticTaskSearchRequest(request)) return findTasks(requests, loggedUser, page, pageSize, locale, isIntersection) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/AuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/AuthorizationService.java index 260f705d5e4..cf210345556 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/AuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/AuthorizationService.java @@ -13,8 +13,6 @@ public class AuthorizationService implements IAuthorizationService { @Override public boolean hasAuthority(String authority) { - // TODO: impersonation -// LoggedUser loggedUser = userService.getLoggedUserFromContext().getSelfOrImpersonated(); LoggedUser loggedUser = userService.getLoggedUserFromContext(); return loggedUser.getAuthoritySet().stream().anyMatch(it -> it.getAuthority().equals(authority)); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/UserResourceHelperService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/UserResourceHelperService.java deleted file mode 100644 index de08201760a..00000000000 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/UserResourceHelperService.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.netgrif.application.engine.auth.service; - -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; -import com.netgrif.application.engine.auth.service.interfaces.IUserResourceHelperService; -import com.netgrif.application.engine.auth.web.responsebodies.User; -import com.netgrif.application.engine.auth.web.responsebodies.UserResource; -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Locale; - -@Slf4j -@Service -public class UserResourceHelperService implements IUserResourceHelperService { - - @Autowired - private UserService userService; - - @Autowired - private UserFactory userFactory; - - @Autowired - private IImpersonationService impersonationService; - - @Override - public UserResource getResource(LoggedUser loggedUser, Locale locale, boolean small) { - AbstractUser user = userService.findById(loggedUser.getStringId(), null); - // TODO: impersonation -// User result = loggedUser.isImpersonating() ? -// getLocalisedUser(user, getImpersonated(loggedUser, small), locale) : -// getLocalisedUser(user, locale); - User result = getLocalisedUser(user, locale); - return new UserResource(result, "profile"); - } - - @Override - public User getLocalisedUser(AbstractUser user, AbstractUser impersonated, Locale locale) { - User localisedUser = getLocalisedUser(user, locale); - User impersonatedUser = userFactory.getUser(impersonated, locale); - localisedUser.setImpersonated(impersonatedUser); - return localisedUser; - } - - @Override - public User getLocalisedUser(AbstractUser user, Locale locale) { - return userFactory.getUser(user, locale); - } - - // TODO: for impersonation -// protected AbstractUser getImpersonated(LoggedUser loggedUser, boolean small) { -// AbstractUser impersonated = userService.findById(loggedUser.getImpersonated().getId(), null); -// return impersonationService.reloadImpersonatedUserRoles(impersonated, loggedUser.getId()); -// } -} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserResourceHelperService.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserResourceHelperService.java deleted file mode 100644 index f82c5efe437..00000000000 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/service/interfaces/IUserResourceHelperService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.netgrif.application.engine.auth.service.interfaces; - -import com.netgrif.application.engine.auth.web.responsebodies.User; -import com.netgrif.application.engine.auth.web.responsebodies.UserResource; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; - -import java.util.Locale; - -public interface IUserResourceHelperService { - UserResource getResource(LoggedUser loggedUser, Locale locale, boolean small); - - User getLocalisedUser(AbstractUser user, AbstractUser impersonated, Locale locale); - - User getLocalisedUser(AbstractUser user, Locale locale); -} diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/AuthenticationController.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/AuthenticationController.java index e1f1c07b70d..7debf2ecbda 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/AuthenticationController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/AuthenticationController.java @@ -1,19 +1,19 @@ package com.netgrif.application.engine.auth.web; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.configuration.properties.SecurityConfigurationProperties; -import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.InvalidUserTokenException; -import com.netgrif.application.engine.auth.service.interfaces.IRegistrationService; +import com.netgrif.application.engine.auth.service.UserFactory; import com.netgrif.application.engine.auth.service.UserService; +import com.netgrif.application.engine.auth.service.interfaces.IRegistrationService; import com.netgrif.application.engine.auth.web.requestbodies.ChangePasswordRequest; import com.netgrif.application.engine.auth.web.requestbodies.NewUserRequest; import com.netgrif.application.engine.auth.web.requestbodies.RegistrationRequest; -import com.netgrif.application.engine.auth.service.UserFactory; +import com.netgrif.application.engine.configuration.properties.SecurityConfigurationProperties; import com.netgrif.application.engine.mail.interfaces.IMailAttemptService; import com.netgrif.application.engine.mail.interfaces.IMailService; +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.security.service.ISecurityContextService; +import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource; import freemarker.template.TemplateException; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -33,7 +33,9 @@ import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Base64; +import java.util.Locale; +import java.util.Optional; @Slf4j @RestController @@ -91,8 +93,6 @@ public MessageResource signup(@RequestBody RegistrationRequest regRequest) { @PostMapping(value = "/invite", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaTypes.HAL_JSON_VALUE) public MessageResource invite(@RequestBody NewUserRequest newUserRequest, Authentication auth) { try { - // TODO: impersonation -// if (!serverAuthProperties.isOpenRegistration() && (auth == null || !((LoggedUser) auth.getPrincipal()).getSelfOrImpersonated().isAdmin())) { if (!serverAuthProperties.isOpenRegistration() && (auth == null || !((LoggedUser) auth.getPrincipal()).isAdmin())) { return MessageResource.errorMessage("Only admin can invite new users!"); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java index e03c3f168ef..1e981cf43d5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/auth/web/UserController.java @@ -155,9 +155,7 @@ public ResponseEntity> search(@RequestBody UserSearchRequestBody quer @GetMapping(value = "/{realmId}/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity getUser(@PathVariable("realmId") String realmId, @PathVariable("id") String userId, Locale locale) { LoggedUser actualUser = userService.getLoggedUserFromContext(); - // TODO: impersonation -// LoggedUser loggedUser = actualUser.getSelfOrImpersonated(); - LoggedUser loggedUser = actualUser; + LoggedUser loggedUser = actualUser.getSelfOrImpersonated(); if (!loggedUser.isAdmin() && !Objects.equals(loggedUser.getId(), userId)) { log.info("User [{}] trying to get another user with ID [{}]", actualUser.getUsername(), userId); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); @@ -229,7 +227,7 @@ public ResponseEntity assignRolesToUser(@PathVariable("realmId" } } -// + // // @PreAuthorize("@authorizationService.hasAuthority('ADMIN')") // @Operation(summary = "Assign negative roles to the user", description = "Caller must have the ADMIN role", security = {@SecurityRequirement(name = "X-Auth-Token")}) // @PutMapping(value = "/{realmId}/{id}/negativeRole", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/configuration/NaeSecurityConfiguration.java b/application-engine/src/main/java/com/netgrif/application/engine/configuration/NaeSecurityConfiguration.java index 17a5affe1af..0f54661fb1b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/configuration/NaeSecurityConfiguration.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/configuration/NaeSecurityConfiguration.java @@ -1,16 +1,16 @@ package com.netgrif.application.engine.configuration; -import com.netgrif.application.engine.configuration.properties.SecurityConfigurationProperties; -import com.netgrif.application.engine.objects.auth.domain.Authority; +import com.netgrif.application.engine.auth.repository.ImpersonatorRepository; import com.netgrif.application.engine.auth.service.AuthorityService; import com.netgrif.application.engine.auth.service.UserService; +import com.netgrif.application.engine.configuration.properties.SecurityConfigurationProperties; import com.netgrif.application.engine.configuration.security.ImpersonationRequestFilter; import com.netgrif.application.engine.configuration.security.PublicAuthenticationFilter; import com.netgrif.application.engine.configuration.security.RestAuthenticationEntryPoint; import com.netgrif.application.engine.configuration.security.SecurityContextFilter; import com.netgrif.application.engine.configuration.security.filter.HostValidationRequestFilter; import com.netgrif.application.engine.configuration.security.jwt.IJwtService; -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService; +import com.netgrif.application.engine.objects.auth.domain.Authority; import com.netgrif.application.engine.security.service.ISecurityContextService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -37,7 +37,6 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.ForwardedHeaderFilter; -import java.util.HashSet; import java.util.List; import static org.springframework.http.HttpMethod.OPTIONS; @@ -75,7 +74,7 @@ public class NaeSecurityConfiguration extends AbstractSecurityConfiguration { private ISecurityContextService securityContextService; @Autowired - protected IImpersonationService impersonationService; + protected ImpersonatorRepository impersonatorRepository; @Autowired private List authenticationProviders; @@ -195,6 +194,6 @@ private HostValidationRequestFilter hostValidationRequestFilter() { } private ImpersonationRequestFilter impersonationRequestFilter() { - return new ImpersonationRequestFilter(impersonationService); + return new ImpersonationRequestFilter(impersonatorRepository); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/configuration/SessionRegistryConfiguration.java b/application-engine/src/main/java/com/netgrif/application/engine/configuration/SessionRegistryConfiguration.java index 4e62ffdb6b3..de331e0eda0 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/configuration/SessionRegistryConfiguration.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/configuration/SessionRegistryConfiguration.java @@ -1,6 +1,6 @@ package com.netgrif.application.engine.configuration; -import com.netgrif.application.engine.configuration.properties.ImpersonationConfigurationProperties; +import com.netgrif.application.engine.adapter.spring.configuration.ImpersonationConfigurationProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/AuthenticationService.java b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/AuthenticationService.java index 8d9bbafb2c3..0606532acc3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/AuthenticationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/AuthenticationService.java @@ -1,16 +1,13 @@ package com.netgrif.application.engine.configuration.security; +import com.netgrif.application.engine.auth.repository.ImpersonatorRepository; import com.netgrif.application.engine.configuration.properties.SecurityConfigurationProperties; -import com.netgrif.application.engine.configuration.properties.ServerConfigurationProperties; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.configuration.security.interfaces.IAuthenticationService; -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import jakarta.servlet.http.HttpServletRequest; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationListener; import org.springframework.context.event.EventListener; import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; @@ -32,13 +29,13 @@ public class AuthenticationService implements IAuthenticationService, Applicatio private ConcurrentMap cache; - private final IImpersonationService impersonationService; + private final ImpersonatorRepository impersonatorRepository; private final SecurityConfigurationProperties securityConfigurationProperties; - public AuthenticationService(IImpersonationService impersonationService, + public AuthenticationService(ImpersonatorRepository impersonatorRepository, SecurityConfigurationProperties securityConfigurationProperties) { super(); - this.impersonationService = impersonationService; + this.impersonatorRepository = impersonatorRepository; this.securityConfigurationProperties = securityConfigurationProperties; cache = new ConcurrentHashMap<>(); } @@ -102,7 +99,7 @@ private void timeout(String key) { protected void resolveImpersonatorOnLogin(Object principal) { try { if (principal instanceof LoggedUser) { - impersonationService.removeImpersonator(((LoggedUser) principal).getStringId()); + impersonatorRepository.deleteById(((LoggedUser) principal).getStringId()); } } catch (Exception e) { log.warn("Failed to resolve impersonator " + principal, e); @@ -111,10 +108,11 @@ protected void resolveImpersonatorOnLogin(Object principal) { protected void resolveImpersonatorOnLogout(Object principal) { try { - // TODO: impersonation -// if (principal instanceof LoggedUser && ((LoggedUser) principal).isImpersonating()) { -// impersonationService.onSessionDestroy((LoggedUser) principal); -// } + if (principal instanceof LoggedUser && ((LoggedUser) principal).isImpersonating()) { + impersonatorRepository.deleteById(((LoggedUser) principal).getStringId()); + // TODO: event? +// publisher.publishEvent(new ImpersonationEvent(impersonator, impersonator.getImpersonated(), RunPhase.STOP)); + } } catch (Exception e) { log.warn("Failed to resolve impersonator " + principal, e); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java index 127aed8d690..40e465ad243 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.java @@ -1,9 +1,12 @@ package com.netgrif.application.engine.configuration.security; +import com.netgrif.application.engine.auth.domain.Impersonator; +import com.netgrif.application.engine.auth.repository.ImpersonatorRepository; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; -import com.netgrif.application.engine.impersonation.domain.Impersonator; -import com.netgrif.application.engine.impersonation.domain.repository.ImpersonatorRepository; -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; @@ -11,10 +14,6 @@ import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.filter.OncePerRequestFilter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; import java.util.Optional; @@ -23,10 +22,10 @@ public class ImpersonationRequestFilter extends OncePerRequestFilter { public static final Logger log = LoggerFactory.getLogger(ImpersonationRequestFilter.class); - private final IImpersonationService impersonationService; + private final ImpersonatorRepository impersonatorRepository; - public ImpersonationRequestFilter(IImpersonationService impersonationService) { - this.impersonationService = impersonationService; + public ImpersonationRequestFilter(ImpersonatorRepository impersonatorRepository) { + this.impersonatorRepository = impersonatorRepository; } @Override @@ -46,15 +45,14 @@ public void doFilterInternal(HttpServletRequest servletRequest, HttpServletRespo protected void handleImpersonator(LoggedUser loggedUser, HttpServletRequest servletRequest, HttpServletResponse servletResponse) { try { - // TODO: impersonation -// if (!loggedUser.isImpersonating()) { -// return; -// } -// Optional imp = impersonationService.findImpersonator(loggedUser.getId()); -// if (loggedUser.isImpersonating() && (imp.isEmpty() || !isValid(imp.get()))) { -// imp.ifPresent(imper -> impersonationService.removeImpersonator(loggedUser.getId())); -// logout(servletRequest, servletResponse); -// } + if (!loggedUser.isImpersonating()) { + return; + } + Optional imp = impersonatorRepository.findById(loggedUser.getStringId()); + if (loggedUser.isImpersonating() && (imp.isEmpty() || !isValid(imp.get()))) { + imp.ifPresent(imper -> impersonatorRepository.deleteById(loggedUser.getStringId())); + logout(servletRequest, servletResponse); + } } catch (Exception e) { log.error("ImpersonationRequestFilter error " + e.getMessage(), e); } @@ -63,7 +61,8 @@ protected void handleImpersonator(LoggedUser loggedUser, HttpServletRequest serv protected void handleImpersonated(LoggedUser loggedUser, HttpServletRequest servletRequest) { try { log.debug("Filtering request " + servletRequest.getRequestURI() + ", " + loggedUser.getUsername()); - impersonationService.removeImpersonatorByImpersonated(loggedUser.getStringId()); + Optional impersonatorObject = impersonatorRepository.findByImpersonatedId(loggedUser.getStringId()); + impersonatorObject.ifPresent(impersonatorRepository::delete); } catch (Exception e) { log.error("Failed to resolve impersonators for " + loggedUser.getUsername() + ", " + e.getMessage(), e); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java index f7aba77b5f7..ba82f79314f 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseService.java @@ -4,26 +4,26 @@ import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.mapping.FieldType; import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery; +import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders; import co.elastic.clients.elasticsearch._types.query_dsl.QueryStringQuery; import co.elastic.clients.elasticsearch._types.query_dsl.TermsQueryField; -import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders; import co.elastic.clients.elasticsearch.core.bulk.BulkOperation; import com.netgrif.application.engine.configuration.properties.DataConfigurationProperties; import com.netgrif.application.engine.elastic.domain.BulkOperationWrapper; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; -import com.netgrif.application.engine.objects.elastic.domain.ElasticCase; import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository; import com.netgrif.application.engine.elastic.domain.ElasticQueryConstants; import com.netgrif.application.engine.elastic.service.executors.Executor; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCasePrioritySearch; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService; import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.objects.elastic.domain.ElasticCase; import com.netgrif.application.engine.objects.event.events.workflow.IndexCaseEvent; import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch; +import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference; import com.netgrif.application.engine.utils.FullPageRequest; -import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import jakarta.annotation.PreDestroy; import org.slf4j.Logger; @@ -37,7 +37,7 @@ import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.Order; import org.springframework.stereotype.Service; import java.util.*; @@ -132,11 +132,11 @@ public Page search(List requests, LoggedUser user, Page throw new IllegalArgumentException("Request can not be null!"); } log.debug("Searching for query with logged user [{}]", user.getId()); - // TODO: impersonation -// LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = user; // pageable = resolveUnmappedSortAttributes(pageable); - NativeQuery query = buildQuery(requests, loggedOrImpersonated, pageable, locale, isIntersection); + if (user.isProcessAccessDeny()) { + return new PageImpl<>(Collections.emptyList(), pageable, 0); + } + NativeQuery query = buildQuery(requests, user, pageable, locale, isIntersection); List casePage; long total; if (query != null) { @@ -158,11 +158,11 @@ public long count(List requests, LoggedUser user, Locale loca if (requests == null) { throw new IllegalArgumentException("Request can not be null!"); } + if (user.isProcessAccessDeny()) { + return 0; + } - // TODO: impersonation -// LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = user; - NativeQuery query = buildQuery(requests, loggedOrImpersonated, new FullPageRequest(), locale, isIntersection); + NativeQuery query = buildQuery(requests, user, new FullPageRequest(), locale, isIntersection); if (query != null) { return template.count(query, com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticCase.class); } else { @@ -171,7 +171,7 @@ public long count(List requests, LoggedUser user, Locale loca } protected NativeQuery buildQuery(List requests, LoggedUser user, Pageable pageable, Locale locale, Boolean isIntersection) { - List singleQueries = requests.stream().map(request -> buildSingleQuery(request, user, locale)).collect(Collectors.toList()); + List singleQueries = requests.stream().map(request -> buildSingleQuery(request, user.getSelfOrImpersonated(), locale)).collect(Collectors.toList()); if (isIntersection && !singleQueries.stream().allMatch(Objects::nonNull)) { // one of the queries evaluates to empty set => the entire result is an empty set @@ -186,6 +186,10 @@ protected NativeQuery buildQuery(List requests, LoggedUser us BinaryOperator reductionOperation = isIntersection ? (a, b) -> a.must(b.build()._toQuery()) : (a, b) -> a.should(b.build()._toQuery()); BoolQuery.Builder query = singleQueries.stream().reduce(new BoolQuery.Builder(), reductionOperation); + BoolQuery.Builder impersonatedProcessesQuery = buildAllowedProcessesQuery(user); + if (impersonatedProcessesQuery != null) { + query.filter(impersonatedProcessesQuery.build()._toQuery()); + } NativeQueryBuilder builder = new NativeQueryBuilder() .withQuery(query.build()._toQuery()) @@ -261,6 +265,35 @@ protected void buildPetriNetQuery(CaseSearchRequest request, LoggedUser user, Bo query.filter(petriNetQuery.build()._toQuery()); } + /** + * + * + * @param loggedUser + * @return Method return true if process access is denied (impersonated process list is empty and process allowing flag is set to true) + */ + protected BoolQuery.Builder buildAllowedProcessesQuery(LoggedUser loggedUser) { + if (loggedUser.isAdmin() || !loggedUser.isImpersonating()) { + return null; + } + if (loggedUser.isProcessAccessDeny()) { + return null; + } + if (loggedUser.getImpersonatedProcesses() == null || loggedUser.getImpersonatedProcesses().isEmpty()) { + return null; + } + TermsQueryField identifiers = new TermsQueryField.Builder() + .value(loggedUser.getImpersonatedProcesses().stream().map(FieldValue::of).collect(Collectors.toList())) + .build(); + + BoolQuery.Builder petriNetQuery = new BoolQuery.Builder(); + if (loggedUser.isImpersonatedProcessesListAllowing()) { + petriNetQuery.should(QueryBuilders.terms(term -> term.field("processIdentifier").terms(identifiers))); + } else { + petriNetQuery.mustNot(QueryBuilders.terms(term -> term.field("processIdentifier").terms(identifiers))); + } + return petriNetQuery; + } + /** *
      * {
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java
index c64d947fe6a..2fbb1d44f1b 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticPetriNetService.java
@@ -112,10 +112,7 @@ public Page search(PetriNetSearch requests, LoggedUser user,
             throw new IllegalArgumentException("Request can not be null!");
         }
         log.debug("Searching for PetriNet query with logged user [{}]", user.getId());
-        // TODO: impersonation
-//        LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated();
-        LoggedUser loggedOrImpersonated = user;
-        NativeQuery query = buildQuery(requests, loggedOrImpersonated, pageable, locale, isIntersection);
+        NativeQuery query = buildQuery(requests, user, pageable, locale, isIntersection);
         List netPage;
         long total;
         if (query != null) {
@@ -161,8 +158,9 @@ protected BoolQuery.Builder buildSingleQuery(PetriNetSearch request, LoggedUser
         BoolQuery.Builder query = new BoolQuery.Builder();
 
         buildFullTextQuery(request, query);
-        boolean resultAlwaysEmpty = buildGroupQuery(request, user, locale, query);
-        if (resultAlwaysEmpty) {
+        boolean impersonatedAccessDenied = buildImpersonatedProcessesQuery(user, query);
+        boolean resultAlwaysEmpty = buildGroupQuery(request, user.getSelfOrImpersonated(), locale, query);
+        if (resultAlwaysEmpty || impersonatedAccessDenied) {
             return null;
         }
         return query;
@@ -202,4 +200,28 @@ protected boolean buildGroupQuery(PetriNetSearch request, LoggedUser user, Local
         query.filter(groupQuery.build()._toQuery());
         return false;
     }
+
+    protected boolean buildImpersonatedProcessesQuery(LoggedUser loggedUser, BoolQuery.Builder query) {
+        if (loggedUser.isAdmin() || !loggedUser.isImpersonating()) {
+            return false;
+        }
+        if (loggedUser.isProcessAccessDeny()) {
+            return true;
+        }
+        if (loggedUser.getImpersonatedProcesses() == null || loggedUser.getImpersonatedProcesses().isEmpty()) {
+            return false;
+        }
+        BoolQuery.Builder impersonatedProcessesQuery = new BoolQuery.Builder();
+        if (loggedUser.isImpersonatedProcessesListAllowing()) {
+            loggedUser.getImpersonatedProcesses().stream()
+                    .map(processIdentifier -> termQuery("identifier", processIdentifier))
+                    .forEach(termQuery -> impersonatedProcessesQuery.should(termQuery._toQuery()));
+        } else {
+            loggedUser.getImpersonatedProcesses().stream()
+                    .map(processIdentifier -> termQuery("identifier", processIdentifier))
+                    .forEach(termQuery -> impersonatedProcessesQuery.mustNot(termQuery._toQuery()));
+        }
+        query.filter(impersonatedProcessesQuery.build()._toQuery());
+        return false;
+    }
 }
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java
index 6d554236b6a..57f9ba08ca7 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java
@@ -4,28 +4,26 @@
 import co.elastic.clients.elasticsearch._types.query_dsl.*;
 import com.google.common.collect.ImmutableList;
 import com.netgrif.application.engine.configuration.properties.DataConfigurationProperties;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.objects.elastic.domain.ElasticJob;
 import com.netgrif.application.engine.elastic.domain.ElasticQueryConstants;
-import com.netgrif.application.engine.objects.elastic.domain.ElasticTask;
 import com.netgrif.application.engine.elastic.domain.ElasticTaskJob;
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService;
 import com.netgrif.application.engine.elastic.web.requestbodies.ElasticTaskSearchRequest;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
+import com.netgrif.application.engine.objects.elastic.domain.ElasticJob;
+import com.netgrif.application.engine.objects.elastic.domain.ElasticTask;
 import com.netgrif.application.engine.objects.event.events.task.IndexTaskEvent;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch;
+import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
+import com.netgrif.application.engine.objects.workflow.domain.Task;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
 import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference;
 import com.netgrif.application.engine.utils.FullPageRequest;
-import com.netgrif.application.engine.objects.workflow.domain.Task;
 import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
 import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest;
-import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.PetriNet;
 import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.TaskSearchCaseRequest;
-import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.domain.Page;
@@ -42,7 +40,6 @@
 
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.function.BinaryOperator;
 import java.util.stream.Collectors;
@@ -141,8 +138,9 @@ public void indexNow(ElasticTask task) {
 
     @Override
     public Page search(List requests, LoggedUser user, Pageable pageable, Locale locale, Boolean isIntersection) {
-        // TODO: impersonation
-//        NativeQuery query = buildQuery(requests, user.getSelfOrImpersonated(), pageable, locale, isIntersection);
+        if (user.isProcessAccessDeny()) {
+            return new PageImpl<>(Collections.emptyList(), pageable, 0);
+        }
         NativeQuery query = buildQuery(requests, user, pageable, locale, isIntersection);
         List taskPage;
         long total;
@@ -161,8 +159,9 @@ public Page search(List requests, LoggedUser use
 
     @Override
     public long count(List requests, LoggedUser user, Locale locale, Boolean isIntersection) {
-        // TODO: impersonation
-//        NativeQuery query = buildQuery(requests, user.getSelfOrImpersonated(), new FullPageRequest(), locale, isIntersection);
+        if (user.isProcessAccessDeny()) {
+            return 0;
+        }
         NativeQuery query = buildQuery(requests, user, new FullPageRequest(), locale, isIntersection);
         if (query != null) {
             return template.count(query, com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticTask.class);
@@ -172,7 +171,7 @@ public long count(List requests, LoggedUser user, Loca
     }
 
     protected NativeQuery buildQuery(List requests, LoggedUser user, Pageable pageable, Locale locale, Boolean isIntersection) {
-        List singleQueries = requests.stream().map(request -> buildSingleQuery(request, user, locale)).collect(Collectors.toList());
+        List singleQueries = requests.stream().map(request -> buildSingleQuery(request, user.getSelfOrImpersonated(), locale)).collect(Collectors.toList());
 
         if (isIntersection && !singleQueries.stream().allMatch(Objects::nonNull)) {
             // one of the queries evaluates to empty set => the entire result is an empty set
@@ -187,6 +186,10 @@ protected NativeQuery buildQuery(List requests, Logged
 
         BinaryOperator reductionOperation = isIntersection ? (a, b) -> a.must(b.build()._toQuery()) : (a, b) -> a.should(b.build()._toQuery());
         BoolQuery.Builder query = singleQueries.stream().reduce(new BoolQuery.Builder(), reductionOperation);
+        BoolQuery.Builder impersonatedProcessesQuery = buildAllowedProcessesQuery(user);
+        if (impersonatedProcessesQuery != null) {
+            query.filter(impersonatedProcessesQuery.build()._toQuery());
+        }
 
         NativeQueryBuilder builder = new NativeQueryBuilder();
         return builder
@@ -211,6 +214,7 @@ protected BoolQuery.Builder buildSingleQuery(ElasticTaskSearchRequest request, L
         buildTransitionQuery(request, query);
         buildTagsQuery(request, query);
         buildStringQuery(request, query, user);
+        // TODO: build query for impersonation processes
         boolean resultAlwaysEmpty = buildGroupQuery(request, user, locale, query);
 
         if (resultAlwaysEmpty)
@@ -463,4 +467,27 @@ public boolean buildGroupQuery(TaskSearchRequest request, LoggedUser user, Local
 
         return false;
     }
+
+    protected BoolQuery.Builder buildAllowedProcessesQuery(LoggedUser loggedUser) {
+        if (loggedUser.isAdmin() || !loggedUser.isImpersonating()) {
+            return null;
+        }
+        if (loggedUser.isProcessAccessDeny()) {
+            return null;
+        }
+        if (loggedUser.getImpersonatedProcesses() == null || loggedUser.getImpersonatedProcesses().isEmpty()) {
+            return null;
+        }
+        TermsQueryField identifiers = new TermsQueryField.Builder()
+                .value(loggedUser.getImpersonatedProcesses().stream().map(FieldValue::of).collect(Collectors.toList()))
+                .build();
+
+        BoolQuery.Builder petriNetQuery = new BoolQuery.Builder();
+        if (loggedUser.isImpersonatedProcessesListAllowing()) {
+            petriNetQuery.should(QueryBuilders.terms(term -> term.field("processIdentifier").terms(identifiers)));
+        } else {
+            petriNetQuery.mustNot(QueryBuilders.terms(term -> term.field("processIdentifier").terms(identifiers)));
+        }
+        return petriNetQuery;
+    }
 }
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/web/ElasticController.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/web/ElasticController.java
index 5cc48601259..2dd26b3f523 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/web/ElasticController.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/web/ElasticController.java
@@ -1,10 +1,10 @@
 package com.netgrif.application.engine.elastic.web;
 
 import com.netgrif.application.engine.configuration.properties.DataConfigurationProperties;
+import com.netgrif.application.engine.elastic.service.ReindexingTask;
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticIndexService;
 import com.netgrif.application.engine.elastic.web.requestbodies.IndexParams;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.elastic.service.ReindexingTask;
 import com.netgrif.application.engine.workflow.service.CaseSearchService;
 import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
 import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource;
@@ -18,7 +18,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.hateoas.MediaTypes;
 import org.springframework.http.MediaType;
@@ -102,8 +101,10 @@ public MessageResource reindex(@RequestBody Map searchBody, Auth
 
                 for (int page = 0; page < numOfPages; page++) {
                     log.info("Indexing page {}", page + 1);
-                    Predicate predicate = searchService.buildQuery(searchBody, user, locale);
-                    reindexingTask.forceReindexPage(predicate, page, numOfPages);
+                    if (!user.isProcessAccessDeny()) {
+                        Predicate predicate = searchService.buildQuery(searchBody, user, locale);
+                        reindexingTask.forceReindexPage(predicate, page, numOfPages);
+                    }
                 }
             }
 
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java
index fb56f44eb97..d5aec9c96b0 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/export/service/ExportService.java
@@ -1,7 +1,5 @@
 package com.netgrif.application.engine.export.service;
 
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.auth.service.UserService;
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService;
@@ -10,6 +8,7 @@
 import com.netgrif.application.engine.export.configuration.ExportConfiguration;
 import com.netgrif.application.engine.export.domain.ExportDataConfig;
 import com.netgrif.application.engine.export.service.interfaces.IExportService;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.*;
 import com.netgrif.application.engine.objects.workflow.domain.Case;
@@ -102,12 +101,12 @@ public OutputStream fillCsvCaseData(Predicate predicate, File outFile, ExportDat
 
     @Override
     public OutputStream fillCsvCaseData(List requests, File outFile) throws FileNotFoundException {
-        return fillCsvCaseData(requests, outFile, null, ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
+        return fillCsvCaseData(requests, outFile, null, userService.getLoggedOrSystem(), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
     }
 
     @Override
     public OutputStream fillCsvCaseData(List requests, File outFile, ExportDataConfig config) throws FileNotFoundException {
-        return fillCsvCaseData(requests, outFile, config,  ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
+        return fillCsvCaseData(requests, outFile, config, userService.getLoggedOrSystem(), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
     }
 
     @Override
@@ -159,12 +158,12 @@ public OutputStream buildCaseCsv(List exportCases, ExportDataConfig config
 
     @Override
     public OutputStream fillCsvTaskData(List requests, File outFile) throws FileNotFoundException {
-        return fillCsvTaskData(requests, outFile, null,  ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
+        return fillCsvTaskData(requests, outFile, null, userService.getLoggedOrSystem(), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
     }
 
     @Override
     public OutputStream fillCsvTaskData(List requests, File outFile, ExportDataConfig config) throws FileNotFoundException {
-        return fillCsvTaskData(requests, outFile, config,  ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
+        return fillCsvTaskData(requests, outFile, config, userService.getLoggedOrSystem(), exportConfiguration.getMongoPageSize(), LocaleContextHolder.getLocale(), false);
     }
 
     @Override
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/IllegalImpersonationAttemptException.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/IllegalImpersonationAttemptException.java
deleted file mode 100644
index c75d0aebaf0..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/IllegalImpersonationAttemptException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.netgrif.application.engine.impersonation.exceptions;
-
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-
-public class IllegalImpersonationAttemptException extends Exception {
-
-    public IllegalImpersonationAttemptException(LoggedUser loggedUser, String id) {
-        super(loggedUser.getName() + " cannot impersonate user or config with ID " + id);
-    }
-
-    public IllegalImpersonationAttemptException(String message) {
-        super(message);
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/ImpersonatedUserHasSessionException.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/ImpersonatedUserHasSessionException.java
deleted file mode 100644
index 3f28bf0ff78..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/exceptions/ImpersonatedUserHasSessionException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.netgrif.application.engine.impersonation.exceptions;
-
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import lombok.Getter;
-
-public class ImpersonatedUserHasSessionException extends Exception {
-
-    @Getter
-    private final boolean isImpersonated;
-
-    public ImpersonatedUserHasSessionException(LoggedUser impersonatedLogged, boolean isImpersonated) {
-        super(impersonatedLogged.getName() + " has an existing session!");
-        this.isImpersonated = isImpersonated;
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationAuthorizationService.java
deleted file mode 100644
index 94b492f20b4..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationAuthorizationService.java
+++ /dev/null
@@ -1,207 +0,0 @@
-package com.netgrif.application.engine.impersonation.service;
-
-import com.netgrif.application.engine.configuration.properties.ImpersonationConfigurationProperties;
-import com.netgrif.application.engine.objects.auth.domain.Authority;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
-import com.netgrif.application.engine.auth.service.AuthorityService;
-import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
-import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationAuthorizationService;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
-import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue;
-import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-import com.netgrif.application.engine.objects.workflow.domain.DataField;
-import com.netgrif.application.engine.utils.DateUtils;
-import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.*;
-import java.util.stream.Collectors;
-
-import static com.netgrif.application.engine.startup.runner.ImpersonationRunner.IMPERSONATION_CONFIG_PETRI_NET_IDENTIFIER;
-
-@Service
-public class ImpersonationAuthorizationService implements IImpersonationAuthorizationService {
-
-    @Autowired
-    protected ImpersonationConfigurationProperties properties;
-
-    @Autowired
-    protected UserService userService;
-
-    @Autowired
-    protected IElasticCaseService elasticCaseService;
-
-    @Autowired
-    protected AuthorityService authorityService;
-
-    @Autowired
-    protected IWorkflowService workflowService;
-
-    @Autowired
-    protected ProcessRoleService processRoleService;
-
-    @Override
-    public Page getConfiguredImpersonationUsers(String query, LoggedUser impersonator, Pageable pageable) {
-        if (impersonator.isAdmin()) {
-            return userService.searchAllCoMembers(query, null, null, impersonator, pageable);
-
-        } else {
-            Page cases = searchConfigs(impersonator.getStringId(), pageable);
-            List users = cases.getContent().stream()
-                    .map(c -> ((UserFieldValue) c.getDataSet().get("impersonated").getValue()).getId())
-                    .distinct()
-                    .map(id -> userService.findById(id, null))
-                    .collect(Collectors.toList());
-            return new PageImpl<>(users, pageable, cases.getTotalElements());
-        }
-    }
-
-    @Override
-    public boolean canImpersonate(LoggedUser impersonator, String configId) {
-        Case config = getConfig(configId);
-        return isValidAndContainsUser(config, impersonator.getStringId());
-    }
-
-    @Override
-    public boolean canImpersonateUser(LoggedUser impersonator, String userId) {
-        AbstractUser impersonated = userService.findById(userId, null);
-        return impersonator.isAdmin() || !searchConfigs(impersonator.getStringId(), impersonated.getStringId()).isEmpty();
-    }
-
-    @Override
-    public Page searchConfigs(String impersonatorId, Pageable pageable) {
-        return findCases(makeRequest(impersonatorId, null), pageable);
-    }
-
-    @Override
-    public List searchConfigs(String impersonatorId, String impersonatedId) {
-        Page cases = findCases(makeRequest(impersonatorId, impersonatedId), PageRequest.of(0, properties.getConfigsPerUser()));
-        return cases.getContent();
-    }
-
-    @Override
-    public List getAuthorities(Collection configs, AbstractUser impersonated) {
-        if (configs.isEmpty()) {
-            return new ArrayList<>();
-        }
-        Set authIds = extractSetFromField(configs, "impersonated_authorities");
-        return authorityService.findAllByIds(new ArrayList<>(authIds), Pageable.unpaged()).stream()
-                .filter(configAuth -> impersonated.getAuthoritySet().stream().anyMatch(userAuth -> userAuth.getStringId().equals(configAuth.getStringId())))
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public List getRoles(Collection configs, AbstractUser impersonated) {
-        List impersonatedRoles = new ArrayList<>();
-        impersonatedRoles.add(processRoleService.getDefaultRole());
-        if (configs.isEmpty()) {
-            return impersonatedRoles;
-        }
-        Set roleIds = extractSetFromField(configs, "impersonated_roles");
-        impersonatedRoles.addAll((processRoleService.findByIds(roleIds)).stream()
-                .filter(configRole -> impersonated.getProcessRoles().stream().anyMatch(userRole -> userRole.getStringId().equals(configRole.getStringId())))
-                .toList());
-        return impersonatedRoles;
-    }
-
-    @Override
-    public Case getConfig(String configId) {
-        return workflowService.findOne(configId);
-    }
-
-    @Override
-    public String getImpersonatedUserId(Case config) {
-        return ((UserFieldValue) config.getDataSet().get("impersonated").getValue()).getId();
-    }
-
-    @Override
-    public LocalDateTime getValidUntil(Case config) {
-        return parseTime(config, "valid_to");
-    }
-
-    protected CaseSearchRequest makeRequest(String impersonatorId, String impersonatedId) {
-        CaseSearchRequest request = new CaseSearchRequest();
-        List queries = new ArrayList<>();
-        request.process = Collections.singletonList(new CaseSearchRequest.PetriNet(IMPERSONATION_CONFIG_PETRI_NET_IDENTIFIER));
-        queries.add("(dataSet.impersonators.keyValue:" + impersonatorId + ")");
-        queries.add("(dataSet.is_active.booleanValue:true)");
-        queries.addAll(validityQueries());
-        if (impersonatedId != null) {
-            queries.add("(dataSet.impersonated.userIdValue.keyword:" + impersonatedId + ")");
-        }
-        request.query = combineQueries(queries);
-        return request;
-    }
-
-    protected List validityQueries() {
-        List queries = new ArrayList<>();
-        queries.add("((!(_exists_:dataSet.valid_from.timestampValue)) OR (dataSet.valid_from.timestampValue:<" + DateUtils.localDateTimeToDate(LocalDateTime.now()).getTime() + "))");
-        queries.add("((!(_exists_:dataSet.valid_to.timestampValue)) OR (dataSet.valid_to.timestampValue:>" + DateUtils.localDateTimeToDate(LocalDateTime.now()).getTime() + "))");
-        return queries;
-    }
-
-    protected String combineQueries(List queries) {
-        return "(" + String.join(" AND ", queries) + ")";
-    }
-
-    protected Page findCases(CaseSearchRequest request, Pageable pageable) {
-        return elasticCaseService.search(Collections.singletonList(request), ActorTransformer.toLoggedUser(userService.getSystem()), pageable, Locale.getDefault(), false);
-    }
-
-    protected boolean isValidAndContainsUser(Case config, String id) {
-        Object value = config.getFieldValue("impersonators");
-        if (!(value instanceof Collection)) {
-            return false;
-        }
-        LocalDateTime now = LocalDateTime.now();
-        return (((Collection) value).contains(id)) &&
-                ((Boolean) config.getFieldValue("is_active")) &&
-                validateTime(parseTime(config, "valid_from"), now) &&
-                validateTime(now, parseTime(config, "valid_to"));
-
-    }
-
-    protected boolean validateTime(LocalDateTime first, LocalDateTime second) {
-        if (first == null || second == null) {
-            return true;
-        }
-        return first.isBefore(second) || first.equals(second);
-    }
-
-    protected Set extractSetFromField(Collection cases, String fieldId) {
-        return cases.stream()
-                .map(caze -> getMultichoiceValue(caze.getDataField(fieldId)))
-                .flatMap(List::stream)
-                .collect(Collectors.toSet());
-    }
-
-    protected List getMultichoiceValue(DataField field) {
-        if (field.getValue() == null || !(field.getValue() instanceof List)) {
-            return new ArrayList<>();
-        }
-        return (List) field.getValue();
-    }
-
-    protected LocalDateTime parseTime(Case config, String field) {
-        Object val = config.getFieldValue(field);
-        if (val == null) {
-            return null;
-        }
-        if (val instanceof Date) {
-            return LocalDateTime.ofInstant(((Date) val).toInstant(), ZoneId.systemDefault());
-        }
-        return (LocalDateTime) val;
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationService.java
deleted file mode 100644
index 62a6567054f..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationService.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package com.netgrif.application.engine.impersonation.service;
-
-import com.netgrif.application.engine.adapter.spring.auth.domain.AuthorityImpl;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
-import com.netgrif.application.engine.objects.auth.domain.Authority;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.configuration.properties.ImpersonationConfigurationProperties;
-import com.netgrif.application.engine.objects.event.RunPhase;
-import com.netgrif.application.engine.objects.event.events.user.ImpersonationEvent;
-import com.netgrif.application.engine.impersonation.domain.Impersonator;
-import com.netgrif.application.engine.impersonation.domain.repository.ImpersonatorRepository;
-import com.netgrif.application.engine.impersonation.exceptions.ImpersonatedUserHasSessionException;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationAuthorizationService;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationSessionService;
-import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
-import com.netgrif.application.engine.security.service.ISecurityContextService;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-public class ImpersonationService implements IImpersonationService {
-
-    @Autowired
-    protected ImpersonationConfigurationProperties properties;
-
-    @Autowired
-    protected UserService userService;
-
-    @Autowired
-    protected ApplicationEventPublisher publisher;
-
-    @Autowired
-    protected IImpersonationSessionService sessionService;
-
-    @Autowired
-    protected ISecurityContextService securityContextService;
-
-    @Autowired
-    protected ImpersonatorRepository impersonatorRepository;
-
-    @Autowired
-    protected IImpersonationAuthorizationService impersonationAuthorizationService;
-
-    @Override
-    public LoggedUser impersonateUser(String impersonatedId) throws ImpersonatedUserHasSessionException {
-        if (!properties.isEnabled()) {
-            throw new IllegalArgumentException("Impersonation is not enabled in app properties");
-        }
-        LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser());
-        AbstractUser impersonated = userService.findById(impersonatedId, null);
-
-        List configs = impersonationAuthorizationService.searchConfigs(loggedUser.getStringId(), impersonated.getStringId());
-        LoggedUser impersonatedLogged = ActorTransformer.toLoggedUser(applyRolesAndAuthorities(impersonated, loggedUser.getStringId(), configs));
-
-        return doImpersonate(loggedUser, impersonatedLogged, configs);
-    }
-
-    @Override
-    public LoggedUser impersonateByConfig(String configId) throws ImpersonatedUserHasSessionException {
-        if (!properties.isEnabled()) {
-            throw new IllegalArgumentException("Impersonation is not enabled in app properties");
-        }
-        Case config = impersonationAuthorizationService.getConfig(configId);
-        LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser());
-        AbstractUser impersonated = userService.findById(impersonationAuthorizationService.getImpersonatedUserId(config), null);
-
-        LoggedUser impersonatedLogged = ActorTransformer.toLoggedUser(applyRolesAndAuthorities(impersonated, loggedUser.getStringId(), Collections.singletonList(config)));
-        return doImpersonate(loggedUser, impersonatedLogged, Collections.singletonList(config));
-    }
-
-    protected LoggedUser doImpersonate(LoggedUser loggedUser, LoggedUser impersonatedLogged, List configs) throws ImpersonatedUserHasSessionException {
-        if (sessionService.existsSession(impersonatedLogged.getUsername())) {
-            throw new ImpersonatedUserHasSessionException(impersonatedLogged, false);
-
-        } else if (sessionService.isImpersonated(impersonatedLogged.getStringId())) {
-            throw new ImpersonatedUserHasSessionException(impersonatedLogged, true);
-        }
-        updateImpersonatedId(loggedUser, impersonatedLogged.getStringId(), configs);
-        // TODO: impersonation
-//        loggedUser.impersonate(impersonatedLogged);
-        securityContextService.saveToken(loggedUser.getStringId());
-        securityContextService.reloadSecurityContext(loggedUser);
-        log.info(loggedUser.getName() + " has just impersonated user " + impersonatedLogged.getName());
-        publisher.publishEvent(new ImpersonationEvent(loggedUser, impersonatedLogged, RunPhase.START));
-        return loggedUser;
-    }
-
-    @Override
-    public Optional findImpersonator(String impersonatorId) {
-        return impersonatorRepository.findById(impersonatorId);
-    }
-
-    @Override
-    public void removeImpersonatorByImpersonated(String impersonatedId) {
-        impersonatorRepository.findByImpersonatedId(impersonatedId).ifPresent(impersonatorRepository::delete);
-    }
-
-    @Override
-    public void removeImpersonator(String impersonatorId) {
-        impersonatorRepository.deleteById(impersonatorId);
-    }
-
-    @Override
-    public LoggedUser endImpersonation() {
-        return endImpersonation(userService.getLoggedUserFromContext());
-    }
-
-    @Override
-    public LoggedUser endImpersonation(LoggedUser impersonator) {
-        // TODO: impersonation
-//        LoggedUser impersonated = impersonator.getImpersonated();
-        LoggedUser impersonated = impersonator;
-        removeImpersonator(impersonator.getStringId());
-        // TODO: impersonation
-//        impersonator.clearImpersonated();
-        log.info(impersonator.getName() + " has stopped impersonating user " + impersonated.getName());
-        securityContextService.saveToken(impersonator.getStringId());
-        securityContextService.reloadSecurityContext(impersonator);
-        publisher.publishEvent(new ImpersonationEvent(impersonator, impersonated, RunPhase.STOP));
-        return impersonator;
-    }
-
-    @Override
-    public void onSessionDestroy(LoggedUser impersonator) {
-        removeImpersonator(impersonator.getStringId());
-        // TODO: impersonation
-//        log.info(impersonator.getFullName() + " has logged out and stopped impersonating user " + impersonator.getImpersonated().getFullName());
-        log.info(impersonator.getName() + " has logged out and stopped impersonating user " + impersonator.getName());
-        // TODO: impersonation
-//        publisher.publishEvent(new ImpersonationEvent(impersonator, impersonator.getImpersonated(), RunPhase.STOP));
-        publisher.publishEvent(new ImpersonationEvent(impersonator, impersonator, RunPhase.STOP));
-    }
-
-    @Override
-    public AbstractUser reloadImpersonatedUserRoles(AbstractUser impersonated, String impersonatorId) {
-        Optional context = impersonatorRepository.findByImpersonatedId(impersonated.getStringId());
-        if (context.isPresent()) {
-            List configs = context.get().getConfigIds().stream()
-                    .map(id -> impersonationAuthorizationService.getConfig(id))
-                    .collect(Collectors.toList());
-            return applyRolesAndAuthorities(impersonated, impersonatorId, configs);
-        }
-        return impersonated;
-    }
-
-    @Override
-    public AbstractUser applyRolesAndAuthorities(AbstractUser impersonated, String impersonatorId, List configs) {
-        if ((Boolean) userService.findById(impersonatorId, null).getAuthoritySet().contains(new AuthorityImpl(Authority.admin))) {
-            return impersonated;
-        }
-        List authorities = impersonationAuthorizationService.getAuthorities(configs, impersonated);
-        List roles = impersonationAuthorizationService.getRoles(configs, impersonated);
-
-        impersonated.setAuthoritySet(new HashSet<>(authorities));
-        impersonated.setProcessRoles(new HashSet<>(roles));
-
-        return impersonated;
-    }
-
-    protected void updateImpersonatedId(LoggedUser loggedUser, String id, List configs) {
-        Map configTimeMap = new HashMap<>();
-        configs.forEach((config) -> configTimeMap.put(config, getConfigValidToTime(config)));
-        Optional> earliestEndingConfig = configTimeMap
-                .entrySet().stream()
-                .filter(it -> it.getValue() != null)
-                .min(Map.Entry.comparingByValue());
-        updateImpersonatedId(loggedUser, id, configs, earliestEndingConfig.map(Map.Entry::getValue).orElse(null));
-    }
-
-    protected void updateImpersonatedId(LoggedUser loggedUser, String id, List configs, LocalDateTime validUntil) {
-        removeImpersonator(loggedUser.getStringId());
-        impersonatorRepository.save(new Impersonator(loggedUser.getStringId(), id,
-                configs.stream().map(Case::getStringId).collect(Collectors.toList()),
-                LocalDateTime.now(), validUntil));
-    }
-
-    protected LocalDateTime getConfigValidToTime(Case config) {
-        LocalDateTime limitTime = null;
-        if (config != null) {
-            limitTime = impersonationAuthorizationService.getValidUntil(config);
-        }
-        return limitTime;
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationSessionService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationSessionService.java
deleted file mode 100644
index 73dbb736fd4..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/ImpersonationSessionService.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.netgrif.application.engine.impersonation.service;
-
-import com.netgrif.application.engine.impersonation.domain.repository.ImpersonatorRepository;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationSessionService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.session.FindByIndexNameSessionRepository;
-import org.springframework.session.Session;
-import org.springframework.session.security.SpringSessionBackedSessionRegistry;
-import org.springframework.stereotype.Service;
-
-import java.util.Collection;
-
-@Service
-public class ImpersonationSessionService implements IImpersonationSessionService {
-
-    protected FindByIndexNameSessionRepository sessions;
-    protected SpringSessionBackedSessionRegistry registry;
-    protected ImpersonatorRepository impersonatorRepository;
-
-    @Override
-    public boolean existsSession(String username) {
-        Collection usersSessions = this.sessions.findByPrincipalName(username).values();
-        return usersSessions.stream().anyMatch(session -> !registry.getSessionInformation(session.getId()).isExpired());
-    }
-
-    @Override
-    public boolean isImpersonated(String userId) {
-        return impersonatorRepository.findByImpersonatedId(userId).isPresent();
-    }
-
-    @Autowired
-    @Lazy
-    public void setSessions(FindByIndexNameSessionRepository sessions) {
-        this.sessions = sessions;
-    }
-
-    @Autowired
-    @Lazy
-    public void setRegistry(SpringSessionBackedSessionRegistry registry) {
-        this.registry = registry;
-    }
-
-    @Autowired
-    @Lazy
-    public void setImpersonatorRepository(ImpersonatorRepository impersonatorRepository) {
-        this.impersonatorRepository = impersonatorRepository;
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationAuthorizationService.java
deleted file mode 100644
index 9847904243c..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationAuthorizationService.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.netgrif.application.engine.impersonation.service.interfaces;
-
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.Authority;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
-import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.List;
-
-public interface IImpersonationAuthorizationService {
-
-    Page getConfiguredImpersonationUsers(String query, LoggedUser impersonator, Pageable pageable);
-
-    boolean canImpersonate(LoggedUser loggedUser, String configId);
-
-    boolean canImpersonateUser(LoggedUser impersonator, String userId);
-
-    Page searchConfigs(String impersonatorId, Pageable pageable);
-
-    List searchConfigs(String impersonatorId, String impersonatedId);
-
-    List getAuthorities(Collection configs, AbstractUser impersonated);
-
-    List getRoles(Collection configs, AbstractUser impersonated);
-
-    Case getConfig(String configId);
-
-    String getImpersonatedUserId(Case config);
-
-    LocalDateTime getValidUntil(Case config);
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationService.java
deleted file mode 100644
index e08908673b3..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.netgrif.application.engine.impersonation.service.interfaces;
-
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.impersonation.domain.Impersonator;
-import com.netgrif.application.engine.impersonation.exceptions.ImpersonatedUserHasSessionException;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-
-import java.util.List;
-import java.util.Optional;
-
-public interface IImpersonationService {
-
-    LoggedUser impersonateUser(String impersonatedId) throws ImpersonatedUserHasSessionException;
-
-    LoggedUser impersonateByConfig(String configId) throws ImpersonatedUserHasSessionException;
-
-    Optional findImpersonator(String impersonatorId);
-
-    void removeImpersonatorByImpersonated(String impersonatedId);
-
-    void removeImpersonator(String impersonatorId);
-
-    LoggedUser endImpersonation();
-
-    LoggedUser endImpersonation(LoggedUser impersonator);
-
-    void onSessionDestroy(LoggedUser impersonator);
-
-    AbstractUser reloadImpersonatedUserRoles(AbstractUser impersonated, String impersonatorId);
-
-    AbstractUser applyRolesAndAuthorities(AbstractUser impersonated, String impersonatorId, List configs);
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationSessionService.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationSessionService.java
deleted file mode 100644
index c28dc266758..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/service/interfaces/IImpersonationSessionService.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.netgrif.application.engine.impersonation.service.interfaces;
-
-public interface IImpersonationSessionService {
-    boolean existsSession(String username);
-
-    boolean isImpersonated(String userId);
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationController.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationController.java
deleted file mode 100644
index 2f2b5b189f5..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationController.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.netgrif.application.engine.impersonation.web;
-
-import com.netgrif.application.engine.auth.service.UserResourceHelperService;
-import com.netgrif.application.engine.auth.web.responsebodies.UserResourceAssembler;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
-import com.netgrif.application.engine.workflow.web.responsebodies.ResourceLinkAssembler;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.auth.web.responsebodies.UserResource;
-import com.netgrif.application.engine.impersonation.exceptions.IllegalImpersonationAttemptException;
-import com.netgrif.application.engine.impersonation.exceptions.ImpersonatedUserHasSessionException;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationAuthorizationService;
-import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService;
-import com.netgrif.application.engine.impersonation.web.requestbodies.SearchRequest;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.security.SecurityRequirement;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.web.PagedResourcesAssembler;
-import org.springframework.hateoas.Link;
-import org.springframework.hateoas.MediaTypes;
-import org.springframework.hateoas.PagedModel;
-import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
-import org.springframework.http.MediaType;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Locale;
-
-@RestController
-@RequestMapping("/api/impersonate")
-@ConditionalOnProperty(
-        value = "netgrif.engine.security.web.impersonation-enabled",
-        havingValue = "true",
-        matchIfMissing = true
-)
-@Tag(name = "Impersonation")
-public class ImpersonationController {
-
-    @Autowired
-    protected IImpersonationService impersonationService;
-
-    @Autowired
-    protected IImpersonationAuthorizationService impersonationAuthorizationService;
-
-    @Autowired
-    protected UserService userService;
-
-    @Autowired
-    protected UserResourceHelperService userResourceHelperService;
-
-    @Autowired
-    protected ObjectFactory userResourceAssemblerProvider;
-
-    protected UserResourceAssembler getUserResourceAssembler(Locale locale, boolean small, String selfRel) {
-        UserResourceAssembler result = userResourceAssemblerProvider.getObject();
-        result.initialize(locale, small, selfRel);
-        return result;
-    }
-
-    @Operation(summary = "Search impersonable users", security = {@SecurityRequirement(name = "BasicAuth")})
-    @PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaTypes.HAL_JSON_VALUE)
-    public PagedModel getImpersonationUserOptions(@RequestBody SearchRequest request, Pageable pageable, PagedResourcesAssembler assembler, Authentication auth, Locale locale) {
-        LoggedUser loggedUser = (LoggedUser) auth.getPrincipal();
-        Page page = impersonationAuthorizationService.getConfiguredImpersonationUsers(request.getQuery(), loggedUser, pageable);
-        Link selfLink = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(ImpersonationController.class)
-                .getImpersonationUserOptions(request, pageable, assembler, auth, locale)).withRel("all");
-        PagedModel resources = assembler.toModel(page, getUserResourceAssembler(locale, false, "all"), selfLink);
-        ResourceLinkAssembler.addLinks(resources, AbstractUser.class, selfLink.getRel().toString());
-        return resources;
-    }
-
-    @Operation(summary = "Impersonate user through a specific configuration", security = {@SecurityRequirement(name = "BasicAuth")})
-    @PostMapping("/config/{id}")
-    public UserResource impersonateByConfig(@PathVariable("id") String configId, Locale locale) throws IllegalImpersonationAttemptException, ImpersonatedUserHasSessionException {
-        LoggedUser loggedUser =  ActorTransformer.toLoggedUser(userService.getLoggedUser());
-        if (!impersonationAuthorizationService.canImpersonate(loggedUser, configId)) {
-            throw new IllegalImpersonationAttemptException(loggedUser, configId);
-        }
-        loggedUser = impersonationService.impersonateByConfig(configId);
-        return userResourceHelperService.getResource(loggedUser, locale, false);
-    }
-
-    @Operation(summary = "Impersonate user directly by id", security = {@SecurityRequirement(name = "BasicAuth")})
-    @PostMapping("/user/{id}")
-    public UserResource impersonateUser(@PathVariable("id") String userId, Locale locale) throws IllegalImpersonationAttemptException, ImpersonatedUserHasSessionException {
-        LoggedUser loggedUser =  ActorTransformer.toLoggedUser(userService.getLoggedUser());
-        if (!impersonationAuthorizationService.canImpersonateUser(loggedUser, userId)) {
-            throw new IllegalImpersonationAttemptException(loggedUser, userId);
-        }
-        loggedUser = impersonationService.impersonateUser(userId);
-        return userResourceHelperService.getResource(loggedUser, locale, false);
-    }
-
-    @Operation(summary = "Stop impersonating currently impersonated user", security = {@SecurityRequirement(name = "BasicAuth")})
-    @PostMapping("/clear")
-    public UserResource endImpersonation(Locale locale) {
-        LoggedUser loggedUser = impersonationService.endImpersonation();
-        return userResourceHelperService.getResource(loggedUser, locale, false);
-    }
-
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationControllerAdvice.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationControllerAdvice.java
deleted file mode 100644
index 61bda7893ff..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/ImpersonationControllerAdvice.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.netgrif.application.engine.impersonation.web;
-
-import com.netgrif.application.engine.impersonation.exceptions.IllegalImpersonationAttemptException;
-import com.netgrif.application.engine.impersonation.exceptions.ImpersonatedUserHasSessionException;
-import com.netgrif.application.engine.impersonation.web.responsebodies.ImpersonationNotAvailableResponse;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-@Slf4j
-@RestControllerAdvice(assignableTypes = ImpersonationController.class)
-public class ImpersonationControllerAdvice {
-
-    @ExceptionHandler
-    public ResponseEntity handleException(IllegalImpersonationAttemptException ex) {
-        log.error("Illegal attempt at impersonation", ex);
-        return new ResponseEntity<>(HttpStatus.FORBIDDEN);
-    }
-
-    @ExceptionHandler
-    @ResponseStatus(HttpStatus.BAD_REQUEST)
-    public ImpersonationNotAvailableResponse handleException(ImpersonatedUserHasSessionException ex) {
-        log.error("User is already logged", ex);
-        return new ImpersonationNotAvailableResponse(ex.isImpersonated());
-    }
-
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/requestbodies/SearchRequest.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/requestbodies/SearchRequest.java
deleted file mode 100644
index 84f83785447..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/requestbodies/SearchRequest.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.netgrif.application.engine.impersonation.web.requestbodies;
-
-import lombok.Getter;
-import lombok.Setter;
-
-public class SearchRequest {
-
-    @Setter
-    @Getter
-    protected String query;
-
-    public SearchRequest() {
-    }
-
-    public SearchRequest(String query) {
-        this.query = query;
-    }
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/responsebodies/ImpersonationNotAvailableResponse.java b/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/responsebodies/ImpersonationNotAvailableResponse.java
deleted file mode 100644
index ab670d644f3..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/impersonation/web/responsebodies/ImpersonationNotAvailableResponse.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.netgrif.application.engine.impersonation.web.responsebodies;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class ImpersonationNotAvailableResponse {
-
-    private boolean alreadyImpersonated;
-
-
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java
index 8d20ed2dd55..de0262798c5 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardItemServiceImpl.java
@@ -5,8 +5,6 @@
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
 import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
 import com.netgrif.application.engine.menu.services.interfaces.DashboardItemService;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.common.ResourceNotFoundException;
 import com.netgrif.application.engine.objects.common.ResourceNotFoundExceptionCode;
@@ -64,7 +62,7 @@ public Case getOrCreate(DashboardItemBody body) throws TransitionNotExecutableEx
             return itemCase;
         }
 
-        LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem());
+        LoggedUser loggedUser = userService.getLoggedOrSystem();
         PetriNet petriNet = petriNetService.getDefaultVersionByIdentifier(DashboardItemConstants.PROCESS_IDENTIFIER);
         if (petriNet == null) {
             throw new ResourceNotFoundException(ResourceNotFoundExceptionCode.DEFAULT_PROCESS_NOT_FOUND, "Dashboard item process not found");
@@ -80,7 +78,7 @@ public Case getOrCreate(DashboardItemBody body) throws TransitionNotExecutableEx
      * Updates an existing dashboard item case with new data.
      *
      * @param itemCase The existing {@link Case} to update.
-     * @param body The {@link DashboardItemBody} containing updated data.
+     * @param body     The {@link DashboardItemBody} containing updated data.
      * @return The updated {@link Case} representing the dashboard item.
      * @throws TransitionNotExecutableException if the task transition is not executable.
      */
@@ -112,7 +110,7 @@ protected Case setData(Case useCase, String transId, Map> dataSet) throws TransitionNotExecutableException {
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
+        LoggedUser loggedUser = userService.getLoggedOrSystem();
         String taskId = MenuItemUtils.findTaskIdInCase(useCase, transId);
         Task task = taskService.findOne(taskId);
         task = taskService.assignTask(task, loggedUser).getTask();
@@ -125,7 +123,7 @@ protected Case findCase(String processIdentifier, String query) {
                 .process(Collections.singletonList(new CaseSearchRequest.PetriNet(processIdentifier)))
                 .query(query)
                 .build();
-        Page resultPage = elasticCaseService.search(java.util.List.of(request), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()),
+        Page resultPage = elasticCaseService.search(java.util.List.of(request), userService.getLoggedOrSystem(),
                 PageRequest.of(0, 1), Locale.getDefault(), false);
 
         return resultPage.hasContent() ? resultPage.getContent().get(0) : null;
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java
index 73e6ab67a61..6297b9e1564 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/DashboardManagementServiceImpl.java
@@ -5,8 +5,6 @@
 import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
 import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
 import com.netgrif.application.engine.menu.services.interfaces.DashboardManagementService;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.common.ResourceNotFoundException;
 import com.netgrif.application.engine.objects.common.ResourceNotFoundExceptionCode;
@@ -66,7 +64,7 @@ public Case createDashboardManagement(DashboardManagementBody body) throws Trans
             return managementCase;
         }
         addReferencedMenuItems(body);
-        LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem());
+        LoggedUser loggedUser = userService.getLoggedOrSystem();
         PetriNet petriNet = petriNetService.getDefaultVersionByIdentifier(DashboardManagementConstants.PROCESS_IDENTIFIER);
         if (petriNet == null) {
             throw new ResourceNotFoundException(ResourceNotFoundExceptionCode.DEFAULT_PROCESS_NOT_FOUND, "Dashboard management process not found");
@@ -112,7 +110,7 @@ protected Case setData(Case useCase, String transId, Map> dataSet) throws TransitionNotExecutableException {
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
+        LoggedUser loggedUser = userService.getLoggedOrSystem();
         String taskId = MenuItemUtils.findTaskIdInCase(useCase, transId);
         Task task = taskService.findOne(taskId);
         task = taskService.assignTask(task, loggedUser).getTask();
@@ -125,7 +123,7 @@ protected Case findCase(String processIdentifier, String query) {
                 .process(Collections.singletonList(new CaseSearchRequest.PetriNet(processIdentifier)))
                 .query(query)
                 .build();
-        Page resultPage = elasticCaseService.search(java.util.List.of(request), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()),
+        Page resultPage = elasticCaseService.search(java.util.List.of(request), userService.getLoggedOrSystem(),
                 PageRequest.of(0, 1), Locale.getDefault(), false);
 
         return resultPage.hasContent() ? resultPage.getContent().get(0) : null;
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java
index 0ade5316a66..ad3342e1f01 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/menu/services/MenuItemService.java
@@ -7,7 +7,6 @@
 import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
 import com.netgrif.application.engine.menu.services.interfaces.IMenuItemService;
 import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldType;
@@ -57,8 +56,7 @@ public class MenuItemService implements IMenuItemService {
      */
     @Override
     public Case createFilter(FilterBody body) throws TransitionNotExecutableException {
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
-        Case filterCase = createCase(FilterRunner.FILTER_PETRI_NET_IDENTIFIER, body.getTitle().getDefaultValue(), ActorTransformer.toLoggedUser(loggedUser));
+        Case filterCase = createCase(FilterRunner.FILTER_PETRI_NET_IDENTIFIER, body.getTitle().getDefaultValue(), userService.getLoggedOrSystem());
         filterCase.setIcon(body.getIcon());
         filterCase = workflowService.save(filterCase);
         ToDataSetOutcome dataSetOutcome = body.toDataSet();
@@ -95,7 +93,6 @@ public Case updateFilter(Case filterCase, FilterBody body) {
     @Override
     public Case createMenuItem(MenuItemBody body) throws TransitionNotExecutableException {
         log.debug("Creation of menu item case with identifier [{}] started.", body.getIdentifier());
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
         String sanitizedIdentifier = MenuItemUtils.sanitize(body.getIdentifier());
 
         if (existsMenuItem(sanitizedIdentifier)) {
@@ -109,7 +106,7 @@ public Case createMenuItem(MenuItemBody body) throws TransitionNotExecutableExce
             newName = new I18nString(body.getIdentifier());
         }
         Case menuItemCase = createCase(MenuProcessRunner.MENU_NET_IDENTIFIER, newName.getDefaultValue(),
-                ActorTransformer.toLoggedUser(loggedUser));
+                userService.getLoggedOrSystem());
         menuItemCase = workflowService.save(menuItemCase);
 
         parentItemCase = appendChildCaseIdAndSave(parentItemCase, menuItemCase.getStringId());
@@ -328,7 +325,7 @@ public Case duplicateItem(Case originItem, I18nString newTitle, String newIdenti
             duplicatedViewCase = duplicateView(originViewCase);
         }
         Case duplicated = createCase(MenuProcessRunner.MENU_NET_IDENTIFIER, newTitle.getDefaultValue(),
-                ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()));
+                userService.getLoggedOrSystem());
         duplicated.setDataSet(originItem.getDataSet());
         duplicated.setTitle(newTitle.getDefaultValue());
         duplicated = workflowService.save(duplicated);
@@ -394,7 +391,7 @@ protected Case findCase(String processIdentifier, String query) {
                 .process(Collections.singletonList(new CaseSearchRequest.PetriNet(processIdentifier)))
                 .query(query)
                 .build();
-        Page resultPage = elasticCaseService.search(List.of(request), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()),
+        Page resultPage = elasticCaseService.search(List.of(request), userService.getLoggedOrSystem(),
                 PageRequest.of(0, 1), Locale.getDefault(), false);
 
         return resultPage.hasContent() ? resultPage.getContent().get(0) : null;
@@ -405,7 +402,8 @@ protected long countCases(String processIdentifier, String query) {
                 .process(Collections.singletonList(new CaseSearchRequest.PetriNet(processIdentifier)))
                 .query(query)
                 .build();
-        return elasticCaseService.count(List.of(request), ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()),
+        LoggedUser loggedUser = userService.getLoggedOrSystem();
+        return elasticCaseService.count(List.of(request), loggedUser,
                 Locale.getDefault(), false);
     }
 
@@ -418,7 +416,7 @@ protected Case duplicateView(Case viewCase) throws TransitionNotExecutableExcept
         }
 
         Case duplicatedViewCase = createCase(viewCase.getProcessIdentifier(), viewCase.getTitle(),
-                ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()));
+                userService.getLoggedOrSystem());
         duplicatedViewCase.setDataSet(viewCase.getDataSet());
         workflowService.save(duplicatedViewCase);
 
@@ -464,9 +462,7 @@ protected Case handleView(Case existingViewCase, ViewBody body) throws Transitio
     }
 
     protected Case createView(ViewBody body) throws TransitionNotExecutableException {
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
-        Case viewCase = createCase(body.getViewProcessIdentifier(), body.getViewProcessIdentifier(),
-                ActorTransformer.toLoggedUser(loggedUser));
+        Case viewCase = createCase(body.getViewProcessIdentifier(), body.getViewProcessIdentifier(), userService.getLoggedOrSystem());
 
         Case associatedViewCase = null;
         if (body.hasAssociatedView()) {
@@ -591,7 +587,6 @@ protected Case getOrCreateFolderRecursive(String path, MenuItemBody body) throws
     }
 
     protected Case getOrCreateFolderRecursive(String path, MenuItemBody body, Case childFolderCase) throws TransitionNotExecutableException {
-        AbstractUser loggedUser = userService.getLoggedOrSystem();
         Case folderCase = findFolderCase(path);
         if (folderCase != null) {
             if (childFolderCase != null) {
@@ -600,8 +595,7 @@ protected Case getOrCreateFolderRecursive(String path, MenuItemBody body, Case c
             return folderCase;
         }
 
-        folderCase = createCase(MenuProcessRunner.MENU_NET_IDENTIFIER, body.getMenuName().getDefaultValue(),
-                ActorTransformer.toLoggedUser(loggedUser));
+        folderCase = createCase(MenuProcessRunner.MENU_NET_IDENTIFIER, body.getMenuName().getDefaultValue(), userService.getLoggedOrSystem());
 
         ToDataSetOutcome dataSetOutcome = body.toDataSet(null, path, null);
         if (childFolderCase != null) {
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 882821231aa..8e0f4cf3891 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
@@ -2,35 +2,34 @@
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
+import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
+import com.netgrif.application.engine.auth.service.GroupService;
+import com.netgrif.application.engine.auth.service.UserService;
 import com.netgrif.application.engine.configuration.properties.CacheConfigurationProperties;
+import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetMappingService;
+import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetService;
 import com.netgrif.application.engine.files.minio.StorageConfigurationProperties;
+import com.netgrif.application.engine.importer.service.Importer;
+import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
+import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeleteEvent;
+import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeployEvent;
 import com.netgrif.application.engine.objects.event.events.petrinet.ProcessEvent;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch;
 import com.netgrif.application.engine.objects.petrinet.domain.Transition;
 import com.netgrif.application.engine.objects.petrinet.domain.VersionType;
-import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
-import com.netgrif.application.engine.petrinet.web.responsebodies.ArcImportReference;
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetMappingService;
-import com.netgrif.application.engine.elastic.service.interfaces.IElasticPetriNetService;
-import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeleteEvent;
-import com.netgrif.application.engine.objects.event.events.petrinet.ProcessDeployEvent;
-import com.netgrif.application.engine.importer.service.Importer;
-import com.netgrif.application.engine.auth.service.GroupService;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action;
-import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.FieldActionsRunner;
 import com.netgrif.application.engine.objects.petrinet.domain.events.EventPhase;
-import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository;
 import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingIconKeyException;
 import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException;
 import com.netgrif.application.engine.objects.petrinet.domain.version.Version;
-import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
-import com.netgrif.application.engine.petrinet.web.responsebodies.*;
 import com.netgrif.application.engine.objects.workflow.domain.Case;
 import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.petrinetoutcomes.ImportPetriNetEventOutcome;
+import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.FieldActionsRunner;
+import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository;
+import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
+import com.netgrif.application.engine.petrinet.web.responsebodies.*;
 import com.netgrif.application.engine.workflow.service.interfaces.IEventService;
 import com.netgrif.application.engine.workflow.service.interfaces.IFieldActionsCacheService;
 import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
@@ -61,7 +60,6 @@
 import java.io.InputStream;
 import java.nio.file.Path;
 import java.util.*;
-import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 import static com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService.transformToReference;
@@ -205,12 +203,12 @@ public ImportPetriNetEventOutcome importPetriNet(InputStream xmlFile, VersionTyp
         PetriNet processToMakeNonDefault = checkAndHandleProcessVersion(newProcess, releaseType);
 
         processRoleService.saveAll(newProcess.getRoles().values());
-        newProcess.setAuthor(ActorTransformer.toActorRef(author));
+        newProcess.setAuthor(ActorTransformer.toActorRef(author.getSelfOrImpersonated()));
         Path savedPath = getImporter().saveNetFile(newProcess, new ByteArrayInputStream(xmlCopy.toByteArray()));
         xmlCopy.close();
         log.info("Petri net " + newProcess.getTitle() + " (" + newProcess.getInitials() + " v" + newProcess.getVersion() + ") imported successfully and saved in a folder: " + savedPath.toString());
 
-        runActionAndPublishEvent(outcome, null, newProcess.getPreUploadActions(),  params, new ProcessDeployEvent(outcome, EventPhase.PRE));
+        runActionAndPublishEvent(outcome, null, newProcess.getPreUploadActions(), params, new ProcessDeployEvent(outcome, EventPhase.PRE));
 
         if (processToMakeNonDefault != null) {
             doSaveInternal(processToMakeNonDefault);
@@ -256,13 +254,12 @@ protected void runActionAndPublishEvent(ImportPetriNetEventOutcome outcome, Petr
      *     by 'releaseType' input parameter
      * 
      *
-     * @param newProcess A process to be checked and updated
+     * @param newProcess  A process to be checked and updated
      * @param releaseType requested release type level. It's used for version initialization
-     *
      * @return The process, which has been made non-default or null if no process updated
-     *
      * @throws IllegalArgumentException if the version already exists
-     * */
+     *
+     */
     private PetriNet checkAndHandleProcessVersion(PetriNet newProcess, VersionType releaseType) {
         PetriNet processToMakeNonDefault = null;
 
@@ -514,7 +511,14 @@ public Page getReferencesByVersion(Version version, LoggedUse
 
     @Override
     public List getReferencesByUsersProcessRoles(LoggedUser user, Locale locale) {
-        Query query = Query.query(getProcessRolesCriteria(user));
+        if (user.isProcessAccessDeny()) {
+            return new ArrayList<>();
+        }
+        Criteria processRolesCriteria = getProcessRolesCriteria(user);
+        Criteria impersonatedProcessesCriteria = getImpersonatedProcessesCriteria(user);
+        Query query = impersonatedProcessesCriteria == null
+                ? Query.query(processRolesCriteria)
+                : Query.query(processRolesCriteria.andOperator(impersonatedProcessesCriteria));
         return mongoTemplate.find(query, com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet.class).stream().map(net -> transformToReference(net, locale)).collect(Collectors.toList());
     }
 
@@ -565,13 +569,16 @@ public Page search(PetriNetSearch criteriaClass, LoggedUser u
         Query query = new Query();
         Query queryTotal = new Query();
 
-        // TODO: resolve impersonation
         if (!user.isAdmin()) {
             query.addCriteria(getProcessRolesCriteria(user));
+            if (user.isProcessAccessDeny()) {
+                return Page.empty();
+            }
+            Criteria impersonatedProcessesCriteria = getImpersonatedProcessesCriteria(user);
+            if (impersonatedProcessesCriteria != null) {
+                query.addCriteria(impersonatedProcessesCriteria);
+            }
         }
-//        if (!user.getSelfOrImpersonated().isAdmin())
-//            query.addCriteria(getProcessRolesCriteria(user.getSelfOrImpersonated()));
-
         if (criteriaClass.getIdentifier() != null) {
             this.addValueCriteria(query, queryTotal, Criteria.where("identifier").regex(criteriaClass.getIdentifier(), "i"));
         }
@@ -671,6 +678,16 @@ private Criteria getProcessRolesCriteria(LoggedUser user) {
                 .map(role -> Criteria.where("permissions." + role).exists(true)).toArray(Criteria[]::new));
     }
 
+    private Criteria getImpersonatedProcessesCriteria(LoggedUser user) {
+        if (user.isAdmin() || !user.isImpersonating() || user.getImpersonatedProcesses() == null || user.getImpersonatedProcesses().isEmpty()) {
+            return null;
+        }
+        if (user.isImpersonatedProcessesListAllowing()) {
+            return Criteria.where("identifier").in(user.getImpersonatedProcesses());
+        }
+        return Criteria.where("identifier").nin(user.getImpersonatedProcesses());
+    }
+
     @Override
     public void runActions(List actions, PetriNet petriNet) {
         log.info("Running actions of net [" + petriNet.getStringId() + "]");
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 84d9ca8b62f..4125dcecdd0 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
@@ -5,26 +5,26 @@
 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;
 import com.netgrif.application.engine.auth.service.RealmService;
+import com.netgrif.application.engine.auth.service.UserService;
+import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
 import com.netgrif.application.engine.objects.auth.domain.Group;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
-import com.netgrif.application.engine.auth.service.UserService;
 import com.netgrif.application.engine.objects.auth.domain.Realm;
 import com.netgrif.application.engine.objects.event.events.user.UserRoleChangeEvent;
 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.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;
 import com.netgrif.application.engine.objects.petrinet.domain.events.EventType;
-import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository;
 import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole;
+import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId;
+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.petrinet.domain.repositories.PetriNetRepository;
 import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository;
 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;
@@ -155,7 +155,7 @@ protected void saveUserAndReloadContext(AbstractUser user, LoggedUser loggedUser
 
         String userId = user.getStringId();
         securityContextService.saveToken(userId);
-        if (Objects.equals(userId, loggedUser.getStringId())) {
+        if (Objects.equals(userId, loggedUser.getStringId()) || (loggedUser.isImpersonating() && Objects.equals(userId, loggedUser.getImpersonatedUser().getStringId()))) {
             loggedUser.getProcessRoles().clear();
             loggedUser.setProcessRoles(user.getProcessRoles());
             securityContextService.reloadSecurityContext(loggedUser);
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java
index 67ac0cc5370..a50799dd4d1 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PetriNetController.java
@@ -203,8 +203,12 @@ ResponseEntity> searchPetriNets(@RequestBody Pet
     PagedModel searchElasticPetriNets(@RequestBody PetriNetSearch criteria, Authentication auth, Pageable pageable, PagedResourcesAssembler assembler, Locale locale) {
         LoggedUser user = (LoggedUser) auth.getPrincipal();
         // TODO: add Merge Filters and its operations
-
-        Page nets = elasticService.search(criteria, user, pageable, locale, false);
+        Page nets;
+        if (user.isProcessAccessDeny()) {
+            nets = Page.empty();
+        } else {
+            nets = elasticService.search(criteria, user, pageable, locale, false);
+        }
         Link selfLink = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(PetriNetController.class)
                 .searchElasticPetriNets(criteria, auth, pageable, assembler, locale)).withRel("search_elastic");
 
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PublicPetriNetController.java b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PublicPetriNetController.java
index ab2ce973c53..9b2028b9304 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PublicPetriNetController.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/petrinet/web/PublicPetriNetController.java
@@ -1,12 +1,11 @@
 package com.netgrif.application.engine.petrinet.web;
 
+import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
 import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch;
 import com.netgrif.application.engine.petrinet.domain.version.StringToVersionConverter;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
-import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
 import com.netgrif.application.engine.petrinet.web.responsebodies.*;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -16,10 +15,8 @@
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.web.PagedResourcesAssembler;
-import org.springframework.hateoas.Link;
 import org.springframework.hateoas.MediaTypes;
 import org.springframework.hateoas.PagedModel;
-import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 
@@ -65,13 +62,13 @@ public PetriNetReferenceResource getOne(@PathVariable("id") String id, Locale lo
     @ResponseBody
     public PetriNetReferenceResource getOne(@PathVariable("identifier") String identifier, @PathVariable("version") String version, Locale locale) {
         String resolvedIdentifier = Base64.isBase64(identifier) ? new String(Base64.decodeBase64(identifier)) : identifier;
-        return new PetriNetReferenceResource(this.petriNetService.getReference(resolvedIdentifier, this.converter.convert(version), ActorTransformer.toLoggedUser(userService.getLoggedUser()), locale));
+        return new PetriNetReferenceResource(this.petriNetService.getReference(resolvedIdentifier, this.converter.convert(version), userService.getLoggedUserFromContext(), locale));
     }
 
     @Operation(summary = "Search processes")
     @PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaTypes.HAL_JSON_VALUE)
     public PagedModel searchPetriNets(@RequestBody PetriNetSearch criteria, Pageable pageable, PagedResourcesAssembler assembler, Locale locale) {
-        Page nets = petriNetService.search(criteria, ActorTransformer.toLoggedUser(userService.getLoggedUser()), pageable, locale);
+        Page nets = petriNetService.search(criteria, userService.getLoggedUserFromContext(), pageable, locale);
 //        Link selfLink = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(PublicPetriNetController.class)
 //                .searchPetriNets(criteria, pageable, assembler, locale)).withRel("search");
 //        PagedModel resources = assembler.toModel(nets, new PetriNetReferenceResourceAssembler(), selfLink);
@@ -103,6 +100,6 @@ public DataFieldReferencesResource getDataFieldReferences(@RequestBody List ids, Locale locale) {
         ids.forEach(PetriNetController::decodeUrl);
-        return new TransitionReferencesResource(petriNetService.getTransitionReferences(ids, ActorTransformer.toLoggedUser(userService.getLoggedUser()), locale));
+        return new TransitionReferencesResource(petriNetService.getTransitionReferences(ids, userService.getLoggedUserFromContext(), locale));
     }
 }
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java
index 65a80c0610b..88a06f8cc6b 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/DefaultFiltersRunner.java
@@ -1,19 +1,18 @@
 package com.netgrif.application.engine.startup.runner;
 
-import com.netgrif.application.engine.configuration.properties.FilterConfigurationProperties;
+import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
+import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask;
 import com.netgrif.application.engine.auth.service.UserService;
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
-import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
+import com.netgrif.application.engine.configuration.properties.FilterConfigurationProperties;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
+import com.netgrif.application.engine.objects.workflow.domain.Case;
+import com.netgrif.application.engine.objects.workflow.domain.Task;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
 import com.netgrif.application.engine.startup.ApplicationEngineStartupRunner;
 import com.netgrif.application.engine.startup.ImportHelper;
 import com.netgrif.application.engine.startup.annotation.RunnerOrder;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
-import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask;
-import com.netgrif.application.engine.objects.workflow.domain.Task;
 import com.netgrif.application.engine.workflow.service.interfaces.IDataService;
 import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
 import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
@@ -427,7 +426,7 @@ private Optional createFilterCase(String title, String icon, String filter
             return Optional.empty();
         }
 
-        AbstractUser loggedUser = this.userService.getLoggedOrSystem();
+        LoggedUser loggedUser = this.userService.getLoggedOrSystem();
         if (loggedUser.getStringId().equals(this.userService.getSystem().getStringId())) {
             Case filterCase = this.workflowService.searchOne(QCase.case$.processIdentifier.eq("filter").and(QCase.case$.title.eq(title)).and(QCase.case$.author.id.eq(userService.getSystem().getStringId())));
             if (filterCase != null) {
@@ -436,7 +435,7 @@ private Optional createFilterCase(String title, String icon, String filter
         }
 
         try {
-            Case filterCase = this.workflowService.createCase(filterNet.getStringId(), title, null, ActorTransformer.toLoggedUser(loggedUser)).getCase();
+            Case filterCase = this.workflowService.createCase(filterNet.getStringId(), title, null, loggedUser).getCase();
             filterCase.setIcon(icon);
             filterCase = this.workflowService.save(filterCase);
             Task newFilterTask = this.taskService.searchOne(QTask.task.transitionId.eq(AUTO_CREATE_TRANSITION).and(QTask.task.caseId.eq(filterCase.getStringId())));
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/ImpersonationRunner.java b/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/ImpersonationRunner.java
deleted file mode 100644
index 4244f1e6079..00000000000
--- a/application-engine/src/main/java/com/netgrif/application/engine/startup/runner/ImpersonationRunner.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.netgrif.application.engine.startup.runner;
-
-import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
-import com.netgrif.application.engine.objects.petrinet.domain.VersionType;
-import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
-import com.netgrif.application.engine.startup.ApplicationEngineStartupRunner;
-import com.netgrif.application.engine.startup.ImportHelper;
-import com.netgrif.application.engine.startup.annotation.RunnerOrder;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.stereotype.Component;
-
-import java.util.Optional;
-
-@Slf4j
-@Component
-@RunnerOrder(130)
-@RequiredArgsConstructor
-public class ImpersonationRunner implements ApplicationEngineStartupRunner {
-
-    public static final String IMPERSONATION_CONFIG_FILE_NAME = "engine-processes/impersonation_config.xml";
-    public static final String IMPERSONATION_CONFIG_PETRI_NET_IDENTIFIER = "impersonation_config";
-    public static final String IMPERSONATION_CONFIG_USER_SELECT_FILE_NAME = "engine-processes/impersonation_users_select.xml";
-    public static final String IMPERSONATION_CONFIG_USER_SELECT_PETRI_NET_IDENTIFIER = "impersonation_users_select";
-
-    protected final IPetriNetService petriNetService;
-    protected final ImportHelper helper;
-    protected final SystemUserRunner systemCreator;
-
-    @Override
-    public void run(ApplicationArguments args) throws Exception {
-        createConfigNets();
-    }
-
-    public void createConfigNets() {
-        importProcess("Petri net for impersonation config", IMPERSONATION_CONFIG_PETRI_NET_IDENTIFIER, IMPERSONATION_CONFIG_FILE_NAME);
-        importProcess("Petri net for impersonation user select", IMPERSONATION_CONFIG_USER_SELECT_PETRI_NET_IDENTIFIER, IMPERSONATION_CONFIG_USER_SELECT_FILE_NAME);
-    }
-
-    public Optional importProcess(final String message, String netIdentifier, String netFileName) {
-        PetriNet foundNet = petriNetService.getDefaultVersionByIdentifier(netIdentifier);
-        if (foundNet != null) {
-            log.info("{} has already been imported.", message);
-            return Optional.of(foundNet);
-        }
-
-        Optional net = helper.createNet(netFileName, VersionType.MAJOR, systemCreator.getLoggedSystem());
-        if (net.isEmpty()) {
-            log.error("Import of {} failed!", message);
-        }
-
-        return net;
-    }
-
-}
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/repositories/CaseRepositoryImpl.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/repositories/CaseRepositoryImpl.java
index 9e69bf4e24e..7d1d009b481 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/repositories/CaseRepositoryImpl.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/domain/repositories/CaseRepositoryImpl.java
@@ -1,11 +1,11 @@
 package com.netgrif.application.engine.workflow.domain.repositories;
 
+import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
 import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
+import com.netgrif.application.engine.objects.workflow.domain.QDataField;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
 import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference;
 import com.netgrif.application.engine.petrinet.web.responsebodies.Reference;
-import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
-import com.netgrif.application.engine.objects.workflow.domain.QDataField;
 import com.querydsl.core.types.dsl.BooleanExpression;
 import com.querydsl.core.types.dsl.Expressions;
 import com.querydsl.core.types.dsl.StringExpression;
@@ -30,8 +30,6 @@ public abstract class CaseRepositoryImpl implements CaseRepository {
     @Override
     public void customize(QuerydslBindings bindings, QCase qCase) {
         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-        // TODO: impersonation
-//        List nets = petriNetService.getReferencesByUsersProcessRoles(((LoggedUser) auth.getPrincipal()).getSelfOrImpersonated(), null);
         List nets = petriNetService.getReferencesByUsersProcessRoles(((LoggedUser) auth.getPrincipal()), null);
         Set netIds = nets.stream().map(Reference::getStringId).collect(Collectors.toSet());
         Set netIdentifiers = nets.stream().map(PetriNetReference::getIdentifier).collect(Collectors.toSet());
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java
index a24222a4929..ccb263d6c4a 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationService.java
@@ -1,6 +1,6 @@
 package com.netgrif.application.engine.workflow.service;
 
-import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -17,11 +17,9 @@ protected boolean hasRestrictedPermission(Boolean hasPermission) {
         return hasPermission != null && !hasPermission;
     }
 
-    protected Map getAggregatePermissions(AbstractUser user, Map> permissions) {
+    protected Map getAggregatePermissions(LoggedUser user, Map> permissions) {
         Map aggregatePermissions = new HashMap<>();
 
-//        Set userProcessRoleIDs = user.getSelfOrImpersonated().getProcessRoles().stream().map(role -> role.get_id().toString()).collect(Collectors.toSet());
-        // TODO: impersonation
         Set userProcessRoleIDs = user.getProcessRoles().stream().map(role -> role.get_id().toString()).collect(Collectors.toSet());
 
         for (Map.Entry> role : permissions.entrySet()) {
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java
index 7d4850a1692..5d2e92e9a01 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/CaseSearchService.java
@@ -1,18 +1,18 @@
 package com.netgrif.application.engine.workflow.service;
 
-import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
+import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
 import com.netgrif.application.engine.importer.service.FieldFactory;
+import com.netgrif.application.engine.objects.auth.domain.LoggedUser;
 import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNet;
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldType;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue;
+import com.netgrif.application.engine.objects.workflow.domain.Case;
+import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
 import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference;
 import com.netgrif.application.engine.utils.FullPageRequest;
-import com.netgrif.application.engine.objects.workflow.domain.Case;
-import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId;
-import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase;
 import com.querydsl.core.BooleanBuilder;
 import com.querydsl.core.types.Expression;
 import com.querydsl.core.types.Ops;
@@ -61,7 +61,6 @@ public class CaseSearchService extends MongoSearchService {
 
     public Predicate buildQuery(Map requestQuery, LoggedUser user, Locale locale) {
         BooleanBuilder builder = new BooleanBuilder();
-//        LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated();
 
         if (requestQuery.containsKey(PETRINET)) {
             builder.and(petriNet(requestQuery.get(PETRINET), user, locale));
@@ -95,11 +94,17 @@ public Predicate buildQuery(Map requestQuery, LoggedUser user, L
                 return null;
             }
         }
-        BooleanBuilder permissionConstraints = new BooleanBuilder(buildViewRoleQueryConstraint(user));
-        permissionConstraints.andNot(buildNegativeViewRoleQueryConstraint(user));
-        permissionConstraints.or(buildViewUserQueryConstraint(user));
-        permissionConstraints.andNot(buildNegativeViewUsersQueryConstraint(user));
+
+        LoggedUser impersonationUser = user.getSelfOrImpersonated();
+        BooleanBuilder permissionConstraints = new BooleanBuilder(buildViewRoleQueryConstraint(impersonationUser));
+        permissionConstraints.andNot(buildNegativeViewRoleQueryConstraint(impersonationUser));
+        permissionConstraints.or(buildViewUserQueryConstraint(impersonationUser));
+        permissionConstraints.andNot(buildNegativeViewUsersQueryConstraint(impersonationUser));
         builder.and(permissionConstraints);
+        BooleanExpression impersonatedProcessesConstraints = buildImpersonatedProcessesConstraint(user);
+        if (impersonatedProcessesConstraints != null) {
+            builder.and(impersonatedProcessesConstraints);
+        }
         return builder;
     }
 
@@ -156,6 +161,22 @@ private static BooleanExpression petriNetObject(HashMap query, L
         return null;
     }
 
+    private static BooleanExpression buildImpersonatedProcessesConstraint(LoggedUser loggedUser) {
+        if (loggedUser.isAdmin() || !loggedUser.isImpersonating()) {
+            return null;
+        }
+        if (loggedUser.isProcessAccessDeny()) {
+            return null;
+        }
+        if (loggedUser.getImpersonatedProcesses() == null || loggedUser.getImpersonatedProcesses().isEmpty()) {
+            return null;
+        }
+        if (loggedUser.isImpersonatedProcessesListAllowing()) {
+            return QCase.case$.processIdentifier.in(loggedUser.getImpersonatedProcesses());
+        }
+        return QCase.case$.processIdentifier.notIn(loggedUser.getImpersonatedProcesses());
+    }
+
     public Predicate author(Object query) {
         if (query instanceof ArrayList) {
             BooleanBuilder builder = new BooleanBuilder();
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java
index 4ea645837cc..0f59eeb7135 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/ConfigurableMenuService.java
@@ -1,5 +1,6 @@
 package com.netgrif.application.engine.workflow.service;
 
+import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
 import com.netgrif.application.engine.auth.service.UserService;
 import com.netgrif.application.engine.objects.auth.domain.AbstractUser;
 import com.netgrif.application.engine.objects.auth.domain.ActorTransformer;
@@ -9,10 +10,9 @@
 import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.EnumerationMapField;
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.MultichoiceMapField;
-import com.netgrif.application.engine.petrinet.domain.version.StringToVersionConverter;
 import com.netgrif.application.engine.objects.petrinet.domain.version.Version;
+import com.netgrif.application.engine.petrinet.domain.version.StringToVersionConverter;
 import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
-import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService;
 import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference;
 import com.netgrif.application.engine.utils.FullPageRequest;
 import com.netgrif.application.engine.workflow.service.interfaces.IConfigurableMenuService;
@@ -20,7 +20,10 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 @Service
@@ -42,12 +45,12 @@ public class ConfigurableMenuService implements IConfigurableMenuService {
 
     /**
      * Constructs a map that can be used as a value for any {@link com.netgrif.application.engine.objects.petrinet.domain.dataset.MapOptionsField}.
-     *
+     * 

* The map will contain strings related to process nets authored by the provided user. - * + *

* A key of the map is a string of the form "<net identifier>:<net version>". * The version portion of the string uses the dash (-) character to separate the major, minor a patch version numbers instead of the traditional dot character. - * + *

* A value of the map is an {@link I18nString} with no translations of the form "<net identifier> : <net version>". * The default value of the net title is used. * @@ -56,7 +59,7 @@ public class ConfigurableMenuService implements IConfigurableMenuService { */ @Override public Map getNetsByAuthorAsMapOptions(AbstractUser author, Locale locale) { - LoggedUser loggedAuthor = ActorTransformer.toLoggedUser(author); + LoggedUser loggedAuthor = author instanceof LoggedUser ? (LoggedUser) author : ActorTransformer.toLoggedUser(author); PetriNetSearch requestQuery = new PetriNetSearch(); requestQuery.setAuthor(ActorTransformer.toActorRef(author)); List nets = this.petriNetService.search(requestQuery, loggedAuthor, new FullPageRequest(), locale).getContent(); @@ -114,7 +117,7 @@ public Map getAvailableRolesFromNet(EnumerationMapField proc /** * Constructs a map that can be used as a value for any {@link com.netgrif.application.engine.objects.petrinet.domain.dataset.MapOptionsField}. - * + *

* The map will contain all the options from the input field except for those that are selected in the input field. * * @param mapField a map field whose value complement we want to get @@ -130,11 +133,11 @@ public Map removeSelectedRoles(MultichoiceMapField mapField) /** * Constructs a map that can be used as a value for any {@link com.netgrif.application.engine.objects.petrinet.domain.dataset.MapOptionsField}. - * + *

* The map will contain a union of the options that are already present in the {@code addedRoles} field with the options selected in the {@code rolesAvailable} field. - * + *

* The keys remain unchanged. - * + *

* The values of the map are a combination of the options from the {@code addedRoles} field (they remain unchanged) * and new values corresponding to the new keys from the {@code rolesAvailable} field. The new values are of the form "<original value> (<net title>)" * diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java index 5cb67c54798..b64effed199 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/FilterImportExportService.java @@ -6,34 +6,31 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import com.google.common.collect.Lists; +import com.netgrif.application.engine.auth.service.UserService; +import com.netgrif.application.engine.configuration.properties.FilterConfigurationProperties; +import com.netgrif.application.engine.files.minio.StorageConfigurationProperties; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.files.minio.StorageConfigurationProperties; import com.netgrif.application.engine.objects.common.ResourceNotFoundException; import com.netgrif.application.engine.objects.common.ResourceNotFoundExceptionCode; -import com.netgrif.application.engine.workflow.domain.FilterDeserializer; -import com.netgrif.application.engine.objects.workflow.domain.IllegalFilterFileException; -import com.netgrif.application.engine.auth.service.UserService; -import com.netgrif.application.engine.configuration.properties.FilterConfigurationProperties; -import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; -import com.netgrif.application.engine.objects.workflow.domain.filter.FilterImportExport; -import com.netgrif.application.engine.objects.workflow.domain.filter.FilterImportExportList; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.dataset.EnumerationMapField; import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue; import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior; +import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; +import com.netgrif.application.engine.objects.workflow.domain.*; +import com.netgrif.application.engine.objects.workflow.domain.filter.FilterImportExport; +import com.netgrif.application.engine.objects.workflow.domain.filter.FilterImportExportList; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; -import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; import com.netgrif.application.engine.startup.ImportHelper; +import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; import com.netgrif.application.engine.utils.InputStreamToString; -import com.netgrif.application.engine.objects.workflow.domain.*; +import com.netgrif.application.engine.workflow.domain.FilterDeserializer; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.IFilterImportExportService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; -import com.netgrif.application.engine.objects.workflow.domain.Case; -import com.netgrif.application.engine.objects.workflow.domain.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -252,7 +249,7 @@ protected Map performImport(FilterImportExportList filterList) t filterCase.get().getDataSet().get(FIELD_FILTER).addBehavior(IMPORT_FILTER_TRANSITION, Collections.singleton(FieldBehavior.VISIBLE)); workflowService.save(filterCase.get()); }); - taskService.assignTasks(taskService.findAllById(new ArrayList<>(importedFilterTaskIds.values())), userService.getLoggedUser()); + taskService.assignTasks(taskService.findAllById(new ArrayList<>(importedFilterTaskIds.values())), userService.getLoggedUserFromContext()); changeFilterField(importedFilterTaskIds.values()); return importedFilterTaskIds; } @@ -308,7 +305,7 @@ private void changeVisibilityByAllowedNets(boolean allowedNetsMissing, Case filt protected FilterImportExportList loadFromXML() throws IOException, IllegalFilterFileException { Case exportCase = workflowService.searchOne( QCase.case$.processIdentifier.eq(IMPORT_NET_IDENTIFIER) - .and(QCase.case$.author.id.eq(userService.getLoggedUser().getStringId())) + .and(QCase.case$.author.id.eq(userService.getLoggedUserFromContext().getStringId())) ); FileFieldValue ffv = (FileFieldValue) exportCase.getDataSet().get(UPLOAD_FILE_FIELD).getValue(); @@ -326,7 +323,7 @@ protected FilterImportExportList loadFromXML() throws IOException, IllegalFilter @Transactional protected FileFieldValue createXML(FilterImportExportList filters) throws IOException { - String filePath = fileStorageConfiguration.getPath() + "/filterExport/" + userService.getLoggedUser().getStringId() + "/" + filterProperties.getExport().getFileName(); + String filePath = fileStorageConfiguration.getPath() + "/filterExport/" + userService.getLoggedUserFromContext().getStringId() + "/" + filterProperties.getExport().getFileName(); File f = new File(filePath); f.getParentFile().mkdirs(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java index 5e1030344c9..31df7c5ed64 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MenuImportExportService.java @@ -8,10 +8,6 @@ import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.files.StorageResolverService; import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.workflow.domain.FilterDeserializer; -import com.netgrif.application.engine.workflow.domain.IllegalMenuFileException; -import com.netgrif.application.engine.workflow.service.interfaces.IMenuImportExportService; -import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.dataset.EnumerationMapField; @@ -20,15 +16,20 @@ import com.netgrif.application.engine.objects.petrinet.domain.dataset.MultichoiceMapField; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; -import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; -import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; -import com.netgrif.application.engine.startup.ImportHelper; -import com.netgrif.application.engine.utils.InputStreamToString; -import com.netgrif.application.engine.objects.workflow.domain.*; +import com.netgrif.application.engine.objects.workflow.domain.AuthorizationType; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.QTask; +import com.netgrif.application.engine.objects.workflow.domain.Task; import com.netgrif.application.engine.objects.workflow.domain.menu.Menu; import com.netgrif.application.engine.objects.workflow.domain.menu.MenuAndFilters; import com.netgrif.application.engine.objects.workflow.domain.menu.MenuEntry; import com.netgrif.application.engine.objects.workflow.domain.menu.MenuEntryRole; +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; +import com.netgrif.application.engine.startup.ImportHelper; +import com.netgrif.application.engine.startup.runner.DefaultFiltersRunner; +import com.netgrif.application.engine.utils.InputStreamToString; +import com.netgrif.application.engine.workflow.domain.FilterDeserializer; +import com.netgrif.application.engine.workflow.domain.IllegalMenuFileException; import com.netgrif.application.engine.workflow.service.interfaces.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -270,7 +271,7 @@ public String createMenuItemCase(StringBuilder resultMessage, MenuEntry item, St QTask qTask = new QTask("task"); Task task = taskService.searchOne(qTask.transitionId.eq("init").and(qTask.caseId.eq(menuItemCase.getStringId()))); try { - taskService.assignTask(task, userService.getLoggedUser()); + taskService.assignTask(task, userService.getLoggedUserFromContext()); menuItemCase.getDataSet().get(MENU_IDENTIFIER).setValue(menuIdentifier); menuItemCase.getDataSet().get(PARENT_ID).setValue(parentId); menuItemCase.getDataSet().get(ALLOWED_ROLES).setOptions(allowedRoles); @@ -300,7 +301,7 @@ protected MenuAndFilters loadFromXML(FileFieldValue ffv) throws IOException, Ill protected FileFieldValue createXML(MenuAndFilters menuAndFilters, String parentId, FileField fileField) throws IOException { FileFieldValue ffv = new FileFieldValue(); try { - ffv.setName("menu_" + userService.getLoggedUser().getName().replaceAll("\\s+", "") + ".xml"); + ffv.setName("menu_" + userService.getLoggedUserFromContext().getName().replaceAll("\\s+", "") + ".xml"); ffv.setPath(storageResolverService.resolve(fileField.getStorageType()).getPath(parentId, fileField.getImportId(), ffv.getName())); File f = new File(ffv.getPath()); XmlMapper xmlMapper = new XmlMapper(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java index 3ed448f14d1..726d6deb87a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskAuthorizationService.java @@ -1,14 +1,13 @@ package com.netgrif.application.engine.workflow.service; -import com.netgrif.application.engine.adapter.spring.auth.domain.LoggedUserImpl; -import com.netgrif.application.engine.auth.service.UserService; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.roles.RolePermission; -import com.netgrif.application.engine.petrinet.domain.throwable.IllegalTaskStateException; +import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.objects.workflow.domain.Task; +import com.netgrif.application.engine.petrinet.domain.throwable.IllegalTaskStateException; import com.netgrif.application.engine.workflow.service.interfaces.ITaskAuthorizationService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; +import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,15 +21,10 @@ public class TaskAuthorizationService extends AbstractAuthorizationService imple ITaskService taskService; @Autowired - UserService userService; - - @Override - public Boolean userHasAtLeastOneRolePermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - return userHasAtLeastOneRolePermission(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId), permissions); - } + IWorkflowService workflowService; @Override - public Boolean userHasAtLeastOneRolePermission(AbstractUser user, Task task, RolePermission... permissions) { + public Boolean userHasAtLeastOneRolePermission(LoggedUser user, Task task, RolePermission... permissions) { if (task.getRoles() == null || task.getRoles().isEmpty()) return null; @@ -46,24 +40,15 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, Task task, Rol } @Override - public Boolean userHasUserListPermission(LoggedUser loggedUser, String taskId, RolePermission... permissions) { - return userHasUserListPermission(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId), permissions); - } - - @Override - public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermission... permissions) { + public Boolean userHasUserListPermission(LoggedUser user, Task task, RolePermission... permissions) { if (task.getUserRefs() == null || task.getUserRefs().isEmpty()) return null; - // TODO: impersonation -// if (!task.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { - if (!task.getUsers().containsKey(user.getStringId())) { + if (!task.getUsers().containsKey(user.getSelfOrImpersonatedStringId())) { return null; } - // TODO: impersonation -// Map userPermissions = task.getUsers().get(user.getSelfOrImpersonated().getStringId()); - Map userPermissions = task.getUsers().get(user.getStringId()); + Map userPermissions = task.getUsers().get(user.getSelfOrImpersonatedStringId()); for (RolePermission permission : permissions) { Boolean perm = userPermissions.get(permission.toString()); @@ -75,27 +60,14 @@ public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermi } @Override - public boolean isAssignee(LoggedUser loggedUser, String taskId) { - return isAssignee(userService.transformToUser((LoggedUserImpl) loggedUser), taskService.findById(taskId)); - } - - @Override - public boolean isAssignee(AbstractUser user, String taskId) { - return isAssignee(user, taskService.findById(taskId)); - } - - @Override - public boolean isAssignee(AbstractUser user, Task task) { + public boolean isAssignee(LoggedUser user, Task task) { if (!isAssigned(task)) return false; - else - // TODO: impersonation -// return task.getUserId().equals(user.getSelfOrImpersonated().getStringId()) || (Boolean) user.getAttributeValue("anonymous"); - return task.getUserId().equals(user.getStringId()) || (Boolean) user.getAttributeValue("anonymous"); - } - - private boolean isAssigned(String taskId) { - return isAssigned(taskService.findById(taskId)); + else { + Case caze = workflowService.findOne(task.getCaseId()); + return user.hasProcessAccess(caze.getProcessIdentifier()) + && (task.getUserId().equals(user.getSelfOrImpersonatedStringId()) || (Boolean) user.getAttributeValue("anonymous") || task.getImpersonatorUserId().equals(user.getStringId())); + } } private boolean isAssigned(Task task) { @@ -104,39 +76,38 @@ private boolean isAssigned(Task task) { @Override public boolean canCallAssign(LoggedUser loggedUser, String taskId) { - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.ASSIGN); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.ASSIGN); - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - return loggedUser.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + Task currentTask = taskService.findById(taskId); + Case caze = workflowService.findOne(currentTask.getCaseId()); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, currentTask, RolePermission.ASSIGN); + Boolean userPerm = userHasUserListPermission(loggedUser, currentTask, RolePermission.ASSIGN); + boolean processPerm = loggedUser.hasProcessAccess(caze.getProcessIdentifier()); + return loggedUser.isAdmin() || (processPerm && (userPerm == null ? (rolePerm != null && rolePerm) : userPerm)); } @Override public boolean canCallDelegate(LoggedUser loggedUser, String taskId) { - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.DELEGATE); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.DELEGATE); - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - return loggedUser.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + Task currentTask = taskService.findById(taskId); + Case caze = workflowService.findOne(currentTask.getCaseId()); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, currentTask, RolePermission.DELEGATE); + Boolean userPerm = userHasUserListPermission(loggedUser, currentTask, RolePermission.DELEGATE); + boolean processPerm = loggedUser.hasProcessAccess(caze.getProcessIdentifier()); + return loggedUser.isAdmin() || (processPerm && (userPerm == null ? (rolePerm != null && rolePerm) : userPerm)); } @Override public boolean canCallFinish(LoggedUser loggedUser, String taskId) throws IllegalTaskStateException { - if (!isAssigned(taskId)) + Task currentTask = taskService.findById(taskId); + if (!isAssigned(currentTask)) throw new IllegalTaskStateException("Task with ID '" + taskId + "' cannot be finished, because it is not assigned!"); - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.FINISH); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.FINISH); - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)); - return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, currentTask, RolePermission.FINISH); + Boolean userPerm = userHasUserListPermission(loggedUser, currentTask, RolePermission.FINISH); + return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, currentTask)); } - private boolean canAssignedCancel(AbstractUser user, String taskId) { + private boolean canAssignedCancel(LoggedUser user, String taskId) { Task task = taskService.findById(taskId); - // TODO: impersonation -// if (!isAssigned(task) || !task.getUserId().equals(user.getSelfOrImpersonated().getStringId())) { - if (!isAssigned(task) || !task.getUserId().equals(user.getStringId())) { + if (!isAssigned(task) || !task.getUserId().equals(user.getSelfOrImpersonatedStringId())) { return true; } return (task.getAssignedUserPolicy() == null || task.getAssignedUserPolicy().get("cancel") == null) || task.getAssignedUserPolicy().get("cancel"); @@ -144,27 +115,24 @@ private boolean canAssignedCancel(AbstractUser user, String taskId) { @Override public boolean canCallCancel(LoggedUser loggedUser, String taskId) throws IllegalTaskStateException { - if (!isAssigned(taskId)) + Task currentTask = taskService.findById(taskId); + if (!isAssigned(currentTask)) throw new IllegalTaskStateException("Task with ID '" + taskId + "' cannot be canceled, because it is not assigned!"); - Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, taskId, RolePermission.CANCEL); - Boolean userPerm = userHasUserListPermission(loggedUser, taskId, RolePermission.CANCEL); - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)) && canAssignedCancel(userService.transformToUser((LoggedUserImpl) loggedUser), taskId); - return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, taskId)) && canAssignedCancel(userService.transformToUser((LoggedUserImpl) loggedUser), taskId); + Boolean rolePerm = userHasAtLeastOneRolePermission(loggedUser, currentTask, RolePermission.CANCEL); + Boolean userPerm = userHasUserListPermission(loggedUser, currentTask, RolePermission.CANCEL); + return loggedUser.isAdmin() || ((userPerm == null ? (rolePerm != null && rolePerm) : userPerm) && isAssignee(loggedUser, currentTask)) && canAssignedCancel(loggedUser, taskId); } @Override public boolean canCallSaveData(LoggedUser loggedUser, String taskId) { - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); - return loggedUser.isAdmin() || isAssignee(loggedUser, taskId); + Task currentTask = taskService.findById(taskId); + return loggedUser.isAdmin() || isAssignee(loggedUser, currentTask); } @Override public boolean canCallSaveFile(LoggedUser loggedUser, String taskId) { - // TODO: impersonation -// return loggedUser.getSelfOrImpersonated().isAdmin() || isAssignee(loggedUser, taskId); - return loggedUser.isAdmin() || isAssignee(loggedUser, taskId); + Task currentTask = taskService.findById(taskId); + return loggedUser.isAdmin() || isAssignee(loggedUser, currentTask); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java index 2e9ce479e9e..e454e94e1a0 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java @@ -1,22 +1,25 @@ package com.netgrif.application.engine.workflow.service; +import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNetSearch; +import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId; +import com.netgrif.application.engine.objects.workflow.domain.Task; import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference; import com.netgrif.application.engine.utils.FullPageRequest; -import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId; -import com.netgrif.application.engine.adapter.spring.workflow.domain.QTask; -import com.netgrif.application.engine.objects.workflow.domain.Task; import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest; import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.TaskSearchCaseRequest; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Predicate; -import org.bson.types.ObjectId; +import com.querydsl.core.types.dsl.BooleanExpression; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; import java.util.stream.Collectors; @Service @@ -26,10 +29,8 @@ public class TaskSearchService extends MongoSearchService { private IPetriNetService petriNetService; public Predicate buildQuery(List requests, LoggedUser user, Locale locale, Boolean isIntersection) { - // TODO: impersonation -// LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = user; - List singleQueries = requests.stream().map(r -> this.buildSingleQuery(r, loggedOrImpersonated, locale)).collect(Collectors.toList()); + LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); + List singleQueries = requests.stream().map(r -> this.buildSingleQuery(r, user, locale)).collect(Collectors.toList()); if (isIntersection && !singleQueries.stream().allMatch(Objects::nonNull)) { // one of the queries evaluates to empty set => the entire result is an empty set @@ -53,6 +54,10 @@ public Predicate buildQuery(List requests, LoggedUser user, L permissionConstraints.or(buildViewUserQueryConstraint(loggedOrImpersonated)); permissionConstraints.andNot(buildNegativeViewUsersQueryConstraint(loggedOrImpersonated)); builder.and(permissionConstraints); + BooleanExpression impersonatedProcessesConstraints = buildImpersonatedProcessesConstraint(user); + if (impersonatedProcessesConstraints != null) { + builder.and(impersonatedProcessesConstraints); + } return builder; } @@ -290,6 +295,22 @@ public boolean buildGroupQuery(TaskSearchRequest request, LoggedUser user, Local return false; } + private static BooleanExpression buildImpersonatedProcessesConstraint(LoggedUser loggedUser) { + if (loggedUser.isAdmin() || !loggedUser.isImpersonating()) { + return null; + } + if (loggedUser.isProcessAccessDeny()) { + return null; + } + if (loggedUser.getImpersonatedProcesses() == null || loggedUser.getImpersonatedProcesses().isEmpty()) { + return null; + } + if (loggedUser.isImpersonatedProcessesListAllowing()) { + return QTask.task.processIdentifier.in(loggedUser.getImpersonatedProcesses()); + } + return QTask.task.processIdentifier.notIn(loggedUser.getImpersonatedProcesses()); + } + private void buildTagsQuery(TaskSearchRequest request, BooleanBuilder query) { if (request.tags == null || request.tags.isEmpty()) { return; diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index cc81367878a..6b2486ed134 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -1,13 +1,12 @@ package com.netgrif.application.engine.workflow.service; import com.google.common.collect.Ordering; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.workflow.domain.TaskNotFoundException; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService; +import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.event.events.task.*; import com.netgrif.application.engine.objects.petrinet.domain.*; import com.netgrif.application.engine.objects.petrinet.domain.arcs.Arc; @@ -20,17 +19,20 @@ import com.netgrif.application.engine.objects.petrinet.domain.events.EventType; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import com.netgrif.application.engine.objects.petrinet.domain.throwable.TransitionNotExecutableException; -import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; -import com.netgrif.application.engine.utils.DateUtils; -import com.netgrif.application.engine.utils.FullPageRequest; -import com.netgrif.application.engine.validation.service.interfaces.IValidationService; -import com.netgrif.application.engine.objects.workflow.domain.*; +import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId; +import com.netgrif.application.engine.objects.workflow.domain.Task; +import com.netgrif.application.engine.objects.workflow.domain.TaskPair; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.SetDataEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.taskoutcomes.*; -import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.objects.workflow.domain.triggers.TimeTrigger; import com.netgrif.application.engine.objects.workflow.domain.triggers.Trigger; +import com.netgrif.application.engine.utils.DateUtils; +import com.netgrif.application.engine.utils.FullPageRequest; +import com.netgrif.application.engine.validation.service.interfaces.IValidationService; +import com.netgrif.application.engine.workflow.domain.TaskNotFoundException; +import com.netgrif.application.engine.workflow.domain.repositories.TaskRepository; import com.netgrif.application.engine.workflow.service.interfaces.IDataService; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; @@ -139,9 +141,7 @@ public AssignTaskEventOutcome assignTask(LoggedUser loggedUser, String taskId, M if (task == null) { throw new TaskNotFoundException("Could not find task with id [" + taskId + "]"); } - - AbstractUser user = getUserFromLoggedUser(loggedUser); - return assignTask(task, user, params); + return assignTask(task, loggedUser, params); } @Override @@ -151,8 +151,7 @@ public AssignTaskEventOutcome assignTask(String taskId) throws TransitionNotExec @Override public AssignTaskEventOutcome assignTask(String taskId, Map params) throws TransitionNotExecutableException { - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); - return assignTask(user, taskId, params); + return assignTask(userService.getLoggedOrSystem(), taskId, params); } @Override @@ -176,9 +175,10 @@ public AssignTaskEventOutcome assignTask(Task task, AbstractUser user, Map params) throws IllegalArgumentException, TransitionNotExecutableException { - LoggedUser user = ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()); + LoggedUser user = userService.getLoggedOrSystem(); return finishTask(user, taskId, params); } @@ -241,19 +247,16 @@ public FinishTaskEventOutcome finishTask(LoggedUser loggedUser, String taskId, M if (task == null) { throw new IllegalArgumentException("Could not find task with id [" + taskId + "]"); } - AbstractUser user = getUserFromLoggedUser(loggedUser); if (task.getUserId() == null) { throw new IllegalArgumentException("Task with id=" + taskId + " is not assigned to any user."); } // TODO: 14. 4. 2017 replace with @PreAuthorize - // TODO: impersonation -// if (!task.getUserId().equals(user.getSelfOrImpersonated().getStringId()) && !((Boolean) loggedUser.getAttributes().containsKey("anonymous"))) { - if (!task.getUserId().equals(user.getStringId()) && !((Boolean) loggedUser.getAttributes().containsKey("anonymous"))) { + if (!task.getUserId().equals(loggedUser.getSelfOrImpersonatedStringId()) && !((Boolean) loggedUser.getAttributes().containsKey("anonymous"))) { throw new IllegalArgumentException("User that is not assigned tried to finish task"); } - return finishTask(task, user, params); + return finishTask(task, loggedUser, params); } @Override @@ -266,9 +269,10 @@ public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map outcomes = new ArrayList<>(eventService.runActions(transition.getPreFinishActions(), useCase, task, transition, params)); @@ -281,6 +285,8 @@ public FinishTaskEventOutcome finishTask(Task task, AbstractUser user, Map outcomes = new ArrayList<>(eventService.runActions(transition.getPreCancelActions(), useCase, task, transition, params)); task = findOne(task.getStringId()); @@ -359,9 +363,7 @@ public CancelTaskEventOutcome cancelTask(Task task, AbstractUser user, Map params) throws TransitionNotExecutableException { AbstractUser delegatedUser = userService.findById(delegatedId, null); - AbstractUser delegateUser = getUserFromLoggedUser(loggedUser); Optional taskOptional = findOptionalById(taskId); if (taskOptional.isEmpty()) { @@ -431,14 +434,17 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg Case useCase = workflowService.findOne(task.getCaseId()); Transition transition = useCase.getPetriNet().getTransition(task.getTransitionId()); - log.info("[" + useCase.getStringId() + "]: Delegating task [" + task.getTitle() + "] to user [" + delegatedUser.getEmail() + "]"); + String userMessage = loggedUser.isImpersonating() + ? "[" + loggedUser.getUsername() + "] in realm [" + loggedUser.getRealmId() + "]. Impersonation for user [" + loggedUser.getImpersonatedUser().getUsername() + "]" + : "[" + loggedUser.getUsername() + "] in realm [" + loggedUser.getRealmId() + "]"; + log.info("[{}]: Delegating task [{}] to user [{}] from user {}", useCase.getStringId(), task.getTitle(), delegatedUser.getEmail(), userMessage); List outcomes = new ArrayList<>(eventService.runActions(transition.getPreDelegateActions(), useCase, task, transition, params)); task = findOne(task.getStringId()); DelegateTaskEventOutcome outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); useCase = evaluateRules(new DelegateTaskEvent(outcome, EventPhase.PRE)); delegate(delegatedUser, task, useCase); - publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.PRE, delegateUser, delegatedUser.getStringId())); + publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.PRE, loggedUser, delegatedUser.getStringId())); outcomes.addAll(eventService.runActions(transition.getPostDelegateActions(), useCase, task, transition, params)); useCase = evaluateRules(new DelegateTaskEvent(new DelegateTaskEventOutcome(useCase, task, outcomes), EventPhase.POST)); @@ -447,10 +453,8 @@ public DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String deleg outcome = new DelegateTaskEventOutcome(useCase, task, outcomes); addMessageToOutcome(transition, EventType.DELEGATE, outcome); - publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.POST, delegateUser, delegatedUser.getStringId())); - // TODO: impersonation -// log.info("Task [" + task.getTitle() + "] in case [" + useCase.getTitle() + "] assigned to [" + delegateUser.getSelfOrImpersonated().getEmail() + "] was delegated to [" + delegatedUser.getEmail() + "]"); - log.info("Task [" + task.getTitle() + "] in case [" + useCase.getTitle() + "] assigned to [" + delegateUser.getEmail() + "] was delegated to [" + delegatedUser.getEmail() + "]"); + publisher.publishEvent(new DelegateTaskEvent(outcome, EventPhase.POST, loggedUser, delegatedUser.getStringId())); + log.info("Task [{}] in case [{}] assigned to {} was delegated to [{}]", task.getTitle(), useCase.getTitle(), userMessage, delegatedUser.getEmail()); return outcome; } @@ -460,6 +464,8 @@ protected void delegate(AbstractUser delegated, Task task, Case useCase) throws task.setUserId(delegated.getStringId()); task.setUserRealmId(delegated.getRealmId()); task.setUser(delegated); + task.setImpersonatorUsername(null); + task.setImpersonatorUserId(null); save(task); } else { assignTaskToUser(delegated, task, useCase.getStringId()); @@ -652,26 +658,30 @@ public Task findOne(String taskId) { @Override public Page getAll(LoggedUser loggedUser, Pageable pageable, Locale locale) { List tasks; - // TODO: impersonation -// LoggedUser loggedOrImpersonated = loggedUser.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = loggedUser; - if (loggedOrImpersonated.getProcessRoles().isEmpty()) { + if (loggedUser.getProcessRoles().isEmpty() || loggedUser.isProcessAccessDeny()) { tasks = new ArrayList<>(); return new PageImpl<>(tasks, pageable, 0L); } else { StringBuilder queryBuilder = new StringBuilder(); queryBuilder.append("{$or:["); - loggedOrImpersonated.getProcessRoles().forEach(role -> { + loggedUser.getProcessRoles().forEach(role -> { queryBuilder.append("{\"roles."); queryBuilder.append(role); queryBuilder.append("\":{$exists:true}},"); }); - if (!loggedOrImpersonated.getProcessRoles().isEmpty()) - queryBuilder.deleteCharAt(queryBuilder.length() - 1); - else - queryBuilder.append("{}"); + queryBuilder.deleteCharAt(queryBuilder.length() - 1); queryBuilder.append("]}"); + if (loggedUser.isImpersonating() && loggedUser.getImpersonatedProcesses() != null && !loggedUser.getImpersonatedProcesses().isEmpty()) { + String processList = loggedUser.getImpersonatedProcesses().stream() + .map(p -> "\"" + p + "\"") + .collect(Collectors.joining(",")); + if (loggedUser.isImpersonatedProcessesListAllowing()) { + queryBuilder.append(",\"processIdentifier\":{$in:[").append(processList).append("]}"); + } else { + queryBuilder.append(",\"processIdentifier\":{$nin:[").append(processList).append("]}"); + } + } BasicQuery query = new BasicQuery(queryBuilder.toString()); query = (BasicQuery) query.with(pageable); tasks = mongoTemplate.find(query, Task.class); @@ -682,6 +692,9 @@ public Page getAll(LoggedUser loggedUser, Pageable pageable, Locale locale @Override public Page search(List requests, Pageable pageable, LoggedUser user, Locale locale, Boolean isIntersection) { + if (user.isProcessAccessDeny()) { + return Page.empty(); + } com.querydsl.core.types.Predicate searchPredicate = searchService.buildQuery(requests, user, locale, isIntersection); if (searchPredicate != null) { Page page = taskRepository.findAll(searchPredicate, pageable); @@ -695,6 +708,9 @@ public Page search(List requests, Pageable pageable, Lo @Override public long count(List requests, LoggedUser user, Locale locale, Boolean isIntersection) { + if (user.isProcessAccessDeny()) { + return 0; + } com.querydsl.core.types.Predicate searchPredicate = searchService.buildQuery(requests, user, locale, isIntersection); if (searchPredicate != null) { return taskRepository.count(searchPredicate); @@ -741,9 +757,7 @@ public List findAllById(List ids) { @Override public Page findByUser(Pageable pageable, AbstractUser user) { - // TODO: impersonation -// return loadUsers(taskRepository.findByUserId(pageable, user.getSelfOrImpersonated().getStringId())); - return loadUsers(taskRepository.findByUserId(pageable, user.getStringId())); + return loadUsers(taskRepository.findByUserId(pageable, user.getSelfOrImpersonatedStringId())); } @Override @@ -834,6 +848,7 @@ private Task createFromTransition(Transition transition, Case useCase) { final Task task = com.netgrif.application.engine.adapter.spring.workflow.domain.Task.with() .title(transition.getTitle()) .processId(useCase.getPetriNetId()) + .processIdentifier(useCase.getProcessIdentifier()) .caseId(useCase.get_id().toString()) .transitionId(transition.getImportId()) .layout(transition.getLayout()) @@ -982,12 +997,4 @@ public SetDataEventOutcome getMainOutcome(Map outco mainOutcome.addOutcomes(new ArrayList<>(outcomes.values())); return mainOutcome; } - - protected AbstractUser getUserFromLoggedUser(LoggedUser loggedUser) { - AbstractUser user = userService.findById(loggedUser.getStringId(), loggedUser.getRealmId()); - // TODO: impersonation -// AbstractUser fromLogged = userService.transformToUser((LoggedUserImpl) loggedUser); -// user.setImpersonated(fromLogged.getImpersonated()); - return user; - } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/UserFilterSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/UserFilterSearchService.java index 6edd03cdac0..0e14ea09d39 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/UserFilterSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/UserFilterSearchService.java @@ -3,7 +3,6 @@ import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService; import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.startup.runner.FilterRunner; import com.netgrif.application.engine.workflow.service.interfaces.IUserFilterSearchService; @@ -33,12 +32,12 @@ public List autocompleteFindFilters(String userInput) { .query( String.format("(title:%s*) AND ((dataSet.visibility.keyValue:private AND authorEmail:%s) OR (dataSet.visibility.keyValue:public))", userInput, - userService.getLoggedUser().getEmail()) + userService.getLoggedUserFromContext().getEmail()) ) .transition(Collections.singletonList("view_filter")) .build() ), - ActorTransformer.toLoggedUser(userService.getLoggedOrSystem()), + userService.getLoggedOrSystem(), PageRequest.of(0, 100), LocaleContextHolder.getLocale(), true); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java index 707e33353dc..102b5d5193a 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowAuthorizationService.java @@ -1,12 +1,10 @@ package com.netgrif.application.engine.workflow.service; -import com.netgrif.application.engine.auth.service.UserService; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRolePermission; -import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.objects.workflow.domain.Case; +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowAuthorizationService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import org.springframework.beans.factory.annotation.Autowired; @@ -24,30 +22,24 @@ public class WorkflowAuthorizationService extends AbstractAuthorizationService i @Autowired private IPetriNetService petriNetService; - @Autowired - private UserService userService; - @Override public boolean canCallDelete(LoggedUser user, String caseId) { Case requestedCase = workflowService.findOne(caseId); - // TODO: impersonation -// Boolean rolePerm = userHasAtLeastOneRolePermission(userService.transformToUser((LoggedUserImpl) user.getSelfOrImpersonated()), requestedCase.getPetriNet(), ProcessRolePermission.DELETE); -// Boolean userPerm = userHasUserListPermission(userService.transformToUser((LoggedUserImpl) user.getSelfOrImpersonated()), requestedCase, ProcessRolePermission.DELETE); -// return user.getSelfOrImpersonated().isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); - Boolean rolePerm = userHasAtLeastOneRolePermission(userService.transformToUser(user), requestedCase.getPetriNet(), ProcessRolePermission.DELETE); - Boolean userPerm = userHasUserListPermission(userService.transformToUser(user), requestedCase, ProcessRolePermission.DELETE); - return user.isAdmin() || (userPerm == null ? (rolePerm != null && rolePerm) : userPerm); + Boolean rolePerm = userHasAtLeastOneRolePermission(user.getSelfOrImpersonated(), requestedCase.getPetriNet(), ProcessRolePermission.DELETE); + Boolean userPerm = userHasUserListPermission(user.getSelfOrImpersonated(), requestedCase, ProcessRolePermission.DELETE); + boolean processPerm = user.hasProcessAccess(requestedCase.getProcessIdentifier()); + return user.isAdmin() || (processPerm && (userPerm == null ? (rolePerm != null && rolePerm) : userPerm)); } @Override public boolean canCallCreate(LoggedUser user, String netId) { PetriNet net = petriNetService.getPetriNet(netId); - // TODO: impersonation - return user.isAdmin() || userHasAtLeastOneRolePermission(userService.transformToUser(user), net, ProcessRolePermission.CREATE); + boolean processPerm = user.hasProcessAccess(net.getIdentifier()); + return user.isAdmin() || (processPerm && userHasAtLeastOneRolePermission(user, net, ProcessRolePermission.CREATE)); } @Override - public Boolean userHasAtLeastOneRolePermission(AbstractUser user, PetriNet net, ProcessRolePermission... permissions) { + public Boolean userHasAtLeastOneRolePermission(LoggedUser user, PetriNet net, ProcessRolePermission... permissions) { Map aggregatePermissions = getAggregatePermissions(user, net.getPermissions()); for (ProcessRolePermission permission : permissions) { @@ -60,18 +52,15 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, PetriNet net, } @Override - public Boolean userHasUserListPermission(AbstractUser user, Case useCase, ProcessRolePermission... permissions) { + public Boolean userHasUserListPermission(LoggedUser user, Case useCase, ProcessRolePermission... permissions) { if (useCase.getUserRefs() == null || useCase.getUserRefs().isEmpty()) return null; - // TODO: impersonation -// if (!useCase.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { - if (!useCase.getUsers().containsKey(user.getStringId())) { + if (!useCase.getUsers().containsKey(user.getSelfOrImpersonatedStringId())) { return null; } - // TODO: impersonation - Map userPermissions = useCase.getUsers().get(user.getStringId()); + Map userPermissions = useCase.getUsers().get(user.getSelfOrImpersonatedStringId()); for (ProcessRolePermission permission : permissions) { Boolean perm = userPermissions.get(permission.toString()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index 218e6facfa4..ef2ab1dd580 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -1,38 +1,37 @@ package com.netgrif.application.engine.workflow.service; import com.google.common.collect.Ordering; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; -import com.netgrif.application.engine.objects.workflow.domain.Case; -import com.netgrif.application.engine.objects.auth.domain.LoggedUser; +import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseMappingService; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService; import com.netgrif.application.engine.event.evaluators.Evaluator; +import com.netgrif.application.engine.event.services.EvaluationService; +import com.netgrif.application.engine.importer.service.FieldFactory; +import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; +import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.event.events.workflow.CaseEvent; import com.netgrif.application.engine.objects.event.events.workflow.CreateCaseEvent; import com.netgrif.application.engine.objects.event.events.workflow.DeleteCaseEvent; -import com.netgrif.application.engine.event.services.EvaluationService; -import com.netgrif.application.engine.importer.service.FieldFactory; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field; import com.netgrif.application.engine.objects.petrinet.domain.dataset.TaskField; import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue; import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListFieldValue; -import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.FieldActionsRunner; import com.netgrif.application.engine.objects.petrinet.domain.events.CaseEventType; import com.netgrif.application.engine.objects.petrinet.domain.events.EventPhase; -import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; -import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService; -import com.netgrif.application.engine.security.service.EncryptionService; -import com.netgrif.application.engine.utils.FullPageRequest; import com.netgrif.application.engine.objects.workflow.domain.*; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.EventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.DeleteCaseEventOutcome; +import com.netgrif.application.engine.objects.workflow.service.InitValueExpressionEvaluator; +import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.FieldActionsRunner; +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService; +import com.netgrif.application.engine.security.service.EncryptionService; +import com.netgrif.application.engine.utils.FullPageRequest; import com.netgrif.application.engine.workflow.domain.repositories.CaseRepository; import com.netgrif.application.engine.workflow.service.interfaces.IEventService; -import com.netgrif.application.engine.objects.workflow.service.InitValueExpressionEvaluator; import com.netgrif.application.engine.workflow.service.interfaces.ITaskService; import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService; import com.querydsl.core.types.Predicate; @@ -204,6 +203,9 @@ public Page search(Predicate predicate, Pageable pageable) { @Override public Page search(Map request, Pageable pageable, LoggedUser user, Locale locale) { + if (user.isProcessAccessDeny()) { + return Page.empty(); + } Predicate searchPredicate = searchService.buildQuery(request, user, locale); Page page; if (searchPredicate != null) { @@ -218,6 +220,9 @@ public Page search(Map request, Pageable pageable, LoggedU @Override public long count(Map request, LoggedUser user, Locale locale) { + if (user.isProcessAccessDeny()) { + return 0; + } Predicate searchPredicate = searchService.buildQuery(request, user, locale); if (searchPredicate != null) { return repository.count(searchPredicate); @@ -320,9 +325,7 @@ public CreateCaseEventOutcome createCase(String netId, Function ma } public CreateCaseEventOutcome createCase(String netId, Function makeTitle, String color, LoggedUser user, Map params) { - // TODO: impersonation -// LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); - LoggedUser loggedOrImpersonated = user; + LoggedUser loggedOrImpersonated = user.getSelfOrImpersonated(); PetriNet petriNet = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet((com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet) petriNetService.get(new ObjectId(netId))); // int rulesExecuted; Case useCase = new com.netgrif.application.engine.adapter.spring.workflow.domain.Case(petriNet); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java index 99b0c8e56b9..b18ebb82925 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskAuthorizationService.java @@ -1,25 +1,17 @@ package com.netgrif.application.engine.workflow.service.interfaces; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.roles.RolePermission; -import com.netgrif.application.engine.petrinet.domain.throwable.IllegalTaskStateException; import com.netgrif.application.engine.objects.workflow.domain.Task; +import com.netgrif.application.engine.petrinet.domain.throwable.IllegalTaskStateException; public interface ITaskAuthorizationService { - Boolean userHasAtLeastOneRolePermission(LoggedUser loggedUser, String taskId, RolePermission... permissions); - - Boolean userHasAtLeastOneRolePermission(AbstractUser user, Task task, RolePermission... permissions); - - Boolean userHasUserListPermission(LoggedUser loggedUser, String taskId, RolePermission... permissions); - - Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermission... permissions); - boolean isAssignee(LoggedUser loggedUser, String taskId); + Boolean userHasAtLeastOneRolePermission(LoggedUser user, Task task, RolePermission... permissions); - boolean isAssignee(AbstractUser user, String taskId); + Boolean userHasUserListPermission(LoggedUser user, Task task, RolePermission... permissions); - boolean isAssignee(AbstractUser user, Task task); + boolean isAssignee(LoggedUser user, Task task); boolean canCallAssign(LoggedUser loggedUser, String taskId); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowAuthorizationService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowAuthorizationService.java index f99f950a31e..e63e7a7de68 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowAuthorizationService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowAuthorizationService.java @@ -1,6 +1,5 @@ package com.netgrif.application.engine.workflow.service.interfaces; -import com.netgrif.application.engine.objects.auth.domain.AbstractUser; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.objects.petrinet.domain.PetriNet; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRolePermission; @@ -12,7 +11,7 @@ public interface IWorkflowAuthorizationService { boolean canCallCreate(LoggedUser user, String netId); - Boolean userHasAtLeastOneRolePermission(AbstractUser user, PetriNet net, ProcessRolePermission... permissions); + Boolean userHasAtLeastOneRolePermission(LoggedUser user, PetriNet net, ProcessRolePermission... permissions); - Boolean userHasUserListPermission(AbstractUser user, Case useCase, ProcessRolePermission... permissions); + Boolean userHasUserListPermission(LoggedUser user, Case useCase, ProcessRolePermission... permissions); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java index 43d3ce9b7d3..3e56435e312 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/AbstractTaskController.java @@ -107,7 +107,7 @@ public LocalisedTaskResource getOne(String taskId, Locale locale) { public EntityModel assign(LoggedUser loggedUser, String taskId, Locale locale) { try { - return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " assigned to " + loggedUser.getName(), + return EventOutcomeWithMessageResource.successMessage("LocalisedTask " + taskId + " assigned to " + (loggedUser.isImpersonating() ? loggedUser.getImpersonatedUser().getUsername() : loggedUser.getUsername()), LocalisedEventOutcomeFactory.from(taskService.assignTask(loggedUser, taskId), locale)); } catch (TransitionNotExecutableException e) { log.error("Assigning task [" + taskId + "] failed: ", e); @@ -155,7 +155,7 @@ public EntityModel cancel(LoggedUser loggedUser, String } public PagedModel getMy(Authentication auth, Pageable pageable, PagedResourcesAssembler assembler, Locale locale) { - Page page = taskService.findByUser(pageable, userService.transformToUser(((LoggedUserImpl) auth.getPrincipal()))); + Page page = taskService.findByUser(pageable, ((LoggedUserImpl) auth.getPrincipal())); Link selfLink = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) .getMy(auth, pageable, assembler, locale)).withRel("my"); PagedModel resources = assembler.toModel(page, new TaskResourceAssembler(locale), selfLink); @@ -164,7 +164,7 @@ public PagedModel getMy(Authentication auth, Pageable pag } public PagedModel getMyFinished(Pageable pageable, Authentication auth, PagedResourcesAssembler assembler, Locale locale) { - Page page = taskService.findByUser(pageable, userService.transformToUser(((LoggedUserImpl) auth.getPrincipal()))); + Page page = taskService.findByUser(pageable, ((LoggedUserImpl) auth.getPrincipal())); Link selfLink = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(TaskController.class) .getMyFinished(pageable, auth, assembler, locale)).withRel("finished"); PagedModel resources = assembler.toModel(page, new TaskResourceAssembler(locale), selfLink); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java index 932db377fe0..69ff8911db5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicTaskController.java @@ -1,7 +1,6 @@ package com.netgrif.application.engine.workflow.web; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.workflow.domain.MergeFilterOperation; @@ -81,7 +80,7 @@ public List getTasksOfCase(@PathVariable("id") String caseId, Loc description = "Caller doesn't fulfill the authorisation requirements" )}) public EntityModel assign(@PathVariable("id") String taskId, Locale locale) { - LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); + LoggedUser loggedUser = userService.getLoggedUserFromContext(); return super.assign(loggedUser, taskId, locale); } @@ -96,7 +95,7 @@ public EntityModel assign(@PathVariable("id") String ta description = "Caller doesn't fulfill the authorisation requirements" )}) public EntityModel finish(@PathVariable("id") String taskId, Locale locale) { - LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); + LoggedUser loggedUser = userService.getLoggedUserFromContext(); return super.finish(loggedUser, taskId, locale); } @@ -111,7 +110,7 @@ public EntityModel finish(@PathVariable("id") String ta description = "Caller doesn't fulfill the authorisation requirements" )}) public EntityModel cancel(@PathVariable("id") String taskId, Locale locale) { - LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); + LoggedUser loggedUser = userService.getLoggedUserFromContext(); return super.cancel(loggedUser, taskId, locale); } @@ -210,6 +209,6 @@ public EntityModel deleteNamedFile(@PathVariable("id") @Operation(summary = "Generic task search on Mongo database") @PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaTypes.HAL_JSON_VALUE) public PagedModel search(Pageable pageable, @RequestBody SingleTaskSearchRequestAsList searchBody, @RequestParam(defaultValue = "OR") MergeFilterOperation operation, PagedResourcesAssembler assembler, Locale locale) { - return super.searchPublic(ActorTransformer.toLoggedUser(userService.getLoggedUser()), pageable, searchBody, operation, assembler, locale); + return super.searchPublic(userService.getLoggedUserFromContext(), pageable, searchBody, operation, assembler, locale); } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java index 0683e405e4b..a836967b8d5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/PublicWorkflowController.java @@ -1,9 +1,8 @@ package com.netgrif.application.engine.workflow.web; +import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.eventoutcomes.LocalisedEventOutcomeFactory; -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; -import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessage; import com.netgrif.application.engine.workflow.domain.eventoutcomes.response.EventOutcomeWithMessageResource; @@ -47,7 +46,7 @@ public PublicWorkflowController(IWorkflowService workflowService, UserService us @PostMapping(value = "/case", consumes = "application/json;charset=UTF-8", produces = MediaTypes.HAL_JSON_VALUE) @Operation(summary = "Create new case") public EntityModel createCase(@RequestBody CreateCaseBody body, Locale locale) { - LoggedUser loggedUser = ActorTransformer.toLoggedUser(userService.getLoggedUser()); + LoggedUser loggedUser = userService.getLoggedUserFromContext(); try { CreateCaseEventOutcome outcome = this.workflowService.createCase(body.netId, body.title, body.color, loggedUser, locale); return EventOutcomeWithMessageResource.successMessage("Case created successfully", diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java index bad76f64af2..72ca21d2891 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/WorkflowController.java @@ -144,7 +144,8 @@ public PagedModel searchMongo(@RequestBody Map sea @Operation(summary = "Get count of the cases", security = {@SecurityRequirement(name = "BasicAuth")}) @PostMapping(value = "/case/count", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public CountResponse count(@RequestBody SingleCaseSearchRequestAsList searchBody, @RequestParam(defaultValue = "OR") MergeFilterOperation operation, Authentication auth, Locale locale) { - long count = elasticCaseService.count(searchBody.getList(), (LoggedUser) auth.getPrincipal(), locale, operation == MergeFilterOperation.AND); + LoggedUser loggedUser = (LoggedUser) auth.getPrincipal(); + long count = elasticCaseService.count(searchBody.getList(), loggedUser, locale, operation == MergeFilterOperation.AND); return CountResponse.caseCount(count); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java index b226b7e8895..e9427b8373c 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java @@ -26,6 +26,8 @@ public class Task { private String transitionId; + private String processIdentifier; + private TaskLayout layout; private String title; @@ -80,6 +82,7 @@ public Task(com.netgrif.application.engine.objects.workflow.domain.Task task, Lo this._id = task.getObjectId(); this.caseId = task.getCaseId(); this.transitionId = task.getTransitionId(); + this.processIdentifier = task.getProcessIdentifier(); this.layout = task.getLayout(); this.title = task.getTitle().getTranslation(locale); this.caseColor = task.getCaseColor(); @@ -111,6 +114,7 @@ public Task(ElasticTask entity) { _id = new ProcessResourceId(entity.getId()); caseId = entity.getCaseId(); transitionId = entity.getTransitionId(); + processIdentifier = entity.getProcessIdentifier(); title = entity.getTitle().getDefaultValue(); caseTitle = entity.getCaseTitle(); priority = entity.getPriority(); diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/TestHelper.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/TestHelper.groovy index f6921558abe..9df0f1ad7a6 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/TestHelper.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/TestHelper.groovy @@ -1,15 +1,15 @@ package com.netgrif.application.engine -import com.netgrif.application.engine.auth.service.UserService import com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticCase -import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository import com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticPetriNet import com.netgrif.application.engine.adapter.spring.elastic.domain.ElasticTask +import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService +import com.netgrif.application.engine.auth.service.UserService +import com.netgrif.application.engine.elastic.domain.ElasticCaseRepository import com.netgrif.application.engine.elastic.domain.ElasticTaskRepository import com.netgrif.application.engine.elastic.service.ElasticIndexService import com.netgrif.application.engine.petrinet.domain.repository.UriNodeRepository import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository -import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.runner.* import com.netgrif.application.engine.workflow.service.interfaces.IFieldActionsCacheService @@ -71,9 +71,6 @@ class TestHelper { @Autowired private MenuProcessRunner menuProcessRunner - @Autowired - private ImpersonationRunner impersonationRunner - @Autowired private ElasticsearchRunner elasticsearchRunner @@ -104,7 +101,6 @@ class TestHelper { groupRunner.run() filterRunner.run() menuProcessRunner.run() - impersonationRunner.run() superCreator.run() finisherRunner.run() } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy deleted file mode 100644 index 5fef3a0e8e3..00000000000 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/impersonation/ImpersonationServiceTest.groovy +++ /dev/null @@ -1,354 +0,0 @@ -package com.netgrif.application.engine.impersonation - -import com.netgrif.application.engine.TestHelper -import com.netgrif.application.engine.auth.service.AuthorityService -import com.netgrif.application.engine.auth.service.UserService -import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService -import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationAuthorizationService -import com.netgrif.application.engine.impersonation.service.interfaces.IImpersonationService -import com.netgrif.application.engine.objects.auth.domain.AbstractUser -import com.netgrif.application.engine.objects.auth.domain.ActorTransformer -import com.netgrif.application.engine.objects.auth.domain.Authority - -import com.netgrif.application.engine.objects.auth.domain.User -import com.netgrif.application.engine.objects.auth.domain.enums.UserState -import com.netgrif.application.engine.objects.petrinet.domain.I18nString -import com.netgrif.application.engine.objects.petrinet.domain.PetriNet -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListFieldValue -import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole -import com.netgrif.application.engine.objects.workflow.domain.Case -import com.netgrif.application.engine.objects.workflow.domain.Task -import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService -import com.netgrif.application.engine.startup.ImportHelper -import com.netgrif.application.engine.startup.runner.ImpersonationRunner -import com.netgrif.application.engine.workflow.service.interfaces.* -import com.netgrif.application.engine.workflow.web.requestbodies.TaskSearchRequest -import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.TaskSearchCaseRequest -import groovy.json.JsonSlurper -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.context.SpringBootTest -import org.springframework.context.i18n.LocaleContextHolder -import org.springframework.data.domain.PageRequest -import org.springframework.http.MediaType -import org.springframework.mock.web.MockHttpServletRequest -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken -import org.springframework.security.core.Authentication -import org.springframework.security.core.GrantedAuthority -import org.springframework.security.core.context.SecurityContextHolder -import org.springframework.security.web.authentication.WebAuthenticationDetails -import org.springframework.session.web.http.SessionRepositoryFilter -import org.springframework.test.context.ActiveProfiles -import org.springframework.test.context.junit.jupiter.SpringExtension -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import org.springframework.web.context.WebApplicationContext - -import java.time.LocalDateTime - -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -@Disabled("Impersonation not reworked yet") -@SpringBootTest -@ActiveProfiles(["test"]) -@ExtendWith(SpringExtension.class) -class ImpersonationServiceTest { - - public static final String X_AUTH_TOKEN = "x-auth-token" - - @Autowired - private TestHelper testHelper - - @Autowired - private ImportHelper helper - - @Autowired - private UserService userService - - @Autowired - private IElasticCaseService elasticCaseService - - @Autowired - private IWorkflowService workflowService - - @Autowired - private IDataService dataService - - @Autowired - private ITaskService taskService - - @Autowired - private IPetriNetService petriNetService - - @Autowired - private AuthorityService authorityService - - @Autowired - private IImpersonationService impersonationService - - @Autowired - private IImpersonationAuthorizationService impersonationAuthorizationService - - @Autowired - private ITaskAuthorizationService taskAuthorizationService - - @Autowired - private IWorkflowAuthorizationService workflowAuthorizationService - - @Autowired - private WebApplicationContext wac - - MockMvc mvc - - Authentication auth1 - Authentication auth2 - Authentication adminUserAuth - - AbstractUser user1 - AbstractUser user2 - AbstractUser adminUser - - PetriNet testNet - - @BeforeEach - void before() { - testHelper.truncateDbs() - - SessionRepositoryFilter filter = wac.getBean(SessionRepositoryFilter.class); - mvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(filter).apply(springSecurity()).build() - - testNet = helper.createNet("impersonation_test.xml").get() - def authority = authorityService.getOrCreate(Authority.user) - def authorityAnon = authorityService.getOrCreate(Authority.anonymous) - def authorityAdmin = authorityService.getOrCreate(Authority.admin) - - user1 = helper.createUser(new User(firstName: "Test", lastName: "User", email: "test@netgrif.com", "username": "test@netgrif.com", password: "password", state: UserState.ACTIVE), - [authority] as Authority[], - [] as ProcessRole[]) - - auth1 = new UsernamePasswordAuthenticationToken(ActorTransformer.toLoggedUser(user1), (user1 as User).password, user1.authoritySet as List) - auth1.setDetails(new WebAuthenticationDetails(new MockHttpServletRequest())) - - user2 = helper.createUser(new User(firstName: "Test", lastName: "User2", email: "test2@netgrif.com", "username": "test2@netgrif.com", password: "password", state: UserState.ACTIVE), - [authority, authorityAnon] as Authority[], - testNet.roles.values() as ProcessRole[]) - - auth2 = new UsernamePasswordAuthenticationToken(ActorTransformer.toLoggedUser(user2), (user2 as User).password, user2.authoritySet as List) - auth2.setDetails(new WebAuthenticationDetails(new MockHttpServletRequest())) - - adminUser = helper.createUser(new User(firstName: "Admin", lastName: "User", email: "admin@netgrif.com", "username": "admin@netgrif.com", password: "password", state: UserState.ACTIVE), - [authority, authorityAdmin] as Authority[], - testNet.roles.values() as ProcessRole[]) - - adminUserAuth = new UsernamePasswordAuthenticationToken(ActorTransformer.toLoggedUser(adminUser), (adminUser as User).password, adminUser.authoritySet as List) - adminUserAuth.setDetails(new WebAuthenticationDetails(new MockHttpServletRequest())) - } - - @Test - void testImpersonationAdmin() { - // TODO: impersonation -// SecurityContextHolder.getContext().setAuthentication(adminUserAuth) -// assert impersonationAuthorizationService.canImpersonateUser(userService.loggedUserFromContext, user2.stringId) -// impersonationService.impersonateUser(user2.stringId) -// def impersonated = userService.loggedUser.getSelfOrImpersonated() -// assert userService.loggedUser.isImpersonating() -// assert impersonated.stringId == user2.stringId -// assert impersonated.authorities.collect { it.stringId }.sort() == user2.authorities.collect { it.stringId }.sort() -// assert impersonated.processRoles.collect { it.stringId }.sort() == user2.processRoles.collect { it.stringId }.sort() - } - - @Test - void testImpersonation() { - // TODO: impersonation -// def config = setup() -// assert impersonationAuthorizationService.canImpersonate(userService.loggedUserFromContext, config.stringId) -// impersonationService.impersonateByConfig(config.stringId) -// assert userService.loggedUser.isImpersonating() -// assert userService.loggedUser.getSelfOrImpersonated().stringId == user2.stringId -// -// impersonationService.endImpersonation() -// assert !userService.loggedUser.isImpersonating() - } - - @Test - void testImpersonationRolesAndAuths() { - // TODO: impersonation -// def role = user2.processRoles.find { it.importId == "test_role" } -// def auth = user2.authorities.find { it.name == Authority.user } -// def config = setup([role.stringId], [auth.stringId, authorityService.getOrCreate(Authority.admin).stringId]) -// -// impersonationService.impersonateByConfig(config.stringId) -// def impersonatedRoles = userService.loggedUser.getImpersonated().getProcessRoles() -// def impersonatedAuths = userService.loggedUser.getImpersonated().getAuthorities() -// assert impersonatedRoles.size() == 2 && impersonatedRoles.any { it.stringId == role.stringId } -// // default role counts -// assert impersonatedAuths.size() == 1 && impersonatedAuths[0].stringId == auth.stringId -// -// def transformedUser = ActorTransformer.toLoggedUser(userService.loggedUser) -// def transformedUserImpersonated = transformedUser.getSelfOrImpersonated() -// assert transformedUser.isImpersonating() -// assert transformedUserImpersonated.getProcessRoles().size() == 2 && transformedUserImpersonated.getProcessRoles().any { it.stringId == role.stringId } -// // default role counts -// assert transformedUserImpersonated.getAuthoritySet().size() == 1 && (transformedUserImpersonated.getAuthoritySet()[0] as Authority).stringId == auth.stringId - } - - @Test - void testTaskSearchAssignFinish() { - def config = setup() - impersonationService.impersonateByConfig(config.stringId) - - assert workflowAuthorizationService.canCallCreate(userService.loggedUserFromContext, testNet.stringId) - def testCase = createTestCase() - assert workflowAuthorizationService.canCallDelete(userService.loggedUserFromContext, testCase.stringId) - def testTask1 = loadTask(testCase, "t1") - - sleep(8000) // elastic - - def caseReq = new CaseSearchRequest() - caseReq.process = [new CaseSearchRequest.PetriNet(testCase.processIdentifier)] - def cases = elasticCaseService.search([caseReq], ActorTransformer.toLoggedUser(userService.loggedUser) , PageRequest.of(0, 1), LocaleContextHolder.locale, false) - assert !cases.content.isEmpty() - - def searchReq = new TaskSearchRequest() - searchReq.transitionId = ["t1"] - searchReq.useCase = [new TaskSearchCaseRequest(testCase.stringId, null)] - def tasks = taskService.search([searchReq], PageRequest.of(0, 1), ActorTransformer.toLoggedUser(userService.loggedUser) , LocaleContextHolder.locale, false) - assert tasks.content[0].stringId == testTask1.stringId - - assert taskAuthorizationService.canCallAssign(userService.loggedUserFromContext, testTask1.stringId) - taskService.assignTask(ActorTransformer.toLoggedUser(userService.loggedUser) , testTask1.stringId) - testTask1 = reloadTask(testTask1) - assert testTask1.userId == user2.stringId - - assert taskAuthorizationService.canCallSaveData(userService.loggedUserFromContext, testTask1.stringId) - assert taskAuthorizationService.canCallSaveFile(userService.loggedUserFromContext, testTask1.stringId) - - assert taskAuthorizationService.canCallFinish(userService.loggedUserFromContext, testTask1.stringId) - taskService.finishTask(ActorTransformer.toLoggedUser(userService.loggedUser) , testTask1.stringId) - } - - @Test - void testAuthorization() { - def config = setup() - sleep(4000) // elastic - - def logged = ActorTransformer.toLoggedUser(userService.loggedUser) - assert impersonationAuthorizationService.canImpersonate(logged, config.stringId) - assert impersonationAuthorizationService.canImpersonateUser(logged, user2.stringId) - - config.dataSet["valid_to"].value = LocalDateTime.now().minusMinutes(1) - workflowService.save(config) - sleep(4000) - - assert !impersonationAuthorizationService.canImpersonate(logged, config.stringId) - assert !impersonationAuthorizationService.canImpersonateUser(logged, user2.stringId) - } - - - @Test - @Disabled("Disabled until user refactor is merged in v7.0.0") - void testAuthMe() { - def config = setup() - def result = mvc.perform(get("/api/auth/login") - .with(httpBasic(user1.email, "password")) - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andReturn() - def token = result.response.getHeader(X_AUTH_TOKEN) - - result = mvc.perform(post("/api/impersonate/config/" + config.stringId) - .header(X_AUTH_TOKEN, token) - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andReturn() - - result = mvc.perform(get("/api/users/me") - .header(X_AUTH_TOKEN, token) - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andReturn() - - String string = result.getResponse().getContentAsString() - def json = new JsonSlurper().parse(string.getBytes()) - assert json["impersonated"] != null - // TODO this assert does not pass -> need fixing after user / impersonation refactor - - result = mvc.perform(post("/api/impersonate/clear") - .header(X_AUTH_TOKEN, token) - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andReturn() - - result = mvc.perform(get("/api/users/me") - .header(X_AUTH_TOKEN, token) - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8")) - .andExpect(status().isOk()) - .andReturn() - - string = result.getResponse().getContentAsString() - json = new JsonSlurper().parse(string.getBytes()) - assert json["impersonated"] == null - } - - def setup(List roles = null, List auths = null) { - def config = createConfigCase(user2, user1.stringId, roles, auths) - SecurityContextHolder.getContext().setAuthentication(auth1) - return config - } - - def createConfigCase(AbstractUser user, String impersonator, List roles = null, List auths = null) { - def caze = helper.createCase("config", petriNetService.getDefaultVersionByIdentifier(ImpersonationRunner.IMPERSONATION_CONFIG_PETRI_NET_IDENTIFIER)) - def owner = new UserFieldValue(user) - caze.dataSet["impersonated"].value = owner - caze.dataSet["impersonated_email"].value = owner.username - caze.dataSet["config_owner"].value = new UserListFieldValue([owner]) - caze.dataSet["impersonators"].value = [impersonator] - caze.dataSet["impersonated_roles"].value = roles ?: user.processRoles.stringId as List - caze.dataSet["impersonated_authorities"].value = auths ?: user.authoritySet.stringId as List - caze.dataSet["valid_from"].value = LocalDateTime.now().minusDays(1) - - /* set options so elastic indexing works */ - caze.dataSet["impersonators"].options = [(impersonator): new I18nString(impersonator)] - caze.dataSet["impersonated_roles"].options = (caze.dataSet["impersonated_roles"].value as List).collectEntries { [(it): new I18nString(it as String)] } as Map - caze.dataSet["impersonated_authorities"].options = (caze.dataSet["impersonated_authorities"].value as List).collectEntries { [(it): new I18nString(it as String)] } as Map - caze = workflowService.save(caze) - def initTask = caze.tasks.find { it.transition == "t2" }.task - taskService.assignTask(ActorTransformer.toLoggedUser(userService.system), initTask) - taskService.finishTask(ActorTransformer.toLoggedUser(userService.system), initTask) - return workflowService.findOne(caze.stringId) - } - - def createTestCase() { - return helper.createCase("test", testNet) - } - - def setData(Case caze, String transition, Map dataSet) { - dataService.setData(caze.tasks.find { it.transition == transition }.task, helper.populateDataset(dataSet.collectEntries { - [(it.key): (["value": it.value, "type": "text"])] - })) - return workflowService.findOne(caze.stringId) - } - - def loadTask(Case caze, String trans) { - return taskService.findById(caze.tasks.find { it.transition == trans }.task) - } - - def reloadTask(Task task) { - return taskService.findById(task.stringId) - } - -} diff --git a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationServiceTest.java b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationServiceTest.java index e2b9f2757fe..43ac195dc5b 100644 --- a/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationServiceTest.java +++ b/application-engine/src/test/java/com/netgrif/application/engine/workflow/service/AbstractAuthorizationServiceTest.java @@ -1,6 +1,7 @@ package com.netgrif.application.engine.workflow.service; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; import com.netgrif.application.engine.objects.auth.domain.User; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; import org.junit.jupiter.api.Test; @@ -19,7 +20,8 @@ @ExtendWith(SpringExtension.class) class AbstractAuthorizationServiceTest { - static class MockAuthorizationService extends AbstractAuthorizationService { } + static class MockAuthorizationService extends AbstractAuthorizationService { + } @Test public void hasPermission() { @@ -57,7 +59,7 @@ public void getAggregatePermissions() { netPermissions.put(roles.get(2).getStringId(), getInitEntryValue()); // situation 1 - Map aggregatePermission = mockInstance.getAggregatePermissions(user, netPermissions); + Map aggregatePermission = mockInstance.getAggregatePermissions(ActorTransformer.toLoggedUser(user), netPermissions); assert aggregatePermission.get("create"); assert aggregatePermission.get("view"); @@ -66,7 +68,7 @@ public void getAggregatePermissions() { // situation 2 netPermissions.get(roles.get(0).getStringId()).put("create", false); netPermissions.get(roles.get(1).getStringId()).put("delete", false); - aggregatePermission = mockInstance.getAggregatePermissions(user, netPermissions); + aggregatePermission = mockInstance.getAggregatePermissions(ActorTransformer.toLoggedUser(user), netPermissions); assert !aggregatePermission.get("create"); assert aggregatePermission.get("view"); diff --git a/docs/javadoc/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.html b/docs/javadoc/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.html index 1b8ba8e6e0e..53d404226f6 100644 --- a/docs/javadoc/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.html +++ b/docs/javadoc/com/netgrif/application/engine/configuration/security/ImpersonationRequestFilter.html @@ -254,7 +254,7 @@

Method Summary

protected boolean -isValid​(Impersonator impersonator) +isValid​(Impersonator impersonator)   @@ -380,7 +380,7 @@

handleImpersonated

javax.servlet.http.HttpServletRequest servletRequest)
- +
    diff --git a/docs/javadoc/com/netgrif/application/engine/impersonation/domain/Impersonator.html b/docs/javadoc/com/netgrif/application/engine/impersonation/domain/Impersonator.html index a068e7080b3..425a2c33c5d 100644 --- a/docs/javadoc/com/netgrif/application/engine/impersonation/domain/Impersonator.html +++ b/docs/javadoc/com/netgrif/application/engine/impersonation/domain/Impersonator.html @@ -119,7 +119,7 @@

    Class Impersonator

  • java.lang.Object
    • -
    • com.netgrif.application.engine.impersonation.domain.Impersonator
    • +
    • com.netgrif.application.engine.auth.domain.Impersonator
@@ -137,7 +137,7 @@

Class Impersonator

implements java.io.Serializable
See Also:
-
Serialized Form
+
Serialized Form
diff --git a/docs/javadoc/com/netgrif/application/engine/impersonation/domain/class-use/Impersonator.html b/docs/javadoc/com/netgrif/application/engine/impersonation/domain/class-use/Impersonator.html index 22b624fa32f..d1f001a4094 100644 --- a/docs/javadoc/com/netgrif/application/engine/impersonation/domain/class-use/Impersonator.html +++ b/docs/javadoc/com/netgrif/application/engine/impersonation/domain/class-use/Impersonator.html @@ -3,7 +3,7 @@ -Uses of Class com.netgrif.application.engine.impersonation.domain.Impersonator (NETGRIF Application Engine 6.4.0 API) +Uses of Class com.netgrif.application.engine.auth.domain.Impersonator (NETGRIF Application Engine 6.4.0 API) @@ -22,7 +22,7 @@