From 91656a2640ed8b4234b3bbf14e761194c70e9da7 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 3 Dec 2025 10:32:25 +0100 Subject: [PATCH 01/48] [NAE-2266] Introduce active version of process - change user field types to actor field types in process files - update initialization of ActorListField in ActionDelegate and DataService - introduce new way of initialization of ActorField in ActionDelegate and DataService - refactor attributes of elastic data fields - update ElasticCaseMappingService according to refactored fields - update Importer to work also with actor field types - refactor ActorField and ActorListField (renamed user fields) - apply polymorphism on actor field values (user field values) - introduce GroupFieldValue --- .../logic/action/ActionDelegate.groovy | 26 +++++- .../engine/auth/web/UserController.java | 22 ++--- .../service/ElasticCaseMappingService.java | 88 +++++++------------ .../elastic/service/ElasticTaskService.java | 1 + .../engine/export/service/ExportService.java | 10 ++- .../engine/importer/service/FieldFactory.java | 30 ++++--- .../engine/importer/service/Importer.java | 4 +- .../fieldbuilder/TextFieldBuilder.java | 14 +-- .../workflow/service/CaseSearchService.java | 3 +- .../engine/workflow/service/DataService.java | 34 ++++--- .../engine/workflow/service/TaskService.java | 12 +-- .../workflow/service/WorkflowService.java | 13 ++- .../service/interfaces/IDataService.java | 2 +- .../src/main/resources/petriNets/all_data.xml | 6 +- .../engine-processes/impersonation_config.xml | 13 +-- .../auth/TaskAuthorizationServiceTest.groovy | 2 +- .../elastic/DataSearchRequestTest.groovy | 5 +- .../ImpersonationServiceTest.groovy | 4 +- .../petrinet/domain/dataset/FieldTest.groovy | 8 +- docs/_media/roles/usersRef_net.xml | 4 +- .../objects/elastic/domain/ActorField.java | 79 +++++++++++++++++ .../elastic/domain/ActorListField.java | 17 ++++ .../elastic/domain/ActorMappingData.java | 3 + .../objects/elastic/domain/BooleanField.java | 4 +- .../objects/elastic/domain/ButtonField.java | 4 +- .../objects/elastic/domain/CaseField.java | 10 +-- .../objects/elastic/domain/DataField.java | 17 ++-- .../objects/elastic/domain/DateField.java | 7 +- .../domain/FieldWithAllowedNetsField.java | 6 +- .../objects/elastic/domain/FileField.java | 58 ++++++------ .../objects/elastic/domain/FilterField.java | 5 +- .../objects/elastic/domain/I18nField.java | 17 ++-- .../objects/elastic/domain/MapField.java | 30 ++++--- .../objects/elastic/domain/NumberField.java | 4 +- .../elastic/domain/StringCollectionField.java | 8 +- .../objects/elastic/domain/TextField.java | 10 +-- .../objects/elastic/domain/UserField.java | 82 ----------------- .../objects/elastic/domain/UserListField.java | 37 -------- .../{UserListField.java => ActorField.java} | 23 ++--- .../domain/dataset/ActorFieldValue.java | 26 ++++++ .../domain/dataset/ActorListField.java | 41 +++++++++ .../domain/dataset/ActorListFieldValue.java | 39 ++++++++ .../petrinet/domain/dataset/FieldType.java | 4 +- .../domain/dataset/GroupFieldValue.java | 45 ++++++++++ .../petrinet/domain/dataset/UserField.java | 39 -------- .../domain/dataset/UserFieldValue.java | 20 ++--- .../domain/dataset/UserListFieldValue.java | 36 -------- .../localised/LocalisedFieldFactory.java | 12 +-- .../dataset/localised/LocalisedUserField.java | 4 +- .../localised/LocalisedUserListField.java | 4 +- .../engine/objects/workflow/domain/Case.java | 8 +- .../spring/elastic/domain/ActorField.java | 59 +++++++++++++ .../spring/elastic/domain/ActorListField.java | 53 +++++++++++ .../spring/elastic/domain/BooleanField.java | 6 +- .../spring/elastic/domain/ButtonField.java | 6 +- .../spring/elastic/domain/CaseField.java | 12 ++- .../spring/elastic/domain/DateField.java | 7 +- .../spring/elastic/domain/FileField.java | 20 ++++- .../spring/elastic/domain/FilterField.java | 15 +++- .../spring/elastic/domain/I18nField.java | 5 +- .../spring/elastic/domain/MapField.java | 6 +- .../spring/elastic/domain/NumberField.java | 4 +- .../elastic/domain/StringCollectionField.java | 12 ++- .../spring/elastic/domain/TextField.java | 12 ++- .../spring/elastic/domain/UserField.java | 50 ----------- .../spring/elastic/domain/UserListField.java | 44 ---------- 66 files changed, 729 insertions(+), 582 deletions(-) create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorMappingData.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java rename nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/{UserListField.java => ActorField.java} (54%) create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserField.java delete mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListFieldValue.java create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorField.java create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorListField.java delete mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserField.java delete mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserListField.java 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 0fb4207abbc..d12c9fabb3c 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 @@ -33,6 +33,7 @@ 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.Group 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 @@ -781,10 +782,27 @@ class ActionDelegate { if (field instanceof NumberField) { value = value as Double } - if (field instanceof UserListField && (value instanceof String[] || value instanceof List)) { - LinkedHashSet users = new LinkedHashSet<>() - value.each { id -> users.add(new UserFieldValue(userService.findById(id as String, null))) } - value = new UserListFieldValue(users) + if (field instanceof ActorListField && (value instanceof String[] || value instanceof List)) { + LinkedHashSet actorFieldValues = new LinkedHashSet<>() + value.each { id -> + AbstractUser user = userService.findById(id as String, null) + if (user != null) { + actorFieldValues.add(new UserFieldValue(user)) + } else { + Group group = groupService.findById((String) id) + actorFieldValues.add(new GroupFieldValue(group)) + } + } + value = new ActorListFieldValue(actorFieldValues) + } + if (field instanceof ActorField && value instanceof String) { + AbstractUser user = userService.findById(value, null) + if (user != null) { + value = new UserFieldValue(user) + } else { + Group group = groupService.findById(value) + value = new GroupFieldValue(group) + } } // if (field instanceof TaskField && targetTask.isPresent()) { // dataService.validateTaskRefValue(value, targetTask.get().getStringId()); 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..2818d2d98ae 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 @@ -181,17 +181,17 @@ public ResponseEntity getUser(@PathVariable("realmId") String realmId, @Pa // return null; // } // LoggedUser loggedUser = (LoggedUser) auth.getPrincipal(); -// String userId = updates.getStringId(); +// String actorId = updates.getStringId(); // IUser user; // try { -// user = userService.findById(userId, updatedUser.getRealmId()); +// user = userService.findById(actorId, updatedUser.getRealmId()); // } catch (IllegalArgumentException e) { -// log.error("Could not find user with id [{}]", userId, e); +// log.error("Could not find user with id [{}]", actorId, e); // return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); // } // user = userService.update(user, updates.getUpdatedUser()); -// securityContextService.saveToken(userId); -// if (Objects.equals(loggedUser.getId(), userId)) { +// securityContextService.saveToken(actorId); +// if (Objects.equals(loggedUser.getId(), actorId)) { // loggedUser.setFirstName(user.getFirstName()); // loggedUser.setLastName(user.getLastName()); // securityContextService.reloadSecurityContext(loggedUser); @@ -239,15 +239,15 @@ public ResponseEntity assignRolesToUser(@PathVariable("realmId" // @ApiResponse(responseCode = "403", description = "Caller doesn't fulfill the authorisation requirements"), // @ApiResponse(responseCode = "500", description = "Internal server error") // }) -// public ResponseEntity assignNegativeRolesToUser(@PathVariable("realmId") String realmId, @PathVariable("id") String userId, @RequestBody Set roleIds, Authentication auth) { +// public ResponseEntity assignNegativeRolesToUser(@PathVariable("realmId") String realmId, @PathVariable("id") String actorId, @RequestBody Set roleIds, Authentication auth) { // try { -// AbstractUser user = userService.findById(userId, realmId); +// AbstractUser user = userService.findById(actorId, realmId); // processRoleService.assignNegativeRolesToUser(user, roleIds.stream().map(ProcessResourceId::new).collect(Collectors.toSet()), (LoggedUser) auth.getPrincipal()); -// log.info("Negative process roles {} assigned to user [{}]", roleIds, userId); -// return ResponseEntity.ok(ResponseMessage.createSuccessMessage("Selected negative roles assigned to user " + userId)); +// log.info("Negative process roles {} assigned to user [{}]", roleIds, actorId); +// return ResponseEntity.ok(ResponseMessage.createSuccessMessage("Selected negative roles assigned to user " + actorId)); // } catch (IllegalArgumentException e) { -// log.error("Assigning negative roles to user with id [{}] has failed!", userId, e); -// return ResponseEntity.badRequest().body(ResponseMessage.createErrorMessage("Assigning negative roles to user " + userId + " has failed!")); +// log.error("Assigning negative roles to user with id [{}] has failed!", actorId, e); +// return ResponseEntity.badRequest().body(ResponseMessage.createErrorMessage("Assigning negative roles to user " + actorId + " has failed!")); // } // } // diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java index 23ec0930def..a0a082dee25 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java @@ -1,7 +1,5 @@ package com.netgrif.application.engine.elastic.service; -import com.netgrif.application.engine.objects.elastic.domain.UserField; -import com.netgrif.application.engine.objects.elastic.domain.UserListField; import com.netgrif.application.engine.objects.elastic.domain.*; import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseMappingService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; @@ -36,7 +34,7 @@ protected void populateDataSet(ElasticCase transformedCase, Case useCase) { } protected Optional transformDataField(String fieldId, Case useCase) { - Field netField = useCase.getField(fieldId); + Field netField = useCase.getField(fieldId); com.netgrif.application.engine.objects.workflow.domain.DataField caseField = useCase.getDataField(fieldId); if (caseField.getValue() == null) { @@ -51,8 +49,8 @@ protected Optional transformDataField(String fieldId, Case useCase) { return this.transformNumberField(caseField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.ButtonField) { return this.transformButtonField(caseField); - } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.UserField) { - return this.transformUserField(caseField); + } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorField) { + return this.transformActorField(caseField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField) { return this.transformDateField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField) netField); } else if (netField instanceof DateTimeField) { @@ -67,7 +65,7 @@ protected Optional transformDataField(String fieldId, Case useCase) { return this.transformFileField(caseField); } else if (netField instanceof FileListField) { return this.transformFileListField(caseField); - } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListField) { + } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListField) { return this.transformUserListField(caseField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) { return this.transformI18nField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) netField); @@ -88,7 +86,7 @@ protected Optional transformDataField(String fieldId, Case useCase) { protected Optional transformMultichoiceMapField (com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceMap, MultichoiceMapField netField) { Optional optValues = this.getMultichoiceValue(multichoiceMap, netField); - if (!optValues.isPresent()) { + if (optValues.isEmpty()) { return Optional.empty(); } Set mapValues = optValues.get(); @@ -110,22 +108,22 @@ protected Optional transformDataField(String fieldId, Case useCase) { return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.I18nField(keys, values, ((I18nString) dataField.getValue()).getTranslations())); } - protected Optional transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) { - String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]); - String[] referencedCases = ((List) dataField.getValue()).toArray(new String[0]); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets)); + protected Optional transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, + com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) { + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField( + (List) dataField.getValue(), dataField.getAllowedNets())); } - protected Optional transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) { - String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]); - Map filterMetadata = dataField.getFilterMetadata(); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata)); + protected Optional transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, + com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) { + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField( + dataField.getValue().toString(), dataField.getAllowedNets(), dataField.getFilterMetadata())); } - protected Optional transformStringCollectionField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.StringCollectionField netField) { + protected Optional transformStringCollectionField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, + com.netgrif.application.engine.objects.petrinet.domain.dataset.StringCollectionField netField) { if (dataField.getValue() != null && dataField.getValue() instanceof Collection && !((Collection) dataField.getValue()).isEmpty()) { - String[] values = ((Collection) dataField.getValue()).toArray(new String[0]); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.StringCollectionField(values)); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.StringCollectionField((List) dataField.getValue())); } return Optional.empty(); } @@ -135,7 +133,8 @@ protected Optional transformStringCollectionField(com.netgrif.applica Map options = this.getFieldOptions(enumMap, netField); String selectedKey = (String) enumMap.getValue(); I18nString selectedValue = options.get(selectedKey); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField(new AbstractMap.SimpleEntry<>(selectedKey, selectedValue != null ? selectedValue : new I18nString("")))); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField( + new AbstractMap.SimpleEntry<>(selectedKey, selectedValue != null ? selectedValue : new I18nString("")))); } private Map getFieldOptions @@ -149,7 +148,7 @@ protected Optional transformStringCollectionField(com.netgrif.applica protected Optional transformMultichoiceField (com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceField, MultichoiceField netField) { Optional optValues = this.getMultichoiceValue(multichoiceField, netField); - if (!optValues.isPresent()) { + if (optValues.isEmpty()) { return Optional.empty(); } Set values = optValues.get(); @@ -165,7 +164,7 @@ protected Optional transformStringCollectionField(com.netgrif.applica log.error("MultichoiceField has element value of illegal type! Expected: I18nString, Found: " + value.getClass().getCanonicalName()); } }); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(translations.toArray(new String[0]))); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(translations)); } private Optional getMultichoiceValue(com.netgrif.application.engine.objects.workflow.domain.DataField @@ -188,7 +187,7 @@ private Optional getMultichoiceValue(com.netgrif.application.engine.objects (com.netgrif.application.engine.objects.workflow.domain.DataField enumField) { Object value = enumField.getValue(); if (value instanceof I18nString) { - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(I18nStringUtils.collectTranslations((I18nString) value).toArray(new String[0]))); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(I18nStringUtils.collectTranslations((I18nString) value))); } else if (value instanceof String) { return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField((String) value)); } else { @@ -211,46 +210,27 @@ private Optional getMultichoiceValue(com.netgrif.application.engine.objects return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ButtonField((Integer) buttonField.getValue())); } - protected Optional transformUserField - (com.netgrif.application.engine.objects.workflow.domain.DataField userField) { - UserFieldValue user = (UserFieldValue) userField.getValue(); - if (user == null) + protected Optional transformActorField + (com.netgrif.application.engine.objects.workflow.domain.DataField actorField) { + ActorFieldValue actorFieldValue = (ActorFieldValue) actorField.getValue(); + if (actorFieldValue == null) return Optional.empty(); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserField(this.transformUserValue(user))); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ActorField(actorFieldValue.buildMappingData())); } protected Optional transformUserListField - (com.netgrif.application.engine.objects.workflow.domain.DataField userListField) { - UserListFieldValue userListValue = (UserListFieldValue) userListField.getValue(); - UserField.UserMappingData[] userMappingData = userListValue.getUserValues().stream().map(this::transformUserListValue).toArray(UserField.UserMappingData[]::new); - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserListField(userMappingData)); - } - - private UserField.UserMappingData transformUserValue(UserFieldValue user) { - return new UserField.UserMappingData(user.getId(), user.getRealmId(), user.getUsername(), buildFullName(user.getFirstName(), user.getLastName()).toString()); - } - - private UserListField.UserMappingData transformUserListValue(UserFieldValue user) { - return new UserListField.UserMappingData(user.getId(), user.getRealmId(), user.getUsername(), buildFullName(user.getFirstName(), user.getLastName()).toString()); - } - - private StringBuilder buildFullName(String name, String surname) { - StringBuilder fullName = new StringBuilder(); - if (name != null) { - fullName.append(name); - fullName.append(" "); - } - if (surname != null) { - fullName.append(surname); - } - return fullName; + (com.netgrif.application.engine.objects.workflow.domain.DataField actorListField) { + ActorListFieldValue actorListFieldValue = (ActorListFieldValue) actorListField.getValue(); + List actorMappingDataList = actorListFieldValue.getActorValues().stream() + .map(ActorFieldValue::buildMappingData) + .toList(); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ActorListField(actorMappingDataList)); } protected Optional transformDateField (com.netgrif.application.engine.objects.workflow.domain.DataField dateField, com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField netField) { - if (dateField.getValue() instanceof LocalDate) { - LocalDate date = (LocalDate) dateField.getValue(); + if (dateField.getValue() instanceof LocalDate date) { return formatDateField(LocalDateTime.of(date, LocalTime.MIDNIGHT)); } else if (dateField.getValue() instanceof Date) { // log.warn(String.format("DateFields should have LocalDate values! DateField (%s) with Date value found! Value will be converted for indexation.", netField.getImportId())); @@ -310,7 +290,7 @@ private Optional formatDateField(LocalDateTime date) { protected Optional transformFileListField (com.netgrif.application.engine.objects.workflow.domain.DataField fileListField) { - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField(((FileListFieldValue) fileListField.getValue()).getNamesPaths().toArray(new FileFieldValue[0]))); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField(((FileListFieldValue) fileListField.getValue()).getNamesPaths())); } protected Optional transformOtherFields 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..082557c849c 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 @@ -325,6 +325,7 @@ protected void buildTitleQuery(ElasticTaskSearchRequest request, BoolQuery.Build * Tasks assigned to user with id 1 OR 2 */ protected void buildUserQuery(ElasticTaskSearchRequest request, BoolQuery.Builder query) { + // todo 2285 if (request.user == null || request.user.isEmpty()) { return; } 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..84dccaea712 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 @@ -273,17 +273,19 @@ public String resolveFieldValue(Case exportCase, String exportFieldId) { case TASK_REF: fieldValue = String.join(";", ((TaskField) fieldData).getValue()); break; - case USER: + case ACTOR: fieldValue = ((UserFieldValue) fieldData).getUsername(); break; case DATE: fieldValue = ((LocalDate) fieldData).toString(); break; case DATETIME: - fieldValue = ((Date) fieldData).toString(); + fieldValue = fieldData.toString(); break; - case USERLIST: - fieldValue = ((UserListField) fieldData).getValue().getUserValues().stream().map(UserFieldValue::getId).collect(Collectors.joining(";")); + case ACTORLIST: + fieldValue = ((ActorListField) fieldData).getValue().getActorValues().stream() + .map(ActorFieldValue::getId) + .collect(Collectors.joining(";")); break; case NUMBER: fieldValue = fieldData.toString(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java index e0a0e55bbd5..8b7fd21c347 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java @@ -223,11 +223,13 @@ Field getField(Data data, Importer importer) throws IllegalArgumentException, Mi case NUMBER: field = buildNumberField(data); break; + case ACTOR: case USER: - field = buildUserField(data, importer); + field = buildActorField(data, importer); break; + case ACTOR_LIST: case USER_LIST: - field = buildUserListField(data, importer); + field = buildActorListField(data, importer); break; case CASE_REF: field = buildCaseField(data); @@ -505,22 +507,22 @@ private CaseField buildCaseField(Data data) { return field; } - private UserField buildUserField(Data data, Importer importer) { + private ActorField buildActorField(Data data, Importer importer) { String[] roles = data.getValues().stream() .map(value -> importer.getRoles().get(value.getValue()).getStringId()) .toArray(String[]::new); - UserField field = new UserField(roles); + ActorField field = new ActorField(roles); setDefaultValues(field, data, inits -> { field.setDefaultValue(null); }); return field; } - private UserListField buildUserListField(Data data, Importer importer) { + private ActorListField buildActorListField(Data data, Importer importer) { String[] roles = data.getValues().stream() .map(value -> importer.getRoles().get(value.getValue()).getStringId()) .toArray(String[]::new); - UserListField field = new UserListField(roles); + ActorListField field = new ActorListField(roles); setDefaultValues(field, data, inits -> { }); return field; @@ -709,18 +711,19 @@ private void resolveDataValues(Field field, Case useCase, String fieldId) { case FILELIST: parseFileListValue((FileListField) field, useCase, fieldId); break; - case USER: - parseUserValues((UserField) field, useCase, fieldId); + case ACTOR: + parseUserValues((ActorField) field, useCase, fieldId); break; - case USERLIST: - parseUserListValues((UserListField) field, useCase, fieldId); + case ACTORLIST: + parseUserListValues((ActorListField) field, useCase, fieldId); break; default: field.setValue(useCase.getFieldValue(fieldId)); } } - private void parseUserValues(UserField field, Case useCase, String fieldId) { + private void parseUserValues(ActorField field, Case useCase, String fieldId) { + // todo 2285 DataField userField = useCase.getDataField(fieldId); if (userField.getChoices() != null) { Set roles = userField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); @@ -729,13 +732,14 @@ private void parseUserValues(UserField field, Case useCase, String fieldId) { field.setValue((UserFieldValue) useCase.getFieldValue(fieldId)); } - private void parseUserListValues(UserListField field, Case useCase, String fieldId) { + private void parseUserListValues(ActorListField field, Case useCase, String fieldId) { + // todo 2285 DataField userListField = useCase.getDataField(fieldId); if (userListField.getChoices() != null) { Set roles = userListField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); field.setRoles(roles); } - field.setValue((UserListFieldValue) useCase.getFieldValue(fieldId)); + field.setValue((ActorListFieldValue) useCase.getFieldValue(fieldId)); } private Double parseNumberValue(Case useCase, String fieldId) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java index b52ee3581b4..2a7edf9f4ca 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java @@ -75,7 +75,7 @@ public class Importer { protected ProcessRole anonymousRole; @Getter protected Map roles; - protected Map fields; + protected Map> fields; protected Map transitions; protected Map places; protected Map transactions; @@ -489,7 +489,7 @@ protected void createArc(com.netgrif.application.engine.objects.importer.model.A @Transactional protected void createDataSet(Data importData) throws MissingIconKeyException { - Field field = fieldFactory.getField(importData, this); + Field field = fieldFactory.getField(importData, this); net.addDataSetField(field); fields.put(importData.getId(), field); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java index 65376084e27..c23e8823d8b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java @@ -1,13 +1,10 @@ package com.netgrif.application.engine.pdf.generator.service.fieldbuilder; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.*; import com.netgrif.application.engine.pdf.generator.config.PdfResourceConfigurationProperties; import com.netgrif.application.engine.pdf.generator.domain.PdfField; import com.netgrif.application.engine.pdf.generator.domain.PdfTextField; import com.netgrif.application.engine.objects.petrinet.domain.DataGroup; -import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue; -import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileListFieldValue; -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.utils.DateUtils; import com.netgrif.application.engine.objects.petrinet.domain.dataset.localised.LocalisedField; import org.jsoup.Jsoup; @@ -59,11 +56,14 @@ public PdfField buildField(DataGroup dataGroup, LocalisedField field, int lastX, case FILELIST: value = field.getValue() != null ? resolveFileListNames((FileListFieldValue) field.getValue()) : ""; break; - case USER: + case ACTOR: value = field.getValue() != null ? ((UserFieldValue) field.getValue()).getFullName() : ""; break; - case USERLIST: - value = field.getValue() != null ? ((UserListFieldValue) field.getValue()).getUserValues().stream().map(UserFieldValue::getFullName).collect(Collectors.joining(", ")) : ""; + case ACTORLIST: + // todo 2285 + value = field.getValue() != null ? ((ActorListFieldValue) field.getValue()).getActorValues().stream() + .map(ActorFieldValue::getFullName) + .collect(Collectors.joining(", ")) : ""; break; default: value = field.getValue() != null ? Jsoup.parse(field.getValue().toString()).text() : ""; 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 923d17bfa54..2d44b3dfe6b 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 @@ -226,7 +226,8 @@ public Predicate data(Object data) { FieldType type = FieldType.fromString(entry.getKey()); switch (type) { - case USER: + case ACTOR: + // todo 2285 Path valuePath = Expressions.simplePath(UserFieldValue.class, QCase.case$.dataSet.get((String) k), "value"); Path idPath = Expressions.stringPath(valuePath, "id"); Expression constant = Expressions.constant(Long.valueOf("" + fieldValue)); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index b74c8337fce..52a75dcb7cd 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -7,8 +7,10 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.netgrif.application.engine.auth.service.GroupService; import com.netgrif.application.engine.configuration.properties.DataConfigurationProperties; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.auth.domain.Group; import com.netgrif.application.engine.workflow.domain.EventNotExecutableException; import com.netgrif.application.engine.auth.service.UserService; import com.netgrif.application.engine.objects.petrinet.domain.I18nString; @@ -48,7 +50,6 @@ import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.data.domain.Page; @@ -83,6 +84,9 @@ public class DataService implements IDataService { @Autowired protected UserService userService; + @Autowired + protected GroupService groupService; + @Autowired protected FieldFactory fieldFactory; @@ -748,9 +752,14 @@ public List> getImmediateFields(Task task) { } @Override - public UserFieldValue makeUserFieldValue(String id) { + public ActorFieldValue makeActorFieldValue(String id) { AbstractUser user = userService.findById(id, null); - return new UserFieldValue(user); + if (user != null) { + return new UserFieldValue(user); + } else { + Group group = groupService.findById(id); + return new GroupFieldValue(group); + } } private void updateDataset(Case useCase) { @@ -775,7 +784,7 @@ public Case applyFieldConnectedChanges(Case useCase, String fieldId) { @Override public Case applyFieldConnectedChanges(Case useCase, Field field) { switch (field.getType()) { - case USERLIST: + case ACTORLIST: return workflowService.resolveUserRef(useCase); default: return useCase; @@ -866,16 +875,12 @@ private Object parseFieldsValues(JsonNode jsonNode, DataField dataField, String value = parseI18nString(node.get("value")); break; case "user": + case "actor": if (node.get("value") == null || node.get("value").isNull()) { value = null; break; } -// User user = new User(userService.findById(node.get("value").asLong(), true)); -// user.setPassword(null); -// user.setGroups(null); -// user.setAuthorities(null); -// user.setUserProcessRoles(null); - value = makeUserFieldValue(node.get("value").asText()); + value = makeActorFieldValue(node.get("value").asText()); break; case "number": if (node.get("value") == null || node.get("value").isNull()) { @@ -909,11 +914,12 @@ private Object parseFieldsValues(JsonNode jsonNode, DataField dataField, String value = parseListStringValues(node); break; case "userList": + case "actorList": if (node.get("value") == null) { value = null; break; } - value = makeUserListFieldValue(node); + value = makeActorListFieldValue(node); break; case "button": if (node.get("value") == null) { @@ -952,9 +958,9 @@ private Set parseMultichoiceFieldValues(ObjectNode node) { return set; } - private UserListFieldValue makeUserListFieldValue(ObjectNode nodes) { - Set userIds = new LinkedHashSet<>(parseListStringValues(nodes)); - return new UserListFieldValue(userIds.stream().map(this::makeUserFieldValue).collect(Collectors.toSet())); + private ActorListFieldValue makeActorListFieldValue(ObjectNode nodes) { + Set actorIds = new LinkedHashSet<>(parseListStringValues(nodes)); + return new ActorListFieldValue(actorIds.stream().map(this::makeActorFieldValue).collect(Collectors.toSet())); } private List parseListStringValues(ObjectNode node) { 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 ac21c61ae5f..1a525e82d85 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 @@ -3,6 +3,8 @@ 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.objects.petrinet.domain.dataset.ActorFieldValue; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListFieldValue; import com.netgrif.application.engine.workflow.domain.TaskNotFoundException; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.UserService; @@ -14,8 +16,6 @@ import com.netgrif.application.engine.objects.petrinet.domain.arcs.ArcOrderComparator; import com.netgrif.application.engine.objects.petrinet.domain.arcs.ResetArc; import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field; -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.events.EventPhase; import com.netgrif.application.engine.objects.petrinet.domain.events.EventType; import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole; @@ -808,10 +808,11 @@ public void resolveUserRef(Case useCase) { @Override public Task resolveUserRef(Task task, Case useCase) { + // todo 2285 task.getUsers().clear(); task.getNegativeViewUsers().clear(); task.getUserRefs().forEach((id, permission) -> { - List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(id).getValue()); + List userIds = getExistingUsers((ActorListFieldValue) useCase.getDataSet().get(id).getValue()); if (userIds != null && userIds.size() != 0 && permission.containsKey("view") && !permission.get("view")) { task.getNegativeViewUsers().addAll(userIds); } else if (userIds != null && userIds.size() != 0) { @@ -822,10 +823,11 @@ public Task resolveUserRef(Task task, Case useCase) { return taskRepository.save(task); } - private List getExistingUsers(UserListFieldValue userListValue) { + private List getExistingUsers(ActorListFieldValue userListValue) { + // todo 2285 if (userListValue == null) return null; - return userListValue.getUserValues().stream().map(UserFieldValue::getId) + return userListValue.getActorValues().stream().map(ActorFieldValue::getId) .filter(id -> userService.findById(id, null) != null) .collect(Collectors.toList()); } 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 9fdb0e83f11..e156204cb83 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 @@ -2,6 +2,7 @@ import com.google.common.collect.Ordering; import com.netgrif.application.engine.objects.auth.domain.ActorTransformer; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.*; import com.netgrif.application.engine.objects.workflow.domain.Case; import com.netgrif.application.engine.objects.auth.domain.LoggedUser; import com.netgrif.application.engine.auth.service.UserService; @@ -15,10 +16,6 @@ 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; @@ -239,7 +236,8 @@ public Case resolveUserRef(Case useCase) { } private void resolveUserRefPermissions(Case useCase, String userListId, Map permission) { - List userIds = getExistingUsers((UserListFieldValue) useCase.getDataSet().get(userListId).getValue()); + // todo 2285 + List userIds = getExistingUsers((ActorListFieldValue) useCase.getDataSet().get(userListId).getValue()); if (userIds != null && userIds.size() != 0) { if (permission.containsKey("view") && !permission.get("view")) { useCase.getNegativeViewUsers().addAll(userIds); @@ -249,10 +247,11 @@ private void resolveUserRefPermissions(Case useCase, String userListId, Map getExistingUsers(UserListFieldValue userListValue) { + private List getExistingUsers(ActorListFieldValue userListValue) { + // todo 2285 if (userListValue == null) return null; - return userListValue.getUserValues().stream().map(UserFieldValue::getId) + return userListValue.getActorValues().stream().map(ActorFieldValue::getId) .filter(id -> userService.findById(id, null) != null) .collect(Collectors.toList()); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java index 4426b3500ad..0965e4905f5 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IDataService.java @@ -87,7 +87,7 @@ public interface IDataService { List> getImmediateFields(Task task); - UserFieldValue makeUserFieldValue(String id); + ActorFieldValue makeActorFieldValue(String id); Case applyFieldConnectedChanges(Case useCase, String fieldId); diff --git a/application-engine/src/main/resources/petriNets/all_data.xml b/application-engine/src/main/resources/petriNets/all_data.xml index f65ed4ae659..66d60298dc5 100644 --- a/application-engine/src/main/resources/petriNets/all_data.xml +++ b/application-engine/src/main/resources/petriNets/all_data.xml @@ -176,17 +176,17 @@ File List - + user User - + userList1 UserList - + userList2 UserList diff --git a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml index 65128115668..76e43bfc5a5 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml @@ -93,11 +93,12 @@ impersonated: f.impersonated, config_owner: f.config_owner; - def user = userService.loggedOrSystem - change impersonated value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue(user.stringId, user.firstName, user.lastName, user.username) } - change impersonated_email value { user.username } + def user = userService.loggedOrSystem + change impersonated value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue(user.stringId, user.firstName, user.lastName, user.username) } + change impersonated_email value { user.username } - change config_owner value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListFieldValue([impersonated.value]) } + // todo 2285 + change config_owner value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListFieldValue([impersonated.value]) } @@ -147,7 +148,7 @@ - + config_owner </data> @@ -193,7 +194,7 @@ </actions> </event> </data> - <data type="user" immediate="true"> + <data type="actor" immediate="true"> <id>impersonated</id> <title name="impersonated">User to impersonate diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index 93934b83367..696d3d57d0a 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -125,7 +125,7 @@ class TaskAuthorizationServiceTest { // [auths.get("user")] as Authority[], // [processRoles.find({ it.name.equals("role") })] as ProcessRole[]) // -// userId = user.getStringId() +// actorId = user.getStringId() // this.userWithRoleAuth = new UsernamePasswordAuthenticationToken(USER_WITH_ROLE_EMAIL, "password") // // importHelper.createUser(new User(firstName: "NoRole", lastName: "User", email: USER_WITHOUT_ROLE_EMAIL, password: "password", state: UserState.ACTIVE), diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy index 0f88aadaf8a..6b4655edb8a 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/elastic/DataSearchRequestTest.groovy @@ -12,7 +12,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.dataset.ChoiceFiel import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileListFieldValue 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.dataset.ActorListFieldValue import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService import com.netgrif.application.engine.startup.ImportHelper import com.netgrif.application.engine.startup.runner.SuperCreatorRunner @@ -123,7 +123,8 @@ class DataSearchRequestTest { _case.dataSet["multichoice_map"].value = ["alice", "bob"].toSet() _case.dataSet["file"].value = FileFieldValue.fromString("singlefile.txt") _case.dataSet["fileList"].value = FileListFieldValue.fromString("multifile1.txt,multifile2.pdf") - _case.dataSet["userList"].value = new UserListFieldValue([dataService.makeUserFieldValue(testUser1.stringId), dataService.makeUserFieldValue(testUser2.stringId)]) + // todo 2285 + _case.dataSet["userList"].value = new ActorListFieldValue([dataService.makeActorFieldValue(testUser1.stringId), dataService.makeActorFieldValue(testUser2.stringId)]) _case.dataSet["i18n_text"].value.defaultValue = "Modified i18n text value" _case.dataSet["i18n_divider"].value.defaultValue = "Modified i18n divider value" workflowService.save(_case) 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 index b6b97f53520..58a8315f9fa 100644 --- 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 @@ -16,7 +16,7 @@ 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.dataset.ActorListFieldValue 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 @@ -315,7 +315,7 @@ class ImpersonationServiceTest { 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["config_owner"].value = new ActorListFieldValue([owner]) // todo 2285 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 diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy index 280b33c817d..4399657f637 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/petrinet/domain/dataset/FieldTest.groovy @@ -20,8 +20,8 @@ import com.netgrif.application.engine.objects.petrinet.domain.dataset.Multichoic import com.netgrif.application.engine.objects.petrinet.domain.dataset.NumberField import com.netgrif.application.engine.objects.petrinet.domain.dataset.TaskField import com.netgrif.application.engine.objects.petrinet.domain.dataset.TextField -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserField -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListField +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorField +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListField import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -180,7 +180,7 @@ class FieldTest { } private void assertUserField() { - UserField field = net.dataSet["user"] as UserField + ActorField field = net.dataSet["user"] as ActorField assert field.description.defaultValue == "User field description" assert field.name.defaultValue == "User" assert field.placeholder.defaultValue == "User field placeholder" @@ -203,7 +203,7 @@ class FieldTest { } private void assertUserList() { - UserListField field = net.dataSet["emptyUserList"] as UserListField + ActorListField field = net.dataSet["emptyUserList"] as ActorListField assert field.name.defaultValue == "Empty user list" assert field.description.defaultValue == "User list description" assert field.defaultValue == null diff --git a/docs/_media/roles/usersRef_net.xml b/docs/_media/roles/usersRef_net.xml index 39db84655a5..f815f18385f 100644 --- a/docs/_media/roles/usersRef_net.xml +++ b/docs/_media/roles/usersRef_net.xml @@ -48,11 +48,11 @@ remove Remove from user ref - + user_list_1 User list 1 - + user_list_2 User list 2 diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java new file mode 100644 index 00000000000..f82148efae3 --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java @@ -0,0 +1,79 @@ +package com.netgrif.application.engine.objects.elastic.domain; + +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorFieldValue; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.GroupFieldValue; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +public abstract class ActorField extends DataField { + + protected List usernameValue; + protected List fullNameValue; + protected List actorIdValue; + protected List actorRealmIdValue; + + public ActorField(ActorMappingData mappingData) { + this(List.of(mappingData)); + } + + public ActorField(List mappingDataList) { + super(); + if (mappingDataList == null || mappingDataList.isEmpty()) { + return; + } + + this.usernameValue = new ArrayList<>(); + this.fullNameValue = new ArrayList<>(); + this.actorIdValue = new ArrayList<>(); + this.actorRealmIdValue = new ArrayList<>(); + for (ActorMappingData mappingData : mappingDataList) { + this.fullNameValue.add(mappingData.fullName()); + this.actorIdValue.add(mappingData.actorId()); + if (mappingData.actorRealmId() != null) { + this.actorRealmIdValue.add(mappingData.actorRealmId()); + } + if (mappingData.username() == null) { + this.fulltextValue.add(mappingData.fullName()); + } else { + this.usernameValue.add(mappingData.username()); + super.fulltextValue.add(String.format("%s %s", mappingData.fullName(), mappingData.username())); + } + } + } + + @Override + public Object getValue() { + if (this.actorIdValue != null && this.actorIdValue.size() == 1) { + return buildFieldValue(0); + } else if (this.actorIdValue != null && this.actorIdValue.size() > 1) { + return IntStream.range(0, this.actorIdValue.size()).mapToObj(this::buildFieldValue).toList(); + } + return null; + } + + protected ActorFieldValue buildFieldValue(int idx) { + String username = this.usernameValue.get(idx); + if (username == null) { + return new GroupFieldValue(this.actorIdValue.get(idx), this.actorRealmIdValue.get(idx), this.fullNameValue.get(idx)); + } else { + String fullName = this.fullNameValue.get(idx) != null ? this.fullNameValue.get(idx) : ""; + String[] fullNameSplit = fullName.split(" ", 2); + String firstName = fullNameSplit.length > 0 ? fullNameSplit[0] : ""; + String lastName = fullNameSplit.length > 1 ? fullNameSplit[1] : ""; + return new UserFieldValue(this.actorIdValue.get(idx), this.actorRealmIdValue.get(idx), firstName, lastName, username); + } + } +} + + diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java new file mode 100644 index 00000000000..afb66b2713b --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorListField.java @@ -0,0 +1,17 @@ +package com.netgrif.application.engine.objects.elastic.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public abstract class ActorListField extends ActorField { + + public ActorListField(List actorMappingDataList) { + super(actorMappingDataList); + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorMappingData.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorMappingData.java new file mode 100644 index 00000000000..35e9fbc7534 --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorMappingData.java @@ -0,0 +1,3 @@ +package com.netgrif.application.engine.objects.elastic.domain; + +public record ActorMappingData(String actorId, String actorRealmId, String username, String fullName) {} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java index 9e23aa144f7..c45c1fc8083 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java @@ -10,7 +10,7 @@ @EqualsAndHashCode(callSuper = true) public abstract class BooleanField extends DataField { - public Boolean booleanValue; + protected Boolean booleanValue; public BooleanField(Boolean value) { super(value.toString()); @@ -19,6 +19,6 @@ public BooleanField(Boolean value) { @Override public Object getValue() { - return booleanValue; + return this.booleanValue; } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java index 3564ddca342..cbd3c1400ab 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java @@ -10,7 +10,7 @@ @EqualsAndHashCode(callSuper = true) public abstract class ButtonField extends DataField { - public Integer buttonValue; + protected Integer buttonValue; public ButtonField(Integer value) { super(value.toString()); @@ -19,6 +19,6 @@ public ButtonField(Integer value) { @Override public Object getValue() { - return buttonValue; + return this.buttonValue; } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java index 48292624f38..f5007ee46a4 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java @@ -13,15 +13,15 @@ @EqualsAndHashCode(callSuper = true) public abstract class CaseField extends FieldWithAllowedNetsField { - private List caseValue; + protected List caseValue; - public CaseField(String[] fullTextValue, String[] allowedNets) { - super(fullTextValue, allowedNets); - this.caseValue = Arrays.asList(fullTextValue); + public CaseField(List caseValue, List allowedNets) { + super(caseValue, allowedNets); + this.caseValue = caseValue; } @Override public Object getValue() { - return new ArrayList<>(List.of(fulltextValue)); + return this.caseValue; } } \ No newline at end of file diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java index 7c054eee54b..816c7cdd416 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java @@ -1,29 +1,34 @@ package com.netgrif.application.engine.objects.elastic.domain; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.io.Serial; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; @Data @NoArgsConstructor @EqualsAndHashCode -@AllArgsConstructor public abstract class DataField implements Serializable { @Serial private static final long serialVersionUID = 2035013102812591274L; - public String[] fulltextValue; + protected List fulltextValue = new ArrayList<>(); DataField(String fulltextValue) { - this.fulltextValue = new String[1]; - this.fulltextValue[0] = fulltextValue; + this(List.of(fulltextValue)); + } + + DataField(List fulltextValue) { + if (fulltextValue != null) { + this.fulltextValue.addAll(fulltextValue); + } } public Object getValue() { - return (fulltextValue != null && fulltextValue.length > 0) ? fulltextValue[0] : null; + return (!fulltextValue.isEmpty()) ? fulltextValue.getFirst() : null; } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java index 7d30aedcb0e..008cfda5560 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java @@ -14,9 +14,8 @@ @EqualsAndHashCode(callSuper = true) public abstract class DateField extends DataField { - public LocalDateTime dateValue; - - public Long timestampValue; + protected LocalDateTime dateValue; + protected Long timestampValue; public DateField(String value, LocalDateTime dateTime) { super(value); @@ -26,6 +25,6 @@ public DateField(String value, LocalDateTime dateTime) { @Override public Object getValue() { - return dateValue; + return this.dateValue; } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java index 4194ba0f812..6cfa59c48d8 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java @@ -12,14 +12,14 @@ @EqualsAndHashCode(callSuper = true) public abstract class FieldWithAllowedNetsField extends DataField { - public String[] allowedNets; + protected List allowedNets; - public FieldWithAllowedNetsField(String fullTextValue, String[] allowedNets) { + public FieldWithAllowedNetsField(String fullTextValue, List allowedNets) { super(fullTextValue); this.allowedNets = allowedNets; } - public FieldWithAllowedNetsField(String[] fullTextValue, String[] allowedNets) { + public FieldWithAllowedNetsField(List fullTextValue, List allowedNets) { super(fullTextValue); this.allowedNets = allowedNets; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java index 875c5740800..9d5d66c7da1 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java @@ -6,50 +6,46 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.stream.IntStream; -import java.util.stream.Stream; @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) public abstract class FileField extends DataField { - public String[] filePath; + protected List filePath; + protected List fileNameValue; + protected List fileExtensionValue; - public String[] fileNameValue; - - public String[] fileExtensionValue; - - public FileField(FileFieldValue value) { - super(value.getName()); - this.filePath = new String[1]; - this.fileNameValue = new String[1]; - this.fileExtensionValue = new String[1]; - FileNameAndExtension extracted = this.extractFileExtensionFromName(value.getName()); - this.filePath[0] = value.getPath(); - this.fileNameValue[0] = extracted.name; - this.fileExtensionValue[0] = extracted.extension; + public FileField(FileFieldValue fileFieldValue) { + this(List.of(fileFieldValue)); } - public FileField(FileFieldValue[] values) { - super(new String[values.length]); - this.fileNameValue = new String[values.length]; - this.fileExtensionValue = new String[values.length]; - for (int i = 0; i < values.length; i++) { - FileNameAndExtension extracted = this.extractFileExtensionFromName(values[i].getName()); - this.fileNameValue[i] = extracted.name; - this.fileExtensionValue[i] = extracted.extension; - super.fulltextValue[i] = values[i].getName(); + public FileField(List fileFieldValues) { + if (fileFieldValues == null || fileFieldValues.isEmpty()) { + return; + } + this.fileNameValue = new ArrayList<>(); + this.fileExtensionValue = new ArrayList<>(); + for (FileFieldValue fileFieldValue : fileFieldValues) { + FileNameAndExtension extracted = this.extractFileExtensionFromName(fileFieldValue.getName()); + this.fileNameValue.add(extracted.name); + this.fileExtensionValue.add(extracted.extension); + this.fulltextValue.add(fileFieldValue.getName()); } } @Override public Object getValue() { - if (fileNameValue != null && fileNameValue.length == 1) { - return new FileFieldValue(fileNameValue[0] + "." + fileExtensionValue[0], filePath[0]); - } else if (fileNameValue != null && fileNameValue.length > 1) { - return IntStream.range(0, fileNameValue.length).mapToObj(i -> new FileFieldValue(fileNameValue[i] + "." + fileExtensionValue[i], filePath[i])).toList(); + if (this.fileNameValue != null && this.fileNameValue.size() == 1) { + return new FileFieldValue(nameWithExtension(this.fileNameValue.getFirst(), this.fileExtensionValue.getFirst()), + this.filePath.getFirst()); + } else if (this.fileNameValue != null && this.fileNameValue.size() > 1) { + return IntStream.range(0, this.fileNameValue.size()) + .mapToObj(i -> new FileFieldValue(nameWithExtension(this.fileNameValue.get(i), this.fileExtensionValue.get(i)), + this.filePath.get(i))).toList(); } return null; } @@ -62,6 +58,10 @@ private FileNameAndExtension extractFileExtensionFromName(String filename) { return new FileNameAndExtension(filename, null); } + private static String nameWithExtension(String fileName, String extension) { + return fileName + "." + extension; + } + @AllArgsConstructor private static class FileNameAndExtension { public String name; diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java index 1a4a02bd587..5eb8622a89a 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java @@ -5,6 +5,7 @@ import lombok.NoArgsConstructor; import java.util.HashMap; +import java.util.List; import java.util.Map; @Data @@ -12,9 +13,9 @@ @EqualsAndHashCode(callSuper = true) public abstract class FilterField extends FieldWithAllowedNetsField { - public Map filterMetadata; + protected Map filterMetadata; - public FilterField(String fullTextValue, String[] allowedNets, Map filterMetadata) { + public FilterField(String fullTextValue, List allowedNets, Map filterMetadata) { super(fullTextValue, allowedNets); this.filterMetadata = filterMetadata != null ? filterMetadata : new HashMap<>(); } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java index fa6b590f4cf..5f526e4c022 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java @@ -5,29 +5,26 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Map; -import java.util.Set; +import java.util.*; @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) public abstract class I18nField extends TextField { - public String[] keyValue; - - public Map translations; + protected Set keyValue; + protected Map translations; public I18nField(Set keys, Set values, Map translations) { - super(new String[0]); - this.keyValue = keys.toArray(new String[0]); - this.textValue = values.toArray(new String[0]); + super(new ArrayList<>(values)); + this.keyValue = keys; this.translations = translations; } @Override public Object getValue() { - if (textValue != null && textValue.length > 0) { - return new I18nString(textValue[0], translations); + if (this.textValue != null && !this.textValue.isEmpty()) { + return new I18nString(this.textValue.getFirst(), this.translations); } return null; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java index d57d980ad40..5e684ab1c90 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java @@ -12,32 +12,34 @@ @EqualsAndHashCode(callSuper = true) public abstract class MapField extends TextField { - public String[] keyValue; - public Map keyValueTranslations; + protected List keyValue; + protected Map keyValueTranslations; public MapField(Map.Entry valueTranslationPair) { this(List.of(valueTranslationPair)); } public MapField(List> valueTranslationPairs) { - super(new String[0]); - this.keyValue = new String[valueTranslationPairs.size()]; + if (valueTranslationPairs == null || valueTranslationPairs.isEmpty()) { + return; + } List values = new ArrayList<>(); + this.keyValue = new ArrayList<>(); this.keyValueTranslations = new HashMap<>(); - for (int i = 0; i < valueTranslationPairs.size(); i++) { - this.keyValue[i] = valueTranslationPairs.get(i).getKey(); - values.addAll(I18nStringUtils.collectTranslations(valueTranslationPairs.get(i).getValue())); - this.keyValueTranslations.put(valueTranslationPairs.get(i).getKey(), valueTranslationPairs.get(i).getValue()); + for (Map.Entry valueTranslationPair : valueTranslationPairs) { + this.keyValue.add(valueTranslationPair.getKey()); + values.addAll(I18nStringUtils.collectTranslations(valueTranslationPair.getValue())); + this.keyValueTranslations.put(valueTranslationPair.getKey(), valueTranslationPair.getValue()); } - this.textValue = values.toArray(new String[0]); - this.fulltextValue = values.toArray(new String[0]); + this.textValue = values; + this.fulltextValue = values; } public Object getValue() { - if (keyValue != null && keyValue.length == 1) { - return keyValue[0]; - } else if (keyValue != null && keyValue.length > 1) { - return new LinkedHashSet<>(Arrays.asList(keyValue)); + if (this.keyValue != null && this.keyValue.size() == 1) { + return this.keyValue.getFirst(); + } else if (this.keyValue != null && this.keyValue.size() > 1) { + return new LinkedHashSet<>(this.keyValue); } return null; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java index 21cf9441285..c918841a519 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java @@ -10,7 +10,7 @@ @EqualsAndHashCode(callSuper = true) public abstract class NumberField extends DataField { - public Double numberValue; + protected Double numberValue; public NumberField(Double value) { super(value.toString()); @@ -18,6 +18,6 @@ public NumberField(Double value) { } public Object getValue() { - return numberValue; + return this.numberValue; } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java index c4b4cb972c2..f289a8f654b 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/StringCollectionField.java @@ -5,14 +5,16 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.util.List; + @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) -public abstract class StringCollectionField extends TextField { +public abstract class StringCollectionField extends DataField { - public String[] collectionValue; + protected List collectionValue; - public StringCollectionField(String[] values) { + public StringCollectionField(List values) { super(values); this.collectionValue = values; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java index 83a85604982..1d90991f76c 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java @@ -4,20 +4,20 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.util.List; + @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) public abstract class TextField extends DataField { - public String[] textValue; + protected List textValue; public TextField(String value) { - super(value); - this.textValue = new String[1]; - this.textValue[0] = value; + this(List.of(value)); } - public TextField(String[] values) { + public TextField(List values) { super(values); this.textValue = values; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java deleted file mode 100644 index e08b3852f2a..00000000000 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.netgrif.application.engine.objects.elastic.domain; - -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -import java.util.stream.IntStream; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -public abstract class UserField extends DataField { - - // TODO JOFO: put group into userField - private String[] usernameValue; - - private String[] fullNameValue; - - private String[] userIdValue; - - private String[] userRealmIdValue; - - public UserField(UserMappingData value) { - super(String.format("%s %s", value.fullName, value.username)); - this.usernameValue = new String[1]; - this.fullNameValue = new String[1]; - this.userIdValue = new String[1]; - this.userRealmIdValue = new String[1]; - this.usernameValue[0] = value.username; - this.fullNameValue[0] = value.fullName; - this.userIdValue[0] = value.userId; - this.userRealmIdValue[0] = value.userRealmId; - } - - public UserField(UserMappingData[] values) { - super(new String[values.length]); - this.usernameValue = new String[values.length]; - this.fullNameValue = new String[values.length]; - this.userIdValue = new String[values.length]; - this.userRealmIdValue = new String[values.length]; - for (int i = 0; i < values.length; i++) { - this.usernameValue[i] = values[i].username; - this.fullNameValue[i] = values[i].fullName; - this.userIdValue[i] = values[i].userId; - this.userRealmIdValue[i] = values[i].userRealmId; - super.fulltextValue[i] = String.format("%s %s", values[i].fullName, values[i].username); - } - } - - @Override - public Object getValue() { - if (userIdValue != null && userIdValue.length == 1) { - String fullName = fullNameValue[0] != null ? fullNameValue[0] : ""; - String[] fullNameSplit = fullName.split(" ", 2); - String firstName = fullNameSplit.length > 0 ? fullNameSplit[0] : ""; - String lastName = fullNameSplit.length > 1 ? fullNameSplit[1] : ""; - return new UserFieldValue(userIdValue[0], userRealmIdValue[0], firstName, lastName, usernameValue[0]); - } else if (userIdValue != null && userIdValue.length > 1) { - return IntStream.range(0, userIdValue.length).mapToObj(i -> { - String fullName = fullNameValue[i] != null ? fullNameValue[i] : ""; - String[] fullNameSplit = fullName.split(" ", 2); - String firstName = fullNameSplit.length > 0 ? fullNameSplit[0] : ""; - String lastName = fullNameSplit.length > 1 ? fullNameSplit[1] : ""; - return new UserFieldValue(userIdValue[i], userRealmIdValue[i], firstName, lastName, usernameValue[i]); - }).toList(); - } - return null; - } - - @AllArgsConstructor - public static class UserMappingData { - public String userId; - public String userRealmId; - public String username; - public String fullName; - } -} - - diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java deleted file mode 100644 index 1693fa5c2b8..00000000000 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserListField.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.netgrif.application.engine.objects.elastic.domain; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -public abstract class UserListField extends UserField { - - private String[] usernameValue; - - private String[] fullNameValue; - - private String[] userIdValue; - - private String[] userRealmIdValue; - - public UserListField(UserMappingData[] values) { - super(values); - this.usernameValue = new String[values.length]; - this.fullNameValue = new String[values.length]; - this.userIdValue = new String[values.length]; - this.userRealmIdValue = new String[values.length]; - for (int i = 0; i < values.length; i++) { - this.usernameValue[i] = values[i].username; - this.fullNameValue[i] = values[i].fullName; - this.userIdValue[i] = values[i].userId; - this.userRealmIdValue[i] = values[i].userRealmId; - super.fulltextValue[i] = String.format("%s %s", values[i].fullName, values[i].username); - } - } - -} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java similarity index 54% rename from nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListField.java rename to nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java index 727d0a411c1..9837e5ec86c 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorField.java @@ -9,30 +9,31 @@ @Setter @Getter -public class UserListField extends Field { +public class ActorField extends Field { private Set roles; - public UserListField() { - super(); - this.roles = new HashSet<>(); + public ActorField() { + this(new HashSet<>()); + } + + public ActorField(String[] roles) { + this(new HashSet<>(Arrays.asList(roles))); } - public UserListField(String[] values) { - this(); - if (values != null) { - this.roles.addAll(Arrays.asList(values)); - } + public ActorField(Set roles) { + super(); + this.roles = roles == null ? new HashSet<>() : roles; } @Override public FieldType getType() { - return FieldType.USERLIST; + return FieldType.ACTOR; } @Override public Field clone() { - UserListField clone = new UserListField(); + ActorField clone = new ActorField(); super.clone(clone); clone.setRoles(this.roles); return clone; diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java new file mode 100644 index 00000000000..d02f6c5c39d --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java @@ -0,0 +1,26 @@ +package com.netgrif.application.engine.objects.petrinet.domain.dataset; + +import com.netgrif.application.engine.objects.elastic.domain.ActorMappingData; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public abstract class ActorFieldValue implements Serializable { + + protected String id; + protected String realmId; + + public abstract String getFullName(); + public abstract String toString(); + public abstract boolean equals(Object obj); + public abstract ActorMappingData buildMappingData(); + + public int hashCode() { + return this.id.hashCode(); + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java new file mode 100644 index 00000000000..40e2eb745dc --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java @@ -0,0 +1,41 @@ +package com.netgrif.application.engine.objects.petrinet.domain.dataset; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +@Setter +@Getter +public class ActorListField extends Field { + + private Set roles; + + public ActorListField() { + this(new HashSet<>()); + } + + public ActorListField(String[] roles) { + this(new HashSet<>(Arrays.asList(roles))); + } + + public ActorListField(Set roles) { + super(); + this.roles = roles == null ? new HashSet<>() : roles; + } + + @Override + public FieldType getType() { + return FieldType.ACTORLIST; + } + + @Override + public Field clone() { + ActorListField clone = new ActorListField(); + super.clone(clone); + clone.setRoles(this.roles); + return clone; + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java new file mode 100644 index 00000000000..3b736de7a36 --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListFieldValue.java @@ -0,0 +1,39 @@ +package com.netgrif.application.engine.objects.petrinet.domain.dataset; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; + +public class ActorListFieldValue implements Serializable { + + @Serial + private static final long serialVersionUID = 5228212326431238485L; + private Set actorValues; + + public ActorListFieldValue() { + this(new LinkedHashSet<>()); + } + + public ActorListFieldValue(Collection actorValues) { + this(new LinkedHashSet<>(actorValues)); + } + + public ActorListFieldValue(LinkedHashSet actorValues) { + this.actorValues = actorValues; + } + + public LinkedHashSet getActorValues() { + return (LinkedHashSet) actorValues; + } + + public void setActorValues(Collection actorValues) { + this.actorValues = new LinkedHashSet<>(actorValues); + } + + @Override + public String toString() { + return actorValues.toString(); + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java index 3b9280d09ac..df99a1017e6 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/FieldType.java @@ -15,8 +15,8 @@ public enum FieldType { MULTICHOICE("multichoice"), MULTICHOICE_MAP("multichoice_map"), NUMBER("number"), - USER("user"), - USERLIST("userList"), + ACTOR("actor"), + ACTORLIST("actorList"), TABULAR("tabular"), CASE_REF("caseRef"), DATETIME("dateTime"), diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java new file mode 100644 index 00000000000..070076b844a --- /dev/null +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/GroupFieldValue.java @@ -0,0 +1,45 @@ +package com.netgrif.application.engine.objects.petrinet.domain.dataset; + +import com.netgrif.application.engine.objects.auth.domain.Group; +import com.netgrif.application.engine.objects.elastic.domain.ActorMappingData; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class GroupFieldValue extends ActorFieldValue { + + protected String name; + + public GroupFieldValue(String id, String realmId, String name) { + super(id, realmId); + this.name = name; + } + + public GroupFieldValue(Group group) { + this(group.getStringId(), group.getRealmId(), group.getDisplayName()); + } + + @Override + public String getFullName() { + return name; + } + + @Override + public String toString() { + return "GroupFieldValue{" + ", name='" + name + "'}"; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof GroupFieldValue)) { + return false; + } + return this.id != null && ((GroupFieldValue) obj).getId() != null && this.id.equals(((GroupFieldValue) obj).getId()); + } + + @Override + public ActorMappingData buildMappingData() { + return new ActorMappingData(this.id, this.realmId, null, this.getFullName()); + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserField.java deleted file mode 100644 index e37975f5688..00000000000 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserField.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.netgrif.application.engine.objects.petrinet.domain.dataset; - -import lombok.Getter; -import lombok.Setter; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -@Setter -@Getter -public class UserField extends Field { - private Set roles; - - public UserField() { - super(); - this.roles = new HashSet<>(); - } - - public UserField(String[] values) { - this(); - if (values != null) { - this.roles.addAll(Arrays.asList(values)); - } - } - - @Override - public FieldType getType() { - return FieldType.USER; - } - - @Override - public Field clone() { - UserField clone = new UserField(); - super.clone(clone); - clone.setRoles(this.roles); - return clone; - } -} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java index 705db48500c..a8ee0edefb7 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java @@ -1,27 +1,25 @@ package com.netgrif.application.engine.objects.petrinet.domain.dataset; import com.netgrif.application.engine.objects.auth.domain.AbstractUser; +import com.netgrif.application.engine.objects.elastic.domain.ActorMappingData; import lombok.Getter; import lombok.NoArgsConstructor; import java.io.Serial; -import java.io.Serializable; @Getter @NoArgsConstructor -public class UserFieldValue implements Serializable { +public class UserFieldValue extends ActorFieldValue { @Serial private static final long serialVersionUID = 5228212326436828485L; - protected String id; - protected String realmId; + protected String firstName; protected String lastName; protected String username; public UserFieldValue(String id, String realmId, String firstName, String lastName, String username) { - this.id = id; - this.realmId = realmId; + super(id, realmId); this.firstName = firstName; this.lastName = lastName; this.username = username; @@ -31,6 +29,7 @@ public UserFieldValue(AbstractUser user) { this(user.getStringId(), user.getRealmId(), user.getFirstName(), user.getLastName(), user.getUsername()); } + @Override public String getFullName() { return firstName + " " + lastName; } @@ -40,10 +39,6 @@ public String toString() { return "UserFieldValue{" + ", name='" + firstName + "'" + ", surname='" + lastName + "'" + ", username='" + username + "'" + "}"; } - public int hashCode() { - return this.id.hashCode(); - } - @Override public boolean equals(Object obj) { if (!(obj instanceof UserFieldValue)) { @@ -51,4 +46,9 @@ public boolean equals(Object obj) { } return this.id != null && ((UserFieldValue) obj).getId() != null && this.id.equals(((UserFieldValue) obj).getId()); } + + @Override + public ActorMappingData buildMappingData() { + return new ActorMappingData(this.id, this.realmId, this.username, this.getFullName()); + } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListFieldValue.java deleted file mode 100644 index 2f56e0e9f7e..00000000000 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserListFieldValue.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.netgrif.application.engine.objects.petrinet.domain.dataset; - -import java.io.Serial; -import java.io.Serializable; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.Set; - -public class UserListFieldValue implements Serializable { - - @Serial - private static final long serialVersionUID = 5228212326431238485L; - private Set userValues; - - public UserListFieldValue() { - this.userValues = new LinkedHashSet(); - } - - public UserListFieldValue(Collection userValues) { - this(); - this.userValues = new LinkedHashSet(userValues); - } - - public LinkedHashSet getUserValues() { - return (LinkedHashSet) userValues; - } - - public void setUserValues(Collection userValues) { - this.userValues = new LinkedHashSet(userValues); - } - - @Override - public String toString() { - return userValues.toString(); - } -} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedFieldFactory.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedFieldFactory.java index 6de69d25858..310fa8fddf0 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedFieldFactory.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedFieldFactory.java @@ -23,10 +23,10 @@ public static LocalisedField from(Field field, Locale locale) { return fromDateTime((DateTimeField) field, locale); } else if (field instanceof BooleanField) { return fromBoolean((BooleanField) field, locale); - } else if (field instanceof UserField) { - return fromUser((UserField) field, locale); - } else if (field instanceof UserListField) { - return fromUserList((UserListField) field, locale); + } else if (field instanceof ActorField) { + return fromUser((ActorField) field, locale); + } else if (field instanceof ActorListField) { + return fromUserList((ActorListField) field, locale); } else if (field instanceof EnumerationMapField) { return fromEnumerationMap((EnumerationMapField) field, locale); } else if (field instanceof MultichoiceMapField) { @@ -68,11 +68,11 @@ private static LocalisedField fromBoolean(BooleanField field, Locale locale) { return new LocalisedBooleanField(field, locale); } - private static LocalisedField fromUser(UserField field, Locale locale) { + private static LocalisedField fromUser(ActorField field, Locale locale) { return new LocalisedUserField(field, locale); } - private static LocalisedField fromUserList(UserListField field, Locale locale) { + private static LocalisedField fromUserList(ActorListField field, Locale locale) { return new LocalisedUserListField(field, locale); } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java index 40b92570ecb..9c677087eff 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserField.java @@ -1,6 +1,6 @@ package com.netgrif.application.engine.objects.petrinet.domain.dataset.localised; -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserField; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorField; import lombok.Data; import lombok.EqualsAndHashCode; @@ -13,7 +13,7 @@ public class LocalisedUserField extends LocalisedField { private Set roles; - public LocalisedUserField(UserField field, Locale locale) { + public LocalisedUserField(ActorField field, Locale locale) { super(field, locale); this.roles = field.getRoles(); } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java index b6a13bacb2e..76aaed5a3cf 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/localised/LocalisedUserListField.java @@ -1,6 +1,6 @@ package com.netgrif.application.engine.objects.petrinet.domain.dataset.localised; -import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserListField; +import com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListField; import lombok.Data; import lombok.EqualsAndHashCode; @@ -13,7 +13,7 @@ public class LocalisedUserListField extends LocalisedField { private Set roles; - public LocalisedUserListField(UserListField field, Locale locale) { + public LocalisedUserListField(ActorListField field, Locale locale) { super(field, locale); this.roles = field.getRoles(); } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index 34c21683987..57408847209 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -198,11 +198,11 @@ public void populateDataSet(InitValueExpressionEvaluator initValueExpressionEval if (field.getComponent() != null) { this.dataSet.get(key).setComponent(field.getComponent()); } - if (field instanceof UserField) { - this.dataSet.get(key).setChoices(((UserField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + if (field instanceof ActorField) { + this.dataSet.get(key).setChoices(((ActorField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); } - if (field instanceof UserListField) { - this.dataSet.get(key).setChoices(((UserListField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); + if (field instanceof ActorListField) { + this.dataSet.get(key).setChoices(((ActorListField) field).getRoles().stream().map(I18nString::new).collect(Collectors.toSet())); } if (field instanceof FieldWithAllowedNets) { this.dataSet.get(key).setAllowedNets(((FieldWithAllowedNets) field).getAllowedNets()); diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorField.java new file mode 100644 index 00000000000..deb17b92d14 --- /dev/null +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorField.java @@ -0,0 +1,59 @@ +package com.netgrif.application.engine.adapter.spring.elastic.domain; + +import com.netgrif.application.engine.objects.elastic.domain.ActorMappingData; +import lombok.NoArgsConstructor; +import org.springframework.data.elasticsearch.annotations.Field; + +import java.util.Arrays; +import java.util.List; + +import static org.springframework.data.elasticsearch.annotations.FieldType.Text; + +@NoArgsConstructor +public class ActorField extends com.netgrif.application.engine.objects.elastic.domain.ActorField { + + public ActorField(ActorMappingData value) { + super(value); + } + + @Deprecated + public ActorField(ActorMappingData[] values) { + this(Arrays.asList(values)); + } + + public ActorField(List values) { + super(values); + } + + @Override + @Field(type = Text) + public List getFulltextValue() { + return super.getFulltextValue(); + } + + @Override + @Field(type = Text) + public List getUsernameValue() { + return super.getUsernameValue(); + } + + @Override + @Field(type = Text) + public List getFullNameValue() { + return super.getFullNameValue(); + } + + @Override + @Field(type = Text) + public List getActorIdValue() { + return super.getActorIdValue(); + } + + @Override + @Field(type = Text) + public List getActorRealmIdValue() { + return super.getActorRealmIdValue(); + } +} + + diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorListField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorListField.java new file mode 100644 index 00000000000..ffb1326a039 --- /dev/null +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ActorListField.java @@ -0,0 +1,53 @@ +package com.netgrif.application.engine.adapter.spring.elastic.domain; + +import com.netgrif.application.engine.objects.elastic.domain.ActorMappingData; +import lombok.NoArgsConstructor; +import org.springframework.data.elasticsearch.annotations.Field; + +import java.util.Arrays; +import java.util.List; + +import static org.springframework.data.elasticsearch.annotations.FieldType.Text; + +@NoArgsConstructor +public class ActorListField extends com.netgrif.application.engine.objects.elastic.domain.ActorListField { + + @Deprecated + public ActorListField(ActorMappingData[] values) { + this(Arrays.asList(values)); + } + + public ActorListField(List actorMappingDataList) { + super(actorMappingDataList); + } + + @Override + @Field(type = Text) + public List getFulltextValue() { + return super.getFulltextValue(); + } + + @Override + @Field(type = Text) + public List getUsernameValue() { + return super.getUsernameValue(); + } + + @Override + @Field(type = Text) + public List getFullNameValue() { + return super.getFullNameValue(); + } + + @Override + @Field(type = Text) + public List getActorIdValue() { + return super.getActorIdValue(); + } + + @Override + @Field(type = Text) + public List getActorRealmIdValue() { + return super.getActorRealmIdValue(); + } +} diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java index 32392622807..1873667374f 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/BooleanField.java @@ -3,6 +3,8 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Boolean; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -19,12 +21,12 @@ public BooleanField(Boolean value) { @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Boolean) public Boolean getBooleanValue() { - return booleanValue; + return super.getBooleanValue(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ButtonField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ButtonField.java index 5322cdd317f..ca048da7a2e 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ButtonField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/ButtonField.java @@ -5,6 +5,8 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Integer; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -19,12 +21,12 @@ public ButtonField(Integer value) { @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Integer) public Integer getButtonValue() { - return buttonValue; + return super.getButtonValue(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java index 7596000d6f1..5c3e4303b27 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java @@ -3,6 +3,7 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.Arrays; import java.util.List; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -10,19 +11,24 @@ @NoArgsConstructor public class CaseField extends com.netgrif.application.engine.objects.elastic.domain.CaseField { + @Deprecated public CaseField(String[] values, String[] allowedNets) { + this(Arrays.asList(values), Arrays.asList(allowedNets)); + } + + public CaseField(List values, List allowedNets) { super(values, allowedNets); } @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Text) - public String[] getAllowedNets() { - return super.allowedNets; + public List getAllowedNets() { + return super.getAllowedNets(); } @Override diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/DateField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/DateField.java index 2ce6f55f20f..25cbf362d6a 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/DateField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/DateField.java @@ -6,6 +6,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import java.time.LocalDateTime; +import java.util.List; import static org.springframework.data.elasticsearch.annotations.FieldType.Long; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -19,17 +20,17 @@ public DateField(String value, LocalDateTime dateTime) { @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second_millis) public LocalDateTime getDateValue() { - return dateValue; + return super.getDateValue(); } @Field(type = Long) public Long getTimestampValue() { - return timestampValue; + return super.getTimestampValue(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java index 4990f7299fc..54f7760d15b 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FileField.java @@ -5,6 +5,11 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Keyword; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -16,23 +21,32 @@ public FileField(FileFieldValue value) { super(value); } + @Deprecated public FileField(FileFieldValue[] values) { + this(Arrays.asList(values)); + } + + public FileField(List values) { super(values); } + public FileField(HashSet values) { + this(new ArrayList<>(values)); + } + @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Text) - public String[] getFileNameValue() { + public List getFileNameValue() { return super.getFileNameValue(); } @Field(type = Keyword) - public String[] getFileExtensionValue() { + public List getFileExtensionValue() { return super.getFileExtensionValue(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java index e3322b1fe31..dcd0a9cccb7 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java @@ -3,6 +3,8 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.Arrays; +import java.util.List; import java.util.Map; import static org.springframework.data.elasticsearch.annotations.FieldType.*; @@ -10,23 +12,28 @@ @NoArgsConstructor public class FilterField extends com.netgrif.application.engine.objects.elastic.domain.FilterField { + @Deprecated public FilterField(String value, String[] allowedNets, Map filterMetadata) { + this(value, Arrays.asList(allowedNets), filterMetadata); + } + + public FilterField(String value, List allowedNets, Map filterMetadata) { super(value, allowedNets, filterMetadata); } @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Text) - public String[] getAllowedNets() { - return super.allowedNets; + public List getAllowedNets() { + return super.getAllowedNets(); } @Field(type = Flattened) public Map getFilterMetadata() { - return super.filterMetadata; + return super.getFilterMetadata(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java index 6e7345b5596..9a194fff246 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java @@ -3,6 +3,7 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.List; import java.util.Map; import java.util.Set; @@ -18,12 +19,12 @@ public I18nField(Set keys, Set values, Map trans @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Text) - public String[] getKeyValue() { + public Set getKeyValue() { return super.getKeyValue(); } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java index 217ab8001da..46e685cff08 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/MapField.java @@ -23,17 +23,17 @@ public MapField(List> valuePairs) { @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Field(type = Keyword) - public String[] getKeyValue() { + public List getKeyValue() { return super.getKeyValue(); } @Field(type = Flattened, index = false) public Map getKeyValueTranslations() { - return super.keyValueTranslations; + return super.getKeyValueTranslations(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java index f643393df65..b2d27ef0dcd 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/NumberField.java @@ -3,6 +3,8 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Double; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -15,7 +17,7 @@ public NumberField(Double value) { @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java index 4786a4d2d4a..2c1eeca5a94 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/StringCollectionField.java @@ -5,6 +5,9 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.Arrays; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Keyword; import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @@ -13,19 +16,24 @@ @EqualsAndHashCode(callSuper = true) public class StringCollectionField extends com.netgrif.application.engine.objects.elastic.domain.StringCollectionField { + @Deprecated public StringCollectionField(String[] values) { + super(Arrays.asList(values)); + } + + public StringCollectionField(List values) { super(values); } @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Override @Field(type = Keyword) - public String[] getCollectionValue() { + public List getCollectionValue() { return super.getCollectionValue(); } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/TextField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/TextField.java index e1a09218675..f1d0c6e01bf 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/TextField.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/TextField.java @@ -5,6 +5,9 @@ import lombok.NoArgsConstructor; import org.springframework.data.elasticsearch.annotations.Field; +import java.util.Arrays; +import java.util.List; + import static org.springframework.data.elasticsearch.annotations.FieldType.Text; @Data @@ -16,19 +19,24 @@ public TextField(String value) { super(value); } + @Deprecated public TextField(String[] values) { + this(Arrays.asList(values)); + } + + public TextField(List values) { super(values); } @Override @Field(type = Text) - public String[] getFulltextValue() { + public List getFulltextValue() { return super.getFulltextValue(); } @Override @Field(type = Text) - public String[] getTextValue() { + public List getTextValue() { return super.getTextValue(); } } diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserField.java deleted file mode 100644 index 7268f5b9f91..00000000000 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserField.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.netgrif.application.engine.adapter.spring.elastic.domain; - -import lombok.NoArgsConstructor; -import org.springframework.data.elasticsearch.annotations.Field; - -import static org.springframework.data.elasticsearch.annotations.FieldType.Text; - -@NoArgsConstructor -public class UserField extends com.netgrif.application.engine.objects.elastic.domain.UserField { - - public UserField(UserMappingData value) { - super(value); - } - - public UserField(UserMappingData[] values) { - super(values); - } - - @Override - @Field(type = Text) - public String[] getFulltextValue() { - return super.getFulltextValue(); - } - - @Override - @Field(type = Text) - public String[] getUsernameValue() { - return super.getUsernameValue(); - } - - @Override - @Field(type = Text) - public String[] getFullNameValue() { - return super.getFullNameValue(); - } - - @Override - @Field(type = Text) - public String[] getUserIdValue() { - return super.getUserIdValue(); - } - - @Override - @Field(type = Text) - public String[] getUserRealmIdValue() { - return super.getUserRealmIdValue(); - } -} - - diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserListField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserListField.java deleted file mode 100644 index 8619879c718..00000000000 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/UserListField.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.netgrif.application.engine.adapter.spring.elastic.domain; - -import lombok.NoArgsConstructor; -import org.springframework.data.elasticsearch.annotations.Field; - -import static org.springframework.data.elasticsearch.annotations.FieldType.Text; - -@NoArgsConstructor -public class UserListField extends com.netgrif.application.engine.objects.elastic.domain.UserListField { - - public UserListField(UserMappingData[] values) { - super(values); - } - - @Override - @Field(type = Text) - public String[] getFulltextValue() { - return super.getFulltextValue(); - } - - @Override - @Field(type = Text) - public String[] getUsernameValue() { - return super.getUsernameValue(); - } - - @Override - @Field(type = Text) - public String[] getFullNameValue() { - return super.getFullNameValue(); - } - - @Override - @Field(type = Text) - public String[] getUserIdValue() { - return super.getUserIdValue(); - } - - @Override - @Field(type = Text) - public String[] getUserRealmIdValue() { - return super.getUserRealmIdValue(); - } -} From 2bdb241a9f1f6dff6bedb6a44f367ae0ea41e71f Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 3 Dec 2025 13:13:59 +0100 Subject: [PATCH 02/48] [NAE-2285] Group as a value of userlists - resolve todos --- .../elastic/service/ElasticTaskService.java | 1 - .../engine/importer/service/FieldFactory.java | 24 +++++++++---------- .../fieldbuilder/TextFieldBuilder.java | 1 - .../workflow/service/CaseSearchService.java | 5 ++-- .../engine-processes/impersonation_config.xml | 1 - 5 files changed, 13 insertions(+), 19 deletions(-) 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 082557c849c..6d554236b6a 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 @@ -325,7 +325,6 @@ protected void buildTitleQuery(ElasticTaskSearchRequest request, BoolQuery.Build * Tasks assigned to user with id 1 OR 2 */ protected void buildUserQuery(ElasticTaskSearchRequest request, BoolQuery.Builder query) { - // todo 2285 if (request.user == null || request.user.isEmpty()) { return; } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java index 8b7fd21c347..b7ab15b8f1e 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/FieldFactory.java @@ -712,31 +712,29 @@ private void resolveDataValues(Field field, Case useCase, String fieldId) { parseFileListValue((FileListField) field, useCase, fieldId); break; case ACTOR: - parseUserValues((ActorField) field, useCase, fieldId); + parseActorValues((ActorField) field, useCase, fieldId); break; case ACTORLIST: - parseUserListValues((ActorListField) field, useCase, fieldId); + parseActorListValues((ActorListField) field, useCase, fieldId); break; default: field.setValue(useCase.getFieldValue(fieldId)); } } - private void parseUserValues(ActorField field, Case useCase, String fieldId) { - // todo 2285 - DataField userField = useCase.getDataField(fieldId); - if (userField.getChoices() != null) { - Set roles = userField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); + private void parseActorValues(ActorField field, Case useCase, String fieldId) { + DataField actorField = useCase.getDataField(fieldId); + if (actorField.getChoices() != null) { + Set roles = actorField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); field.setRoles(roles); } - field.setValue((UserFieldValue) useCase.getFieldValue(fieldId)); + field.setValue((ActorFieldValue) useCase.getFieldValue(fieldId)); } - private void parseUserListValues(ActorListField field, Case useCase, String fieldId) { - // todo 2285 - DataField userListField = useCase.getDataField(fieldId); - if (userListField.getChoices() != null) { - Set roles = userListField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); + private void parseActorListValues(ActorListField field, Case useCase, String fieldId) { + DataField actorListField = useCase.getDataField(fieldId); + if (actorListField.getChoices() != null) { + Set roles = actorListField.getChoices().stream().map(I18nString::getDefaultValue).collect(Collectors.toSet()); field.setRoles(roles); } field.setValue((ActorListFieldValue) useCase.getFieldValue(fieldId)); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java index c23e8823d8b..b32a73d6642 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java @@ -60,7 +60,6 @@ public PdfField buildField(DataGroup dataGroup, LocalisedField field, int lastX, value = field.getValue() != null ? ((UserFieldValue) field.getValue()).getFullName() : ""; break; case ACTORLIST: - // todo 2285 value = field.getValue() != null ? ((ActorListFieldValue) field.getValue()).getActorValues().stream() .map(ActorFieldValue::getFullName) .collect(Collectors.joining(", ")) : ""; 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 2d44b3dfe6b..c5d8593f3e0 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 @@ -5,8 +5,8 @@ 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.ActorFieldValue; 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.petrinet.service.interfaces.IPetriNetService; import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference; import com.netgrif.application.engine.utils.FullPageRequest; @@ -227,8 +227,7 @@ public Predicate data(Object data) { switch (type) { case ACTOR: - // todo 2285 - Path valuePath = Expressions.simplePath(UserFieldValue.class, QCase.case$.dataSet.get((String) k), "value"); + Path valuePath = Expressions.simplePath(ActorFieldValue.class, QCase.case$.dataSet.get((String) k), "value"); Path idPath = Expressions.stringPath(valuePath, "id"); Expression constant = Expressions.constant(Long.valueOf("" + fieldValue)); predicates.add(Expressions.predicate(Ops.EQ, idPath, constant)); diff --git a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml index 76e43bfc5a5..de7fecf8432 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml @@ -97,7 +97,6 @@ change impersonated value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue(user.stringId, user.firstName, user.lastName, user.username) } change impersonated_email value { user.username } - // todo 2285 change config_owner value { new com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListFieldValue([impersonated.value]) } From 47b2abd84fa1579cd4bfcf4fdca73c01e78c61e3 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 3 Dec 2025 15:29:40 +0100 Subject: [PATCH 03/48] [NAE-2285] Group as a value of userlists - add todos - use actorRef instead of userRef in processes - update process model validations - remove unnecessary transactional annotations - update process importer - use actorRef keyword instead of userRef in the project - update initialization of actorRef attributes in Case and Task --- .../importer/service/DataValidator.java | 5 +- .../importer/service/DocumentValidator.java | 1 + .../importer/service/IModelValidator.java | 4 +- .../engine/importer/service/Importer.java | 98 ++++++------------- .../importer/service/TransitionValidator.java | 1 + .../workflow/service/CaseSearchService.java | 17 ++-- .../engine/workflow/service/DataService.java | 2 +- .../service/TaskAuthorizationService.java | 6 +- .../workflow/service/TaskSearchService.java | 26 +++-- .../engine/workflow/service/TaskService.java | 69 ++++++++----- .../service/WorkflowAuthorizationService.java | 8 +- .../workflow/service/WorkflowService.java | 52 ++++++---- .../service/interfaces/ITaskService.java | 4 +- .../service/interfaces/IWorkflowService.java | 2 +- .../workflow/web/responsebodies/Task.java | 2 +- .../engine-processes/impersonation_config.xml | 16 +-- .../engine/importer/UserListTest.groovy | 4 +- .../ElasticSearchViewPermissionTest.groovy | 6 +- .../QueryDSLViewPermissionTest.groovy | 8 +- .../engine/workflow/UserRefsTest.groovy | 2 +- .../petriNets/impersonation_test.xml | 4 +- ...ssions_anonymous_role_shadowed_userref.xml | 8 +- ...sions_anonymous_role_shadowed_usersref.xml | 8 +- ...missions_default_role_shadowed_userref.xml | 8 +- ...issions_default_role_shadowed_usersref.xml | 8 +- ...thorization_service_test_with_userRefs.xml | 32 +++--- .../src/test/resources/user_list.xml | 8 +- .../src/test/resources/userrefs_test.xml | 8 +- .../view_permission_with_userRefs_test.xml | 16 +-- ...thorization_service_test_with_userRefs.xml | 8 +- docs/_media/roles/usersRef_net.xml | 8 +- docs/roles/permissions.md | 34 ++++--- docs/roles/userlist.md | 8 +- .../objects/elastic/domain/ElasticCase.java | 8 +- .../objects/elastic/domain/ElasticTask.java | 16 ++- .../objects/petrinet/domain/PetriNet.java | 14 +-- .../objects/petrinet/domain/Transition.java | 14 +-- .../engine/objects/workflow/domain/Case.java | 59 +++++------ .../engine/objects/workflow/domain/Task.java | 77 ++++++++------- .../adapter/spring/workflow/domain/Case.java | 8 +- .../adapter/spring/workflow/domain/Task.java | 14 ++- 41 files changed, 358 insertions(+), 343 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java index b0bf2752e11..5146d7347a1 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java @@ -1,6 +1,7 @@ package com.netgrif.application.engine.importer.service; import com.netgrif.application.engine.objects.importer.model.Data; +import com.netgrif.application.engine.objects.importer.model.DataType; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -14,11 +15,13 @@ public void checkDeprecatedAttributes(Data data) { validateAttribute(data.getValid() != null && !data.getValid().isEmpty() ? data.getValid() : null, "valid", data.getId()); validateAttribute(data.getFormat(), "format", data.getId()); validateAttribute(data.getValues() != null && !data.getValues().isEmpty() ? data.getValues() : null, "values", data.getId()); + validateAttribute(data.getType() != null && data.getType().equals(DataType.USER) ? data.getType() : null, "type: " + DataType.USER.name(), data.getId()); + validateAttribute(data.getType() != null && data.getType().equals(DataType.USER_LIST) ? data.getType() : null, "type: " + DataType.USER_LIST.name(), data.getId()); } protected void validateAttribute(Object attr, String attrName, String fieldName) { if (attr != null) { - log.warn("Data attribute [" + attrName + "] on field [" + fieldName + "] is deprecated."); + log.warn("Data attribute [{}] on field [{}] is deprecated.", attrName, fieldName); } } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DocumentValidator.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DocumentValidator.java index d2e948ba66f..2745e32df0d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DocumentValidator.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DocumentValidator.java @@ -11,6 +11,7 @@ public class DocumentValidator implements IDocumentValidator { @Override public void checkDeprecatedAttributes(Document document) { validateAttribute(document.getUsersRef(), "usersRef"); + validateAttribute(document.getUsersRef(), "userRef"); } @Override diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java index 334b9f7bf70..e6d8b0852b4 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/IModelValidator.java @@ -11,11 +11,11 @@ default void validateAttribute(Object attr, String attrName) { Logger log = LoggerFactory.getLogger(IModelValidator.class); if (attr instanceof Collection && !((Collection) attr).isEmpty()) { - log.warn("Data attribute [" + attrName + "] is deprecated."); + log.warn("Data attribute [{}] is deprecated.", attrName); } if (!(attr instanceof Collection) && attr != null) { - log.warn("Data attribute [" + attrName + "] is deprecated."); + log.warn("Data attribute [{}] is deprecated.", attrName); } } } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java index 2a7edf9f4ca..dd83498036b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java @@ -44,7 +44,6 @@ import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; -import org.springframework.transaction.annotation.Transactional; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; @@ -129,7 +128,6 @@ public class Importer { @Autowired private ILogicValidator logicValidator; - @Transactional public Optional importPetriNet(InputStream xml) throws MissingPetriNetMetaDataException, MissingIconKeyException { try { initialize(); @@ -141,7 +139,6 @@ public Optional importPetriNet(InputStream xml) throws MissingPetriNet return Optional.empty(); } - @Transactional public Optional importPetriNet(File xml) throws MissingPetriNetMetaDataException, MissingIconKeyException { try { return importPetriNet(new FileInputStream(xml)); @@ -165,7 +162,6 @@ protected void initialize() { this.functions = new LinkedList<>(); } - @Transactional protected void unmarshallXml(InputStream xml) throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(Document.class); @@ -173,7 +169,6 @@ protected void unmarshallXml(InputStream xml) throws JAXBException { document = (Document) jaxbUnmarshaller.unmarshal(xml); } - @Transactional public Path saveNetFile(PetriNet net, InputStream xmlFile) throws IOException { File savedFile = new File(fileStorageConfiguration.getArchivedPath() + net.getStringId() + "-" + net.getTitle() + FILE_EXTENSION); savedFile.getParentFile().mkdirs(); @@ -182,12 +177,11 @@ public Path saveNetFile(PetriNet net, InputStream xmlFile) throws IOException { return savedFile.toPath(); } - @Transactional protected Optional createPetriNet() throws MissingPetriNetMetaDataException, MissingIconKeyException { net = new com.netgrif.application.engine.adapter.spring.petrinet.domain.PetriNet(); net.setVersion(null); - documentValidator.checkConflictingAttributes(document, document.getUsersRef(), document.getUserRef(), "usersRef", "userRef"); + documentValidator.checkConflictingAttributes(document, document.getUsersRef(), document.getActorRef(), "usersRef", "userRef"); documentValidator.checkDeprecatedAttributes(document); document.getI18N().forEach(this::addI18N); @@ -213,8 +207,9 @@ protected Optional createPetriNet() throws MissingPetriNetMetaDataExce actionRefs.forEach(this::resolveActionRefs); document.getFunction().forEach(this::createFunction); document.getRoleRef().forEach(this::resolveRoleRef); - document.getUsersRef().forEach(this::resolveUserRef); - document.getUserRef().forEach(this::resolveUserRef); + document.getUsersRef().forEach(this::resolveActorRef); // deprecated + document.getUserRef().forEach(this::resolveActorRef); // deprecated + document.getActorRef().forEach(this::resolveActorRef); addPredefinedRolesWithDefaultPermissions(); @@ -235,7 +230,6 @@ protected Optional createPetriNet() throws MissingPetriNetMetaDataExce return Optional.of(net); } - @Transactional protected void resolveRoleRef(CaseRoleRef roleRef) { CaseLogic logic = roleRef.getCaseLogic(); String roleId = getRole(roleRef.getId()).getStringId(); @@ -250,7 +244,6 @@ protected void resolveRoleRef(CaseRoleRef roleRef) { net.addPermission(roleId, roleFactory.getProcessPermissions(logic)); } - @Transactional protected void createFunction(com.netgrif.application.engine.objects.importer.model.Function function) { com.netgrif.application.engine.objects.petrinet.domain.Function fun = functionFactory.getFunction(function); @@ -258,33 +251,29 @@ protected void createFunction(com.netgrif.application.engine.objects.importer.mo functions.add(fun); } - @Transactional - protected void resolveUserRef(CaseUserRef userRef) { - CaseLogic logic = userRef.getCaseLogic(); - String usersId = userRef.getId(); + protected void resolveActorRef(CaseActorRef actorRef) { + CaseLogic logic = actorRef.getCaseLogic(); + String actorFieldId = actorRef.getId(); - if (logic == null || usersId == null) { + if (logic == null || actorFieldId == null) { return; } - net.addUserPermission(usersId, roleFactory.getProcessPermissions(logic)); + net.addActorPermission(actorFieldId, roleFactory.getProcessPermissions(logic)); } - @Transactional protected void resolveProcessEvents(ProcessEvents processEvents) { if (processEvents != null && processEvents.getEvent() != null) { net.setProcessEvents(createProcessEventsMap(processEvents.getEvent())); } } - @Transactional protected void resolveCaseEvents(CaseEvents caseEvents) { if (caseEvents != null && caseEvents.getEvent() != null) { net.setCaseEvents(createCaseEventsMap(caseEvents.getEvent())); } } - @Transactional protected void evaluateFunctions() { try { actionsCacheService.evaluateFunctions(functions); @@ -293,7 +282,6 @@ protected void evaluateFunctions() { } } - @Transactional protected void evaluateActions(String s, Action action) { try { actionsRunner.getActionCode(action, functions, true); @@ -302,7 +290,6 @@ protected void evaluateActions(String s, Action action) { } } - @Transactional protected void resolveActionRefs(String actionId, Action action) { Action referenced = actions.get(actionId); if (referenced == null) { @@ -312,13 +299,11 @@ protected void resolveActionRefs(String actionId, Action action) { action.setTrigger(referenced.getTrigger()); } - @Transactional protected void addI18N(I18N importI18N) { String locale = importI18N.getLocale(); importI18N.getI18NString().forEach(translation -> addTranslation(translation, locale)); } - @Transactional protected void addTranslation(I18NStringType i18NStringType, String locale) { String name = i18NStringType.getName(); I18nString translation = getI18n(name); @@ -329,7 +314,6 @@ protected void addTranslation(I18NStringType i18NStringType, String locale) { translation.addTranslation(locale, i18NStringType.getValue()); } - @Transactional protected void applyMapping(Mapping mapping) throws MissingIconKeyException { Transition transition = getTransition(mapping.getTransitionRef()); mapping.getRoleRef().forEach(roleRef -> addRoleLogic(transition, roleRef)); @@ -340,7 +324,7 @@ protected void applyMapping(Mapping mapping) throws MissingIconKeyException { mapping.getTrigger().forEach(trigger -> addTrigger(transition, trigger)); } - @Transactional + protected void resolveDataActions(Data data) { String fieldId = data.getId(); if (data.getEvent() != null && !data.getEvent().isEmpty()) { @@ -378,7 +362,6 @@ private void addActionsToEvent(List actions, DataEventType type, Map actions = buildActionRefs(data.getActionRef()); @@ -398,7 +381,6 @@ protected Action fromActionRef(ActionRef actionRef) { return placeholder; } - @Transactional protected void resolveTransitionActions(com.netgrif.application.engine.objects.importer.model.Transition trans) { if (trans.getDataRef() != null) { resolveDataRefActions(trans.getDataRef(), trans); @@ -412,7 +394,6 @@ protected void resolveTransitionActions(com.netgrif.application.engine.objects.i } } - @Transactional protected void resolveDataRefActions(List dataRef, com.netgrif.application.engine.objects.importer.model.Transition trans) { dataRef.forEach(ref -> { String fieldId = getField(ref.getId()).getStringId(); @@ -459,7 +440,6 @@ protected DataEvent createDefaultEvent(List actions, DataEventType type) return event; } - @Transactional protected void createArc(com.netgrif.application.engine.objects.importer.model.Arc importArc) { Arc arc = arcFactory.getArc(importArc); arc.setImportId(importArc.getId()); @@ -487,7 +467,6 @@ protected void createArc(com.netgrif.application.engine.objects.importer.model.A net.addArc(arc); } - @Transactional protected void createDataSet(Data importData) throws MissingIconKeyException { Field field = fieldFactory.getField(importData, this); @@ -495,7 +474,6 @@ protected void createDataSet(Data importData) throws MissingIconKeyException { fields.put(importData.getId(), field); } - @Transactional protected void createTransition(com.netgrif.application.engine.objects.importer.model.Transition importTransition) throws MissingIconKeyException { transitionValidator.checkConflictingAttributes(importTransition, importTransition.getUsersRef(), importTransition.getUserRef(), "usersRef", "userRef"); transitionValidator.checkDeprecatedAttributes(importTransition); @@ -523,15 +501,18 @@ protected void createTransition(com.netgrif.application.engine.objects.importer. addRoleLogic(transition, roleRef) ); } - /* @Deprecated - This 'importTransition.getUsersRef()' is deprecated, will be removed in future releases*/ + /* @Deprecated - This 'importTransition.getUsersRef()' is deprecated, will be removed in future releases */ if (importTransition.getUsersRef() != null) { - importTransition.getUsersRef().forEach(usersRef -> - addUserLogic(transition, usersRef)); + importTransition.getUsersRef().forEach(usersRef -> addActorLogic(transition, usersRef)); } + /* @Deprecated - This 'importTransition.getUserRef()' is deprecated, will be removed in future releases */ if (importTransition.getUserRef() != null) { - importTransition.getUserRef().forEach(userRef -> - addUserLogic(transition, userRef)); + importTransition.getUserRef().forEach(userRef -> addActorLogic(transition, userRef)); + } + + if (importTransition.getActorRef() != null) { + importTransition.getActorRef().forEach(actorRef -> addActorLogic(transition, actorRef)); } if (importTransition.getDataRef() != null) { @@ -568,7 +549,6 @@ protected void createTransition(com.netgrif.application.engine.objects.importer. transitions.put(importTransition.getId(), transition); } - @Transactional protected void addAssignedUserPolicy(com.netgrif.application.engine.objects.importer.model.Transition importTransition, Transition transition) { if (importTransition.getAssignedUser().isCancel() != null) { transition.getAssignedUserPolicy().put("cancel", importTransition.getAssignedUser().isCancel()); @@ -578,7 +558,6 @@ protected void addAssignedUserPolicy(com.netgrif.application.engine.objects.impo } } - @Transactional protected com.netgrif.application.engine.objects.petrinet.domain.events.Event addEvent(String transitionId, com.netgrif.application.engine.objects.importer.model.Event imported) { com.netgrif.application.engine.objects.petrinet.domain.events.Event event = new com.netgrif.application.engine.objects.petrinet.domain.events.Event(); event.setImportId(imported.getId()); @@ -591,7 +570,6 @@ protected com.netgrif.application.engine.objects.petrinet.domain.events.Event ad return event; } - @Transactional protected com.netgrif.application.engine.objects.petrinet.domain.events.ProcessEvent addProcessEvent(com.netgrif.application.engine.objects.importer.model.ProcessEvent imported) { com.netgrif.application.engine.objects.petrinet.domain.events.ProcessEvent event = new com.netgrif.application.engine.objects.petrinet.domain.events.ProcessEvent(); event.setMessage(toI18NString(imported.getMessage())); @@ -603,7 +581,6 @@ protected com.netgrif.application.engine.objects.petrinet.domain.events.ProcessE return event; } - @Transactional protected com.netgrif.application.engine.objects.petrinet.domain.events.CaseEvent addCaseEvent(com.netgrif.application.engine.objects.importer.model.CaseEvent imported) { com.netgrif.application.engine.objects.petrinet.domain.events.CaseEvent event = new com.netgrif.application.engine.objects.petrinet.domain.events.CaseEvent(); event.setMessage(toI18NString(imported.getMessage())); @@ -654,7 +631,6 @@ protected List parsePhaseActions(String fieldId, EventPhaseType phase, D return actionList; } - @Transactional protected void addDefaultRole(Transition transition) { if (!net.isDefaultRoleEnabled() || isDefaultRoleReferenced(transition)) { return; @@ -666,7 +642,6 @@ protected void addDefaultRole(Transition transition) { transition.addRole(defaultRole.getStringId(), roleFactory.getPermissions(logic)); } - @Transactional protected void addAnonymousRole(Transition transition) { if (!net.isAnonymousRoleEnabled() || isAnonymousRoleReferenced(transition)) { return; @@ -677,7 +652,6 @@ protected void addAnonymousRole(Transition transition) { transition.addRole(anonymousRole.getStringId(), roleFactory.getPermissions(logic)); } - @Transactional protected void addDefaultPermissions() { if (!net.isDefaultRoleEnabled() || isDefaultRoleReferencedOnNet()) { return; @@ -690,7 +664,6 @@ protected void addDefaultPermissions() { net.addPermission(defaultRole.getStringId(), roleFactory.getProcessPermissions(logic)); } - @Transactional protected void addAnonymousPermissions() { if (!net.isAnonymousRoleEnabled() || isAnonymousRoleReferencedOnNet()) { return; @@ -702,7 +675,6 @@ protected void addAnonymousPermissions() { net.addPermission(anonymousRole.getStringId(), roleFactory.getProcessPermissions(logic)); } - @Transactional protected void addDataWithDefaultGroup(Transition transition, DataRef dataRef) throws MissingIconKeyException { DataGroup dataGroup = new com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup(); dataGroup.setImportId(transition.getImportId() + "_" + dataRef.getId() + "_" + System.currentTimeMillis()); @@ -719,7 +691,6 @@ protected void addDataWithDefaultGroup(Transition transition, DataRef dataRef) t addDataComponent(transition, dataRef); } - @Transactional protected void addDataGroup(Transition transition, com.netgrif.application.engine.objects.importer.model.DataGroup importDataGroup, int index) throws MissingIconKeyException { String alignment = importDataGroup.getAlignment() != null ? importDataGroup.getAlignment().value() : ""; DataGroup dataGroup = new com.netgrif.application.engine.adapter.spring.workflow.domain.DataGroup(); @@ -748,7 +719,6 @@ protected void addDataGroup(Transition transition, com.netgrif.application.engin } } - @Transactional protected void addToTransaction(Transition transition, TransactionRef transactionRef) { Transaction transaction = getTransaction(transactionRef.getId()); if (transaction == null) { @@ -757,7 +727,6 @@ protected void addToTransaction(Transition transition, TransactionRef transactio transaction.addTransition(transition); } - @Transactional protected void addRoleLogic(Transition transition, RoleRef roleRef) { Logic logic = roleRef.getLogic(); String roleId = getRole(roleRef.getId()).getStringId(); @@ -775,22 +744,20 @@ protected void addRoleLogic(Transition transition, RoleRef roleRef) { transition.addRole(roleId, roleFactory.getPermissions(logic)); } - @Transactional - protected void addUserLogic(Transition transition, UserRef userRef) { - Logic logic = userRef.getLogic(); - String userRefId = userRef.getId(); + protected void addActorLogic(Transition transition, ActorRef actorRef) { + Logic logic = actorRef.getLogic(); + String actorFieldId = actorRef.getId(); - if (logic == null || userRefId == null) { + if (logic == null || actorFieldId == null) { return; } logicValidator.checkConflictingAttributes(logic, logic.isAssigned(), logic.isAssign(), "assigned", "assign"); logicValidator.checkDeprecatedAttributes(logic); - transition.addUserRef(userRefId, roleFactory.getPermissions(logic)); + transition.addActorRef(actorFieldId, roleFactory.getPermissions(logic)); } - @Transactional protected void addDataLogic(Transition transition, DataRef dataRef) { Logic logic = dataRef.getLogic(); try { @@ -810,7 +777,6 @@ protected void addDataLogic(Transition transition, DataRef dataRef) { } } - @Transactional protected void addDataLayout(Transition transition, DataRef dataRef) { Layout layout = dataRef.getLayout(); try { @@ -841,7 +807,6 @@ protected void addDataLayout(Transition transition, DataRef dataRef) { } } - @Transactional protected void addDataComponent(Transition transition, DataRef dataRef) throws MissingIconKeyException { String fieldId = getField(dataRef.getId()).getStringId(); Component component = null; @@ -851,7 +816,6 @@ protected void addDataComponent(Transition transition, DataRef dataRef) throws M transition.addDataSet(fieldId, null, null, null, component); } - @Transactional protected Map buildEvents(String fieldId, List events, String transitionId) { Map parsedEvents = new HashMap<>(); @@ -907,7 +871,6 @@ protected com.netgrif.application.engine.objects.petrinet.domain.events.DataEven return dataEvent; } - @Transactional protected List buildActions(List imported, String fieldId, String transitionId) { return imported.stream() .map(action -> parseAction(fieldId, transitionId, action)) @@ -974,7 +937,6 @@ protected boolean containsParams(String definition) { return definition.matches("[\\W\\w\\s]*[\\w]*:[\\s]*[ft].[\\w]+;[\\w\\W\\s]*"); } - @Transactional protected void parseObjectIds(Action action, String fieldId, String transitionId, String definition) { try { Map ids = parseParams(definition); @@ -1030,14 +992,12 @@ protected String getFieldId(String importId) { } } - @Transactional protected void addTrigger(Transition transition, com.netgrif.application.engine.objects.importer.model.Trigger importTrigger) { Trigger trigger = triggerFactory.buildTrigger(importTrigger); transition.addTrigger(trigger); } - @Transactional protected void createPlace(com.netgrif.application.engine.objects.importer.model.Place importPlace) { Place place = new Place(); place.setImportId(importPlace.getId()); @@ -1054,7 +1014,6 @@ protected void createPlace(com.netgrif.application.engine.objects.importer.model places.put(importPlace.getId(), place); } - @Transactional protected void createRole(Role importRole) { if (importRole.getId().equals(ProcessRole.DEFAULT_ROLE)) { throw new IllegalArgumentException("Role ID '" + ProcessRole.DEFAULT_ROLE + "' is a reserved identifier, roles with this ID cannot be defined!"); @@ -1128,7 +1087,6 @@ protected Map perms.containsValue(true)) - || net.getUserRefs().values().stream().anyMatch(perms -> perms.containsValue(true))) { + || net.getActorRefs().values().stream().anyMatch(perms -> perms.containsValue(true))) { return; } @@ -1204,7 +1162,7 @@ protected void addPredefinedRolesWithDefaultPermissions() { protected PetriNet getNetByImportId(String id) { Optional net = service.findByImportId(id); - if (!net.isPresent()) { + if (net.isEmpty()) { throw new IllegalArgumentException(); } return net.get(); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/TransitionValidator.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/TransitionValidator.java index 3389939d19c..d83ec602889 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/TransitionValidator.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/TransitionValidator.java @@ -12,6 +12,7 @@ public class TransitionValidator implements ITransitionValidator { @Override public void checkDeprecatedAttributes(Transition transition) { validateAttribute(transition.getUsersRef(), "usersRef"); + validateAttribute(transition.getUsersRef(), "userRef"); } @Override 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 c5d8593f3e0..24f4a1482f7 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 @@ -34,6 +34,8 @@ @Service public class CaseSearchService extends MongoSearchService { + // todo 2285 this class + private static final Logger log = LoggerFactory.getLogger(CaseSearchService.class.getName()); public static final String ROLE = "role"; @@ -109,16 +111,17 @@ protected Predicate buildViewRoleQueryConstraint(LoggedUser user) { } public Predicate viewRoleQuery(String role) { - return QCase.case$.viewUserRefs.isEmpty().and(QCase.case$.viewRoles.isEmpty()).or(QCase.case$.viewRoles.contains(role)); + return QCase.case$.viewActorRefs.isEmpty().and(QCase.case$.viewRoles.isEmpty()).or(QCase.case$.viewRoles.contains(role)); } protected Predicate buildViewUserQueryConstraint(LoggedUser user) { - Predicate roleConstraints = viewUserQuery(user.getStringId()); + // todo 2285 + Predicate roleConstraints = viewActorQuery(user.getStringId()); return constructPredicateTree(Collections.singletonList(roleConstraints), BooleanBuilder::or); } - public Predicate viewUserQuery(String userId) { - return QCase.case$.viewUserRefs.isEmpty().and(QCase.case$.viewRoles.isEmpty()).or(QCase.case$.viewUsers.contains(userId)); + public Predicate viewActorQuery(String actorId) { + return QCase.case$.viewActorRefs.isEmpty().and(QCase.case$.viewRoles.isEmpty()).or(QCase.case$.viewActors.contains(actorId)); } protected Predicate buildNegativeViewRoleQueryConstraint(LoggedUser user) { @@ -131,12 +134,14 @@ public Predicate negativeViewRoleQuery(String role) { } protected Predicate buildNegativeViewUsersQueryConstraint(LoggedUser user) { + // todo 2285 Predicate roleConstraints = negativeViewUserQuery(user.getStringId()); return constructPredicateTree(Collections.singletonList(roleConstraints), BooleanBuilder::or); } - public Predicate negativeViewUserQuery(String userId) { - return QCase.case$.negativeViewUsers.contains(userId); + public Predicate negativeViewUserQuery(String actorId) { + // todo 2285 + return QCase.case$.negativeViewActors.contains(actorId); } public Predicate petriNet(Object query, LoggedUser user, Locale locale) { diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java index 52a75dcb7cd..bbc3c2961a3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/DataService.java @@ -785,7 +785,7 @@ public Case applyFieldConnectedChanges(Case useCase, String fieldId) { public Case applyFieldConnectedChanges(Case useCase, Field field) { switch (field.getType()) { case ACTORLIST: - return workflowService.resolveUserRef(useCase); + return workflowService.resolveActorRef(useCase); default: return useCase; } 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..720c34f1a48 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 @@ -52,18 +52,18 @@ public Boolean userHasUserListPermission(LoggedUser loggedUser, String taskId, R @Override public Boolean userHasUserListPermission(AbstractUser user, Task task, RolePermission... permissions) { - if (task.getUserRefs() == null || task.getUserRefs().isEmpty()) + if (task.getActorRefs() == null || task.getActorRefs().isEmpty()) return null; // TODO: impersonation // if (!task.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { - if (!task.getUsers().containsKey(user.getStringId())) { + if (!task.getActors().containsKey(user.getStringId())) { return null; } // TODO: impersonation // Map userPermissions = task.getUsers().get(user.getSelfOrImpersonated().getStringId()); - Map userPermissions = task.getUsers().get(user.getStringId()); + Map userPermissions = task.getActors().get(user.getStringId()); for (RolePermission permission : permissions) { Boolean perm = userPermissions.get(permission.toString()); 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 486dbe6f5b6..d9659d911e7 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 @@ -12,7 +12,6 @@ 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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -22,6 +21,8 @@ @Service public class TaskSearchService extends MongoSearchService { + // todo 2285 this class + @Autowired private IPetriNetService petriNetService; @@ -62,7 +63,8 @@ protected Predicate buildRolesQueryConstraint(LoggedUser user) { } protected Predicate buildUserRefQueryConstraint(LoggedUser user) { - Predicate userRefConstraints = userRefQuery(user.getStringId()); + // todo 2285 + Predicate userRefConstraints = actorRefQuery(user.getStringId()); return constructPredicateTree(Collections.singletonList(userRefConstraints), BooleanBuilder::or); } @@ -72,16 +74,18 @@ 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.viewActorRefs.isEmpty().and(QTask.task.viewRoles.isEmpty()).or(QTask.task.viewRoles.contains(role)); } protected Predicate buildViewUserQueryConstraint(LoggedUser user) { + // todo 2285 Predicate userConstraints = viewUsersQuery(user.getStringId()); return constructPredicateTree(Collections.singletonList(userConstraints), BooleanBuilder::or); } - 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)); + public Predicate viewUsersQuery(String actorId) { + // todo 2285 + return QTask.task.negativeViewRoles.isEmpty().and(QTask.task.viewActorRefs.isEmpty()).and(QTask.task.viewRoles.isEmpty()).or(QTask.task.viewActors.contains(actorId)); } protected Predicate buildNegativeViewRoleQueryConstraint(LoggedUser user) { @@ -94,12 +98,14 @@ public Predicate negativeViewRoleQuery(String role) { } protected Predicate buildNegativeViewUsersQueryConstraint(LoggedUser user) { + // todo 2285 Predicate userConstraints = negativeViewUsersQuery(user.getStringId()); return constructPredicateTree(Collections.singletonList(userConstraints), BooleanBuilder::or); } - public Predicate negativeViewUsersQuery(String userId) { - return QTask.task.negativeViewUsers.contains(userId); + public Predicate negativeViewUsersQuery(String actorId) { + // todo 2285 + return QTask.task.negativeViewActors.contains(actorId); } @@ -155,8 +161,8 @@ public Predicate stringIdQuery(String id) { return QTask.task._id.eq(new ProcessResourceId(id)); } - public Predicate userRefQuery(String userId) { - return QTask.task.users.containsKey(userId); + public Predicate actorRefQuery(String actorId) { + return QTask.task.actors.containsKey(actorId); } private void buildCaseQuery(TaskSearchRequest request, BooleanBuilder query) { @@ -278,7 +284,7 @@ public boolean buildGroupQuery(TaskSearchRequest request, LoggedUser user, Local PetriNetSearch processQuery = new PetriNetSearch(); processQuery.setGroup(request.group); List groupProcesses = this.petriNetService.search(processQuery, user, new FullPageRequest(), locale).getContent(); - if (groupProcesses.size() == 0) + if (groupProcesses.isEmpty()) return true; query.and( 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 1a525e82d85..1bfd0a0474f 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,6 +1,7 @@ package com.netgrif.application.engine.workflow.service; import com.google.common.collect.Ordering; +import com.netgrif.application.engine.auth.service.GroupService; 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.ActorFieldValue; @@ -72,6 +73,9 @@ public class TaskService implements ITaskService { @Autowired protected UserService userService; + @Autowired + protected GroupService groupService; + @Autowired protected MongoTemplate mongoTemplate; @@ -524,7 +528,7 @@ public void reloadTasks(Case useCase) { } save(newTasks); delete(disabledTasks, useCase); - useCase = workflowService.resolveUserRef(useCase); + useCase = workflowService.resolveActorRef(useCase); for (Task task : newTasks) { executeIfAutoTrigger(useCase, net, task); @@ -798,37 +802,48 @@ public List save(List tasks) { } @Override - public void resolveUserRef(Case useCase) { + public void resolveActorRef(Case useCase) { useCase.getTasks().forEach(taskPair -> { Optional taskOptional = findOptionalById(taskPair.getTask()); - taskOptional.ifPresent(task -> resolveUserRef(task, useCase)); + taskOptional.ifPresent(task -> resolveActorRef(task, useCase)); }); } @Override - public Task resolveUserRef(Task task, Case useCase) { - // todo 2285 - task.getUsers().clear(); - task.getNegativeViewUsers().clear(); - task.getUserRefs().forEach((id, permission) -> { - List userIds = getExistingUsers((ActorListFieldValue) useCase.getDataSet().get(id).getValue()); - if (userIds != null && userIds.size() != 0 && permission.containsKey("view") && !permission.get("view")) { - task.getNegativeViewUsers().addAll(userIds); - } else if (userIds != null && userIds.size() != 0) { - task.addUsers(new HashSet<>(userIds), permission); + public Task resolveActorRef(Task task, Case useCase) { + task.getActors().clear(); + task.getNegativeViewActors().clear(); + task.getActorRefs().forEach((actorFieldId, permission) -> { + List actorIds = getExistingActors((ActorListFieldValue) useCase.getDataSet().get(actorFieldId).getValue()); + if (actorIds != null && !actorIds.isEmpty() && permission.containsKey("view") && !permission.get("view")) { + task.getNegativeViewActors().addAll(actorIds); + } else if (actorIds != null && !actorIds.isEmpty()) { + task.addActors(new HashSet<>(actorIds), permission); } }); - task.resolveViewUsers(); + task.resolveViewActors(); return taskRepository.save(task); } - private List getExistingUsers(ActorListFieldValue userListValue) { - // todo 2285 - if (userListValue == null) + private List getExistingActors(ActorListFieldValue actorListFieldValue) { + if (actorListFieldValue == null) { return null; - return userListValue.getActorValues().stream().map(ActorFieldValue::getId) - .filter(id -> userService.findById(id, null) != null) + } + return actorListFieldValue.getActorValues().stream() + .map(ActorFieldValue::getId) + .filter(actorId -> { + AbstractUser user = userService.findById(actorId, null); + if (user != null) { + return true; + } + try { + groupService.findById(actorId); + return true; + } catch (IllegalArgumentException ignored) { + return false; + } + }) .collect(Collectors.toList()); } @@ -850,13 +865,13 @@ private Task createFromTransition(Transition transition, Case useCase) { .finishPolicy(transition.getFinishPolicy()) .assignedUserPolicy(new HashMap<>(transition.getAssignedUserPolicy())) .roles(new HashMap<>()) - .userRefs(new HashMap<>()) - .users(new HashMap<>()) + .actorRefs(new HashMap<>()) + .actors(new HashMap<>()) .viewRoles(new LinkedList<>()) - .viewUserRefs(new LinkedList<>()) - .viewUsers(new LinkedList<>()) + .viewActorRefs(new LinkedList<>()) + .viewActors(new LinkedList<>()) .negativeViewRoles(new LinkedList<>()) - .negativeViewUsers(new LinkedList<>()) + .negativeViewActors(new LinkedList<>()) .triggers(new LinkedList<>()) .eventTitles(new HashMap<>()) .build(); @@ -880,11 +895,11 @@ private Task createFromTransition(Transition transition, Case useCase) { } transition.getNegativeViewRoles().forEach(task::addNegativeViewRole); - for (Map.Entry> entry : transition.getUserRefs().entrySet()) { - task.addUserRef(entry.getKey(), entry.getValue()); + for (Map.Entry> entry : transition.getActorRefs().entrySet()) { + task.addActorRef(entry.getKey(), entry.getValue()); } task.resolveViewRoles(); - task.resolveViewUserRefs(); + task.resolveViewActorRefs(); Transaction transaction = useCase.getPetriNet().getTransactionByTransition(transition); if (transaction != null) { 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 e4438d1b863..5ef0a607700 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,6 +1,5 @@ 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; @@ -62,17 +61,18 @@ public Boolean userHasAtLeastOneRolePermission(AbstractUser user, PetriNet net, @Override public Boolean userHasUserListPermission(AbstractUser user, Case useCase, ProcessRolePermission... permissions) { - if (useCase.getUserRefs() == null || useCase.getUserRefs().isEmpty()) + if (useCase.getActorRefs() == null || useCase.getActorRefs().isEmpty()) return null; // TODO: impersonation // if (!useCase.getUsers().containsKey(user.getSelfOrImpersonated().getStringId())) { - if (!useCase.getUsers().containsKey(user.getStringId())) { + // todo 2285 user.groupIds intersection with useCase.actors + if (!useCase.getActors().containsKey(user.getStringId())) { return null; } // TODO: impersonation - Map userPermissions = useCase.getUsers().get(user.getStringId()); + Map userPermissions = useCase.getActors().get(user.getStringId()); 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 e156204cb83..ef50c488325 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,6 +1,8 @@ package com.netgrif.application.engine.workflow.service; import com.google.common.collect.Ordering; +import com.netgrif.application.engine.auth.service.GroupService; +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.*; import com.netgrif.application.engine.objects.workflow.domain.Case; @@ -93,6 +95,9 @@ public class WorkflowService implements IWorkflowService { @Autowired protected UserService userService; + @Autowired + protected GroupService groupService; + @Autowired protected InitValueExpressionEvaluator initValueExpressionEvaluator; @@ -224,35 +229,46 @@ 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); + public Case resolveActorRef(Case useCase) { + useCase.getActors().clear(); + useCase.getNegativeViewActors().clear(); + useCase.getActorRefs().forEach((actorFieldId, permission) -> { + resolveActorRefPermissions(useCase, actorFieldId, permission); }); - useCase.resolveViewUsers(); - taskService.resolveUserRef(useCase); + useCase.resolveViewActors(); + taskService.resolveActorRef(useCase); return save(useCase); } - private void resolveUserRefPermissions(Case useCase, String userListId, Map permission) { - // todo 2285 - List userIds = getExistingUsers((ActorListFieldValue) useCase.getDataSet().get(userListId).getValue()); - if (userIds != null && userIds.size() != 0) { + private void resolveActorRefPermissions(Case useCase, String actorFieldId, Map permission) { + List actorIds = getExistingActors((ActorListFieldValue) useCase.getDataSet().get(actorFieldId).getValue()); + if (actorIds != null && !actorIds.isEmpty()) { if (permission.containsKey("view") && !permission.get("view")) { - useCase.getNegativeViewUsers().addAll(userIds); + useCase.getNegativeViewActors().addAll(actorIds); } else { - useCase.addUsers(new HashSet<>(userIds), permission); + useCase.addActors(new HashSet<>(actorIds), permission); } } } - private List getExistingUsers(ActorListFieldValue userListValue) { - // todo 2285 - if (userListValue == null) + private List getExistingActors(ActorListFieldValue actorListFieldValue) { + if (actorListFieldValue == null) { return null; - return userListValue.getActorValues().stream().map(ActorFieldValue::getId) - .filter(id -> userService.findById(id, null) != null) + } + return actorListFieldValue.getActorValues().stream() + .map(ActorFieldValue::getId) + .filter(actorId -> { + AbstractUser user = userService.findById(actorId, null); + if (user != null) { + return true; + } + try { + groupService.findById(actorId); + return true; + } catch (IllegalArgumentException ignored) { + return false; + } + }) .collect(Collectors.toList()); } diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java index e8bf1f73edd..61d9abe703b 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/ITaskService.java @@ -104,9 +104,9 @@ public interface ITaskService { DelegateTaskEventOutcome delegateTask(LoggedUser loggedUser, String delegatedId, String taskId, Map params) throws TransitionNotExecutableException; - void resolveUserRef(Case useCase); + void resolveActorRef(Case useCase); - Task resolveUserRef(Task task, Case useCase); + Task resolveActorRef(Task task, Case useCase); void delete(List tasks, Case useCase); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java index 74d8eab44a2..131b988dcab 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/interfaces/IWorkflowService.java @@ -27,7 +27,7 @@ public interface IWorkflowService { Page getAll(Pageable pageable); - Case resolveUserRef(Case useCase); + Case resolveActorRef(Case useCase); CreateCaseEventOutcome createCase(String netId, String title, String color, LoggedUser user, Locale locale, Map params); 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..f01584c4965 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 @@ -88,7 +88,7 @@ public Task(com.netgrif.application.engine.objects.workflow.domain.Task task, Lo this.userId = task.getUser() != null ? task.getUser().getStringId() : null; this.userRealmId = task.getUser() != null ? task.getUser().getRealmId() : null; this.roles = task.getRoles(); - this.users = task.getUsers(); + this.users = task.getActors(); this.startDate = task.getStartDate(); this.finishDate = task.getFinishDate(); this.finishedBy = task.getFinishedBy(); diff --git a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml index de7fecf8432..56730468963 100644 --- a/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml +++ b/application-engine/src/main/resources/petriNets/engine-processes/impersonation_config.xml @@ -77,13 +77,13 @@ true - + config_owner true true - + create @@ -363,7 +363,7 @@ true - + config_owner true @@ -372,7 +372,7 @@ true true - + t2_0 4 @@ -546,7 +546,7 @@ true - + config_owner true @@ -555,7 +555,7 @@ true true - + assign @@ -602,7 +602,7 @@ true - + config_owner true @@ -611,7 +611,7 @@ true true - + t4_0 diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy index c9c4fe1e3b8..558518667e0 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy @@ -71,7 +71,7 @@ class UserListTest { ] ])) - assert taskService.findById(task.stringId).users.get(superCreator.getSuperUser().getStringId()) - assert caseRepository.findById(caseOpt.get().stringId).get().users.get(superCreator.getSuperUser().getStringId()) + assert taskService.findById(task.stringId).actors.get(superCreator.getSuperUser().getStringId()) + assert caseRepository.findById(caseOpt.get().stringId).get().actors.get(superCreator.getSuperUser().getStringId()) } } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy index f2e3b280436..8e48196f026 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/ElasticSearchViewPermissionTest.groovy @@ -169,7 +169,7 @@ class ElasticSearchViewPermissionTest { caseSearchRequest.process = [new CaseSearchRequest.PetriNet(netWithUserRefs.getIdentifier())] as List Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) - assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewUsers.contains(testUser.getStringId()) + assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewActors.contains(testUser.getStringId()) workflowService.deleteCase(case_.getStringId()) } @@ -190,7 +190,7 @@ class ElasticSearchViewPermissionTest { caseSearchRequest.process = [new CaseSearchRequest.PetriNet(netWithUserRefs.getIdentifier())] as List Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) - assert casePage.getContent().size() == 0 && case_.negativeViewUsers.contains(testUser.getStringId()) + assert casePage.getContent().size() == 0 && case_.negativeViewActors.contains(testUser.getStringId()) workflowService.deleteCase(case_.getStringId()) } @@ -213,7 +213,7 @@ class ElasticSearchViewPermissionTest { caseSearchRequest.process = [new CaseSearchRequest.PetriNet(netWithUserRefs.getIdentifier())] as List Page casePage = elasticCaseService.search([caseSearchRequest] as List, ActorTransformer.toLoggedUser(testUser), PageRequest.of(0, 20), LocaleContextHolder.getLocale(), false) - assert casePage.getContent().size() == 1 && case_.viewUsers.contains(testUser.stringId) + assert casePage.getContent().size() == 1 && case_.viewActors.contains(testUser.stringId) userService.removeRole(testUser, negViewRole.getStringId()) workflowService.deleteCase(case_.getStringId()) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy index 5cf53bb05c7..64bf7cc00ed 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy @@ -152,7 +152,7 @@ class QueryDSLViewPermissionTest { Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) - assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewUsers.contains(testUser.getStringId()) + assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewActors.contains(testUser.getStringId()) workflowService.deleteCase(case_.getStringId()) } @@ -174,7 +174,7 @@ class QueryDSLViewPermissionTest { Page taskPage = taskService.search([request], PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale(), false) - assert taskPage.getContent().size() == 1 && taskPage.content[0].caseId == case_.stringId && taskPage.content[0].viewUsers.contains(testUser.getStringId()) + assert taskPage.getContent().size() == 1 && taskPage.content[0].caseId == case_.stringId && taskPage.content[0].viewActors.contains(testUser.getStringId()) workflowService.deleteCase(case_.getStringId()) } @@ -210,7 +210,7 @@ class QueryDSLViewPermissionTest { Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) - assert casePage.getContent().size() == 0 && case_.negativeViewUsers.contains(testUser.getStringId()) + assert casePage.getContent().size() == 0 && case_.negativeViewActors.contains(testUser.getStringId()) workflowService.deleteCase(case_.getStringId()) } @@ -233,7 +233,7 @@ class QueryDSLViewPermissionTest { Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) - assert casePage.getContent().size() == 1 && case_.viewUsers.contains(testUser.stringId) + assert casePage.getContent().size() == 1 && case_.viewActors.contains(testUser.stringId) userService.removeRole(testUser, negViewRole.getStringId()) workflowService.deleteCase(case_.getStringId()) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy index 6f6b6aa44c1..d6772257cd1 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy @@ -78,7 +78,7 @@ class UserRefsTest { @Test void testCases() { - newCases.eachWithIndex { Case entry, int i -> assert entry.users.get(userIds.get(i)) != null } + newCases.eachWithIndex { Case entry, int i -> assert entry.actors.get(userIds.get(i)) != null } } diff --git a/application-engine/src/test/resources/petriNets/impersonation_test.xml b/application-engine/src/test/resources/petriNets/impersonation_test.xml index 7a0d1993284..11cdbb07508 100644 --- a/application-engine/src/test/resources/petriNets/impersonation_test.xml +++ b/application-engine/src/test/resources/petriNets/impersonation_test.xml @@ -108,11 +108,11 @@ 580 300 - + user_selection Select user No user selected diff --git a/application-engine/src/main/resources/petriNets/test_model_immediate_data.xml b/application-engine/src/main/resources/petriNets/test_model_immediate_data.xml index 7ef55217802..ad84a9966b0 100644 --- a/application-engine/src/main/resources/petriNets/test_model_immediate_data.xml +++ b/application-engine/src/main/resources/petriNets/test_model_immediate_data.xml @@ -96,7 +96,7 @@ Value 3 Value 3 - + user_field User tester diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index 696d3d57d0a..9d60299a218 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -343,13 +343,13 @@ class TaskAuthorizationServiceTest { } @Test - void testCanAssignWithUsersRef() { + void testCanAssignWithActorsRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_pos_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -360,13 +360,13 @@ class TaskAuthorizationServiceTest { } @Test - void testCannotAssignWithUsersRef() { + void testCannotAssignWithActorsRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_neg_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -377,7 +377,7 @@ class TaskAuthorizationServiceTest { } @Test - void testCanAssignWithNegRoleAndPosUsersRef() { + void testCanAssignWithNegRoleAndPosActorsRef() { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "assign_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test assign", "", ActorTransformer.toLoggedUser(testUser)).getCase() @@ -385,7 +385,7 @@ class TaskAuthorizationServiceTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "assign_pos_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -423,13 +423,13 @@ class TaskAuthorizationServiceTest { } @Test - void testCanFinishWithUsersRef() { + void testCanFinishWithActorsRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_pos_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -441,13 +441,13 @@ class TaskAuthorizationServiceTest { } @Test - void testCannotFinishWithUsersRef() { + void testCannotFinishWithActorsRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_neg_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -459,7 +459,7 @@ class TaskAuthorizationServiceTest { } @Test - void testCanFinishWithNegRoleAndPosUsersRef() { + void testCanFinishWithNegRoleAndPosActorsRef() { ProcessRole positiveRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "finish_pos_role") userService.addRole(testUser, positiveRole.get_id()) Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Test Finish", "", ActorTransformer.toLoggedUser(testUser)).getCase() @@ -467,7 +467,7 @@ class TaskAuthorizationServiceTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "finish_pos_ul": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy index 6191dd7946e..a7d1038ffd6 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy @@ -231,7 +231,7 @@ class WorkflowAuthorizationServiceTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "pos_user_list": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) @@ -255,11 +255,11 @@ class WorkflowAuthorizationServiceTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "pos_user_list": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ], "neg_user_list": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() workflowService.save(case_) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy index 81383bc8c45..7be72b70ed2 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/filters/FilterImportExportTest.groovy @@ -331,8 +331,8 @@ class FilterImportExportTest { "(processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.date.timestampValue:[1631138400000 TO 1631224800000}) AND " + "(processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.date.timestampValue:[1631138400000 TO 1631311200000}) AND " + "(processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.file.fileNameValue:*asdasd*) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) OR " + - "((dataSet.fileList.fileNameValue:*asdasd*) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.user.userIdValue:<>) AND " + - "(processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.user.userIdValue:7) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) " + + "((dataSet.fileList.fileNameValue:*asdasd*) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.user.actorIdValue:<>) AND " + + "(processIdentifier:6139e51308215f25b0a498c2_all_data)) OR ((dataSet.user.actorIdValue:7) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) " + "OR ((dataSet.datetime.timestampValue:[1631184300000 TO 1631184360000}) AND (processIdentifier:6139e51308215f25b0a498c2_all_data)) OR " + "((dataSet.datetime.timestampValue:[1631184360000 TO 1631270820000}) AND (processIdentifier:6139e51308215f25b0a498c2_all_data))) AND (title:*asdasd*) AND " + "((creationDateSortable:[1631138400000 TO 1631224800000}) OR (creationDateSortable:[1631138400000 TO 1631311200000})) AND " + diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy index 558518667e0..9490312dcc3 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy @@ -67,7 +67,7 @@ class UserListTest { dataService.setData(task.stringId, ImportHelper.populateDataset([ "users_1": [ "value": [superCreator.getSuperUser().getStringId()], - "type" : "userList" + "type" : "actorList" ] ])) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy index 64bf7cc00ed..fd39efbca3e 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy @@ -143,7 +143,7 @@ class QueryDSLViewPermissionTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() case_ = workflowService.save(case_) @@ -163,7 +163,7 @@ class QueryDSLViewPermissionTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() case_ = workflowService.save(case_) @@ -201,7 +201,7 @@ class QueryDSLViewPermissionTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_neg": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() case_ = workflowService.save(case_) @@ -221,7 +221,7 @@ class QueryDSLViewPermissionTest { case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskControllerTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskControllerTest.groovy index 569de8e8944..10f5b88847f 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskControllerTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/TaskControllerTest.groovy @@ -197,7 +197,7 @@ class TaskControllerTest { dataService.setData(task.stringId, ImportHelper.populateDataset([ "performable_users": [ "value": userIds, - "type" : "userList" + "type" : "actorList" ] ])) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy index d6772257cd1..b4cc3eeb00f 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/workflow/UserRefsTest.groovy @@ -68,7 +68,7 @@ class UserRefsTest { _case = dataService.setData(taskId, ImportHelper.populateDataset([ "user_list_1": [ "value": [id], - "type": "userList" + "type": "actorList" ] ] as Map)).getCase() newCases.add(workflowService.save(_case)) diff --git a/application-engine/src/test/resources/all_data.xml b/application-engine/src/test/resources/all_data.xml index f6f084ac274..ab931545505 100644 --- a/application-engine/src/test/resources/all_data.xml +++ b/application-engine/src/test/resources/all_data.xml @@ -112,7 +112,7 @@ pom.xml - + user User @@ -151,7 +151,7 @@ - + userList User list diff --git a/application-engine/src/test/resources/all_data_pdf.xml b/application-engine/src/test/resources/all_data_pdf.xml index e2d8a3f82df..57de226e017 100644 --- a/application-engine/src/test/resources/all_data_pdf.xml +++ b/application-engine/src/test/resources/all_data_pdf.xml @@ -163,7 +163,7 @@ File List - + user User diff --git a/application-engine/src/test/resources/data_test.xml b/application-engine/src/test/resources/data_test.xml index a9e4feb8786..4430ecffdad 100644 --- a/application-engine/src/test/resources/data_test.xml +++ b/application-engine/src/test/resources/data_test.xml @@ -102,7 +102,7 @@ File field description - + user User User field placeholder @@ -135,8 +135,8 @@ processId2 - - + + emptyUserList Empty user list User list description diff --git a/application-engine/src/test/resources/initial_behavior.xml b/application-engine/src/test/resources/initial_behavior.xml index e169b58a7b6..f71727c592b 100644 --- a/application-engine/src/test/resources/initial_behavior.xml +++ b/application-engine/src/test/resources/initial_behavior.xml @@ -85,7 +85,7 @@ File List - + user User diff --git a/application-engine/src/test/resources/mapping_test.xml b/application-engine/src/test/resources/mapping_test.xml index d7ab7541dd6..6b698b2430d 100755 --- a/application-engine/src/test/resources/mapping_test.xml +++ b/application-engine/src/test/resources/mapping_test.xml @@ -75,7 +75,7 @@ 25 Is a burglar alarm fitted and used? - + 27 Property owner 1 diff --git a/application-engine/src/test/resources/org_group.xml b/application-engine/src/test/resources/org_group.xml index 0bbc98fe2af..0bf9c9158d5 100644 --- a/application-engine/src/test/resources/org_group.xml +++ b/application-engine/src/test/resources/org_group.xml @@ -20,7 +20,7 @@ change id value { useCase.stringId } - + author Group Author @@ -35,7 +35,7 @@ workflowService.save(useCase) - + user_selection Select user No user selected diff --git a/application-engine/src/test/resources/pdf_run_action.xml b/application-engine/src/test/resources/pdf_run_action.xml index 3256bae1686..073258bc193 100644 --- a/application-engine/src/test/resources/pdf_run_action.xml +++ b/application-engine/src/test/resources/pdf_run_action.xml @@ -110,7 +110,7 @@ File field placeholder File field description - + user User User field placeholder diff --git a/application-engine/src/test/resources/pdf_test_1.xml b/application-engine/src/test/resources/pdf_test_1.xml index 7ffd56d668f..3fd5f9e2d45 100644 --- a/application-engine/src/test/resources/pdf_test_1.xml +++ b/application-engine/src/test/resources/pdf_test_1.xml @@ -107,7 +107,7 @@ File field placeholder - + user User diff --git a/application-engine/src/test/resources/pdf_test_3.xml b/application-engine/src/test/resources/pdf_test_3.xml index a7ad5d02232..bf78d50c691 100644 --- a/application-engine/src/test/resources/pdf_test_3.xml +++ b/application-engine/src/test/resources/pdf_test_3.xml @@ -154,7 +154,7 @@ boolean_1 set label? - + [object Object]_0 set label placeholder diff --git a/application-engine/src/test/resources/petriNets/all_data_refs.xml b/application-engine/src/test/resources/petriNets/all_data_refs.xml index 69eb782f3b3..676af85e721 100644 --- a/application-engine/src/test/resources/petriNets/all_data_refs.xml +++ b/application-engine/src/test/resources/petriNets/all_data_refs.xml @@ -119,7 +119,7 @@ File list - + user User diff --git a/application-engine/src/test/resources/petriNets/dynamic_init.xml b/application-engine/src/test/resources/petriNets/dynamic_init.xml index ed2792d53af..310c04fe2d0 100644 --- a/application-engine/src/test/resources/petriNets/dynamic_init.xml +++ b/application-engine/src/test/resources/petriNets/dynamic_init.xml @@ -29,7 +29,7 @@ java.time.LocalDateTime.now() - + user user diff --git a/application-engine/src/test/resources/petriNets/impersonation_test.xml b/application-engine/src/test/resources/petriNets/impersonation_test.xml index 11cdbb07508..c549edf14f0 100644 --- a/application-engine/src/test/resources/petriNets/impersonation_test.xml +++ b/application-engine/src/test/resources/petriNets/impersonation_test.xml @@ -30,7 +30,7 @@ file_0 </data> - <data type="userList" immediate="true"> + <data type="actorList" immediate="true"> <id>user_list</id> <title/> </data> diff --git a/application-engine/src/test/resources/poistenie.xml b/application-engine/src/test/resources/poistenie.xml index bdcacd7c715..24f7db81100 100644 --- a/application-engine/src/test/resources/poistenie.xml +++ b/application-engine/src/test/resources/poistenie.xml @@ -127,7 +127,7 @@ <id>26</id> <title>Koľko rokov ste nemali poisťovací prípad? - + 27 Vlastník poistenia 1 diff --git a/application-engine/src/test/resources/poistenie_rozsirene.xml b/application-engine/src/test/resources/poistenie_rozsirene.xml index 518ed2b9c2d..0235b55ad3d 100644 --- a/application-engine/src/test/resources/poistenie_rozsirene.xml +++ b/application-engine/src/test/resources/poistenie_rozsirene.xml @@ -127,7 +127,7 @@ 26 Koľko rokov ste nemali poisťovací prípad? - + 27 Vlastník poistenia 1 diff --git a/application-engine/src/test/resources/poistenie_transaction.xml b/application-engine/src/test/resources/poistenie_transaction.xml index 139d519e726..e1a83664703 100644 --- a/application-engine/src/test/resources/poistenie_transaction.xml +++ b/application-engine/src/test/resources/poistenie_transaction.xml @@ -140,7 +140,7 @@ 26 Koľko rokov ste nemali poisťovací prípad? - + 27 Vlastník poistenia 1 diff --git a/application-engine/src/test/resources/poistenie_triggers.xml b/application-engine/src/test/resources/poistenie_triggers.xml index 4919206b18e..b6d47b06a60 100644 --- a/application-engine/src/test/resources/poistenie_triggers.xml +++ b/application-engine/src/test/resources/poistenie_triggers.xml @@ -128,7 +128,7 @@ 26 Koľko rokov ste nemali poisťovací prípad? - + 27 Vlastník poistenia 1 diff --git a/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_userref.xml b/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_userref.xml index f63092ada91..854de0968cd 100644 --- a/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_userref.xml +++ b/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_userref.xml @@ -16,7 +16,7 @@ - + userList diff --git a/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_usersref.xml b/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_usersref.xml index ab13e6894db..8cc7bf1b09a 100644 --- a/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_usersref.xml +++ b/application-engine/src/test/resources/predefinedPermissions/role_permissions_anonymous_role_shadowed_usersref.xml @@ -16,7 +16,7 @@ - + userList diff --git a/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_userref.xml b/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_userref.xml index 0a13d4f2758..530f097fc94 100644 --- a/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_userref.xml +++ b/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_userref.xml @@ -16,7 +16,7 @@ - + userList diff --git a/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_usersref.xml b/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_usersref.xml index fb49938736f..b92211ff411 100644 --- a/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_usersref.xml +++ b/application-engine/src/test/resources/predefinedPermissions/role_permissions_default_role_shadowed_usersref.xml @@ -16,7 +16,7 @@ - + userList diff --git a/application-engine/src/test/resources/prikladFM.xml b/application-engine/src/test/resources/prikladFM.xml index d26601a9d87..8b6ee661381 100644 --- a/application-engine/src/test/resources/prikladFM.xml +++ b/application-engine/src/test/resources/prikladFM.xml @@ -36,7 +36,7 @@ 8 Oddelenie - + 9 Odovzdávajúci 1 @@ -86,13 +86,13 @@ 20 Dátum vrátenia - + 21 Vypožičal 1 2 - + 22 Vrátil 1 @@ -130,7 +130,7 @@ 30 Klientské číslo - + 31 Odovzdal 1 @@ -140,13 +140,13 @@ 32 Počet škatúľ - + 33 Kuriér 1 2 - + 34 Spracoval 1 @@ -161,13 +161,13 @@ 36 Počet uvedený v systéme - + 37 Založil 1 2 - + 38 Zapísal do systému 1 diff --git a/application-engine/src/test/resources/prikladFM_import.xml b/application-engine/src/test/resources/prikladFM_import.xml index 4628ff9889d..581c3b7c3bc 100644 --- a/application-engine/src/test/resources/prikladFM_import.xml +++ b/application-engine/src/test/resources/prikladFM_import.xml @@ -37,7 +37,7 @@ 8 Oddelenie - + 9 Odovzdávajúci 1 diff --git a/application-engine/src/test/resources/prikladFM_test.xml b/application-engine/src/test/resources/prikladFM_test.xml index 369a2e491b8..e6ae4568648 100644 --- a/application-engine/src/test/resources/prikladFM_test.xml +++ b/application-engine/src/test/resources/prikladFM_test.xml @@ -40,7 +40,7 @@ 8 Miestnosť - + 9 Odovzdávajúci 1 diff --git a/application-engine/src/test/resources/role_all_data.xml b/application-engine/src/test/resources/role_all_data.xml index 96c9048d849..5b49f72d527 100644 --- a/application-engine/src/test/resources/role_all_data.xml +++ b/application-engine/src/test/resources/role_all_data.xml @@ -186,17 +186,17 @@ File List - + user User - + userList1 UserList - + userList2 UserList diff --git a/application-engine/src/test/resources/set_data_test.xml b/application-engine/src/test/resources/set_data_test.xml index 209ed3ac8f0..0e4fd1b8fb4 100644 --- a/application-engine/src/test/resources/set_data_test.xml +++ b/application-engine/src/test/resources/set_data_test.xml @@ -311,7 +311,7 @@ - + user User diff --git a/application-engine/src/test/resources/task_authorization_service_test_with_userRefs.xml b/application-engine/src/test/resources/task_authorization_service_test_with_userRefs.xml index d0244cb1ce2..1171a5c9f70 100644 --- a/application-engine/src/test/resources/task_authorization_service_test_with_userRefs.xml +++ b/application-engine/src/test/resources/task_authorization_service_test_with_userRefs.xml @@ -20,35 +20,35 @@ finish_neg_role finish neg role - + assign_pos_ul </data> - <data type="userList"> + <data type="actorList"> <id>assign_neg_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>delegate_pos_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>delegate_neg_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>cancel_pos_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>cancel_neg_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>finish_pos_ul</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>finish_neg_ul</id> <title/> </data> diff --git a/application-engine/src/test/resources/user_list.xml b/application-engine/src/test/resources/user_list.xml index daaf660a76d..13f571a9819 100644 --- a/application-engine/src/test/resources/user_list.xml +++ b/application-engine/src/test/resources/user_list.xml @@ -4,7 +4,7 @@ <id>user_list</id> <title>User list ULT - + users_1 diff --git a/application-engine/src/test/resources/userrefs_test.xml b/application-engine/src/test/resources/userrefs_test.xml index 7d0ca4b4da0..c103f712358 100644 --- a/application-engine/src/test/resources/userrefs_test.xml +++ b/application-engine/src/test/resources/userrefs_test.xml @@ -37,11 +37,11 @@ remove Remove from user ref - + user_list_1 User list 1 - + user_list_2 User list 2 diff --git a/application-engine/src/test/resources/view_permission_with_userRefs_test.xml b/application-engine/src/test/resources/view_permission_with_userRefs_test.xml index f142f879e8b..26ee995c240 100644 --- a/application-engine/src/test/resources/view_permission_with_userRefs_test.xml +++ b/application-engine/src/test/resources/view_permission_with_userRefs_test.xml @@ -37,11 +37,11 @@ view_neg_role view role - + view_ul_pos </data> - <data type="userList"> + <data type="actorList"> <id>view_ul_neg</id> <title/> </data> diff --git a/application-engine/src/test/resources/workflow_authorization_service_test_with_userRefs.xml b/application-engine/src/test/resources/workflow_authorization_service_test_with_userRefs.xml index 78d4cd276c3..634e1e300f2 100644 --- a/application-engine/src/test/resources/workflow_authorization_service_test_with_userRefs.xml +++ b/application-engine/src/test/resources/workflow_authorization_service_test_with_userRefs.xml @@ -56,11 +56,11 @@ <id>create_neg_role</id> <name>create role</name> </role> - <data type="userList"> + <data type="actorList"> <id>pos_user_list</id> <title/> </data> - <data type="userList"> + <data type="actorList"> <id>neg_user_list</id> <title/> </data> diff --git a/application-engine/src/test/resources/zaverecna_praca.xml b/application-engine/src/test/resources/zaverecna_praca.xml index f8e40e4354c..ec8404c8a26 100644 --- a/application-engine/src/test/resources/zaverecna_praca.xml +++ b/application-engine/src/test/resources/zaverecna_praca.xml @@ -16,7 +16,7 @@ <id>3</id> <title>Dátum odovzdania - + 4 Vedúci práce 1 @@ -40,12 +40,12 @@ 8 Posudok vedúceho práce - + 9 Oponent práce 3 - + 10 Autor 5 diff --git a/docs/_media/roles/usersRef_functions.groovy b/docs/_media/roles/actorRef_functions.groovy similarity index 100% rename from docs/_media/roles/usersRef_functions.groovy rename to docs/_media/roles/actorRef_functions.groovy diff --git a/docs/_media/roles/usersRef_net.xml b/docs/_media/roles/actorRef_net.xml similarity index 89% rename from docs/_media/roles/usersRef_net.xml rename to docs/_media/roles/actorRef_net.xml index fabbf0449eb..229a4c5582d 100644 --- a/docs/_media/roles/usersRef_net.xml +++ b/docs/_media/roles/actorRef_net.xml @@ -32,13 +32,13 @@ - user_list_1 + actor_list_1 true - + assign @@ -49,11 +49,11 @@ Remove from user ref - user_list_1 + actor_list_1 User list 1 - user_list_2 + actor_list_2 User list 2 @@ -63,8 +63,8 @@ userAddition - userList: f.user_list_1; - change userList value { [getDummyUser()] } + actorList: f.actor_list_1; + change actorList value { [getDummyUser()] } @@ -85,7 +85,7 @@ - user_list_1 + actor_list_1 false @@ -99,8 +99,8 @@ assign - userList: f.user_list_1; - change userList value { [getDummyUser()] } + actorList: f.actor_list_1; + change actorList value { [getDummyUser()] } @@ -114,8 +114,8 @@ remove - userList: f.user_list_1; - change userList value { [] } + actorList: f.actor_list_1; + change actorList value { [] } diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 0bd5aacf956..d993a028b55 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -10,7 +10,7 @@ * [Filter](search/filter.md) * [Import / Export](search/filter_import_export.md) * [Permissions]() - * [User list](roles/userlist.md) + * [Actor list](roles/actorlist.md) * [Permissions](roles/permissions.md) * [Assigned user policy](roles/assigned_user_policy.md) * [Views]() diff --git a/docs/roles/userlist.md b/docs/roles/actorlist.md similarity index 51% rename from docs/roles/userlist.md rename to docs/roles/actorlist.md index 90ebc19e900..4742128c9cc 100644 --- a/docs/roles/userlist.md +++ b/docs/roles/actorlist.md @@ -2,17 +2,17 @@ ## UserList -UserList is a type of data field. Values of this field represent users in system. Some basic information about +ActorList is a type of data field. Values of this field represent actors (users, groups, ...) in system. Some basic information about this field: -- this field does not have any init value, because when the process is created or imported, the given user may not exist +- this field does not have any init value, because when the process is created or imported, the given actor may not exist - we can add values to this field via actions and using frontend component -- it can serve as definition of permissions for volume of users -- value type of this field is ``UserListFieldValue`` +- it can serve as definition of permissions for volume of actors +- value type of this field is ``ActorListFieldValue`` ```xml - - userList1 + + actorList1 </data> ``` @@ -20,26 +20,26 @@ this field: Example action to change value of this field: ```xml <action trigger="set"> - userList: f.userList1; + actorList: f.actorList1; - <!-- Setting with list of user IDs --> - change userList value { ["userId1", "userId2"] } + <!-- Setting with list of actor IDs --> + change actorList value { ["userId1", "groupId1"] } - <!-- Setting with UserListFieldValue --> - change userList value { - new com.netgrif.core.petrinet.domain.dataset.UserListFieldValue( + <!-- Setting with ActorListFieldValue --> + change actorList value { + new com.netgrif.core.petrinet.domain.dataset.ActorListFieldValue( [ new com.netgrif.core.petrinet.domain.dataset.UserFieldValue( "userId1", + "realm1", "John", "Doe", "john@doe.com" ), - new com.netgrif.core.petrinet.domain.dataset.UserFieldValue( - "userId2", - "Alice", - "Doe", - "alice@doe.com" + new com.netgrif.core.petrinet.domain.dataset.GroupFieldValue( + "groupId1", + "realm1", + "A group name" ) ] ) @@ -47,24 +47,24 @@ Example action to change value of this field: </action> ``` -## UserRef +## ActorRef It is a new property of process and transition in PetriNet. It serves as a roleRef with a difference from it: the -content of the userList can be changed at runtime. +content of the actorList can be changed at runtime. -- userRef references userList defined with its ID -- we define permissions for usersRef in a same way as for roleRef +- actorRef references actorList defined with its ID +- we define permissions for actorRef in the same way as for roleRef ```xml <document> ... - <data type="userList"> - <id>userList1</id> + <data type="actorList"> + <id>actorList1</id> <title/> </data> ... <actorRef> - <id>userList1</id> + <id>actorList1</id> <caseLogic> <view>true</view> <delete>true</delete> @@ -74,7 +74,7 @@ content of the userList can be changed at runtime. <transition> <id>1</id> <actorRef> - <id>userList1</id> + <id>actorList1</id> <logic> <perform>true</perform> </logic> @@ -85,13 +85,13 @@ content of the userList can be changed at runtime. ## Setting permissions -If we want to define permission only for a set of users, and we want to change the content of this set runtime, the -userList-usersRef combo is the best way to do so. You have to follow these steps: +If we want to define permission only for a set of actors, and we want to change the content of this set runtime, the +actorList-actorRef combo is the best way to do so. You have to follow these steps: -1. Define new data field of type **userList** - required attribute is only the *id* of field. -2. For case permissions, define **usersRef** in *document* tag, for task permission define it in the corresponding * +1. Define new data field of type **actorList** - required attribute is only the *id* of field. +2. For case permissions, define **actorRef** in *document* tag, for task permission define it in the corresponding * transition* tag -3. Into *logic* property of usersRef we define the permissions with boolean values - true means enable, false mean +3. Into *logic* property of actorRef we define the permissions with boolean values - true means enable, false mean disable the given permission for user. The permissions can be the following: 1. for cases: 1. *view* - enable or disable the displaying of cases @@ -105,6 +105,6 @@ userList-usersRef combo is the best way to do so. You have to follow these steps [Permission resolution](roles/permissions.md?id=permissions) -[UsersRef Petri Net](../_media/roles/usersRef_functions.groovy) +[ActorRef Petri Net](../_media/roles/actorRef_functions.groovy) -[UsersRef Functions](../_media/roles/usersRef_net.xml) +[ActorRef Functions](../_media/roles/actorRef_net.xml) diff --git a/docs/roles/permissions.md b/docs/roles/permissions.md index dd5fee88274..3de367e5033 100644 --- a/docs/roles/permissions.md +++ b/docs/roles/permissions.md @@ -289,18 +289,18 @@ Permission documentation can be found [here](#Permissions). Roles can be referen </document> ``` -## User list +## Actor list -In NAE, user list is a type of data field, that is used for managing access of a set of users (who's ID is in the -given user list) to Petriflow objects and their actions. User list can be defined where other data fields used to be +In NAE, actor list is a type of data field, that is used for managing access of a set of actors (who's ID is in the +given actor list) to Petriflow objects and their actions. Actor list can be defined where other data fields used to be defined, as child element of the root **document** element: ``` <document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://petriflow.com/petriflow.schema.xsd"> ... - <data type="userList"> - <id>user_list_1</id> - <title>User list 1 + + actor_list_1 + Actor list 1 ... diff --git a/docs/search/elastic_mapping.md b/docs/search/elastic_mapping.md index d77dd922216..49e0f0c02ce 100644 --- a/docs/search/elastic_mapping.md +++ b/docs/search/elastic_mapping.md @@ -112,9 +112,9 @@ as _\[Dog, Hund, Pes\]_ in the index. This way, the fields value can be searched Base class for data field mapping. All indexed data variables have these attributes available. -|index|type|value| -|-----|----|-----| -|`dataSet..fulltextValue`|Text array|value depends on the field type:
**boolean**: textual representation of the value
**date** & **dateTime**: date formated as ISO-8601 basic local date format
**file** & **fileList**: names of the contained files
**number**: the value stored as decimal string
**text**: the value itself
**multichoice** & **enumeration**: all translations of the selected options
**multichoiceMap** & **enumerationMap**: all translated values of the selected key-value pairs
**user** & **userList**: full name followed by email as a single string for each selected user| +|index|type| value | +|-----|----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`dataSet..fulltextValue`|Text array| value depends on the field type:
**boolean**: textual representation of the value
**date** & **dateTime**: date formated as ISO-8601 basic local date format
**file** & **fileList**: names of the contained files
**number**: the value stored as decimal string
**text**: the value itself
**multichoice** & **enumeration**: all translations of the selected options
**multichoiceMap** & **enumerationMap**: all translated values of the selected key-value pairs
**actor** & **actorList**: full name for each selected actor | ### BooleanField - boolean @@ -157,10 +157,11 @@ its `toString()` value is stored. |-----|----|-----| |`dataSet..keyValue`|Keyword array|the _key_ part of the selected key-value pairs (i.e. the part stored as the map field value)| -### UserField - user, userList +### ActorField - actor, actorList -|index|type|value| -|-----|----|-----| -|`dataSet..emailValue`|Text array|emails of the selected users| -|`dataSet..fullNameValue`|Text array|full names of the selected users| -|`dataSet..userIdValue`|Long array|IDs of the selected users| \ No newline at end of file +| index |type| value | +|---------------------------------------|----|--------------------------------------| +| `dataSet..usernameValue` |Text array| usernames of the selected users | +| `dataSet..fullNameValue` |Text array| full names of the selected actors | +| `dataSet..actorIdValue` |Text array| IDs of the selected actors | +| `dataSet..actorRealmIdValue` |Text array| IDs of realms of the selected actors | \ No newline at end of file From 78ee4452a6c3ab1444d7a2739a9c4578591b69c6 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 10 Dec 2025 12:20:01 +0100 Subject: [PATCH 15/48] [NAE-2285] Group as a value of userlists - update ActorListTest --- ...erListTest.groovy => ActorListTest.groovy} | 40 +++++++++++++------ .../{user_list.xml => actor_list.xml} | 8 ++-- 2 files changed, 31 insertions(+), 17 deletions(-) rename application-engine/src/test/groovy/com/netgrif/application/engine/importer/{UserListTest.groovy => ActorListTest.groovy} (68%) rename application-engine/src/test/resources/{user_list.xml => actor_list.xml} (90%) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/ActorListTest.groovy similarity index 68% rename from application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy rename to application-engine/src/test/groovy/com/netgrif/application/engine/importer/ActorListTest.groovy index 9490312dcc3..27f2ae9e7ab 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/importer/UserListTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/importer/ActorListTest.groovy @@ -1,6 +1,7 @@ package com.netgrif.application.engine.importer import com.netgrif.application.engine.TestHelper +import com.netgrif.application.engine.auth.service.GroupService import com.netgrif.application.engine.objects.petrinet.domain.VersionType import com.netgrif.application.engine.objects.petrinet.domain.throwable.MissingPetriNetMetaDataException import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService @@ -27,25 +28,28 @@ import java.util.stream.Collectors @SpringBootTest @ActiveProfiles(["test"]) @ExtendWith(SpringExtension.class) -class UserListTest { +class ActorListTest { @Autowired - private TestHelper testHelper; + private TestHelper testHelper @Autowired - private IPetriNetService petriNetService; + private IPetriNetService petriNetService @Autowired - private SuperCreatorRunner superCreator; + private SuperCreatorRunner superCreator @Autowired - private CaseRepository caseRepository; + private CaseRepository caseRepository @Autowired - private IDataService dataService; + private IDataService dataService @Autowired - private ITaskService taskService; + private GroupService groupService + + @Autowired + private ITaskService taskService @BeforeEach void before() { @@ -53,14 +57,14 @@ class UserListTest { } @Test - void testUserList() throws MissingPetriNetMetaDataException, IOException { - ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/user_list.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()); + void testActorList() throws MissingPetriNetMetaDataException, IOException { + ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/actor_list.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) - assert net.getNet() != null; - Optional caseOpt = caseRepository.findOne(QCase.case$.title.eq("User List")); + assert net.getNet() != null + Optional caseOpt = caseRepository.findOne(QCase.case$.title.eq("Actor List")) - assert caseOpt.isPresent(); - assert caseOpt.get().getDataSet().get("text").getValue() == "Its working..."; + assert caseOpt.isPresent() + assert caseOpt.get().getDataSet().get("text").getValue() == "Its working..." Task task = taskService.findByCases(new FullPageRequest(), Collections.singletonList(caseOpt.get().getStringId())).stream().collect(Collectors.toList()).get(0) @@ -73,5 +77,15 @@ class UserListTest { assert taskService.findById(task.stringId).actors.get(superCreator.getSuperUser().getStringId()) assert caseRepository.findById(caseOpt.get().stringId).get().actors.get(superCreator.getSuperUser().getStringId()) + + dataService.setData(task.stringId, ImportHelper.populateDataset([ + "users_1": [ + "value": [groupService.getDefaultSystemGroup().getStringId()], + "type" : "actorList" + ] + ])) + + assert taskService.findById(task.stringId).actors.get(groupService.getDefaultSystemGroup().getStringId()) + assert caseRepository.findById(caseOpt.get().stringId).get().actors.get(groupService.getDefaultSystemGroup().getStringId()) } } diff --git a/application-engine/src/test/resources/user_list.xml b/application-engine/src/test/resources/actor_list.xml similarity index 90% rename from application-engine/src/test/resources/user_list.xml rename to application-engine/src/test/resources/actor_list.xml index 13f571a9819..ab8e804402e 100644 --- a/application-engine/src/test/resources/user_list.xml +++ b/application-engine/src/test/resources/actor_list.xml @@ -1,8 +1,8 @@ - user_list - User list + actor_list + Actor list ULT users_1 @@ -19,7 +19,7 @@ upload - createCase("user_list", "User List") + createCase("actor_list", "Actor List") @@ -39,7 +39,7 @@ pdf - createCase("user_list", "Destruct") + createCase("actor_list", "Destruct") From db36f564e18b28336a62c90b820ce1fe355e8987 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 10 Dec 2025 13:13:05 +0100 Subject: [PATCH 16/48] [NAE-2285] Group as a value of userlists - update QueryDSLViewPermissionTest - update TaskAuthorizationServiceTest - update WorkflowAuthorizationServiceTest --- .../auth/TaskAuthorizationServiceTest.groovy | 73 ++++++++-- .../WorkflowAuthorizationServiceTest.groovy | 21 ++- .../QueryDSLViewPermissionTest.groovy | 134 ++++++++++++++---- 3 files changed, 187 insertions(+), 41 deletions(-) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy index 9d60299a218..583d5ceb798 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/TaskAuthorizationServiceTest.groovy @@ -1,5 +1,6 @@ package com.netgrif.application.engine.auth +import com.netgrif.application.engine.auth.service.GroupService 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 @@ -91,6 +92,9 @@ class TaskAuthorizationServiceTest { @Autowired private IWorkflowService workflowService + @Autowired + private GroupService groupService + @Autowired TestHelper testHelper @@ -352,10 +356,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "assign_pos_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + + assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + workflowService.deleteCase(case_.stringId) } @@ -369,10 +381,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) assert !taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "assign_neg_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + + assert !taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + workflowService.deleteCase(case_.stringId) } @@ -388,10 +408,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "assign_pos_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + + assert taskAuthorizationService.canCallAssign(ActorTransformer.toLoggedUser(testUser), taskId) + userService.removeRole(testUser, positiveRole.get_id()) workflowService.deleteCase(case_.stringId) } @@ -432,11 +460,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "finish_pos_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + workflowService.deleteCase(case_.stringId) } @@ -450,11 +485,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) assert !taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "finish_neg_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + assert !taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + workflowService.deleteCase(case_.stringId) } @@ -470,11 +512,18 @@ class TaskAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) - sleep(4000) taskService.assignTask(ActorTransformer.toLoggedUser(testUser), taskId) assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "finish_pos_ul": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + assert taskAuthorizationService.canCallFinish(ActorTransformer.toLoggedUser(testUser), taskId) + userService.removeRole(testUser, positiveRole.get_id()) workflowService.deleteCase(case_.stringId) } diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy index a7d1038ffd6..3df4f1df38c 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/auth/WorkflowAuthorizationServiceTest.groovy @@ -1,6 +1,7 @@ package com.netgrif.application.engine.auth import com.netgrif.application.engine.TestHelper +import com.netgrif.application.engine.auth.service.GroupService 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 @@ -73,6 +74,9 @@ class WorkflowAuthorizationServiceTest { @Autowired private IDataService dataService + @Autowired + private GroupService groupService + @Autowired TestHelper testHelper @@ -219,7 +223,7 @@ class WorkflowAuthorizationServiceTest { @Test - void testCanCallDeleteRoleFalseUserRefTrue() { + void testCanCallDeleteRoleFalseActorRefTrue() { ProcessRole posDeleteRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "delete_pos_role") ProcessRole negDeleteRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "delete_neg_role") @@ -234,7 +238,15 @@ class WorkflowAuthorizationServiceTest { "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) + + assert workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "pos_user_list": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() assert workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) @@ -243,7 +255,7 @@ class WorkflowAuthorizationServiceTest { } @Test - void testCanCallDeleteRoleFalseUserRefTrueUserRefFalse() { + void testCanCallDeleteRoleFalseActorRefTrueActorRefFalse() { ProcessRole posDeleteRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "delete_pos_role") ProcessRole negDeleteRole = this.netWithUserRefs.getRoles().values().find(v -> v.getImportId() == "delete_neg_role") @@ -258,11 +270,10 @@ class WorkflowAuthorizationServiceTest { "type": "actorList" ], "neg_user_list": [ - "value": [testUser.stringId], + "value": [groupService.getDefaultSystemGroup().stringId], "type": "actorList" ] ] as Map)).getCase() - workflowService.save(case_) assert !workflowAuthorizationService.canCallDelete(ActorTransformer.toLoggedUser(testUser), case_.getStringId()) diff --git a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy index fd39efbca3e..b35fa48586d 100644 --- a/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy +++ b/application-engine/src/test/groovy/com/netgrif/application/engine/permissions/QueryDSLViewPermissionTest.groovy @@ -1,6 +1,7 @@ package com.netgrif.application.engine.permissions import com.netgrif.application.engine.auth.service.AuthorityService +import com.netgrif.application.engine.auth.service.GroupService 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 @@ -58,6 +59,9 @@ class QueryDSLViewPermissionTest { @Autowired private AuthorityService authorityService + @Autowired + private GroupService groupService + @Autowired private IDataService dataService @@ -72,7 +76,7 @@ class QueryDSLViewPermissionTest { private Authority userAuthority @BeforeEach - void inti() { + void init() { testHelper.truncateDbs() ImportPetriNetEventOutcome net = petriNetService.importPetriNet(new FileInputStream("src/test/resources/view_permission_test.xml"), VersionType.MAJOR, superCreator.getLoggedSuper()) assert net.getNet() != null @@ -127,7 +131,7 @@ class QueryDSLViewPermissionTest { } @Test - void testSearchQueryDSLViewWithoutUserRef() { + void testSearchQueryDSLViewWithoutActorRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) @@ -137,44 +141,86 @@ class QueryDSLViewPermissionTest { } @Test - void testSearchQueryDSLViewWithPosUserRef() { + void testSearchQueryDSLViewWithPosActorRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], "type": "actorList" ] ] as Map)).getCase() - case_ = workflowService.save(case_) - sleep(4000) - Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) - assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId && case_.viewActors.contains(testUser.getStringId()) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 0 + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 1 && casePage.getContent()[0].stringId == case_.stringId + && case_.viewActors.contains(groupService.getDefaultSystemGroup().getStringId()) + workflowService.deleteCase(case_.getStringId()) } @Test - void testSearchTaskQueryDSLViewWithPosUserRef() { + void testSearchTaskQueryDSLViewWithPosActorRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], "type": "actorList" ] ] as Map)).getCase() - case_ = workflowService.save(case_) - sleep(4000) - TaskSearchRequest request = new TaskSearchRequest() request.process = [new com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.PetriNet(netWithUserRefs.getStringId())] Page taskPage = taskService.search([request], PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale(), false) - assert taskPage.getContent().size() == 1 && taskPage.content[0].caseId == case_.stringId && taskPage.content[0].viewActors.contains(testUser.getStringId()) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [], + "type": "actorList" + ] + ] as Map)).getCase() + request = new TaskSearchRequest() + request.process = [new com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.PetriNet(netWithUserRefs.getStringId())] + taskPage = taskService.search([request], PageRequest.of(0, 20), + ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale(), false) + assert taskPage.getContent().size() == 0 + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + request = new TaskSearchRequest() + request.process = [new com.netgrif.application.engine.workflow.web.requestbodies.taskSearch.PetriNet(netWithUserRefs.getStringId())] + taskPage = taskService.search([request], PageRequest.of(0, 20), + ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale(), false) + assert taskPage.getContent().size() == 1 && taskPage.content[0].caseId == case_.stringId + && taskPage.content[0].viewActors.contains(groupService.getDefaultSystemGroup().stringId) + workflowService.deleteCase(case_.getStringId()) } @@ -195,45 +241,85 @@ class QueryDSLViewPermissionTest { } @Test - void testSearchQueryDSLViewWithNegUserRef() { + void testSearchQueryDSLViewWithNegActorRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_neg": [ "value": [testUser.stringId], "type": "actorList" + ], + "view_ul_pos": [ + "value": [testUser.stringId], + "type": "actorList" ] ] as Map)).getCase() - case_ = workflowService.save(case_) - sleep(4000) - Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) - assert casePage.getContent().size() == 0 && case_.negativeViewActors.contains(testUser.getStringId()) + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_neg": [ + "value": [], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 1 && case_.negativeViewActors.isEmpty() + + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_neg": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 0 && case_.negativeViewActors.contains(groupService.getDefaultSystemGroup().stringId) + workflowService.deleteCase(case_.getStringId()) } @Test - void testSearchQueryDSLViewWithNegRoleAndPosUserRef() { + void testSearchQueryDSLViewWithNegRoleAndPosActorRef() { Case case_ = workflowService.createCase(netWithUserRefs.getStringId(), "Permission test", "", ActorTransformer.toLoggedUser(testUser)).getCase() String taskId = (new ArrayList<>(case_.getTasks())).get(0).task + + ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") + userService.addRole(testUser, negViewRole.getStringId()) + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ "view_ul_pos": [ "value": [testUser.stringId], "type": "actorList" ] ] as Map)).getCase() + Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 1 && case_.viewActors.contains(testUser.stringId) - ProcessRole negViewRole = this.net.getRoles().values().find(v -> v.getImportId() == "view_neg_role") - userService.addRole(testUser, negViewRole.getStringId()) - case_ = workflowService.save(case_) - sleep(4000) + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 0 && case_.viewActors.isEmpty() - Page casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, + case_ = dataService.setData(taskId, ImportHelper.populateDataset([ + "view_ul_pos": [ + "value": [groupService.getDefaultSystemGroup().stringId], + "type": "actorList" + ] + ] as Map)).getCase() + casePage = workflowService.search(["petriNet": ["identifier": netWithUserRefs.getIdentifier()], "fullText": "VPT"] as Map, PageRequest.of(0, 20), ActorTransformer.toLoggedUser(testUser), LocaleContextHolder.getLocale()) + assert casePage.getContent().size() == 1 && case_.viewActors.contains(groupService.getDefaultSystemGroup().stringId) - assert casePage.getContent().size() == 1 && case_.viewActors.contains(testUser.stringId) userService.removeRole(testUser, negViewRole.getStringId()) workflowService.deleteCase(case_.getStringId()) } From d8f536e68479bf352b58395c51eae4a5b05fb849 Mon Sep 17 00:00:00 2001 From: chvostek Date: Wed, 10 Dec 2025 13:48:09 +0100 Subject: [PATCH 17/48] [NAE-2285] Group as a value of userlists - update documentation --- docs/roles/actorlist.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/roles/actorlist.md b/docs/roles/actorlist.md index 4742128c9cc..514eac24bdf 100644 --- a/docs/roles/actorlist.md +++ b/docs/roles/actorlist.md @@ -1,6 +1,6 @@ -# UserList and UsersRef +# ActorList and ActorRef -## UserList +## ActorList ActorList is a type of data field. Values of this field represent actors (users, groups, ...) in system. Some basic information about this field: From f7954c6867f167a119aa6dc7d4978dff722e9fb8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 12:26:14 +0100 Subject: [PATCH 18/48] [NAE-2285] Group as a value of userlists - rename variables --- .../elastic/service/ElasticViewPermissionService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java index 9c8f0b73d48..a4e51e1994d 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java @@ -33,16 +33,16 @@ protected void buildViewPermissionQuery(BoolQuery.Builder query, LoggedUser user BoolQuery positiveRoleSetMinusNegativeRole = setMinus(positiveViewRole, negativeViewRole); /* Build positive view actorList query */ - BoolQuery positiveViewUser = buildPositiveViewActor(viewPermNotExists, user); + BoolQuery positiveViewActor = buildPositiveViewActor(viewPermNotExists, user); /* Role query union positive view actorList */ - BoolQuery roleSetMinusPositiveUserList = union(positiveRoleSetMinusNegativeRole, positiveViewUser); + BoolQuery roleSetMinusPositiveActorList = union(positiveRoleSetMinusNegativeRole, positiveViewActor); /* Build negative view actorList query */ - BoolQuery negativeViewUser = buildNegativeViewActor(user); + BoolQuery negativeViewActor = buildNegativeViewActor(user); /* Role-UserListPositive set-minus negative view actorList */ - BoolQuery permissionQuery = setMinus(roleSetMinusPositiveUserList, negativeViewUser); + BoolQuery permissionQuery = setMinus(roleSetMinusPositiveActorList, negativeViewActor); query.filter(permissionQuery._toQuery()); } From f08fa0d50e9ed762ba4f0b1acb832dc2b1e4a3a7 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 12:29:25 +0100 Subject: [PATCH 19/48] [NAE-2285] Group as a value of userlists - fix possible side-effects in LoggedUser --- .../engine/elastic/service/ElasticViewPermissionService.java | 5 +---- .../engine/workflow/service/MongoSearchService.java | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java index a4e51e1994d..e8362e13fc3 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticViewPermissionService.java @@ -91,10 +91,7 @@ private BoolQuery buildNegativeViewActor(LoggedUser user) { } private TermsQueryField buildTermsQueryFieldOfUser(LoggedUser loggedUser) { - Set actorIds = loggedUser.getGroupIds(); - if (actorIds == null) { - actorIds = new HashSet<>(); - } + Set actorIds = loggedUser.getGroupIds() == null ? new HashSet<>() : new HashSet<>(loggedUser.getGroupIds()); actorIds.add(loggedUser.getStringId()); return new TermsQueryField.Builder() .value(actorIds.stream().map(FieldValue::of).toList()) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java index b9e819996bd..a193fc651ce 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/MongoSearchService.java @@ -269,10 +269,7 @@ protected BooleanBuilder constructPredicateTree(List getActorIdsOfUser(LoggedUser loggedUser) { - Set actorIds = loggedUser.getGroupIds(); - if (actorIds == null) { - actorIds = new HashSet<>(); - } + Set actorIds = loggedUser.getGroupIds() == null ? new HashSet<>() : new HashSet<>(loggedUser.getGroupIds()); actorIds.add(loggedUser.getStringId()); return actorIds; } From 7fa1aec1fbc7afff3bd45893829a7ef3ae9df81b Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 12:53:45 +0100 Subject: [PATCH 20/48] [NAE-2285] Group as a value of userlists - fix ExportService actor field handling --- .../application/engine/export/service/ExportService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 84dccaea712..2e806ae1ebe 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 @@ -274,7 +274,13 @@ public String resolveFieldValue(Case exportCase, String exportFieldId) { fieldValue = String.join(";", ((TaskField) fieldData).getValue()); break; case ACTOR: - fieldValue = ((UserFieldValue) fieldData).getUsername(); + if (fieldData instanceof UserFieldValue) { + fieldValue = ((UserFieldValue) fieldData).getUsername(); + } else if (fieldData instanceof GroupFieldValue) { + fieldValue = ((GroupFieldValue) fieldData).getName(); + } else { + fieldValue = ""; + } break; case DATE: fieldValue = ((LocalDate) fieldData).toString(); From 68a7dafa7afe1f730d145afdde510b4b023ca68a Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:29:41 +0100 Subject: [PATCH 21/48] [NAE-2285] Group as a value of userlists - remove boilerplate code --- .../application/engine/importer/service/DataValidator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java index 5146d7347a1..cb9bb77f366 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/DataValidator.java @@ -15,8 +15,8 @@ public void checkDeprecatedAttributes(Data data) { validateAttribute(data.getValid() != null && !data.getValid().isEmpty() ? data.getValid() : null, "valid", data.getId()); validateAttribute(data.getFormat(), "format", data.getId()); validateAttribute(data.getValues() != null && !data.getValues().isEmpty() ? data.getValues() : null, "values", data.getId()); - validateAttribute(data.getType() != null && data.getType().equals(DataType.USER) ? data.getType() : null, "type: " + DataType.USER.name(), data.getId()); - validateAttribute(data.getType() != null && data.getType().equals(DataType.USER_LIST) ? data.getType() : null, "type: " + DataType.USER_LIST.name(), data.getId()); + validateAttribute(data.getType() == DataType.USER ? Boolean.TRUE : null, "type: " + DataType.USER.name(), data.getId()); + validateAttribute(data.getType() == DataType.USER_LIST ? Boolean.TRUE : null, "type: " + DataType.USER_LIST.name(), data.getId()); } protected void validateAttribute(Object attr, String attrName, String fieldName) { From 7a04102526834aad8ac263987ab3600d46a5c188 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:33:05 +0100 Subject: [PATCH 22/48] [NAE-2285] Group as a value of userlists - fix possible casting exception --- .../pdf/generator/service/fieldbuilder/TextFieldBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java index b32a73d6642..3ad0644db09 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/pdf/generator/service/fieldbuilder/TextFieldBuilder.java @@ -57,7 +57,7 @@ public PdfField buildField(DataGroup dataGroup, LocalisedField field, int lastX, value = field.getValue() != null ? resolveFileListNames((FileListFieldValue) field.getValue()) : ""; break; case ACTOR: - value = field.getValue() != null ? ((UserFieldValue) field.getValue()).getFullName() : ""; + value = field.getValue() != null ? ((ActorFieldValue) field.getValue()).getFullName() : ""; break; case ACTORLIST: value = field.getValue() != null ? ((ActorListFieldValue) field.getValue()).getActorValues().stream() From 599e171d9dc7942aefa58cceb4fdea7f4a13876a Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:44:33 +0100 Subject: [PATCH 23/48] [NAE-2285] Group as a value of userlists - fix doc link --- docs/roles/actorlist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/roles/actorlist.md b/docs/roles/actorlist.md index 514eac24bdf..70129c9bb8a 100644 --- a/docs/roles/actorlist.md +++ b/docs/roles/actorlist.md @@ -103,7 +103,7 @@ actorList-actorRef combo is the best way to do so. You have to follow these step 4. *cancel* - enable or disable canceling of tasks 5. *finish* - enable or disable finish of tasks -[Permission resolution](roles/permissions.md?id=permissions) +[Permission resolution](permissions.md?id=permissions) [ActorRef Petri Net](../_media/roles/actorRef_functions.groovy) From abf422edd0cc7e58f283c3b0d7205ac573e5996b Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:47:08 +0100 Subject: [PATCH 24/48] [NAE-2285] Group as a value of userlists - fix tags in code snippets --- docs/roles/permissions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/roles/permissions.md b/docs/roles/permissions.md index 3de367e5033..7d8566248a3 100644 --- a/docs/roles/permissions.md +++ b/docs/roles/permissions.md @@ -261,7 +261,7 @@ Permission documentation can be found [here](#Permissions). Roles can be referen process_role - false + false true @@ -279,7 +279,7 @@ Permission documentation can be found [here](#Permissions). Roles can be referen process_role - false + false true @@ -321,7 +321,7 @@ Permission documentation can be found [here](#Permissions). Actor list can be re actor_list_1 - false + false true @@ -339,7 +339,7 @@ Permission documentation can be found [here](#Permissions). Actor list can be re actor_list_1 - false + false true @@ -386,7 +386,7 @@ permissions for case created from process as follows: process_role - false + false false false @@ -395,7 +395,7 @@ permissions for case created from process as follows: actor_list_1 - true + true true true @@ -437,7 +437,7 @@ permissions for task created from transition as follows: process_role true - false + false true @@ -445,7 +445,7 @@ permissions for task created from transition as follows: actor_list_1 - false + false true From 27635faf593f1a11606b8383798cef2a31998021 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:48:31 +0100 Subject: [PATCH 25/48] [NAE-2285] Group as a value of userlists - fix terminology --- docs/roles/permissions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/roles/permissions.md b/docs/roles/permissions.md index 7d8566248a3..9dd3f21640b 100644 --- a/docs/roles/permissions.md +++ b/docs/roles/permissions.md @@ -369,8 +369,8 @@ $$((R_{p} \setminus R_{n}) \cup A_{p}) \setminus A_{n}$$ Explained in words: An actor list is stronger than a role and a forbidding/revoking (negative - `false`) association is stronger than a granting (positive - `true`) association. An actor must be granted a permission from at least one source in order to be allowed to perform an operation. -A granting (positive) user list association overrides a forbidding (negative) role association. -A forbidding (negative) user list association overrides any granting (positive) association. +A granting (positive) actor list association overrides a forbidding (negative) role association. +A forbidding (negative) actor list association overrides any granting (positive) association. There are two types of permissions - case permissions and task permissions. From f8fda0d71fea4f8b34a826cf80f9a5643e207994 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:50:10 +0100 Subject: [PATCH 26/48] [NAE-2285] Group as a value of userlists - fix typo --- docs/search/elastic_mapping.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/search/elastic_mapping.md b/docs/search/elastic_mapping.md index 49e0f0c02ce..5b65f410ade 100644 --- a/docs/search/elastic_mapping.md +++ b/docs/search/elastic_mapping.md @@ -112,9 +112,9 @@ as _\[Dog, Hund, Pes\]_ in the index. This way, the fields value can be searched Base class for data field mapping. All indexed data variables have these attributes available. -|index|type| value | -|-----|----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|`dataSet..fulltextValue`|Text array| value depends on the field type:
**boolean**: textual representation of the value
**date** & **dateTime**: date formated as ISO-8601 basic local date format
**file** & **fileList**: names of the contained files
**number**: the value stored as decimal string
**text**: the value itself
**multichoice** & **enumeration**: all translations of the selected options
**multichoiceMap** & **enumerationMap**: all translated values of the selected key-value pairs
**actor** & **actorList**: full name for each selected actor | +|index|type| value | +|-----|----|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`dataSet..fulltextValue`|Text array| value depends on the field type:
**boolean**: textual representation of the value
**date** & **dateTime**: date formatted as ISO-8601 basic local date format
**file** & **fileList**: names of the contained files
**number**: the value stored as decimal string
**text**: the value itself
**multichoice** & **enumeration**: all translations of the selected options
**multichoiceMap** & **enumerationMap**: all translated values of the selected key-value pairs
**actor** & **actorList**: full name for each selected actor | ### BooleanField - boolean From d672bc873512647abf020c1905a1aa205bfb74e8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 13:59:27 +0100 Subject: [PATCH 27/48] [NAE-2285] Group as a value of userlists - add explicit setter in ButtonField --- .../engine/objects/elastic/domain/ButtonField.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java index cbd3c1400ab..4685b936ec2 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java @@ -17,6 +17,11 @@ public ButtonField(Integer value) { this.buttonValue = value; } + public void setButtonValue(Integer value) { + this.fulltextValue.add(value.toString()); + this.buttonValue = value; + } + @Override public Object getValue() { return this.buttonValue; From aac78a551474e098f0c044f44b84ba4b41097134 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:16:38 +0100 Subject: [PATCH 28/48] [NAE-2285] Group as a value of userlists - fix NPE --- .../application/engine/objects/elastic/domain/TextField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java index 1d90991f76c..7879435de0a 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/TextField.java @@ -14,7 +14,7 @@ public abstract class TextField extends DataField { protected List textValue; public TextField(String value) { - this(List.of(value)); + this(value != null ? List.of(value) : List.of()); } public TextField(List values) { From cf802f46549e1afbf4c6e7d72a481dc5fc3253e4 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:20:35 +0100 Subject: [PATCH 29/48] [NAE-2285] Group as a value of userlists - fix NPE - fix serialization --- .../objects/petrinet/domain/dataset/ActorFieldValue.java | 7 ++++++- .../objects/petrinet/domain/dataset/UserFieldValue.java | 5 ----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java index d02f6c5c39d..1c13aa25659 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorFieldValue.java @@ -5,13 +5,18 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.io.Serial; import java.io.Serializable; +import java.util.Objects; @Getter @NoArgsConstructor @AllArgsConstructor public abstract class ActorFieldValue implements Serializable { + @Serial + private static final long serialVersionUID = -6421919316454802530L; + protected String id; protected String realmId; @@ -21,6 +26,6 @@ public abstract class ActorFieldValue implements Serializable { public abstract ActorMappingData buildMappingData(); public int hashCode() { - return this.id.hashCode(); + return Objects.hashCode(this.id); } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java index a8ee0edefb7..7e262b687a3 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/UserFieldValue.java @@ -5,15 +5,10 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import java.io.Serial; - @Getter @NoArgsConstructor public class UserFieldValue extends ActorFieldValue { - @Serial - private static final long serialVersionUID = 5228212326436828485L; - protected String firstName; protected String lastName; protected String username; From 5eb459828b3ca36ce66abe31cd65523aab428ce1 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:23:22 +0100 Subject: [PATCH 30/48] [NAE-2285] Group as a value of userlists - fix NPE --- .../engine/objects/petrinet/domain/dataset/ActorListField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java index 40e2eb745dc..eb5da665e98 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java @@ -18,7 +18,7 @@ public ActorListField() { } public ActorListField(String[] roles) { - this(new HashSet<>(Arrays.asList(roles))); + this(roles == null ? new HashSet<>() : new HashSet<>(Arrays.asList(roles))); } public ActorListField(Set roles) { From 98f89de46222dc4cf001bc159acb39304f73eda1 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:24:07 +0100 Subject: [PATCH 31/48] [NAE-2285] Group as a value of userlists - fix collection sharing when cloning --- .../engine/objects/petrinet/domain/dataset/ActorListField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java index eb5da665e98..75ce25fb160 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ActorListField.java @@ -35,7 +35,7 @@ public FieldType getType() { public Field clone() { ActorListField clone = new ActorListField(); super.clone(clone); - clone.setRoles(this.roles); + clone.setRoles(this.roles == null ? null : new HashSet<>(this.roles)); return clone; } } From a7139d63fb419eb7a354a96d5c38408b1cecba58 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:27:11 +0100 Subject: [PATCH 32/48] [NAE-2285] Group as a value of userlists - add null check --- .../application/engine/objects/petrinet/domain/PetriNet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java index 71cdc58a2f5..3dc49d4dee9 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/PetriNet.java @@ -224,6 +224,9 @@ public void addFunction(Function function) { } public void addActorPermission(String actorFieldId, Map permissions) { + if (permissions == null || permissions.isEmpty()) { + return; + } if (this.actorRefs.containsKey(actorFieldId) && this.actorRefs.get(actorFieldId) != null) { this.actorRefs.get(actorFieldId).putAll(permissions); } else { From 612216ee745adae1e98760e7b6fba1204edf5f70 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:29:40 +0100 Subject: [PATCH 33/48] [NAE-2285] Group as a value of userlists - add null check --- .../application/engine/objects/petrinet/domain/Transition.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java index 8e605205975..1516eb40ffc 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java @@ -135,6 +135,9 @@ public void addNegativeViewRole(String roleId) { } public void addActorRef(String actorFieldId, Map permissions) { + if (actorFieldId == null) { + throw new IllegalArgumentException("actorFieldId must not be null"); + } if (actorRefs.containsKey(actorFieldId) && actorRefs.get(actorFieldId) != null) { actorRefs.get(actorFieldId).putAll(permissions); } else { From 7364c84fc02286b69cdbd8b3da899f136dadfdf5 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:34:06 +0100 Subject: [PATCH 34/48] [NAE-2285] Group as a value of userlists - rename method --- .../engine/elastic/service/ElasticCaseMappingService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java index a0a082dee25..158d2d73438 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java @@ -66,7 +66,7 @@ protected Optional transformDataField(String fieldId, Case useCase) { } else if (netField instanceof FileListField) { return this.transformFileListField(caseField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.ActorListField) { - return this.transformUserListField(caseField); + return this.transformActorListField(caseField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) { return this.transformI18nField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) netField); } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField) { @@ -218,7 +218,7 @@ private Optional getMultichoiceValue(com.netgrif.application.engine.objects return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ActorField(actorFieldValue.buildMappingData())); } - protected Optional transformUserListField + protected Optional transformActorListField (com.netgrif.application.engine.objects.workflow.domain.DataField actorListField) { ActorListFieldValue actorListFieldValue = (ActorListFieldValue) actorListField.getValue(); List actorMappingDataList = actorListFieldValue.getActorValues().stream() From 4b3ac779b96e0335e3e6ac0395aa32659c1a6883 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:36:30 +0100 Subject: [PATCH 35/48] [NAE-2285] Group as a value of userlists - add comment --- .../engine/workflow/service/AbstractAuthorizationService.java | 2 ++ 1 file changed, 2 insertions(+) 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 d23389ae938..17debfa2b3c 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 @@ -82,6 +82,8 @@ protected static void putPermissionIfNotAlreadyNegative(Map per protected static void putPermissionIfNotAlreadyNegative(Map permissions, String permType, Boolean permValue) { Boolean existingPermValue = permissions.get(permType); + // Overwrite if no existing value OR existing is positive (true). + // Existing negative (false) permissions are never overwritten to preserve explicit denials. if (existingPermValue == null || existingPermValue) { permissions.put(permType, permValue); } From 10e05d5b72e956c05d751630b9970ee642781057 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:46:14 +0100 Subject: [PATCH 36/48] [NAE-2285] Group as a value of userlists - fix index out of bounds exception --- .../application/engine/objects/elastic/domain/ActorField.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java index f82148efae3..debc70d0def 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ActorField.java @@ -40,9 +40,7 @@ public ActorField(List mappingDataList) { for (ActorMappingData mappingData : mappingDataList) { this.fullNameValue.add(mappingData.fullName()); this.actorIdValue.add(mappingData.actorId()); - if (mappingData.actorRealmId() != null) { - this.actorRealmIdValue.add(mappingData.actorRealmId()); - } + this.actorRealmIdValue.add(mappingData.actorRealmId()); if (mappingData.username() == null) { this.fulltextValue.add(mappingData.fullName()); } else { From 44ca46ad04da1842ad7fc1957c33dfac0ac620a8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:51:42 +0100 Subject: [PATCH 37/48] [NAE-2285] Group as a value of userlists - fix FileField initialization --- .../application/engine/objects/elastic/domain/FileField.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java index 9d5d66c7da1..9b2218411e8 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java @@ -29,11 +29,13 @@ public FileField(List fileFieldValues) { } this.fileNameValue = new ArrayList<>(); this.fileExtensionValue = new ArrayList<>(); + this.filePath = new ArrayList<>(); for (FileFieldValue fileFieldValue : fileFieldValues) { FileNameAndExtension extracted = this.extractFileExtensionFromName(fileFieldValue.getName()); this.fileNameValue.add(extracted.name); this.fileExtensionValue.add(extracted.extension); this.fulltextValue.add(fileFieldValue.getName()); + this.filePath.add(fileFieldValue.getPath()); } } From 5fccd48bae770585aaf67be0c0d7ed89bbcd48fd Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 14:55:20 +0100 Subject: [PATCH 38/48] [NAE-2285] Group as a value of userlists - fix handling of null extension --- .../application/engine/objects/elastic/domain/FileField.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java index 9b2218411e8..6bc562d7ee9 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java @@ -61,6 +61,9 @@ private FileNameAndExtension extractFileExtensionFromName(String filename) { } private static String nameWithExtension(String fileName, String extension) { + if (extension == null || extension.isEmpty()) { + return fileName; + } return fileName + "." + extension; } From 03a956154bc0291abf174890eb2b071ff82d0319 Mon Sep 17 00:00:00 2001 From: chvostek Date: Fri, 12 Dec 2025 15:28:30 +0100 Subject: [PATCH 39/48] [NAE-2285] Group as a value of userlists - add null check --- .../engine/objects/petrinet/domain/Transition.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java index 1516eb40ffc..9af5b43166b 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/Transition.java @@ -138,10 +138,11 @@ public void addActorRef(String actorFieldId, Map permissions) { if (actorFieldId == null) { throw new IllegalArgumentException("actorFieldId must not be null"); } + Map safePermissions = (permissions == null) ? new HashMap<>() : permissions; if (actorRefs.containsKey(actorFieldId) && actorRefs.get(actorFieldId) != null) { - actorRefs.get(actorFieldId).putAll(permissions); + actorRefs.get(actorFieldId).putAll(safePermissions); } else { - actorRefs.put(actorFieldId, permissions); + actorRefs.put(actorFieldId, safePermissions); } } From ff7ce23381e9328328989f1ffaf4726168a25fd4 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 08:12:14 +0100 Subject: [PATCH 40/48] [NAE-2285] Group as a value of userlists - fix possible casting exception --- .../engine/elastic/service/ElasticCaseMappingService.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java index 158d2d73438..8bc66877104 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java @@ -122,8 +122,9 @@ protected Optional transformFilterFieldField(com.netgrif.application. protected Optional transformStringCollectionField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.StringCollectionField netField) { - if (dataField.getValue() != null && dataField.getValue() instanceof Collection && !((Collection) dataField.getValue()).isEmpty()) { - return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.StringCollectionField((List) dataField.getValue())); + if (dataField.getValue() != null && dataField.getValue() instanceof Collection dataFieldValue && !dataFieldValue.isEmpty()) { + List dataFieldValueAsList = dataFieldValue.stream().map(String::valueOf).toList(); + return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.StringCollectionField(dataFieldValueAsList)); } return Optional.empty(); } From b67faebb244cf4ef45e07b3b8b86872ade9d12ae Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 08:48:44 +0100 Subject: [PATCH 41/48] [NAE-2285] Group as a value of userlists - fix mutating referenced collection --- .../engine/workflow/service/AbstractAuthorizationService.java | 2 ++ 1 file changed, 2 insertions(+) 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 17debfa2b3c..40a199c799e 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 @@ -53,6 +53,8 @@ protected Map findUserPermissions(Map(permissions); Set intersectionOfActorIds = new HashSet<>(docPermissions.keySet()); intersectionOfActorIds.retainAll(user.getGroupIds()); From 5ed4b5212c39f6014dbb8d6cbd9d67a494f31a70 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:00:20 +0100 Subject: [PATCH 42/48] [NAE-2285] Group as a value of userlists - fix NPE in AbstractAuthorizationService --- .../engine/workflow/service/AbstractAuthorizationService.java | 3 +++ 1 file changed, 3 insertions(+) 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 40a199c799e..fb2a37662de 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 @@ -77,6 +77,9 @@ protected Map findUserPermissions(Map permissions, Map newPermissions) { + if (newPermissions == null) { + return; + } for (Map.Entry entry : newPermissions.entrySet()) { putPermissionIfNotAlreadyNegative(permissions, entry.getKey(), entry.getValue()); } From 289911ed855be39da8991918d3ae5ac5080fcbe2 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:02:51 +0100 Subject: [PATCH 43/48] [NAE-2285] Group as a value of userlists - optimize for loop in AbstractAuthorizationService --- .../workflow/service/AbstractAuthorizationService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 fb2a37662de..2b5d8b96031 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 @@ -66,10 +66,8 @@ protected Map findUserPermissions(Map(); } - for (Map.Entry> entry : docPermissions.entrySet()) { - if (intersectionOfActorIds.contains(entry.getKey())) { - putPermissionIfNotAlreadyNegative(permissions, entry.getValue()); - } + for (String actorId : intersectionOfActorIds) { + putPermissionIfNotAlreadyNegative(permissions, docPermissions.get(actorId)); } return permissions; From 166747ec1bef456d3199e7cf38ea247ccae9a49f Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:05:05 +0100 Subject: [PATCH 44/48] [NAE-2285] Group as a value of userlists - fix NPE in FileField --- .../application/engine/objects/elastic/domain/FileField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java index 6bc562d7ee9..e83cc67b5fa 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java @@ -20,7 +20,7 @@ public abstract class FileField extends DataField { protected List fileExtensionValue; public FileField(FileFieldValue fileFieldValue) { - this(List.of(fileFieldValue)); + this(fileFieldValue == null ? null : List.of(fileFieldValue)); } public FileField(List fileFieldValues) { From fcb5ed36a2407525f1dd672ccf10276ad280a3e9 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:07:50 +0100 Subject: [PATCH 45/48] [NAE-2285] Group as a value of userlists - fix NPE in ButtonField and value duplicates --- .../application/engine/objects/elastic/domain/ButtonField.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java index 4685b936ec2..1c2b0f924b8 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java @@ -18,7 +18,8 @@ public ButtonField(Integer value) { } public void setButtonValue(Integer value) { - this.fulltextValue.add(value.toString()); + this.fulltextValue.clear(); + this.fulltextValue.add(value == null ? null : value.toString()); this.buttonValue = value; } From 353503e27016154ac83d4b6413e582c07ea45bd8 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:18:55 +0100 Subject: [PATCH 46/48] [NAE-2285] Group as a value of userlists - add nullcheck in AbstractAuthorizationService --- .../engine/workflow/service/AbstractAuthorizationService.java | 3 +++ 1 file changed, 3 insertions(+) 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 2b5d8b96031..4a31058c948 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 @@ -84,6 +84,9 @@ protected static void putPermissionIfNotAlreadyNegative(Map per } protected static void putPermissionIfNotAlreadyNegative(Map permissions, String permType, Boolean permValue) { + if (permValue == null) { + return; + } Boolean existingPermValue = permissions.get(permType); // Overwrite if no existing value OR existing is positive (true). // Existing negative (false) permissions are never overwritten to preserve explicit denials. From f4ec90fb583eccae784f59158033507c4ec10a99 Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 09:19:32 +0100 Subject: [PATCH 47/48] [NAE-2285] Group as a value of userlists - fix NPE in ButtonField --- .../application/engine/objects/elastic/domain/ButtonField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java index 1c2b0f924b8..233691679b5 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java @@ -13,7 +13,7 @@ public abstract class ButtonField extends DataField { protected Integer buttonValue; public ButtonField(Integer value) { - super(value.toString()); + super(value == null ? null : value.toString()); this.buttonValue = value; } From 80f2493263083bebf8a558ba062b63f8b353110a Mon Sep 17 00:00:00 2001 From: chvostek Date: Mon, 15 Dec 2025 11:04:05 +0100 Subject: [PATCH 48/48] [NAE-2285] Group as a value of userlists - fix NPE in FileField --- .../application/engine/objects/elastic/domain/FileField.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java index e83cc67b5fa..78abe5501ab 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java @@ -31,6 +31,9 @@ public FileField(List fileFieldValues) { this.fileExtensionValue = new ArrayList<>(); this.filePath = new ArrayList<>(); for (FileFieldValue fileFieldValue : fileFieldValues) { + if (fileFieldValue == null) { + continue; + } FileNameAndExtension extracted = this.extractFileExtensionFromName(fileFieldValue.getName()); this.fileNameValue.add(extracted.name); this.fileExtensionValue.add(extracted.extension);