Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NAE-2016] Global roles for menu items permissions #276

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.netgrif.application.engine.petrinet.domain.dataset.logic.validation.V
import com.netgrif.application.engine.petrinet.domain.roles.ProcessRole
import com.netgrif.application.engine.petrinet.domain.version.Version
import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService
import com.netgrif.application.engine.petrinet.service.interfaces.IProcessRoleService
import com.netgrif.application.engine.petrinet.service.interfaces.IUriService
import com.netgrif.application.engine.rules.domain.RuleRepository
import com.netgrif.application.engine.startup.DefaultFiltersRunner
Expand Down Expand Up @@ -91,6 +92,7 @@ class ActionDelegate {
static final String ALWAYS_GENERATE = "always"
static final String ONCE_GENERATE = "once"
static final String TRANSITIONS = "transitions"
public static final String GLOBAL_ROLE = "GLOBAL_ROLE"

@Value('${nae.mail.from}')
private String mailFrom
Expand Down Expand Up @@ -128,6 +130,9 @@ class ActionDelegate {
@Autowired
INextGroupService nextGroupService

@Autowired
IProcessRoleService processRoleService

@Autowired
IRegistrationService registrationService

Expand Down Expand Up @@ -624,13 +629,13 @@ class ActionDelegate {
}

def change(Field field, Case targetCase = this.useCase, Optional<Task> targetTask = this.task) {
[about : { cl -> // TODO: deprecated
[about : { cl -> // TODO: deprecated
changeFieldValue(field, cl, targetCase, targetTask)
},
value : { cl ->
changeFieldValue(field, cl, targetCase, targetTask)
value : { cl ->
changeFieldValue(field, cl, targetCase, targetTask)
},
choices : { cl ->
choices : { cl ->
if (!(field instanceof MultichoiceField || field instanceof EnumerationField))
return

Expand All @@ -649,7 +654,7 @@ class ActionDelegate {
}
saveChangedChoices(field, targetCase, targetTask)
},
allowedNets: { cl ->
allowedNets : { cl ->
if (!(field instanceof CaseField)) // TODO make this work with FilterField as well
return

Expand All @@ -667,7 +672,7 @@ class ActionDelegate {
}
saveChangedAllowedNets(field, targetCase, targetTask)
},
options : { cl ->
options : { cl ->
if (!(field instanceof MultichoiceMapField || field instanceof EnumerationMapField
|| field instanceof MultichoiceField || field instanceof EnumerationField))
return
Expand Down Expand Up @@ -703,7 +708,7 @@ class ActionDelegate {
}

},
validations: { cl ->
validations : { cl ->
changeFieldValidations(field, cl, targetCase, targetTask)
},
componentProperties: { cl ->
Expand Down Expand Up @@ -755,9 +760,9 @@ class ActionDelegate {
value.each { id -> users.add(new UserFieldValue(userService.findById(id as String, false))) }
value = new UserListFieldValue(users)
}
if (field instanceof TaskField && targetTask.isPresent()) {
dataService.validateTaskRefValue(value, targetTask.get().getStringId());
}
// if (field instanceof TaskField && targetTask.isPresent()) {
// dataService.validateTaskRefValue(value, targetTask.get().getStringId());
// }
field.value = value
saveChangedValue(field, targetCase)
}
Expand Down Expand Up @@ -1633,7 +1638,7 @@ class ActionDelegate {
"filterType" : "Case",
"defaultSearchCategories": true,
"inheritAllowedNets" : false
] }</pre>
] }</pre>
* <li> <code>changeFilter filter title { new I18nString("New title") }</code>
* <li> <code>changeFilter filter title { "New title" }</code>
* <li> <code>changeFilter filter icon { "filter_alt" }</code>
Expand Down Expand Up @@ -1881,52 +1886,52 @@ class ActionDelegate {
* @param item {@link Case} instance of preference_item.xml
*/
def changeMenuItem(Case item) {
[allowedRoles : { cl ->
[allowedRoles : { cl ->
updateMenuItemRoles(item, cl as Closure, MenuItemConstants.PREFERENCE_ITEM_FIELD_ALLOWED_ROLES.attributeId)
},
bannedRoles : { cl ->
bannedRoles : { cl ->
updateMenuItemRoles(item, cl as Closure, MenuItemConstants.PREFERENCE_ITEM_FIELD_BANNED_ROLES.attributeId)
},
caseDefaultHeaders: { cl ->
caseDefaultHeaders : { cl ->
String defaultHeaders = cl() as String
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_CASE_DEFAULT_HEADERS.attributeId): ["type": "text", "value": defaultHeaders]
])
},
taskDefaultHeaders: { cl ->
taskDefaultHeaders : { cl ->
String defaultHeaders = cl() as String
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_TASK_DEFAULT_HEADERS.attributeId): ["type": "text", "value": defaultHeaders]
])
},
filter : { cl ->
filter : { cl ->
def filter = cl() as Case
setData("change_filter", item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_NEW_FILTER_ID.attributeId): ["type": "text", "value": filter.stringId]
])
},
uri : { cl ->
uri : { cl ->
def uri = cl() as String
def aCase = useCase
if (useCase == null || item.stringId != useCase.stringId) {
aCase = workflowService.findOne(item.stringId)
}
moveMenuItem(aCase, uri)
},
title : { cl ->
title : { cl ->
def value = cl()
I18nString newName = (value instanceof I18nString) ? value : new I18nString(value as String)
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_MENU_NAME.attributeId): ["type": "i18n", "value": newName]
])
},
menuIcon : { cl ->
menuIcon : { cl ->
def value = cl()
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_MENU_ICON.attributeId): ["type": "text", "value": value]
])
},
tabIcon : { cl ->
tabIcon : { cl ->
def value = cl()
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_TAB_ICON.attributeId): ["type": "text", "value": value]
Expand All @@ -1938,13 +1943,13 @@ class ActionDelegate {
(MenuItemConstants.PREFERENCE_ITEM_FIELD_REQUIRE_TITLE_IN_CREATION.attributeId): ["type": "boolean", "value": value]
])
},
useCustomView: { cl ->
useCustomView : { cl ->
def value = cl()
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_USE_CUSTOM_VIEW.attributeId): ["type": "boolean", "value": value]
])
},
customViewSelector: { cl ->
customViewSelector : { cl ->
def value = cl()
setData(MenuItemConstants.PREFERENCE_ITEM_SETTINGS_TRANS_ID.attributeId, item, [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_CUSTOM_VIEW_SELECTOR.attributeId): ["type": "text", "value": value]
Expand Down Expand Up @@ -2136,7 +2141,7 @@ class ActionDelegate {

protected Case getOrCreateFolderItem(String uri) {
UriNode node = uriService.getOrCreate(uri, UriContentType.CASE)
MenuItemBody body = new MenuItemBody(new I18nString(node.name),"folder")
MenuItemBody body = new MenuItemBody(new I18nString(node.name), "folder")
return getOrCreateFolderRecursive(node, body)
}

Expand Down Expand Up @@ -2255,30 +2260,30 @@ class ActionDelegate {

Task newItemTask = findTask { it._id.eq(new ObjectId(duplicated.tasks.find { it.transition == MenuItemConstants.PREFERENCE_ITEM_FIELD_INIT_TRANS_ID.attributeId }.task)) }
Map updatedDataSet = [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_DUPLICATE_TITLE.attributeId): [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_DUPLICATE_TITLE.attributeId) : [
"value": null,
"type": "text"
"type" : "text"
],
(MenuItemConstants.PREFERENCE_ITEM_FIELD_DUPLICATE_IDENTIFIER.attributeId): [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_DUPLICATE_IDENTIFIER.attributeId) : [
"value": null,
"type": "text"
"type" : "text"
],
(MenuItemConstants.PREFERENCE_ITEM_FIELD_MENU_NAME.attributeId): [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_MENU_NAME.attributeId) : [
"value": newTitle,
"type": "i18n"
"type" : "i18n"
],
(MenuItemConstants.PREFERENCE_ITEM_FIELD_TAB_NAME.attributeId): [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_TAB_NAME.attributeId) : [
"value": newTitle,
"type": "i18n"
"type" : "i18n"
],
(MenuItemConstants.PREFERENCE_ITEM_FIELD_NODE_PATH.attributeId): [
(MenuItemConstants.PREFERENCE_ITEM_FIELD_NODE_PATH.attributeId) : [
"value": newNodePath,
"type": "text"
"type" : "text"
],
// Must be reset by button, because we have the same dataSet reference between originItem and duplicated
(MenuItemConstants.PREFERENCE_ITEM_FIELD_DUPLICATE_RESET_CHILD_ITEM_IDS.attributeId): [
"value": 0,
"type": "button"
"type" : "button"
],
]
assignTask(newItemTask)
Expand Down Expand Up @@ -2492,20 +2497,36 @@ class ActionDelegate {

private Map<String, I18nString> collectRolesForPreferenceItem(List<ProcessRole> roles) {
return roles.collectEntries { role ->
PetriNet net = petriNetService.get(new ObjectId(role.netId))
return [(role.importId + ":" + net.identifier), ("$role.name ($net.title)" as String)]
if (role.isGlobal()) {
return [(role.importId + ":" + GLOBAL_ROLE), ("$role.name (🌍 Global role)" as String)]
} else {
PetriNet net = petriNetService.get(new ObjectId(role.netId))
return [(role.importId + ":" + net.identifier), ("$role.name ($net.title)" as String)]
}
} as Map<String, I18nString>
}

private Map<String, I18nString> collectRolesForPreferenceItem(Map<String, String> roles) {
Map<String, PetriNet> temp = [:]
return roles.collectEntries { entry ->
if (!temp.containsKey(entry.value)) {
temp.put(entry.value, petriNetService.getNewestVersionByIdentifier(entry.value))
if (entry.value.equals(GLOBAL_ROLE)) {
Set<ProcessRole> findGlobalRole = processRoleService.findAllByImportId(ProcessRole.GLOBAL + entry.key)
if (findGlobalRole == null || findGlobalRole.isEmpty()) {
return
}
ProcessRole role = findGlobalRole.find { it.isGlobal() }
if (role == null) {
return
}
return [(role.importId + ":" + GLOBAL_ROLE), ("$role.name (🌍 Global role)" as String)]
} else {
if (!temp.containsKey(entry.value)) {
temp.put(entry.value, petriNetService.getNewestVersionByIdentifier(entry.value))
}
PetriNet net = temp[entry.value]
ProcessRole role = net.roles.find { it.value.importId == entry.key }.value
return [(role.importId + ":" + net.identifier), ("$role.name ($net.title)" as String)]
}
PetriNet net = temp[entry.value]
ProcessRole role = net.roles.find { it.value.importId == entry.key }.value
return [(role.importId + ":" + net.identifier), ("$role.name ($net.title)" as String)]
} as Map<String, I18nString>
}

Expand Down Expand Up @@ -2802,7 +2823,7 @@ class ActionDelegate {
Map<String, I18nString> findOptionsBasedOnSelectedNode(UriNode node, List<String> splitPathList) {
Map<String, I18nString> options = new HashMap<>()

options.putAll(splitPathList.collectEntries { [(it): new I18nString(it)]})
options.putAll(splitPathList.collectEntries { [(it): new I18nString(it)] })

Set<String> childrenIds = node.getChildrenId()
if (!childrenIds.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ public interface ProcessRoleRepository extends MongoRepository<ProcessRole, Stri

Set<ProcessRole> findAllByImportId(String importId);

Set<ProcessRole> findAllByGlobalIsTrue();

void deleteAllBy_idIn(Collection<ObjectId> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ public List<ProcessRole> findAll() {
return processRoleRepository.findAll();
}

@Override
public Set<ProcessRole> findAllGlobalRoles() {
return processRoleRepository.findAllByGlobalIsTrue();
}

@Override
public List<ProcessRole> findAll(String netId) {
Optional<PetriNet> netOptional = netRepository.findById(netId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public interface IProcessRoleService {

List<ProcessRole> findAll();

Set<ProcessRole> findAllGlobalRoles();

List<ProcessRole> findAll(String netId);

ProcessRole defaultRole();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.netgrif.application.engine.petrinet.domain.version.StringToVersionConverter;
import com.netgrif.application.engine.petrinet.domain.version.Version;
import com.netgrif.application.engine.petrinet.service.PetriNetService;
import com.netgrif.application.engine.petrinet.service.interfaces.IProcessRoleService;
import com.netgrif.application.engine.petrinet.web.responsebodies.PetriNetReference;
import com.netgrif.application.engine.utils.FullPageRequest;
import com.netgrif.application.engine.workflow.service.interfaces.IConfigurableMenuService;
Expand All @@ -23,11 +24,17 @@
@Service
public class ConfigurableMenuService implements IConfigurableMenuService {

protected final String GLOBAL_ROLE = "GLOBAL_ROLE";

@Autowired
private PetriNetService petriNetService;

@Autowired
private StringToVersionConverter converter;

@Autowired
private IProcessRoleService processRoleService;

/**
* Constructs a map that can be used as a value for any {@link com.netgrif.application.engine.petrinet.domain.dataset.MapOptionsField}.
*
Expand All @@ -51,7 +58,8 @@ public Map<String, I18nString> getNetsByAuthorAsMapOptions(IUser author, Locale
requestQuery.setAuthor(authorQuery);
List<PetriNetReference> nets = this.petriNetService.search(requestQuery, loggedAuthor, new FullPageRequest(), locale).getContent();

Map<String, I18nString> options = new HashMap<>();
Map<String, I18nString> options = new LinkedHashMap<>();
options.put("GLOBAL_ROLE", new I18nString("🌍 Global role"));

for (PetriNetReference net : nets) {
String[] versionSplit = net.getVersion().split("\\.");
Expand Down Expand Up @@ -80,14 +88,24 @@ public Map<String, I18nString> getNetsByAuthorAsMapOptions(IUser author, Locale
@Override
public Map<String, I18nString> getAvailableRolesFromNet(EnumerationMapField processField, MultichoiceMapField permittedRoles, MultichoiceMapField bannedRoles) {

if (GLOBAL_ROLE.equals(processField.getValue())) {
return processRoleService.findAllGlobalRoles().stream()
.filter(role -> !permittedRoles.getOptions().containsKey(role.getImportId() + ":" + GLOBAL_ROLE)
&& !bannedRoles.getOptions().containsKey(role.getImportId() + ":" + GLOBAL_ROLE))
.collect(Collectors.toMap(
role -> role.getImportId() + ":" + GLOBAL_ROLE,
role -> new I18nString(role.getName())
));
}

String netImportId = processField.getValue().split(":")[0];
String versionString = processField.getValue().split(":")[1].replace("-", ".");
Version version = converter.convert(versionString);
PetriNet net = petriNetService.getPetriNet(netImportId, version);

return net.getRoles().values().stream()
.filter(role -> (!permittedRoles.getOptions().containsKey(role.getImportId() + ":" + netImportId)
&& !bannedRoles.getOptions().containsKey(role.getImportId() + ":" + netImportId)))
&& !bannedRoles.getOptions().containsKey(role.getImportId() + ":" + netImportId) && !role.isGlobal()))
.collect(Collectors.toMap(o -> o.getImportId() + ":" + netImportId, v -> new I18nString(v.getName())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ private Object parseFieldsValues(JsonNode jsonNode, DataField dataField, String
break;
case "taskRef":
List<String> listTask = parseListStringValues(node);
validateTaskRefValue(listTask, taskId);
// validateTaskRefValue(listTask, taskId);
value = listTask;
break;
case "stringCollection":
Expand Down Expand Up @@ -1114,9 +1114,10 @@ public void validateCaseRefValue(List<String> value, List<String> allowedNets) t
});
}

public void validateTaskRefValue(List<String> taskIds, String restrictedTaskId) throws IllegalArgumentException {
if (taskIds != null && taskIds.contains(restrictedTaskId)) {
throw new IllegalArgumentException(String.format("Task with id '%s' cannot be added to task ref, since it is a task which is displaying task ref", restrictedTaskId));
}
}
// public void validateTaskRefValue(List<String> taskIds, String restrictedTaskId) throws IllegalArgumentException {
// if (taskIds != null && taskIds.contains(restrictedTaskId)) {
// throw new IllegalArgumentException(String.format("Task with id '%s' cannot be added to task ref, since it is a task which is displaying task ref", restrictedTaskId));
// }
// }

}
Loading
Loading