“It’s better to wait for a productive programmer to become available than it is to wait for the first available programmer to become productive.”
— Steve McConnell
With the completion of the set-up widget, we can now turn our attention to the missing Script Include functions and the initial registration process that one of those functions will be calling on the Host instance. Since I always like to start with the easy/familiar stuff first (that checks more things off of the “to do” list faster than the other way around!), let’s jump into the createUpdateWorker() function that inserts or updates the Service Account in the sys_user table. But before we do that, we will need to create a special Role for these worker accounts that has limited privileges.
To create a new Role, navigate to System Security -> Roles and click on the New button to bring up the input form. The only field that we need to fill out is the Suffix, which we will set to worker.
Once we have saved our Role, we will want to bring up the form again and grab the sys_id using the Copy sys_id option on the hamburger menu. We will use that to set the value of one of the constants that we will define at the top of our Script Include.
WORKER_ROOT: 'csworker1.',
WORKER_ROLE: 'f1421a6c2fe430104425fcecf699b6a9',
The other constant is the prefix for the user ID for the Service Account, to which we will append the name of the instance. Now that we have defined our Role and set up our constants, we can build the code that will create the account.
var user_name = this.WORKER_ROOT + gs.getProperty('instance_name');
var userGR = new GlideRecord('sys_user');
if (!userGR.get('user_name', user_name)) {
userGR.initialize();
userGR.user_name = user_name;
userGR.insert();
}
userGR.first_name = 'CS';
userGR.last_name = 'Worker';
userGR.title = 'Collaboration Store Worker';
userGR.active = true;
userGR.locked_out = false;
userGR.web_service_access_only = true;
userGR.user_password.setDisplayValue(passwd);
userGR.update();
Since it is possible that an earlier failed attempt to set up the app already created the account, we first check for that, and if it isn’t already present in the sys_user table, then we create it. Then we set the appropriate fields to their current values and update the record. One thing to note is the way in which we update the user_password field, which is different than all of the others. Because the value of that field is one-way encrypted, we have to set the Display Value instead of the Value. It took me a bit of research to figure that out; it is not very well documented anywhere that I could find.
Once we create the account, we then have to assign it to the Role that we created earlier. Once again, this may have already been done in an earlier failed attempt, so we have to check for that before proceeding.
var userRoleGR = new GlideRecord('sys_user_has_role');
userRoleGR.addEncodedQuery('user=' + userGR.getUniqueValue() + '^role=' + this.WORKER_ROLE);
userRoleGR.query();
if (!userRoleGR.next()) {
userRoleGR.initialize();
userRoleGR.user = userGR.getUniqueValue();
userRoleGR.role = this.WORKER_ROLE;
userRoleGR.insert();
}
That takes care of creating/updating the account and applying the Role. Putting it all together, the entire function looks like this:
createUpdateWorker: function(passwd) {
var user_name = this.WORKER_ROOT + gs.getProperty('instance_name');
var userGR = new GlideRecord('sys_user');
if (!userGR.get('user_name', user_name)) {
userGR.initialize();
userGR.user_name = user_name;
userGR.insert();
}
userGR.first_name = 'CS';
userGR.last_name = 'Worker';
userGR.title = 'Collaboration Store Worker';
userGR.active = true;
userGR.locked_out - false;
userGR.web_service_access_only = true;
userGR.user_password.setDisplayValue(passwd);
userGR.update();
var userRoleGR = new GlideRecord('sys_user_has_role');
userRoleGR.addEncodedQuery('user=' + userGR.getUniqueValue() + '^role=' + this.WORKER_ROLE);
userRoleGR.query();
if (!userRoleGR.next()) {
userRoleGR.initialize();
userRoleGR.user = userGR.getUniqueValue();
userRoleGR.role = this.WORKER_ROLE;
userRoleGR.insert();
}
},
Well, that takes care of the easy part. Next time, we will start digging into the more complex elements of the remaining work needed to complete the set-up process.
Maex says:
var userRoleGR = new GlideRecord('sys_user_has_role');
userRoleGR.addEncodedQuery('user=' + userGR.getUniqueValue() + '^role=' + this.WORKER_ROLE);
userRoleGR.setLimit(1);
userRoleGR.query();
if (!userRoleGR.next()) {
userRoleGR.initialize();
userRoleGR.user = userGR.getUniqueValue();
userRoleGR.role = this.WORKER_ROLE;
userRoleGR.insert();
}
Your code shows a lot of experience. Very clean and secure! We’re using tests for naming conventions (like you GR for GlideRecords) and also we try to use EVERYTIME setLimit (there is nearly no reason not to use limits in case you run into unexpeced amount for query results – i know you are using an if later ;-)).
Are you experimenting with ui builder?
snhackery says:
No, I have not, as yet, had an opportunity to play around with UI Builder. Maybe some day …