Restrict @mention to users with read access to record
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā11-03-2023 11:16 AM - edited ā11-03-2023 11:44 AM
My client would like to limit who can be @mentioned on a ticket platform wide to only people with read access to the ticket. I created a Before Query business rule on the User table based on another community post - this business rule does work to limit @mention to users with the hr admin role, however I want to see if we can limit to users with read access to the record instead. Advice on how to modify business rule or a different approach would be appreciated! Thanks
(function executeRule(current, previous /*null when async*/ ) {
try {
if (gs.action.getGlideURI() != '') {
if (gs.action.getGlideURI().getMap() != '') {
if (gs.action.getGlideURI().toString().startsWith('api/now/form/mention/record/')) {
current.addEncodedQuery('roles=sn_hr_core.admin');
current.addActiveQuery();
gs.addInfoMessage(current); // Returns "sys_user"
}
}
}
} catch (errObj) {
gs.error('Global_Set_Filter_Mention-' + errObj);
}
})(current, previous);
If we have a method to prevent any @mention from additional comments that would be +1 as the client is wondering this as well
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā11-03-2023 11:33 AM
You can use the ".canRead()" method.
I'm not very familiar with GlideURI methods, but after returning the sys user record, you can easily check that record with user.canRead() to return t/f if they can read the record in question.
https://developer.servicenow.com/dev.do#!/reference/api/tokyo/server/no-namespace/c_GlideElementScop...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā11-03-2023 12:11 PM
Unfortunately we aren't returning a user record that is usable, the query business rule seems to be querying the whole table when it appears, see the snippet below
gs.addInfoMessage(current); // Returns "sys_user"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā11-03-2023 12:40 PM
yea, you need a while/next loop after the query to iterate the individual user results returned by the glideURI and check/try/test them against canread();
Something like this (not tested code, treat as pseudo code):
(function executeRule(current, previous /*null when async*/ ) {
try {
if (gs.action.getGlideURI() != '') {
if (gs.action.getGlideURI().getMap() != '') {
if (gs.action.getGlideURI().toString().startsWith('api/now/form/mention/record/')) {
//current.addEncodedQuery('roles=sn_hr_core.admin'); // unless you also need them to have that role...
current.addActiveQuery();
gs.addInfoMessage(current); // Returns "sys_user"
current.query();
while (current.next()) {
if (current.canRead()) {
var message = current + "can read this record";
gs.addInfoMessage(message);
}
}
}
}
}
} catch (errObj) {
gs.error('Global_Set_Filter_Mention-' + errObj);
}
})(current, previous);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ā11-03-2023 02:12 PM
So I think this is getting me close, when I @mention "Tester" it pulls up 2 test users but my infomessage shows them both having read access, I tried impersonating using some syntax I found in an OOB I think we need to impersonate these users because I read that canRead() only works with the logged in user, and when I implemented the impersonation it locks me out of my instance and I have to manually logout, would you know where I should reverse the impersonation if that is possible? Thanks for all the good tips
(function executeRule(current, previous /*null when async*/ ) {
try {
if (gs.action.getGlideURI() != '') {
if (gs.action.getGlideURI().getMap() != '') {
if (gs.action.getGlideURI().toString().startsWith('api/now/form/mention/record/')) {
//current.addEncodedQuery('roles=sn_hr_core.admin'); // unless you also need them to have that role...
current.addActiveQuery();
current.query();
while (current.next()) {
// var session = GlideSession.get();
// session.impersonate(current);
if (current.canRead()) {
var message = current.name + "can read this record";
gs.addInfoMessage(message);
}
}
}
}
}
} catch (errObj) {
gs.error('Global_Set_Filter_Mention-' + errObj);
}
})(current, previous);