Technical Articles
How to Automate User Administration in the Cloud – SAP Best Practices Identity Lifecycle Service (IDLS) for SAP Cloud Identity Services (CIS)
Why you need it
The SAP Cloud Identity Services (CIS) do not provide an option to execute custom logic in case of any event within the Identity Directory Service (IDDS).
The SAP Best Practices Identity Lifecycle Service (IDLS) provides you the power to implement custom logic into the CIS. Based on the event of modification inside the IDDS, the service executes logic you can specify and implement in JavaScript.
Three example use cases:
- Automatic calculation of mail address in the event of a name change
- De-/Activation of identities based on hire and termination data (or any other data available inside the IDDS)
- Automatic assignment of groups based on organisational information like cost center
How it works
- The IDLS is polling the user information from the IDDS frequently (frequency can be defined).
- The IDLS detects modifications within the user data to pile it up in a queue in the Event Mesh service.
- The IDLS executes the custom logic.
- The IDLS writes back the modification into the IDDS.
The Best Practices service comes with a set of predefined JavaScript functions – just like good old SAP IdM – that you can utilize to perform certain operations inside IDDS (like searching for or modifying an entry inside IDDS).
Sample Script
Below you can find a sample script that covers both above-mentioned scenarios: Recalculation of a mail address, including uniqueness check and the assignment of a group according to the users cost center.
function eventTriggered(value, event) {
if (event.getValue() == "Changed") {
if (value instanceof Java.type("com.sap.openapi.idds.model.User")) {
let changesMap = new Map(Object.entries(JSON.parse(changes)));
changesMap.forEach((valueAttr, key) => {
print(`Changes: ${value.getUserName()} : ${key} `);
if (key == 'familyName' || key == 'givenName') {
handleUserNameChanged(value);
}
if (key == 'costCenter') {
addUserToGroupByCC(value);
}
});
utils.patchValues('user', value);
}
}
}
function handleUserNameChanged(user) {
let name = user.getName();
var familyName = name.getFamilyName();
var givenName = name.getGivenName();
var emailList = [];
var email = `${givenName}.${familyName}@company.com`;
email = deleteUmlauts(email);
var index = 1;
while (utils.getValueByEntry("email", email)) {
email = `${givenName}.${familyName}${index}@company.com`;
index++;
}
user.getEmails().forEach(element => {
element.setValue(email);
element.display(email);
element.setPrimary(true);
element.setType(utils.getEmailType('work'));
emailList.push(element);
});
print(emailList);
user.setEmails(emailList);
user.setUserName(email);
}
function addUserToGroupByCC(user) {
if (user.isActive()) {
var listGroups = utils.getGroups();
listGroups.forEach((group) => {
let name = group.getGroupExentsion().getName();
print(`Cost Center Name: ${name}`);
if(name.indexOf("_") > -1) {
let cc_number = name.substring(name.indexOf("_") + 1)
print(`Cost Center Number: ${name}`);
if (cc_number == (user.getEnterpriseUser().getCostCenter())) {
utils.addUserToGroup(user.getId(), group.getId());
}
}
});
}
}
function deleteUmlauts(value) {
value = value.replace(/\u00e4/g, "ae");
value = value.replace(/\u00fc/g, "ue");
value = value.replace(/\u00f6/g, "oe");
value = value.replace(/\u00df/g, "ss");
value = value.replace(/\u00dc/g, "Ue");
value = value.replace(/\u00c4/g, "Ae");
value = value.replace(/\u00d6/g, "Oe");
return value;
}
The function “EventTriggered” is called for every modification the IDSL has detected before. Inside this function the modifications are classified (“Created”,”Changed”,”Deleted”) and the according data to the event are provided (e.g. the modified name). This function is required as it is the main entrance function for the IDSL.
The functions handleUserNameChanged and addUserToGroupByCC are called if name or cost center are modified and perform the according operations. These functions are examples and more of this type can be added by you.
Predefined Script Functions
This is a list of the script functions currently available:
patchValues
- Input Parameters:<entryType>,<JSONEntry>
- Updating the entry in the IDDS
getValueByEntry
- Input Parameters: <searchAttribute>,<searchValue>
- Return Value: Boolean (true if entry was found in the IDDS)
- Search for an entry in IDDS by attribute name and value
addUserToGroup
- Input Parameters: <userScimId>,<groupScimId>
- Adding a user as member of a group inside the IDDS
deleteUserFromGroup
- Input Parameters: <userScimId>,<groupScimId>
- Removing a user as member from a group inside the IDDS
deleteUser
- InputParameters: <userScimId>
- Delete a user form IDDS
deleteGroup
- InputParameters: <groupScimId>
- Delete a group form IDDS
getGroups
- Returning a List of all groups inside the IDDS
Prerequisites
The following BTP Services are required to be available in order to be able to use this SAP Best Practices Service:
- SAP Cloud Identity Services
- SAP Cloud Foundry Runtime Environment
- SAP Event Mesh Service
- SAP Object Store Service
Further Information
If you want to know more about this service and how to deploy it, please get in contact with me directly or send an email to security.consulting@sap.com.
Hello Norman, the mentioned email address dont work 🙂
Hi Carsten, thanks for the hint, fixed it.