ACL with GlideRecord
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-24-2024 08:47 PM
answer = false;
var assignmentGroups;
var groupArray = [];
if (current) {
assignmentGroups = current.getValue('related_assignment_groups').toString();// a list field which holds all the related assignment groups worked on that ticket
groupArray = assignmentGroups.split(',');
//To check if the current user is a manager of any of the related groups if yes, then show the record
var groupGR = new GlideRecord('sys_user_group');
groupGR.addQuery('manager', gs.getUserID());
groupGR.addQuery('sys_id', 'IN', groupArray);
groupGR.query();
if (groupGR.next()) {
answer = true;
} else {
//to check if the user is a member of any of the related groups list.
answer = groupArray.some(function(group) {
return gs.getUser().isMemberOf(group.trim());
});
}
}
Johnny
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-24-2024 09:28 PM - edited 01-24-2024 09:29 PM
Hi @JohnnySnow ,
pretty good question and there are not many users/admins/developers who are concerned about the performance of ACLs!
I have done extensive research into the performance of ACLs and have come to the conclusion that, as always, there is no "good" or "bad". ServiceNow itself uses GlideRecord queries very intensively in its own ACLs.
If have two optimizations:
- After
insertgroupGR.addQuery('sys_id', 'IN', groupArray);
as you only need one result row. This is a common best practice and not only related to ACLsgroupGR.setLimit(1);
- In the else branch, you are performing for each group individually a:
I'm not sure whether ServiceNow is caching group memberships of users and you could think about to use the same approach as before with a GlideRecord query to check the membership on table sys_user_grmember.return gs.getUser().isMemberOf(group.trim())
Maik
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-28-2024 03:43 PM
@Maik Skoddow Thanks for the reply, I didnt quite understand the 2nd point. Are you asking me to write a before BR on sys_user_grmember? Can you please elaborate?
Johnny
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-28-2024 06:18 PM
I'm not sure if you meant this, but now instead of 2 different queries, I'm using 1 query as below (hopefully better than the previous code)
answer = false;
var assignmentGroups;
var groupArray = [];
if (current) {
assignmentGroups = current.getValue('related_assignment_groups').toString();
groupArray = assignmentGroups.split(',');
var grpmemGR = new GlideRecord('sys_user_grmember');
var qc = grpmemGR.addQuery('group.manager', gs.getUserID());
qc.addOrCondition('user', gs.getUserID());
grpmemGR.addQuery('group', 'IN', groupArray);
grpmemGR.setLimit(1);
grpmemGR.query();
if (grpmemGR.next()) {
answer = true;
}
}
Johnny
Please mark this response as correct or helpful if it assisted you with your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
01-28-2024 09:03 PM
Hi @JohnnySnow
I am delighted as this is a great solution!
If all your business tests are passing, you can take this.
Last and minor optimization: There is no need to split the assignment groups into an array. You can pass the comma-separated string directly to the GlideRecord query:
assignmentGroups = current.getValue('related_assignment_groups') || '';
if (assignmentGroups.length > 0) {
var grpmemGR = new GlideRecord('sys_user_grmember');
var qc = grpmemGR.addQuery('group.manager', gs.getUserID());
qc.addOrCondition('user', gs.getUserID());
grpmemGR.addQuery('group', 'IN', assignmentGroups );
grpmemGR.setLimit(1);
grpmemGR.query();
if (grpmemGR.next()) {
answer = true;
}
}
Hint:
The
|| ''
at the end of the first line makes sure that in case there is no value in related_assignment_groups, at least an empty string is returned. That way, it is possible (and required!) to test if related_assignment_groups has a value or not.
Maik