We are delighted to share our new EIC Delivery Methodology for efficiently managing Saviynt Implementations and delivering quick time to value. CLICK HERE.

REST connector - get user manager

tgloblek
New Contributor III
New Contributor III

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!

5 REPLIES 5

RakeshMG
Saviynt Employee
Saviynt Employee

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


​Regards

Rakesh M Goudar

tgloblek
New Contributor III
New Contributor III

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 UsersCannot 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]

RakeshMG
Saviynt Employee
Saviynt Employee

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 

RakeshMG_0-1675329674461.png

{
"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": ""
}
]
}


​Regards

Rakesh M Goudar

tgloblek
New Contributor III
New Contributor III

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. 

tgloblek
New Contributor III
New Contributor III

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": ""
}