Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Business rule query

Merza Lyn
Giga Guru

We created a business rule to restrict Risk and Risk acceptance task to search if logged in user is not the same as the owner and assigned_to.

 

sn_risk_risk - Owner

(function executeRule(current, previous /*null when async*/) {
   // Allow admins and users with specific roles to bypass the restriction
   if (gs.hasRole('admin') || gs.hasRole('sn_risk.global_manager') || gs.hasRole('sn_grc.admin')) {
       return;
   }

   var user = gs.getUser();
   var userRecord = new GlideRecord('sys_user');

   if (userRecord.get(user.getID())) {
       var userCountry = userRecord.location.country;

       // If user's country is defined, filter the query
       if (userCountry) {
           // Add condition: Owner's country must match user's country
           current.addQuery('owner.location.country', userCountry);
       } else {
           // If user has no country, restrict all records
           current.addQuery('sys_id', '');
       }
   } else {
       // If user record not found, restrict all records
       current.addQuery('sys_id', '');
   }
})(current, previous);

 

sn_risk_acceptance_task

(function executeRule(current, previous /*null when async*/) {
   // Allow admins and users with specific roles to bypass the restriction
   if (gs.hasRole('admin') || gs.hasRole('sn_risk.global_manager') || gs.hasRole('sn_grc.admin')) {
       return;
   }
   var user = gs.getUser();
   var userRecord = new GlideRecord('sys_user');
   if (userRecord.get(user.getID())) {
       var userCountry = userRecord.location.country;
       // If user's country is defined, filter the query
       if (userCountry) {
           // Add condition: Owner's country must match user's country for the task
           current.addQuery('assigned_to.location.country', userCountry);
       } else {
           // If user has no country, restrict all records
           current.addQuery('sys_id', '');
       }
       // Check if the risk acceptance task has an associated parent risk
       if (current.risk) {
           var parentRisk = new GlideRecord('sn_risk_risk');
           if (parentRisk.get(current.risk)) {
               // If the parent risk exists and has an owner
               var parentRiskOwnerCountry = parentRisk.owner.location.country;
               // If the parent risk owner is from a different country, allow access to the task
               if (parentRiskOwnerCountry !== userCountry) {
                   // Allow access to the risk task even if country mismatch exists
                   current.addQuery('sys_id', current.sys_id);  // Ensure the task remains accessible
               }
           }
       }
   } else {
       // If user record not found, restrict all records
       current.addQuery('sys_id', '');
   }
})(current, previous);

 

However, there are cases that when the Owner of the Risk assigned the risk acceptance task to user that located in other country. So the assigned_to cannot view the Parent risk.

 

Sample this Risk.

Owner is from Korea

MerzaLyn_2-1741655320704.png

 

And the risk acceptance task is assigned to Scott that is located in the US.

MerzaLyn_3-1741655348550.png

So Scott cannot view the parent risk because him and the owner are not in the same country.

MerzaLyn_4-1741655430555.png

How can I exempt that case in my BRs?

13 REPLIES 13

Medi C
Giga Sage
Giga Sage

Hi @Merza Lyn 

Could you please try the following on sn_risk_risk table:

(function executeRule(current, previous /*null when async*/) {
   // Allow admins and users with specific roles to bypass the restriction
   if (gs.hasRole('admin') || gs.hasRole('sn_risk.global_manager') || gs.hasRole('sn_grc.admin')) {
       return;
   }

   var user = gs.getUser();
   var userRecord = new GlideRecord('sys_user');

   if (userRecord.get(user.getID())) {
       var userCountry = userRecord.location.country;

       if (userCountry) {
           // Add condition: Owner's country must match user's country
           var riskQuery = current.addQuery('owner.location.country', userCountry);
           
           // OR condition: Check if the user is assigned to a related risk acceptance task
           var taskQuery = riskQuery.addOrCondition();
           taskQuery.addJoinQuery('sn_risk_acceptance_task', 'sys_id', 'risk')
                    .addCondition('assigned_to', user.getID());
       } else {
           // If user has no country, restrict all records
           current.addQuery('sys_id', '');
       }
   } else {
       // If user record not found, restrict all records
       current.addQuery('sys_id', '');
   }
})(current, previous);

 

 


If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.

Hi @Medi C ,

 

I tried, but it is not working. I mean Scott still cannot view the parent risk record.

Hi @Merza Lyn,

Any errors thrown in the logs? I have adjusted the script, could you please use this one instead:

(function executeRule(current, previous /*null when async*/) {
    // Allow admins and users with specific roles to bypass the restriction
    if (gs.hasRole('admin') || gs.hasRole('sn_risk.global_manager') || gs.hasRole('sn_grc.admin')) {
        return;
    }

    var user = gs.getUser();
    var userRecord = new GlideRecord('sys_user');
    
    // Ensure user record is found
    if (!userRecord.get(user.getID())) {
        current.addQuery('sys_id', '');  // Restrict access if user record is not found
        return;
    }

    var userCountry = userRecord.location.country;  // Get user's country

    // Prepare the base query condition for Risk Acceptance Task assignment
    var taskGR = new GlideRecord('sn_risk_acceptance_task');
    taskGR.addEncodedQuery('assigned_to', user.getID() + '^risk=' + current.sys_id);
    taskGR.query();

    var riskIds = [];
    while (taskGR.next()) {
        if (taskGR.risk) {
            riskIds.push(taskGR.risk.toString());
        }
    }

    // Build the query based on user country and task-related risks
    var query = "";

    if (riskIds.length > 0) {
        query += "sys_idIN" + riskIds.join(',');
    }

    if (userCountry) {
        query += query == "" ? "owner.location.country=" + userCountry : "^owner.location.country=" + userCountry;
    }

    // Apply the query to restrict access based on the constructed query
    if (query != "") {
        current.addEncodedQuery(query);  // Use addEncodedQuery for complex queries
    } else {
        current.addQuery('sys_id', '');  // Restrict if no valid conditions are found
    }

})(current, previous);

 


If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.

Hi @Medi C 

This is what I saw in the system logs.

MerzaLyn_0-1741663032149.png