Handle unmapped fields
Summarize
Summary of Handle Unmapped Fields
This guide provides instructions for managing unmapped fields during SCIM customization in ServiceNow, specifically for the sysuser and sysusergroup tables. It outlines the processes for creating or updating SCIM clients and customizing SCIM responses.
Show less
Key Features
- Customization of SCIM Client: Admins can utilize custom scripts in onBefore and onAfter functions to handle unmapped fields. This includes overriding RTE mappings and invoking scriptable APIs to transform data across tables.
- SCIM Context Access: The method
snauth.SCIM2Util.getScimProviderCustomizationContext()allows access to SCIM request context, facilitating interaction with SCIM resources during different operations (POST, PUT, PATCH). - Response Customization: Customization of GET API responses can be achieved by extending the SCIMProviderCustomization script and overriding methods for user and group resource responses.
Key Outcomes
By following this guide, ServiceNow customers can effectively manage unmapped fields, ensuring that additional attributes can be processed and returned in SCIM operations. This enhances integration capabilities and allows for more tailored user and group data handling.
You can handle unmapped fields in SCIM customization in different ways.
During SCIM customization, the fields that are not part of the sys_user and sys_user_group tables can be mapped by performing the following functions.
Customize SCIM (Create or Update)
You can create or update the SCIM Client.
- The SCIM admin can add custom scripts in the onBefore and onAfter scripts for fields that are not mapped in ETL Definition or RTE.
- The SCIM admin can override RTE Mappings by adding custom scripts in the onBefore and onAfter scripts.
- You can invoke a scriptable API in the RTE onBefore or onAfter scripts to access incoming request and perform transformations on other tables, lists, and unmapped attributes.
- You can use the
sn_auth.SCIM2Util.getScimProviderCustomizationContext()
method to provide the SCIM request context that contains the
scimResource object. The
scimResource in context represents the following in
each operation:
- POST: The SCIM resource sent in the request payload.
- PUT: The current SCIM resource from database replaced with the SCIM resource sent in thee request payload.
- PATCH: The current SCIM resource from the database after performing the patch operations.
(function onAfter(source, target, importLog) {
var ctx = sn_auth.SCIM2Util.getScimProviderCustomizationContext();
gs.info("scim context ee: " + JSON.stringify(ctx.scimResource));
var roles = ctx.scimResource.roles;
if(roles) {
var removingRolesGR = new GlideRecord("sys_user_has_role");
removingRolesGR.addQuery("user", target.sys_user[0].sys_id);
removingRolesGR.query();
removingRolesGR.deleteMultiple();
for (var i = 0; i < roles.length; i++) {
var addingRolesGR = new GlideRecord("sys_user_has_role");
addingRolesGR.setValue("user", target.sys_user[0].sys_id);
addingRolesGR.setValue("role", roles[i].value);
addingRolesGR.setValue("state", "active");
addingRolesGR.insert();
}
}
var customUserExtn = new global.SCIMProviderCustomization().getCustomExtensionUrn('User');
var salary = ctx.scimResource[customUserExtn].salary;
if (salary) {
var gr = new GlideRecord("u_user_salary");
gr.addQuery("user", target.sys_user[0].sys_id);
gr.query();
if (gr.next()) {
gr.setValue("salary", salary);
gs.info("scim update: " + gr.update());
} else {
gr.setValue("salary", salary);
gr.setValue("user", target.sys_user[0].sys_id);
gr.insert();
}
}
})(source, target, importLog);Customize SCIM response
For the GET API calls, any response back to the SCIM client can be customized using the script by extending the SCIMProviderCustomization script.
While extending the script, the author can override the customizeUserResponse and customizeGroupResponse methods to modify the responses for User and Group resources.
The com.snc.integration.scim2.provider.customization.script.id property enables the SCIM plugin to use the script that should be used for response customization.
var SCIMCustomizationScript = Class.create();
SCIMCustomizationScript.prototype = Object.extendsObject(SCIMProviderCustomization, {
initialize: function() {
SCIMProviderCustomization.prototype.initialize.call(this);
},
customizeUserResponse: function(context) {
try {
var rolesGR = new GlideRecord("sys_user_has_role");
rolesGR.addQuery("user", context.scimResource.id);
rolesGR.query();
var i = 0;
context.scimResource.roles = [];
while (rolesGR.next()) {
context.scimResource.roles[i] = {
display: rolesGR.getElement('role.name').getValue(),
value: rolesGR.getElement('role.sys_id').getValue()
};
i++;
}
var userGR = new GlideRecord("u_user_salary");
userGR.addQuery("user", context.scimResource.id);
userGR.query();
if (userGR.next()) {
var salary = userGR.getValue("salary");
if (salary) {
var customExtensionValue = SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context);
customExtensionValue.salary = salary;
SCIMProviderCustomization.prototype.setCustomExtensionNodeValue.call(this, "User", context, customExtensionValue);
}
}
} catch (ex) {
gs.error("err: " + ex);
}
return context;
},
customizeGroupResponse: function(context) {
return context;
},
type: 'SCIMCustomizationScript'
});- The parameter that the customizeUserResponse and customizeGroupResponse methods contain is a context object with one attribute called scimResource. This attribute has all the attributes of a user or group resource object.
- A customized script include can only be created and viewed by the admin.
- If a user or group resource is modified, then you must return the context back.
- If there are no modification of any attribute in the resource object, then set the com.snc.integration.scim2.provider.customization.script.id to empty or return as null.
- If certain attributes are persisted through the onAfter
script, they must be populated with database values in the
scimResource object inside the customized script.
This action is required so that the system can do the following:
- To get the correct scimResource object in onAfter scripts during the PUT and PATCH operation.
- To include the attributes that persisted through the onAfter script in the response back to the client.
Helper functions
The following are some of the helper functions for SCIM customization. These functions enable you to fetch or set different types of information.
| Function | Purpose |
|---|---|
| SCIMProviderCustomization.prototype.getCustomExtensionUrn.call(this, "User"); | Fetch the value of custom extension schema. |
| SCIMProviderCustomization.prototype.getServiceNowExtensionUrn.call(this, "User"); | Fetch the value of the ServiceNow extension schema. |
| SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context); | Fetch the custom schema node from the response. |
| SCIMProviderCustomization.prototype.getServiceNowExtensionNodeValue.call(this, "User", context); | Fetch the ServiceNow schema node from the response |
| SCIMProviderCustomization.prototype.setCustomExtensionNodeValue.call(this, "User", context, customExtensionValue); | Set the custom schema node in the response. |
var customExtensionUrn =
SCIMProviderCustomization.prototype.getCustomExtensionUrn.call(this, "User");
var customExtensionValue =
SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context);
customExtensionValue.age = "18";
SCIMProviderCustomization.prototype.setCustomExtensionNodeValue call(this, "User", context, customExtensionValue);