Skip to content

Commit

Permalink
[NAE-2016] Global roles for menu items permissions
Browse files Browse the repository at this point in the history
- pridanie globalnej roly:
 def allowedRoles = [ "system"    : "GLOBAL_ROLE",
                      "super_admin"    : "GLOBAL_ROLE" ]

- edit preference_item.xml
  • Loading branch information
machacjozef committed Nov 18, 2024
1 parent 86df06b commit f00373e
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 51 deletions.
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

0 comments on commit f00373e

Please sign in to comment.