Tip For Creating Complex Before Query Business Rules

Before query business rules are great! I absolutely love them and use them all the time.

Sometimes though, I do find myself getting into a bit of a twist with the logic in the code.

Before I show you what I do now to overcome it, i’ll quickly explain what a before query business rule is. Put simply, it’s exactly as the name implies. It’s a business rule that runs before querying the database. More specifically, it can add additional query parameters to the search automatically and invisibly to the user.

For example, if a user wants to view all users, they can go to the sys_user table with no query parameters.

The system will essentially do the following code to bring back the results:

var current = new GlideRecord('sys_user');
current.query();

Now, if you want to only allow users to view active users, this is where a before query business rule comes into play. If I gave you the above script and asked you to only return active users, you would amend the code to be:

var current = new GlideRecord('sys_user');
current.addActiveQuery();
current.query();

A before query business rule is no different. You’d create the business rule and add the line current.addActiveQuery() to the body and that’s it (side note, a before query business rule is one where the ‘when’ field is set as before and the ‘query checkbox is ticked’). So essentially, the before query business rule is made to add additional query conditions to the query GlideRecord. The above example can be seen in the business rule called ‘user query’ out of the box on the sys_user table.

Now that’s out of the way, adding a simple parameter like above to a query is simple, but when you have 5/6 different parameters and different conditions for each one, and different values, things gets a little/lot more complicated.

The way I get around that is simple.
Continue reading

Securing The Activity Formatter (Or Any Formatter For That Matter)

The activity formatter on a form is a great part of ServiceNow. As long as it’s added to the form, and the table is audited, you can get a quick glance of the most important updates.

However, my only issue with it (and it’s my issue with all formatters), is that you can’t apply an ACL to it. For some users, I don’t want them to see it at all, but I don’t want to have to create a custom view just to hide it.

What I did therefore was found a way to apply ACLs to the formatter. This little trick can be used on all formatters.

Continue reading

Enhancing The Impersonate Functionality

Update: This has now been added OOB to Geneva to the elevate privilege dialog, but not for the impersonate dialog

 

When building security rules, I find myself impersonating back and forward constantly between numerous users trying to test what a user can see or do.

What gets to me is that every time I impersonate, it throws me to the homepage and then I had to navigate again to the correct location I was testing.

You could of course open multiple windows and impersonate in the other one, but things eventually get confusing.

Instead, what I added was the ability to stay on your current page by adding a new checkbox to the impersonation page:

Screen Shot 2015-07-27 at 15.39.29

Continue reading

Speed Up Events and Emails While Testing

So, I’m quite an inpatient person. When I do something, I kind of what it to happen now…

When configuring in ServiceNow, it’s great. I update a business rule and I can immediately see the results.

Only times this isn’t the case, is when triggering an event, waiting to receive an email (and then process it) or waiting to send an email.

In these scenarios, it’s all run from scheduled jobs which trigger once every 2 minutes. To speed things up, I put together the following script below. To make it easier to access, I created a module in one of the administrator applications called ‘Run events’ and make it a type of ‘Script (from arguments)’. Then in the arguments put the following code:

Continue reading

Automated Login Using A HTA File

One of our clients had the concept of kiosks in particular locations/office/factories. These kiosks were used to give users access to a number of applications for information. One of the things they wanted the kiosk to have access to was their ServiceNow knowledge base.

We didn’t want to make the knowledge base public because it contained sensitive information, and at the same time didn’t want the users to have to enter a username and password to login.

I experimented with a login using a HTA file (same technology as Help the help desk functionality). The idea being that this could sit on the desktop and when clicked, will login automatically to ServiceNow.

We never used this solution, but I thought the idea was interesting and one I haven’t played with before so posting it here just as a concept.

So the approach was this (actual code at the end):

I created a new user record specific for each kiosk. The username was the windows username that the kiosk was logged in with. On the user table, we created 2 new fields:

1) u_ip which IP restricted who could access using this account

2) u_automated_login which was a True/False field to determine if this user record could use automated login or not

Then I created a HTA file which would read the username of the logged in user. Then it would do a HTTP post which was the same as the login.do page, except it would also pass an additional parameter across with it of ‘AutomatedLogin’.

Editing the Login installation exit, I then would check if the additional parameter was passed through, if so, I would check if this user had the Automated Login checkbox ticked, and finally, would check if their IP address matched against the one on record. If all these passed, I would log the user in automatically.

 
Continue reading

Domain Separation Transform Maps

To start with, apologies for not posting in ages! I’ve had a few of you guys ask me where I went and to carry on. Life took over and I got too busy, but I’m going to try to revive the blog now.
So with that out of the way, back to the actual post….

For those who have worked on domain separated environment, you will know it often requires different approaches to the same requirements that you’d normally encounter on a non-domain separated environment.

One of the things that you always need to be careful about is integrations, in particular, mapping reference fields. With reference fields, you have the option to create new records on the fly, which I use often in general integrations.

The issue with domains however, is you’re probably doing an integration into a particular domain, but the create option on the transform map will create new records in the global domain – not great.

Also, when mapping to reference fields, you can map using names rather than sys_id. But what happens when you have two records with the same name, one in the global domain and one in your lower domain? You cannot guarantee which one will be selected.

Without a proper solution in place, you can end up with what I call domain cross contamination. For example, a CI in domain1, where the owner is a user in domain2 and the manufacturer a record from domain3. This is not a good situation to be in and rectifying it can be complex!

To get around this, I created the following script which searches a particular domain for the reference record, if it doesn’t exist, it searches the global domain, and then if it still can’t find it, it will create the record in the lower domain if required.
Continue reading