Execute a Script Include as a different user without impersonation

kevinclark-7EL
Tera Contributor

Hey Team!

I've got an instance where we have ACLs that restrict access to the Request Record under certain circumstances (when a request was created from a particular order guide type).

The ACL restrictions explicitly exclude impersonation, and it means that the Out of Box Business Rule that runs when the child sc_req_item is closed is unable to close the related sc_request record.

I've tried refactoring the OOB business rule to abstract the behaviour into a Script Include with the hope that the script include might be able to be executed as a user other than the one that triggered the business rule, but I've run into a brick wall - it seems that both the business rule and script includes are unable to write to the Request record because the current user can't see it.

My Business rule looks like this:

// Initialise the SE Request Closer Script include and pass it the current request ID

gs.log("(7EL) Close Parent Restricted Business rule Triggered against Req Item: "+current.number);

var RequestCloser = new SERequestCloser();  

var currentReq = current.request.sys_id;

RequestCloser.closeParentIfRequired(currentReq);

And my script include does this:

var SERequestCloser = Class.create();

SERequestCloser.prototype = Object.extendsObject(AbstractAjaxProcessor, {

closeParentIfRequired: function(currentReq) {

gs.log("(7EL) Started Request Closer");

  // check to see if any of our peers are currently *not* closed

  var gr = new GlideRecord('sc_req_item');

  gr.addQuery('request', currentReq);

  gr.addQuery('stage', '!=', 'complete');

  gr.addQuery('stage', '!=', 'Request Cancelled');

  gr.query();

gs.log("(7EL) Request Closer has found Request Item record: "+gr.number);

  if (!gr.next()) {

        // no peer task is currently open

        var sc_request = new GlideRecord('sc_request');

        sc_request.addQuery('sys_id', currentReq);

        sc_request.query();

        sc_request.next();

        gs.print("SC_REQUEST.STAGE = " + sc_request.stage + " INDEX = " + sc_request.stage.toString().indexOf('closed'));

      gs.log("(7EL) Request Closer found request record: "+ sc_request.number);

        if (sc_request.stage.toString().indexOf('closed') == -1) {

                sc_request.stage = "closed_complete";

                sc_request.comments.setJournalEntry("Request Automatically Closed as all Line Items were complete");

                sc_request.update();

}

  }

},

      type: 'SERequestCloser'

});

Because the Request Record is not visible to the user executing the BR, neither the GR query nor the sc_request query are able to get the relevant records, and therefore the update at line 23 just creates a new record altogether.   If this is run as a user who has ACL access to the Request record, then this is successful, but it doesn't work otherwise, and I can't grant users access in this case (just yet).  

What would be handy is if I could just call the method closeParentIfRequired as a system user.... any thoughts?   As mentioned before the ACL explicitly excludes impersonation access to the Request table.

6 REPLIES 6

Goran WitchDoc
ServiceNow Employee
ServiceNow Employee

Hi Kevin,



Something else is wrong here. If a script in a BR uses a glideRecord() query it uses the system account and it by that it doesn't care about the ACLs. To make the query adhere to ACLs, you must use the GlideRecordSecure() to get it working. So here must be something else going on.


Does it use the system account via an impersonation initiated by the current user? Our ACLs for this table explicitly disallow impersonation.


Hi Kevin,



if you use gliderecord in a br, it doesn't care "who" you are, doesn't matter if you impersonate or not. Only affects if you use gliderecordsecure



Kind of interesting as well how you created ACLs to disallow impersonations.


kevinclark-7EL
Tera Contributor

Thanks for taking an interest Goran, and thanks for your advice.



I agree that the impersonation limitation is "interesting" The limitation decision was made as part of an attempt to keep administrators from being able to view secure/restricted information about salaries being submitted via Service Catalogue items.   These same ACLs keep the catalogue task fulfiller from being able to read/write   the REQ record which I think might be where the problem lies...



What you said before is that the GlideRecord is run as the system user, however I suspect that the update operation that is executed after the GlideRecord must be run as the current user - when I look at the OOB Business Rule and view the history of changes that are made to the REQ record (including the Additional Comment value of "Request Automatically Closed as all Line Items were complete") I can see that these updates were made by the logged in user, which looks to me like Update functions are executed by the current user.



I've just found a thread on community which might be what I'm looking for - using a method called global.ScheduleOnce:



Update record as other user



I'll let you know how I go...