diff --git a/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java b/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java index cbb88b52fe..6eb471472c 100644 --- a/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java +++ b/src/main/java/com/netgrif/application/engine/elastic/service/ElasticTaskService.java @@ -178,7 +178,6 @@ protected BoolQueryBuilder buildSingleQuery(ElasticTaskSearchRequest request, Lo if (request == null) { throw new IllegalArgumentException("Request can not be null!"); } - addRolesQueryConstraint(request, user); BoolQueryBuilder query = boolQuery(); buildViewPermissionQuery(query, user); @@ -198,17 +197,6 @@ protected BoolQueryBuilder buildSingleQuery(ElasticTaskSearchRequest request, Lo return query; } - protected void addRolesQueryConstraint(ElasticTaskSearchRequest request, LoggedUser user) { - if (request.role != null && !request.role.isEmpty()) { - Set roles = new HashSet<>(request.role); - roles.addAll(user.getProcessRoles()); - request.role = new ArrayList<>(roles); - } else { - request.role = new ArrayList<>(user.getProcessRoles()); - } - } - - /** * Tasks of case with id "5cb07b6ff05be15f0b972c4d" * { diff --git a/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java b/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java index cc736dd348..578b63c563 100644 --- a/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java +++ b/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java @@ -8,93 +8,64 @@ public abstract class ElasticViewPermissionService { protected void buildViewPermissionQuery(BoolQueryBuilder query, LoggedUser user) { - // Check if viewRoles or viewUserRefs exist - BoolQueryBuilder viewPermsExists = boolQuery() - .should(existsQuery("viewRoles")) - .should(existsQuery("viewUserRefs")); - // Condition where these attributes do NOT exist - BoolQueryBuilder viewPermNotExists = boolQuery() - .mustNot(viewPermsExists); - /* Build positive view role query */ - BoolQueryBuilder positiveViewRole = buildPositiveViewRoleQuery(viewPermNotExists, user); +// (Rp!=0 & Rn = 0) + BoolQueryBuilder roleViewQuery = boolQuery() + .filter(buildPositiveViewRoleQuery(user)) + .mustNot(buildNegativeViewRoleQuery(user)); - /* Build negative view role query */ - BoolQueryBuilder negativeViewRole = buildNegativeViewRoleQuery(user); - - /* Positive view role set-minus negative view role */ - BoolQueryBuilder positiveRoleSetMinusNegativeRole = setMinus(positiveViewRole, negativeViewRole); - - /* Build positive view userList query */ - BoolQueryBuilder positiveViewUser = buildPositiveViewUser(viewPermNotExists, user); - - /* Role query union positive view userList */ - BoolQueryBuilder roleSetMinusPositiveUserList = union(positiveRoleSetMinusNegativeRole, positiveViewUser); - - /* Build negative view userList query */ - BoolQueryBuilder negativeViewUser = buildNegativeViewUser(user); - - /* Role-UserListPositive set-minus negative view userList */ - BoolQueryBuilder permissionQuery = setMinus(roleSetMinusPositiveUserList, negativeViewUser); +// ((Rp!=0 & Rn = 0) or Up!=0) + BoolQueryBuilder roleOrPositiveUserQuery = boolQuery().should(roleViewQuery) + .should(buildPositiveViewUser(user)) + .minimumShouldMatch(1); - query.filter(permissionQuery); +// (((Rp!=0 & Rn = 0) or Up!=0) & Un=0) == 1 + query.filter(roleOrPositiveUserQuery) + .mustNot(buildNegativeViewUser(user)); } /** * Build a positive view role query using termsQuery for efficiency. * This reduces the number of clauses by sending all roles at once. */ - private BoolQueryBuilder buildPositiveViewRoleQuery(BoolQueryBuilder viewPermNotExists, LoggedUser user) { + private BoolQueryBuilder buildPositiveViewRoleQuery(LoggedUser user) { BoolQueryBuilder positiveViewRole = boolQuery(); if (!user.getProcessRoles().isEmpty()) { positiveViewRole.should(termsQuery("viewRoles", user.getProcessRoles())); } - positiveViewRole.should(viewPermNotExists); + positiveViewRole.minimumShouldMatch(1); return positiveViewRole; } /** - * Build a negative view role query by excluding negative roles. + * Build a negative view role query. */ private BoolQueryBuilder buildNegativeViewRoleQuery(LoggedUser user) { BoolQueryBuilder negativeViewRole = boolQuery(); if (!user.getProcessRoles().isEmpty()) { - negativeViewRole.mustNot(termsQuery("negativeViewRoles", user.getProcessRoles())); + negativeViewRole.should(termsQuery("negativeViewRoles", user.getProcessRoles())); } + negativeViewRole.minimumShouldMatch(1); return negativeViewRole; } /** - * Build a positive view user query using filter (as score is not needed). + * Build a positive view user query. */ - private BoolQueryBuilder buildPositiveViewUser(BoolQueryBuilder viewPermNotExists, LoggedUser user) { - return boolQuery() - .should(viewPermNotExists) - .filter(termQuery("viewUsers", user.getId())); + private BoolQueryBuilder buildPositiveViewUser(LoggedUser user) { + BoolQueryBuilder positiveViewUser = boolQuery(); + positiveViewUser.should(termQuery("viewUsers", user.getId())); + positiveViewUser.minimumShouldMatch(1); + return positiveViewUser; } /** - * Build a negative view user query to exclude the specified user. + * Build a negative view user query. */ private BoolQueryBuilder buildNegativeViewUser(LoggedUser user) { - return boolQuery() - .mustNot(termQuery("negativeViewUsers", user.getId())); - } - - private BoolQueryBuilder setMinus(BoolQueryBuilder positiveSet, BoolQueryBuilder negativeSet) { - BoolQueryBuilder positiveSetMinusNegativeSet = boolQuery(); - positiveSetMinusNegativeSet.must(positiveSet); - positiveSetMinusNegativeSet.must(negativeSet); - return positiveSetMinusNegativeSet; - } - - /** - * Unions two queries using OR with a minimum_should_match of 1. - */ - private BoolQueryBuilder union(BoolQueryBuilder setA, BoolQueryBuilder setB) { - return boolQuery() - .should(setA) - .should(setB) - .minimumShouldMatch(1); + BoolQueryBuilder negativeViewUser = boolQuery(); + negativeViewUser.should(termQuery("negativeViewUsers", user.getId())); + negativeViewUser.minimumShouldMatch(1); + return negativeViewUser; } } diff --git a/src/main/java/com/netgrif/application/engine/importer/service/Importer.java b/src/main/java/com/netgrif/application/engine/importer/service/Importer.java index 596db2e301..a488d03643 100644 --- a/src/main/java/com/netgrif/application/engine/importer/service/Importer.java +++ b/src/main/java/com/netgrif/application/engine/importer/service/Importer.java @@ -1156,11 +1156,10 @@ protected void addPredefinedRolesWithDefaultPermissions(com.netgrif.application. return; } } - // Don't add if positive roles or triggers or positive user refs - if ((importTransition.getRoleRef() != null && importTransition.getRoleRef().stream().anyMatch(this::hasPositivePermission)) - || (importTransition.getTrigger() != null && !importTransition.getTrigger().isEmpty()) - || (importTransition.getUsersRef() != null && importTransition.getUsersRef().stream().anyMatch(this::hasPositivePermission)) - || (importTransition.getUserRef() != null && importTransition.getUserRef().stream().anyMatch(this::hasPositivePermission))) { + + if ((importTransition.getRoleRef() != null && !importTransition.getRoleRef().isEmpty()) || + (importTransition.getUsersRef() != null && !importTransition.getUsersRef().isEmpty()) || + (importTransition.getUserRef() != null && !importTransition.getUserRef().isEmpty())) { return; } @@ -1168,20 +1167,9 @@ protected void addPredefinedRolesWithDefaultPermissions(com.netgrif.application. addAnonymousRole(transition); } - protected boolean hasPositivePermission(PermissionRef permissionRef) { - return (permissionRef.getLogic().isPerform() != null && permissionRef.getLogic().isPerform()) - || (permissionRef.getLogic().isCancel() != null && permissionRef.getLogic().isCancel()) - || (permissionRef.getLogic().isView() != null && permissionRef.getLogic().isView()) - || (permissionRef.getLogic().isAssign() != null && permissionRef.getLogic().isAssign()) - || (permissionRef.getLogic().isAssigned() != null && permissionRef.getLogic().isAssigned()) - || (permissionRef.getLogic().isFinish() != null && permissionRef.getLogic().isFinish()) - || (permissionRef.getLogic().isDelegate() != null && permissionRef.getLogic().isDelegate()); - } - protected void addPredefinedRolesWithDefaultPermissions() { // only if no positive role associations and no positive user ref associations - if (net.getPermissions().values().stream().anyMatch(perms -> perms.containsValue(true)) - || net.getUserRefs().values().stream().anyMatch(perms -> perms.containsValue(true))) { + if (!net.getPermissions().isEmpty() || !net.getUserRefs().isEmpty()) { return; } diff --git a/src/main/java/com/netgrif/application/engine/workflow/domain/Case.java b/src/main/java/com/netgrif/application/engine/workflow/domain/Case.java index 039f6db8b7..49ee45029f 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/domain/Case.java +++ b/src/main/java/com/netgrif/application/engine/workflow/domain/Case.java @@ -354,9 +354,16 @@ public void resolveViewUserRefs() { public void resolveViewUsers() { getViewUsers(); this.viewUsers.clear(); + this.negativeViewUsers.clear(); this.users.forEach((user, perms) -> { - if (perms.containsKey(RolePermission.VIEW.getValue()) && perms.get(RolePermission.VIEW.getValue())) { + if (!perms.containsKey(RolePermission.VIEW.getValue())) { + return; + } + boolean viewPermission = perms.get(RolePermission.VIEW.getValue()); + if(viewPermission){ viewUsers.add(user); + } else { + negativeViewUsers.add(user); } }); } diff --git a/src/main/java/com/netgrif/application/engine/workflow/domain/Task.java b/src/main/java/com/netgrif/application/engine/workflow/domain/Task.java index 75d7e999c4..795059a595 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/domain/Task.java +++ b/src/main/java/com/netgrif/application/engine/workflow/domain/Task.java @@ -329,9 +329,16 @@ public void resolveViewUserRefs() { public void resolveViewUsers() { getViewUsers(); this.viewUsers.clear(); + this.negativeViewUsers.clear(); this.users.forEach((role, perms) -> { - if (perms.containsKey(RolePermission.VIEW.getValue()) && perms.get(RolePermission.VIEW.getValue())) { + if (!perms.containsKey(RolePermission.VIEW.getValue())) { + return; + } + boolean viewPermission = perms.get(RolePermission.VIEW.getValue()); + if (viewPermission) { viewUsers.add(role); + } else { + negativeViewUsers.add(role); } }); } diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java b/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java index aace6fb034..4c5fe9b4a3 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java +++ b/src/main/java/com/netgrif/application/engine/workflow/service/TaskSearchService.java @@ -41,16 +41,17 @@ public Predicate buildQuery(List requests, LoggedUser user, L BooleanBuilder builder = constructPredicateTree(singleQueries, isIntersection ? BooleanBuilder::and : BooleanBuilder::or); - BooleanBuilder constraints = new BooleanBuilder(buildRolesQueryConstraint(loggedOrImpersonated)); - constraints.or(buildUserRefQueryConstraint(loggedOrImpersonated)); - builder.and(constraints); - - BooleanBuilder permissionConstraints = new BooleanBuilder(buildViewRoleQueryConstraint(loggedOrImpersonated)); - permissionConstraints.andNot(buildNegativeViewRoleQueryConstraint(loggedOrImpersonated)); - permissionConstraints.or(buildViewUserQueryConstraint(loggedOrImpersonated)); - permissionConstraints.andNot(buildNegativeViewUsersQueryConstraint(loggedOrImpersonated)); - builder.and(permissionConstraints); - return builder; + // (Rp!=0 & Rn = 0) + BooleanBuilder constraints = new BooleanBuilder(buildViewRoleQueryConstraint(loggedOrImpersonated)) + .andNot(buildNegativeViewRoleQueryConstraint(loggedOrImpersonated)); + + // ((Rp!=0 & Rn = 0) or Up!=0) + constraints.or(buildViewUserQueryConstraint(loggedOrImpersonated)); + + // (((Rp!=0 & Rn = 0) or Up!=0) & Un=0) == 1 + constraints.andNot(buildNegativeViewUsersQueryConstraint(loggedOrImpersonated)); + + return builder.and(constraints); } protected Predicate buildRolesQueryConstraint(LoggedUser user) { @@ -69,7 +70,7 @@ protected Predicate buildViewRoleQueryConstraint(LoggedUser user) { } public Predicate viewRoleQuery(String role) { - return QTask.task.viewUserRefs.isEmpty().and(QTask.task.viewRoles.isEmpty()).or(QTask.task.viewRoles.contains(role)); + return QTask.task.viewRoles.contains(role); } protected Predicate buildViewUserQueryConstraint(LoggedUser user) { @@ -78,7 +79,7 @@ protected Predicate buildViewUserQueryConstraint(LoggedUser user) { } public Predicate viewUsersQuery(String userId) { - return QTask.task.negativeViewRoles.isEmpty().and(QTask.task.viewUserRefs.isEmpty()).and(QTask.task.viewRoles.isEmpty()).or(QTask.task.viewUsers.contains(userId)); + return QTask.task.viewUsers.contains(userId); } protected Predicate buildNegativeViewRoleQueryConstraint(LoggedUser user) { diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 910e759000..a06eec049f 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -780,12 +780,9 @@ public List resolveUserRef(Case useCase) { @Override public Task resolveUserRef(Task task, Case useCase) { task.getUsers().clear(); - task.getNegativeViewUsers().clear(); task.getUserRefs().forEach((id, permission) -> { List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(id).getValue()); - if (userIds != null && !userIds.isEmpty() && permission.containsKey("view") && !permission.get("view")) { - task.getNegativeViewUsers().addAll(userIds); - } else if (userIds != null && !userIds.isEmpty()) { + if (userIds != null && !userIds.isEmpty()) { task.addUsers(new HashSet<>(userIds), permission); } }); diff --git a/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java b/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java index 87bcb62a02..c9d434f753 100644 --- a/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java +++ b/src/main/java/com/netgrif/application/engine/workflow/service/WorkflowService.java @@ -218,7 +218,6 @@ public long count(Map request, LoggedUser user, Locale locale) { @Override public Case resolveUserRef(Case useCase) { useCase.getUsers().clear(); - useCase.getNegativeViewUsers().clear(); useCase.getUserRefs().forEach((id, permission) -> { resolveUserRefPermissions(useCase, id, permission); }); @@ -230,11 +229,7 @@ public Case resolveUserRef(Case useCase) { private void resolveUserRefPermissions(Case useCase, String userListId, Map permission) { List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(userListId).getValue()); if (userIds != null && !userIds.isEmpty()) { - if (permission.containsKey("view") && !permission.get("view")) { - useCase.getNegativeViewUsers().addAll(userIds); - } else { - useCase.addUsers(new HashSet<>(userIds), permission); - } + useCase.addUsers(new HashSet<>(userIds), permission); } } diff --git a/src/test/groovy/com/netgrif/application/engine/workflow/TaskPermissionsTest.groovy b/src/test/groovy/com/netgrif/application/engine/workflow/TaskPermissionsTest.groovy new file mode 100644 index 0000000000..a2e4ee0b4d --- /dev/null +++ b/src/test/groovy/com/netgrif/application/engine/workflow/TaskPermissionsTest.groovy @@ -0,0 +1,276 @@ +package com.netgrif.application.engine.workflow + +import com.netgrif.application.engine.TestHelper +import com.netgrif.application.engine.auth.domain.IUser +import com.netgrif.application.engine.auth.domain.User +import com.netgrif.application.engine.auth.domain.UserState +import com.netgrif.application.engine.auth.service.interfaces.IUserService +import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskService +import com.netgrif.application.engine.elastic.web.requestbodies.ElasticTaskSearchRequest +import com.netgrif.application.engine.petrinet.domain.PetriNet +import com.netgrif.application.engine.petrinet.domain.VersionType +import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.ActionDelegate +import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService +import com.netgrif.application.engine.workflow.domain.Case +import com.netgrif.application.engine.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 +import com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.TaskSearchCaseRequest +import org.junit.jupiter.api.BeforeEach +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.Page +import org.springframework.data.domain.Pageable +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.junit.jupiter.SpringExtension + +import java.util.stream.Collectors + +@SpringBootTest +@ActiveProfiles(["test"]) +@ExtendWith(SpringExtension.class) +class TaskPermissionsTest { + + @Autowired + private IElasticTaskService elasticTaskService + + @Autowired + private ITaskService taskService + + @Autowired + private IWorkflowService workflowService + + @Autowired + private IPetriNetService petriNetService + + @Autowired + private IUserService userService + + @Autowired + private IDataService dataService + + @Autowired + private ActionDelegate actionDelegate + + @Autowired + private TestHelper testHelper + + private static final String TEST_NET = "view_permission_combinations.xml" + private static final String TEST_NET_NO_DEFAULT = "view_permission_combinations_no_default.xml" + private static final String CORRECT_PERMISSIONS_CSV_FILEPATH = "src/test/resources/csv/permissions - correct.csv" + private static final String CORRECT_PERMISSIONS_DEFAULT_DISABLED_CSV_FILEPATH = "src/test/resources/csv/permissions - correct default disabled.csv" + private static Case testCase + private static Case testCaseNoDefault + private static Map testUsers = [:] + private static Map>> correctResults = new HashMap<>() + + @BeforeEach() + void init() { + testHelper.truncateDbs() + actionDelegate.outcomes = [] + testUsers.clear() + correctResults.clear() + testCase = null + testCaseNoDefault = null + + PetriNet net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/" + TEST_NET), VersionType.MAJOR, userService.getLoggedOrSystem().transformToLoggedUser()).getNet() + PetriNet netNoDefault = petriNetService.importPetriNet(new FileInputStream("src/test/resources/petriNets/" + TEST_NET_NO_DEFAULT), VersionType.MAJOR, userService.getLoggedOrSystem().transformToLoggedUser()).getNet() + + testCase = workflowService.createCaseByIdentifier(net.identifier, "Test case", "", userService.getLoggedOrSystem().transformToLoggedUser()).getCase() + testCaseNoDefault = workflowService.createCaseByIdentifier(netNoDefault.identifier, "Test case with no default", "", userService.getLoggedOrSystem().transformToLoggedUser()).getCase() + + [ + new User("no_permissions@mail.com", "password", "No", "Permissions"), + new User("has_role@mail.com", "password", "Has", "Role"), + new User("in_userRef@mail.com", "password", "In", "UserRef"), + new User("both_permissions@mail.com", "password", "Both", "Permissions") + ].each { + it.setState(UserState.ACTIVE) + testUsers.put(it.getEmail(), userService.saveNew(it)) + } + + List withRoles = [testUsers.get("has_role@mail.com"), testUsers.get("both_permissions@mail.com")] + List inUserRef = [testUsers.get("in_userRef@mail.com").stringId, testUsers.get("both_permissions@mail.com").stringId] + + withRoles.forEach { + testUsers.put(it.getEmail(), userService.addRole(testUsers.get(it.getEmail()), net.roles.values().find { role -> role.importId == "process_role" }.stringId)) + testUsers.put(it.getEmail(), userService.addRole(testUsers.get(it.getEmail()), netNoDefault.roles.values().find { role -> role.importId == "process_role" }.stringId)) + } + + testCase = actionDelegate.setData("t_001", testCase, [ + "users": [ + "type" : "userList", + "value": inUserRef + ] + ]).getCase() + + testCaseNoDefault = actionDelegate.setData("t_007", testCaseNoDefault, [ + "users": [ + "type" : "userList", + "value": inUserRef + ] + ]).getCase() + + correctResults = permissionsCsvToExpectedMap() + } + + static Map>> permissionsCsvToExpectedMap() { + Map>> expectedMap = initializeExpectedPermissionsMap() + + addPermissionsCsvToExpectedMap( + CORRECT_PERMISSIONS_CSV_FILEPATH, + "Default enabled", + expectedMap + ) + + addPermissionsCsvToExpectedMap( + CORRECT_PERMISSIONS_DEFAULT_DISABLED_CSV_FILEPATH, + "Default DISabled", + expectedMap + ) + + return expectedMap + } + + static void addPermissionsCsvToExpectedMap(String csvFilePath, + String defaultRoleKey, + Map>> expectedMap) { + File csvFile = new File(csvFilePath) + Map userColumns = userColumns() + + List lines = csvFile.readLines("UTF-8").findAll { it?.trim() } + assert !lines.isEmpty(): "CSV file is empty: ${csvFilePath}" + List header = lines.first().split(",", -1)*.trim() + + int transitionIdIndex = header.indexOf("Transition ID") + assert transitionIdIndex >= 0: "Missing required column 'Transition ID' in ${csvFilePath}" + + lines.tail().each { line -> + List columns = line.split(",", -1)*.trim() + String transitionId = columns[transitionIdIndex] + + userColumns.each { csvColumnName, userEmail -> + int permissionIndex = header.indexOf(csvColumnName) + assert permissionIndex >= 0: "Missing required column '${csvColumnName}' in ${csvFilePath}" + + String permissionValue = columns[permissionIndex] + .replace(".", "") + .trim() + .toUpperCase() + + if (permissionValue == "TRUE") { + expectedMap[userEmail][defaultRoleKey] << transitionId + } + } + } + + expectedMap.values().each { Map> permissionsByDefaultRole -> + permissionsByDefaultRole[defaultRoleKey].sort() + } + } + + static Map>> initializeExpectedPermissionsMap() { + return userColumns().values().collectEntries { String email -> + [ + email, + [ + "Default enabled" : [], + "Default DISabled": [] + ] + ] + } + } + + static Map userColumns() { + return [ + "No permissions" : "no_permissions@mail.com", + "Has role" : "has_role@mail.com", + "Is in userList" : "in_userRef@mail.com", + "Has role and is in userList": "both_permissions@mail.com" + ] + } + + @Test + void testViewPermissions() { + def mapElastic = [:] + def mapMongo = [:] +// todo test for both mongo and elastic + ElasticTaskSearchRequest request = new ElasticTaskSearchRequest() + request.useCase = [new TaskSearchCaseRequest(testCase.stringId, testCase.title)] + + ElasticTaskSearchRequest request2 = new ElasticTaskSearchRequest() + request2.useCase = [new TaskSearchCaseRequest(testCaseNoDefault.stringId, testCaseNoDefault.title)] + + testUsers.forEach((key, value) -> { +// Elastic task search + Page tasks = elasticTaskService.search([request], + value.transformToLoggedUser(), + Pageable.unpaged(), LocaleContextHolder.getLocale(), false) + List list = new ArrayList<>(tasks.content).stream().map(task -> task.transitionId).collect(Collectors.toList()).sort() + + + Page tasks2 = elasticTaskService.search([request2], + value.transformToLoggedUser(), + Pageable.unpaged(), LocaleContextHolder.getLocale(), false) + List list2 = new ArrayList<>(tasks2.content).stream().map(task -> task.transitionId).collect(Collectors.toList()).sort() + +// Mongo task search + Page mongoTasksDefault = taskService.search([request], Pageable.unpaged(), value.transformToLoggedUser(), LocaleContextHolder.getLocale(), false) + List mongoListDefault = new ArrayList<>(mongoTasksDefault.content).stream().map(task -> task.transitionId).collect(Collectors.toList()).sort() + Page mongoTasksNoDefault = taskService.search([request2], Pageable.unpaged(), value.transformToLoggedUser(), LocaleContextHolder.getLocale(), false) + List mongoListNoDefault = new ArrayList<>(mongoTasksNoDefault.content).stream().map(task -> task.transitionId).collect(Collectors.toList()).sort() + + mapElastic.put(key, [ + "Default enabled" : list, + "Default DISabled": list2 + ]) + + mapMongo.put(key, [ + "Default enabled" : mongoListDefault, + "Default DISabled": mongoListNoDefault + ]) + }) + compareTestResultsToExpected(mapElastic, "Elastic search") + compareTestResultsToExpected(mapMongo, "Mongo search") + } + + static void compareTestResultsToExpected(Map>> testResultMap, String searchType) { + println("\n========== ${searchType} - View permissions comparison ==========") + + testUsers.keySet().each { String userEmail -> + println("\nUser: ${userEmail}") + + ["Default enabled", "Default DISabled"].each { String defaultRoleKey -> + Set actualTransitionIds = new TreeSet<>( + testResultMap.get(userEmail)?.get(defaultRoleKey) ?: [] + ) + + Set expectedTransitionIds = new TreeSet<>( + correctResults.get(userEmail)?.get(defaultRoleKey) ?: [] + ) + + Set presentInBoth = new TreeSet<>(actualTransitionIds) + presentInBoth.retainAll(expectedTransitionIds) + + Set presentOnlyInMap = new TreeSet<>(actualTransitionIds) + presentOnlyInMap.removeAll(expectedTransitionIds) + + Set presentOnlyInCorrectResultsWithDefaultRoleMap = new TreeSet<>(expectedTransitionIds) + presentOnlyInCorrectResultsWithDefaultRoleMap.removeAll(actualTransitionIds) + + println("\n${searchType} - ${defaultRoleKey}:") + println("Present in both results (${presentInBoth.size()}): ${presentInBoth}") + println("Present only in test results (${presentOnlyInMap.size()}): ${presentOnlyInMap}") + println("Present only in correct results (${presentOnlyInCorrectResultsWithDefaultRoleMap.size()}): ${presentOnlyInCorrectResultsWithDefaultRoleMap}") + + assert presentInBoth.size() == actualTransitionIds.size() && presentInBoth.size() == expectedTransitionIds.size() + } + } + + println("\n=================================================") + } +} \ No newline at end of file diff --git a/src/test/resources/csv/permissions - correct default disabled.csv b/src/test/resources/csv/permissions - correct default disabled.csv new file mode 100644 index 0000000000..bba1da1c6c --- /dev/null +++ b/src/test/resources/csv/permissions - correct default disabled.csv @@ -0,0 +1,10 @@ +Transition ID,Transition title,roleRef,userRef,No permissions,Has role,Is in userList,Has role and is in userList +t_007,role=true user=true,TRUE,TRUE,FALSE,TRUE,TRUE,TRUE +t_008,role=true user=false,TRUE,FALSE,FALSE,TRUE,FALSE,FALSE +t_009,role=true user=undefined,TRUE,undefined,FALSE,TRUE,FALSE,TRUE +t_016,role=false user=true,FALSE,TRUE,FALSE,FALSE,TRUE,TRUE +t_017,role=false user=false,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE +t_018,role=false user=undefined,FALSE,undefined,FALSE,FALSE,FALSE,FALSE +t_025,role=undefined user=true,undefined,TRUE,FALSE,FALSE,TRUE,TRUE +t_026,role=undefined user=false,undefined,FALSE,FALSE,FALSE,FALSE,FALSE +t_027,role=undefined user=undefined,undefined,undefined,FALSE,FALSE,FALSE,FALSE \ No newline at end of file diff --git a/src/test/resources/csv/permissions - correct.csv b/src/test/resources/csv/permissions - correct.csv new file mode 100644 index 0000000000..feb3ef6f84 --- /dev/null +++ b/src/test/resources/csv/permissions - correct.csv @@ -0,0 +1,28 @@ +Transition ID,Transition title,default role,roleRef,userRef,No permissions,Has role,Is in userList,Has role and is in userList +t_005,role=true default=false user=false,false,true,false,FALSE,FALSE,FALSE,FALSE +t_014,role=false default=false user=false,false,false,false,FALSE,FALSE,FALSE,FALSE +t_023,role=undefined default=false user=false,false,undefined,false,FALSE,FALSE,FALSE,FALSE +t_004,role=true default=false user=true,false,true,true,FALSE,FALSE,TRUE,TRUE +t_013,role=false default=false user=true,false,false,true,FALSE,FALSE,TRUE,TRUE +t_022,role=undefined default=false user=true,false,undefined,true,FALSE,FALSE,TRUE,TRUE +t_006,role=true default=false user=undefined,false,true,undefined,FALSE,FALSE,FALSE,FALSE +t_015,role=false default=false user=undefined,false,false,undefined,FALSE,FALSE,FALSE,FALSE +t_024,role=undefined default=false user=undefined,false,undefined,undefined,FALSE,FALSE,FALSE,FALSE +t_002,role=true default=true user=false,true,true,false,TRUE,TRUE,FALSE,FALSE +t_011,role=false default=true user=false,true,false,false,TRUE,FALSE,FALSE,FALSE +t_020,role=undefined default=true user=false,true,undefined,false,TRUE,TRUE,FALSE,FALSE +t_001,role=true default=true user=true,true,true,true,TRUE,TRUE,TRUE,TRUE +t_010,role=false default=true user=true,true,false,true,TRUE,FALSE,TRUE,TRUE +t_019,role=undefined default=true user=true,true,undefined,true,TRUE,TRUE,TRUE,TRUE +t_003,role=true default=true user=undefined,true,true,undefined,TRUE,TRUE,TRUE,TRUE +t_012,role=false default=true user=undefined,true,false,undefined,TRUE,FALSE,TRUE,FALSE +t_021,role=undefined default=true user=undefined,true,undefined,undefined,TRUE,TRUE,TRUE,TRUE +t_008,role=true default=undefined user=false,undefined,true,false,FALSE,TRUE,FALSE,FALSE +t_017,role=false default=undefined user=false,undefined,false,false,FALSE,FALSE,FALSE,FALSE +t_026,role=undefined default=undefined user=false,undefined,undefined,false,FALSE,FALSE,FALSE,FALSE +t_007,role=true default=undefined user=true,undefined,true,true,FALSE,TRUE,TRUE,TRUE +t_016,role=false default=undefined user=true,undefined,false,true,FALSE,FALSE,TRUE,TRUE +t_025,role=undefined default=undefined user=true,undefined,undefined,true,FALSE,FALSE,TRUE,TRUE +t_009,role=true default=undefined user=undefined,undefined,true,undefined,FALSE,TRUE,FALSE,TRUE +t_018,role=false default=undefined user=undefined,undefined,false,undefined,FALSE,FALSE,FALSE,FALSE +t_027,role=undefined default=undefined user=undefined,undefined,undefined,undefined,TRUE,TRUE,TRUE,TRUE \ No newline at end of file diff --git a/src/test/resources/petriNets/view_permission_combinations.xml b/src/test/resources/petriNets/view_permission_combinations.xml new file mode 100644 index 0000000000..8cf5d10d3d --- /dev/null +++ b/src/test/resources/petriNets/view_permission_combinations.xml @@ -0,0 +1,532 @@ + + + view_permission_combinations + 1.0.0 + VPC + View Permission Combinations + true + + + process_role + Process Role + + + + users + Users + + + + t_001 + 100 + 100 + + + process_role + + true + + + + default + + true + + + + users + + true + + + + + + t_002 + 300 + 100 + + + process_role + + true + + + + default + + true + + + + users + + false + + + + + + t_003 + 500 + 100 + + + process_role + + true + + + + default + + true + + + + + + t_004 + 700 + 100 + + + process_role + + true + + + + default + + false + + + + users + + true + + + + + + t_005 + 900 + 100 + + + process_role + + true + + + + default + + false + + + + users + + false + + + + + + t_006 + 1100 + 100 + + + process_role + + true + + + + default + + false + + + + + + t_007 + 1300 + 100 + + + process_role + + true + + + + users + + true + + + + + + t_008 + 1500 + 100 + + + process_role + + true + + + + users + + false + + + + + + t_009 + 1700 + 100 + + + process_role + + true + + + + + + t_010 + 100 + 300 + + + process_role + + false + + + + default + + true + + + + users + + true + + + + + + t_011 + 300 + 300 + + + process_role + + false + + + + default + + true + + + + users + + false + + + + + + t_012 + 500 + 300 + + + process_role + + false + + + + default + + true + + + + + + t_013 + 700 + 300 + + + process_role + + false + + + + default + + false + + + + users + + true + + + + + + t_014 + 900 + 300 + + + process_role + + false + + + + default + + false + + + + users + + false + + + + + + t_015 + 1100 + 300 + + + process_role + + false + + + + default + + false + + + + + + t_016 + 1300 + 300 + + + process_role + + false + + + + users + + true + + + + + + t_017 + 1500 + 300 + + + process_role + + false + + + + users + + false + + + + + + t_018 + 1700 + 300 + + + process_role + + false + + + + + + t_019 + 100 + 500 + + + default + + true + + + + users + + true + + + + + + t_020 + 300 + 500 + + + default + + true + + + + users + + false + + + + + + t_021 + 500 + 500 + + + default + + true + + + + + + t_022 + 700 + 500 + + + default + + false + + + + users + + true + + + + + + t_023 + 900 + 500 + + + default + + false + + + + users + + false + + + + + + t_024 + 1100 + 500 + + + default + + false + + + + + + t_025 + 1300 + 500 + + + users + + true + + + + + + t_026 + 1500 + 500 + + + users + + false + + + + + + t_027 + 1700 + 500 + + + \ No newline at end of file diff --git a/src/test/resources/petriNets/view_permission_combinations_no_default.xml b/src/test/resources/petriNets/view_permission_combinations_no_default.xml new file mode 100644 index 0000000000..0da52e1f84 --- /dev/null +++ b/src/test/resources/petriNets/view_permission_combinations_no_default.xml @@ -0,0 +1,154 @@ + + + view_permission_combinations_no_default + 1.0.0 + VPC + View Permission Combinations With Default Role Disabled + false + + + process_role + Process Role + + + + users + Users + + + + t_007 + 1300 + 100 + + + process_role + + true + + + + users + + true + + + + + + t_008 + 1500 + 100 + + + process_role + + true + + + + users + + false + + + + + + t_009 + 1700 + 100 + + + process_role + + true + + + + + + t_016 + 1300 + 300 + + + process_role + + false + + + + users + + true + + + + + + t_017 + 1500 + 300 + + + process_role + + false + + + + users + + false + + + + + + t_018 + 1700 + 300 + + + process_role + + false + + + + + + t_025 + 1300 + 500 + + + users + + true + + + + + + t_026 + 1500 + 500 + + + users + + false + + + + + + t_027 + 1700 + 500 + + + \ No newline at end of file