Saturday, October 26, 2013

ServiceNow LDAP, Groups, Roles

A few things to know when writing Javascript in Service Now:

1) When importing groups and users from LDAP, you need to make sure that you map the dn from LDAP to the source field in the sys_user table, as part of the transform map.  Otherwise the OnAfter call of ldapUtils.addMembers(source,target) during the group transform will not be able to associate the user with a group when you go to sync the group.

2) When manipulating roles, you need to modify the sys_user_has_role for users and sys_user_has_group table for groups.  The examples that exist out there now where you just assign this field to a comma delimited list of strings does not work in Calgary.

3) Related to (2), keep in mind that membership of groups works the same way.  There is not a simple Reference. So, to add someone to a group or a role, you need to modify the correct membership table.

Code snippet from our implementation partner:

var roleToAssign = 'itil';
var groupToAssign = "Group Name";

if (!groupHasRole(groupToAssign, roleToAssign)){
   addRoleToGroup(groupToAssign, roleToAssign);
}

function groupHasRole(groupName, roleName){
   var groupRoleGR = new GlideRecord('sys_group_has_role');
   // We presume group and role exist
   groupRoleGR.addQuery('role.name', roleName);
   groupRoleGR.addQuery('group.name', groupName);
   groupRoleGR.query();
   return groupRoleGR.hasNext();
}

function addRoleToGroup(groupName, roleName){
   var newGroupRole = new GlideRecord('sys_group_has_role');
   newGroupRole.initialize();
   newGroupRole.role.setDisplayValue(roleName);
   newGroupRole.group.setDisplayValue(groupName);
   newGroupRole.insert();
}


2 comments:

Anon said...

You may want to re-look at your suggestion of populating "dn" into source. Instead you should probably be populating u_source as that contains the dn, but is prefixed with ldap:. That appears to actually be the proper import.

Thank you for the code snippet on setting a group role, I'm using that in a Clone Cleanup Script!

W said...

Right. You can (and probably should) map u_source to source instead of dn -> source.

source seems to be a 'special' field in the sense that there is no 'source' attribute on the LDAP server. This confused me a little and that's why I mapped dn in (but, as you indicate, you must have the ldap:// prefix and not just a plain dn).

In any event, my main point was not how is source mapped in but rather you must map in source to the user record. Otherwise, the existing libraries won't add the user to the groups.