Before Query Business Rule Script help

Valon Sheremeti
Kilo Guru

Hi all. I was hoping if I can pick your brain to complete business rule script.
Goal: I need to restrict access to certain catalog item variable values so only the following users can query them:

1. Any member of group named "MyGroup" 
OR
2. User who filled the variable itself (this is the userID in sys_created_by field in the table)

 

I've come with the following script and I was hoping if you can help me complete the part of the script in red.
P.S. I was able to get it work by hard coding the sys_id of certain user, but I am unable to make it dynamic for any logged user.

Business Rule
Table: Options [sc_item_option]
When: Before Query
Script:

if((gs.getUserName()!=current.sys_created_by)&&(!gs.getUser().isMemberOf('MyGroup')))
{
current.addQuery('item_option_new','!=','490bd8e51bcdd050af0787bae54bcb75');
}

// 490bd8e51bcdd050af0787bae54bcb75 is the sys_id of catalog item variable

I appreciate your comments 🙂
Val

1 ACCEPTED SOLUTION

Michael Jones -
Giga Sage

Ok - amazing what a few hours of sleep can do. 

Give this a try! The trick was figuring out what was actually being "queried" when a request item was loaded and then working out the details from there. 

 

(function executeRule(current, previous /*null when async*/ ) {

    var looking_for = '490bd8e51bcdd050af0787bae54bcb75'; //this is the id of your variable
    var found_var = false;
	var found_where = '';
    var sc_item_option = new GlideRecord('sc_item_option');
    sc_item_option.addEncodedQuery(current.getEncodedQuery());
	sc_item_option.setWorkflow(false); //critical to prevent recursive loop
    sc_item_option.query();
    while (sc_item_option.next()) {
        if (sc_item_option.item_option_new.sys_id == looking_for) {
			//ok we found the variable, ow we see if it was created by the user, or if the user is not part of the group
			if(sc_item_option.sys_created_by !=  gs.getUserName() && !gs.getUser().isMemberOf('MyGroup')) {
			found_var = true;
			found_where = sc_item_option.getValue('sys_id');
			}
        }

    }

    if (found_var == true ) {
		//If we found the var, the user is not the creator, and is not in the group - exclude that record!
        current.addQuery('sys_id', '!=', found_where);
    }


})(current, previous);

If this was helpful or correct, please be kind and click appropriately!

Michael Jones - Proud member of the CloudPires Team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

View solution in original post

12 REPLIES 12

To your first question, yes - you could change to an array and check if any values in the array are found by adding the for loop.

The performance hit; I was afraid of that. 

Maybe is we wrap things in an if statement to target when someone is viewing via a Request Item vs. the table directly? This isn't exactly what you asked for, but it still keeps that field visible only to the group, and the creator on an item, but if someone tries to go to the table directly, if they are not part of the group, it excludes that variable. Not perfect but I assume the creator probably would not be able to get to the table, and if they're not in the group you want to hide it so..maybe workable? Should hopefully alleviate some of the performance hit..

 

(function executeRule(current, previous /*null when async*/ ) {

//We check to see if the current query is looking for specific records by sys_id
    if (current.getEncodedQuery().indexOf('sys_id') > -1) {
        //If yes, we invoke our filtering process
        var looking_for = '490bd8e51bcdd050af0787bae54bcb75'; //this is the id of your variable
        var found_var = false;
        var found_where = '';
        var sc_item_option = new GlideRecord('sc_item_option');
        sc_item_option.addEncodedQuery(current.getEncodedQuery());
        sc_item_option.setWorkflow(false); //critical to prevent recursive loop
        sc_item_option.query();
        while (sc_item_option.next()) {
            if (sc_item_option.item_option_new.sys_id == looking_for) {
                //ok we found the variable, ow we see if it was created by the user, or if the user is not part of the group
                if (sc_item_option.sys_created_by != gs.getUserName() && !gs.getUser().isMemberOf('MyGroup')) {
                    found_var = true;
                    found_where = sc_item_option.getValue('sys_id');
                }
            }

        }

        if (found_var == true) {
            //If we found the var, the user is not the creator, and is not in the group - exclude that record!
            current.addQuery('sys_id', '!=', found_where);
        }
    } else {
            //if not, we limit the variable to only people in the group
		if(!gs.getUser().isMemberOf('MyGroup')) {
			current.addQuery('item_option_new','!=','490bd8e51bcdd050af0787bae54bcb75');
		}
		
	}


})(current, previous);

Hope that helps!

If this was helpful or correct, please be kind and click appropriately!

Michael Jones - Proud member of the CloudPires Team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

Thanks a lot for your comments Michael.

I was able to convert (looking_for) variable to an array, created a loop and it is working with multiple catalog item variable sys_IDs.

I will unfortunately not be able to use code below as requirements for given catalog item variable values are to be restricted and this opens the door for any itil user to perform sc_item_option.list and be able to access all variable values in a list view.

if (current.getEncodedQuery().indexOf('sys_id') > -1)

I do however appreciate all your comments and feedback 🙂

Hello Michael,

I am trying to sort by u_order what would be the syntax for this?Screenshot 2024-08-13 at 11.01.05 AM.pngScreenshot 2024-08-13 at 11.01.39 AM.png