02/01/2023 04:26 AM
I'm importing users from Azure AD with REST connector. All users in Azure AD have their manager assigned.
On the import of users with REST connector, url https://graph.microsoft.com/v1.0/users?$select=attributes.... returns all attributes selected, but does not return manager information, and if added $expand=manager at the end, it does not work since $expand only works when result is single user (not multiple).
How to retrieve manager from Azure AD and assign it to user in Saviynt using REST connector?
Can it be done with UpdateUserJSON field on the connection? What would be an example for this JSON.
Url through which manager can be retrieved from Azure AD for a single user is https://graph.microsoft.com/v1.0/{{userid}}/manager
Thank you!
Solved! Go to Solution.
02/01/2023 10:33 PM
Please refer to following :
Section "Common Features"
Document
https://docs.saviyntcloud.com/bundle/REST-v2021x/page/Content/Developers-Handbook.htm
Where you can make use of multiple calls :
1 - call1 get all the users
2 - call2 iterate into each user to get the manager info
02/02/2023 01:09 AM
Thanks,
I tried, but gets an error. One difference here is that I'm not importing accounts, but users with UserImportJob (I'm not sure it it makes a difference).
here is JSON:
{
"userParams": {
"connection": "userAuth",
"processingType": "SequentialAndIterative",
"call": {
"call1": {
"callOrder": 0,
"stageNumber": 0,
"connection": "userAuth",
"url": "https://graph.microsoft.com/v1.0/users?(filter and select all columns that are needed)",
"httpMethod": "GET",
"httpHeaders": {
"Authorization": "${access_token}",
"Accept": "application/json",
"consistencyLevel": "eventual"
},
"statusConfig": {
"active": "true",
"inactive": "false"
},
"colsToPropsMap": {
"username": "userPrincipalName~#~char",
"displayname": "displayName~#~char",
"firstname": "givenName~#~char",
"lastname": "surname~#~char",
"country": "country~#~char",
"phonenumber": "mobilePhone~#~char",
"statuskey": "accountEnabled~#~char",
"email": "mail~#~char",
"employeeType": "userType~#~char",
"companyName": "companyName~#~char",
"title": "jobTitle~#~char",
"departmentname": "department~#~char",
"location": "usageLocation~#~char",
"customproperty2": "id~#~char",
"state": "state~#~char",
"customproperty1": "officeLocation~#~char",
"city": "city~#~char",
"phonenumber": "mobilePhone~#~char",
"startdate": "createdDateTime~#~char"
},
"userResponsePath": "value",
"pagination": {
"nextUrl": {
"nextUrlPath": "${(response?.completeResponseMap?.get('@odata.nextLink')==null)? null : response?.completeResponseMap?.get('@odata.nextLink')}"
}
}
},
"call2": {
"callOrder": 1,
"stageNumber": 3,
"connection": "userAuth",
"url": "https://graph.microsoft.com/v1.0/${id}/manager",
"httpMethod": "GET",
"httpHeaders": {
"Authorization": "${access_token}",
"Accept": "application/json"
},
"inputParams": {
"dependentCall": true
},
"listField": "",
"keyField": "id",
"nextApiKeyField": "id",
"colsToPropsMap": {
"owner": "userPrincipalName~#~char",
"customproperty3": "mail~#~char"
},
"userResponsePath": ""
}
}
}
}
and error I get on "User Import via a Connection (UserImportJob)" is
Error Processing Users | Cannot invoke method containsKey() on null object |
Error in getUsersData | Ambiguous method overloading for method java.lang.String#. Cannot resolve which method to invoke for [null] due to overlapping prototypes between: [class [B] [class [C] [class java.lang.String] |
02/02/2023 01:21 AM
For ImportUserJSON following parameter is used to to map user attributes of the target application to user attributes of IGA for user import.
Same details available in the document, please refer to
{
"connection": "userAuth",
" ": "https://{org}/users?api-version=1.6",
"httpMethod": "GET",
"httpHeaders": {
"contentType": "application/x-www-form-urlencoded",
"Authorization": "${access_token}"},
"colsToPropsMap": {
"username": "objectId~#~char",
"status": "accountEnabled~#~char",
"city": city~#~char",
"companyname": "companyName~#~char",
"department": "department~#~char",
"displayname": "displayName~#~char",
"email": "mail~#~char",
"createdon": "created~#~date",
"customproperty12": "#CONST#EndUser~#~char",
"phonenumber": "mobile~#~char",
"firstname": "givenName~#~char",
"lastname": "surname~#~char"},
"errorCode":"400",
"errorCodePath":"errorCode",
"userResponsePath": "results",
"userResponsePath": "value",
"pagination": {
"offset": {
"offsetParam": "Offset",
"batchParam": "Max",
"batchSize": 1000,
"totalCountPath": "total_count"
},
"nextUrl": { "nextUrlPath": "object.userProfile.Link"}
}
}
Support for Multiple API calls
{
"type": "multiCall",
"call": [
{
"name": "call1",
"connection": "acctAuth",
"url": "https://<url>/api/v2/users.json",
"httpMethod": "GET",
"httpHeaders": {
"Content-Type": "application/json",
"Authorization": "${access_token}"
},
"colsToPropsMap": {
"username": "id~#~char",
"customproperty1": "email~#~char"
},
"userResponsePath": "users"
},
{
"name": "call2",
"connection": "acctAuth",
"url": "https://<url>/api/v2/users/${userIdentifier}.json",
"httpMethod": "GET",
"httpHeaders": {
"Authorization": "${access_token}"
},
"colsToPropsMap": {
"username": "user.id~#~char",
"customproperty45": "user.email~#~char"
},
"userResponsePath": ""
}
]
}
02/02/2023 12:45 PM - edited 02/02/2023 01:23 PM
Thanks RakeshMG,
I tried that JSON also but in the second call I cannot extract attribute from first call, logs says its null.
So, in the first call I have "userResponsePath": "value", since response of first API call returns value object with the list of objects that represents users like this.
"value": [
{
"id": "073c5184-121a-4d43-bac1-daff68f87c26",
"userPrincipalName": "suser@domain.com"
},
{
"id": "15600ac9-5475-436e-9a38-2629ac53c6ec",
"userPrincipalName": "firste@domain.com"
},
{
"id": "69af5431-7c5c-477d-af8f-15c33b565c9e",
"userPrincipalName": "bokhan@domain.com"
}
]
}
This works and users are inserted or updated. userPrincipalName from first call is mapped and stored in username on user object. Section of first call is
"colsToPropsMap": {
"username": "userPrincipalName~#~char"
}
Here is the JSON for second call:
{
"name": "call2",
"connection": "userAuth",
"url": "https://graph.microsoft.com/v1.0/users/${userIdentifier}/manager",
"httpMethod": "GET",
"httpHeaders": {
"Authorization": "${access_token}",
"Accept": "application/json"
},
"colsToPropsMap": {
"username": "value.userPrincipalName~#~char",
"owner": "userPrincipalName~#~char",
"customproperty3": "mail~#~char"
},
"userResponsePath": ""
}
So, this call actually gets the manager of user from first call, but since userPrincipalName from first call is not extracted, it does not update the user itself. Logs says "Records missing username" for each user from first response.
02/03/2023 01:54 AM
Resolved!
To get the manager in the second call of REST connector from Azure AD, you need to encode $ sign in the url for graph api call.
It will only evaluate ${userIdentifier} from the first call if there is no other $ signs in the url.
{
"name": "call2",
"connection": "userAuth",
"url": "https://graph.microsoft.com/v1.0/users/${userIdentifier}/?%24expand=manager",
"httpMethod": "GET",
"httpHeaders": {
"Authorization": "${access_token}",
"Accept": "application/json",
"consistencyLevel": "eventual"
},
"colsToPropsMap": {
"username": "userPrincipalName~#~char",
"owner": "manager.userPrincipalName~#~char",
"customproperty3": "manager.displayName~#~char"
},
"userResponsePath": ""
}