Determining if a user can read an article

Michael Todd
Tera Contributor

Hi,

I have a requirement to determine if a user has (read) access to a knowledge article via a email notification script. I am assuming there is an OTTB script include for this but struggling to find anything.

 

Appreciate any suggestions.

Thanks.

1 ACCEPTED SOLUTION

Laszlo Balla
ServiceNow Employee
ServiceNow Employee

I'm afraid none of the other answers give you what you need, as methods like .canRead() automatically take the logged in user's sys_id to check access, and they do not accept any other parameter to check a different user. Furthermore, it is not recommended to call SNC classes, like KBKnowledgeSNC() directly. These classes always have an extended sibling which should be used, in this case it is KBKnowledge(). But as I mentioned, they only take the logged in user's ID, and therefore you should first impersonate your target user. So you will have to do something like this:

/* 
*Check if the logged in user has access to the provided knowledge article
* @Param {string} - sys_id of the knowledge article to check
* @return {boolean} - true if the user has access to the article, false if not
*/

function kbAccess(kba) {
  var kbGr = new GlideRecord('kb_knowledge');
  kbGr.get(kba);
  return (new KBKnowledge().canRead(kbGr));
}

var userToCheck = ''; // Add the sys_id of the user you want to check here
var originalUser = gs.getSession().impersonate(userToCheck ); // impersonate target user
var hasAccessToKBA = kbAccess(kba);
 gs.getSession().impersonate(originalUser ); // impersonate back to the original user

 

View solution in original post

7 REPLIES 7

Thanks Lazlo - this worked perfectly.

 

If it is of benefit to anyone else, this mail script makes use of the sc_2_kb table (articles related to a catalog item). When a RITM is completed, it adds a list of related articles to the body of the email sent to the requestor.

 

The script makes sure the article is published and is accessible to the requesting user.

 

Hope it helps.

 

 

(function runMailScript(/* GlideRecord */ current, /* TemplatePrinter */ template,
          /* Optional EmailOutbound */ email, /* Optional GlideRecord */ email_action,
          /* Optional GlideRecord */ event) {

		function kbAccess(kba) {
		var kbGr = new GlideRecord('kb_knowledge');
		kbGr.get(kba);
		return (new KBKnowledge().canRead(kbGr));
		}
	
          // searches for articles related to the provisioned catalog item and adds links to the email..
		var baseURL = gs.getProperty('glide.servlet.uri');
		var gr = new GlideRecord('sc_2_kb');
		
		//active articles query 
	gr.addEncodedQuery('kb_knowledge.active=true^kb_knowledge.workflow_state=published^kb_knowledge.valid_to>=javascript:gs.beginningOfToday()');
	
		gr.addQuery('sc_cat_item', current.cat_item);
		gr.query();

		if (gr.getRowCount() > 0) { //only if related articles are found
			var i=0;
			
			while (gr.next()) {
				//check the user has access to the article
				var userToCheck = current.request.requested_for; // Add the sys_id of the user you want to check here
				var originalUser = gs.getSession().impersonate(userToCheck); // impersonate target user
				var hasAccessToKBA = kbAccess(gr.kb_knowledge); //do they have access to the article
				gs.getSession().impersonate(originalUser); // impersonate back to the original user
			
				if(hasAccessToKBA == true){ //the user has access
					if(i==0){ //print a subheader before the first article only
						template.print("<p></p><strong>Now that your request is complete, here are some articles that might help</strong><br /><br />");
						}
				var kb_link = baseURL +'/sp?id=kb_article_view&sysparm_article='+gr.kb_knowledge.number;
				template.print("<a href=" + kb_link + ">" + gr.kb_knowledge.short_description + "</a>"+ "<br />");	
				
				i++;
				}
					
			}
		}
})(current, template, email, email_action, event);

 

 

Thanks Laszlo, this works perfectly.

 

If it is of help to anyone, this mail script makes use of the sc_2_kb table (articles linked to catalog item). When a RITM is completed, a list of related articles is added to the body of the email to the requestor. 

The script makes sure the articles are published and the requestor has access.

 

Hope it helps.

 

(function runMailScript(/* GlideRecord */ current, /* TemplatePrinter */ template,
          /* Optional EmailOutbound */ email, /* Optional GlideRecord */ email_action,
          /* Optional GlideRecord */ event) {

		function kbAccess(kba) {
		var kbGr = new GlideRecord('kb_knowledge');
		kbGr.get(kba);
		return (new KBKnowledge().canRead(kbGr));
		}
	
          // searches for articles related to the provisioned catalog item and adds links to the email..
		var baseURL = gs.getProperty('glide.servlet.uri');
		var gr = new GlideRecord('sc_2_kb');
		
		//active articles query 
	gr.addEncodedQuery('kb_knowledge.active=true^kb_knowledge.workflow_state=published^kb_knowledge.valid_to>=javascript&colon;gs.beginningOfToday()');
	
		gr.addQuery('sc_cat_item', current.cat_item);
		gr.query();

		if (gr.getRowCount() > 0) { //only if related articles are found
			var i=0;
			
			while (gr.next()) {
				//check the user has access to the article
				var userToCheck = current.request.requested_for; // Add the sys_id of the user you want to check here
				var originalUser = gs.getSession().impersonate(userToCheck); // impersonate target user
				var hasAccessToKBA = kbAccess(gr.kb_knowledge); //do they have access to the article
				gs.getSession().impersonate(originalUser); // impersonate back to the original user
			
				if(hasAccessToKBA == true){ //the user has access
					if(i==0){ //print a subheader before the first article only
						template.print("<p></p><strong>Now that your request is complete, here are some articles that might help</strong><br /><br />");
						}
				var kb_link = baseURL +'/sp?id=kb_article_view&sysparm_article='+gr.kb_knowledge.number;
				template.print("<a href=" + kb_link + ">" + gr.kb_knowledge.short_description + "</a>"+ "<br />");	
				
				i++;
				}
					
			}
		}

})(current, template, email, email_action, event);

 

Glad it all came together Michael!