Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
27,327

Your one-stop shop for everything related to SAP Analytics Cloud SCIM API is here!
An essential blog for those:

  • that have no interest in how the API works, you just want to use it to fulfil a function
  • system administrators, system integrators or developers that need to understand how the API works, behaves and performs

I introduce two new articles:

  • Sample Scripts
  • Best Practices

 

What are the business benefits and use-cases?

For those using the standard user interface to create or manage your users:

 

Automation

The scripts help to eliminate human errors in addition to saving considerable time performing multiple tasks. For example:

  • Creating users and adding them to multiple teams at the time of creation
  • Defining the users’ membership to multiple teams in one go (by either adding, removing or replacing those memberships)
  • Removing a user from all teams without having to first determine which teams the user is a member of. The standard interface doesn’t make this task so easy

In addition to the above, and whilst using your own Identity Provider with ‘automatic user creation’ and ‘user attribute mapping to teams’ do assist with the above tasks, these sample scripts also enable:

Further automation:

  • Eases the administration of users with team-on-team management capabilities (copy team, add or remove a team to or from another etc.)
  • Updating a whole team of users at a time (for example updating all users of a team with a different BI license type or “active” status etc.)
  • Deleting users or a whole team of users at a time
  • Updating the users’ team membership so they receive publications sent to the team before they login (the user may miss a publication since SAML SSO only updates team membership at the time of login and not before)

 

Improved user creation:

  • Enables correct user settings at time of user creation. Users can be created with non-default settings for language, date/time/number formats, saving all your users from changes these settings
  • Common requirement for SAML SSO based on email or on 'custom' and when dynamic user creation is enabled:
    • Enables user creation with the user id of your choice rather than one determined by SAP . This is often needed to enable easier integration with other systems, typically access control security rights based on acquired data models from BW.
    • Enables user creation with a different user id compared to the SAML mapping property (userName). For example, creating a user with userid M_SHAW, but with a saml property M-SHAW.

(the above 2 sub-points are not applicable when provisioning users via the version 2 of the scim API)

 

Automated Administration tasks:

  • Updating users' SAML mapping property ('email' or 'custom'). This can also be helpful for a project changing the SAMLSSO mapping from 'email' to 'custom'
  • Adding users not in a team, into a team
  • Adding users not in a team or a role, into a team
  • Delete users then delete managers avoiding the problem of not being able to delete a user that is a manager of another user
  • Assigning Managers that currently have a BI concurrent session licence to BI named license
  • Assigning a BI concurrent session license to any user that is disabled avoiding an unnecessarily consumption of a ‘named user’ license
  • Changing the BI concurrent session license for all users, to a named user license. Ideal if you're moving away from concurrent licenses.
  • Reassign users of given manager to another
  • Swap a directly assigned role for a team role, so adopting best practice
  • Assign the correct settings for recently created users that currently have default settings
  • Deactivate and delete dormant users based on their lack of login activity - more details (updated October 2024)

 

  • Enables a multitude of life-cycle management use-cases. For example, transporting users and their relationship to teams and roles from one SAP Analytics Cloud Service to another (this just isn’t possible without these samples)
  • SAP Analytics Cloud can transport teams and their relationships to roles and when it does so, it ‘adds’ the relationships. For many life-cycle management use-cases you often don’t want to ‘add’, but either ‘replace’ or simply ‘keep’ the existing relationships of the target. These samples support these other use-cases easing your management of security across your landscape.
  • Service (tenant) migration use-cases when you’re moving or migrating from one SAP Analytics Cloud Service to another, for example migrating from NEO public to CF private. The samples can transport users* with their settings (of language, date/time/number formats etc.), unlike any user export/import provided by SAP Analytics Cloud.

 

Managing user IDs and general troubleshooting

Two new sample scripts, with version 0.9, where introduced:

  • Migrating the user ID from one ID to another (i.e. changing the user ID) (sample 2666 Migrate user ID). This creates a new target user, based off a source user. It copies all the source user properties (roles, teams, etc.) and creates a new target user but with a user ID of your choice. It optionally deletes the source user. This is perfect if some of your users have the wrong user ID (often the case when using dynamic user creation and the SAML SSO mapping is 'email' or 'custom'.)
  • Scan and repair. Yet to be documented, so stay tuned! (sample 2667 Scan and repair). This identifies inconsistencies of  user definitions and identifies mismatches or potential conflicts between users. This is ideal when you may have some users that fail to login, users fail to be updated via the API, or you are trying to change the SAML SSO setup and it fails mid-process. There is an option to repair too. Basically this is a go-to script to help identify any issues with your users.


For those that don’t need the sample scripts because you’re developing your own solution based off the SCIM API, then the best practices have everything and more you could ask for, from session and error management to sizing and performance. This article will dramatically accelerate your adoption and reduce your project risk.

 

Sample Scripts


I've created 64 sample scripts in Postman (called 'Collections' in Postman) that fulfil a whole range of functions related to the Analytics Cloud SCIM API:

 

SAP Analytics Cloud SCIM API Sample Scripts


These scripts allow you to perform a great number of user management operations and cover everything from creating users, updating users, performing team-on-team operations and even transporting users and teams from one SAP Analytics Cloud service to another!

I've designed these scripts to:

  1. be easily consumable (simple .csv files or .json files are needed)
  2. provide very maximum throughput possible (of not only the Analytics Cloud API, but also of Postman)
  3. return a known result



Creating and updating users


There are some 18 scripts to create and update users! Why so many? Some just read a .csv file so that its super easy for you to use. Others need to read a .json file as they need to read an array (of teams for example). There's different ones depending upon what you're doing, for example some are designed for greatest throughput for creating users, others for updating.

I designed these scripts to cover as many use-cases as possible. For example when updating users, the scripts read an 'action' so you can 'add', 'remove', 'replace' or just 'keep' the existing team and role assignment. (the scripts are versatile allowing you to use different actions for teams and roles)

 

creating or updating a user - actions on roles (left) and teams (right)


Updating users by team


Updating user properties requires an update to each user, but I often hear customers wishing to update a whole team of users. So, I provide scripts that reads a team, and then update all members of that team. For example, script 1451 will update the 'Business Intelligence licence type' for all users of a team. You'll find a script for almost every purpose including updating: active status, manager, datatime/number format, language and many more.

 

Team-on-team

I frequently hear of customers wishing to add a team to another team. Whilst this isn't technically possible, it hasn't stopped me using the API to read a team and add all the users of one team to another. Thus, I have scripts that perform this 'team-on-team' operations. With the 'actions' idea taken to act across teams, it means you can even do things like remove a team from another, as well as perform 'set' operations on teams including 'intersect' and 'exclude':

Team-on-team actions (shown is for users, but roles are also possible)


Transporting users and teams

 


You can't really transport a user from one SAP Analytics Cloud service to another. However that hasn't stopped me using the API to read all the properties of a user and either create or update the same user in another Service! It means I have created scripts that basically transport a user, albeit without their personal folder.

 

Relationships transported between SAP Analytics Cloud Services


Not only do I transport the user, but I also transport all the relationships to roles and teams. My transport scripts are highly versatile allowing you to transport whatever relationship you'd like to or not. I've extended the 'actions' concept from earlier allowing you to perform 'add', 'remove', 'replace' or just 'keep' either the existing teams or roles as you please! This in turn means there are now more life-cycle use-cases supported (as the Service only performs an 'add' operation when it comes to transporting relationships)

And because I'm using the API, you can use my scripts to transport between NEO and Cloud Foundry (or any combination)

For all my sample scripts, if the team doesn't exist, it will create one for you!

 

Getting started

 


These samples, provided 'as is', are available to download from today. Getting started couldn't be easier! It will take novice no more than 40 minutes.

I provide a comprehensive User Guide, an article and a webinar to introduce it all.


Best Practices built-in

The scripts are designed with all the best practices and means you don't need to worry about sessions or error management. That's all taken care for you:

  1. Errors from the API are handled and automatic re-attempts will be made
  2. This includes errors that are exceptionally rare


And the very maximum performance is provided. They are highly intelligent scripts, for example they will:

  1. only perform an update if one is actually needed
  2. determine the 'net' change to a team, and only make the necessary changes
  3. batch requests together so to optimise team updates
  4. they even include automatic and dynamic self-tuning for updating teams by batching and chunking updates!


Demo

If you'd like to cut to the chase and see the scripts in action - preview or download

 

Best Practices


For those that need to understand more about the API then my article on the Best Practices covers everything!

My article is almost a training course on the API and provides practice examples covering things like session management and the basic things like creating or updating users and teams.

 

Managing errors on a create update workflow


I dive into the detail of combining the 'create' and 'update' workflow to help illustrate where care is needed around the API. For example, how to recover from a 409 or a 502 response. I answer the questions like "is it safe to resubmit a POST /Users (create user)"?

I've done all the thinking for you, so you don't need to necessarily work it out for yourself or learn from your mistakes. I've covered the lot including helping you to identify when there might be a error, even very rare errors, and how to resolve them to a known result.

I take a very close look at the different workflows to achieve a particular task and share with you how to get the very maximum throughput possible. For example:

Activity or action:Workflow (not optimised)Optimised workflow
Creating 500 users and adding each user into 3 teams1 hour 15 mins20 mins
Updating 500 users25 mins 4 seconds10 mins 13 secs
Updating 500 users and removing each user from 3 teams, and adding each user into 3 different teams3 hours 37 mins27 mins
Adding 500 users into a team13 minutes13 seconds


Updating teams can be particularly challenging when the membership is over 5000 and the total number of users registered is over 10,000. I share with you how to achieve the maximum throughput and reliability for adding 32767 users into a team on a service with 80000 users registered in it:


No one wants a surprise and so even if you've already implemented a solution using the API, you should find my article useful especially as user volumes increase

 

Performance

Both my articles provide comprehensive information.

Best Practices article provides, for every endpoint the performance of the API for both an empty service and one with 80000 users registered in it. Here's one example:


 

And the samples article provides information on the throughput of the script, including its overhead expressed as a percentage and shown in (brackets). Here's one example:



Articles & downloads


Your complete list of resources is summarised here:

Sample Scripts

 

Sample Scripts Presentation
(version 1.0.2 - October 2021)
Wiki
Preview PPT
Download PPT
Webinar 1h 38 mins
.mp4 Preview
.mp4 Download
Sample Scripts Demo.mp4 Preview
.mp4 Download
 
Sample Scripts User Guide
(version 0.9 - October 2024)
.pdf Download
.pdf Preview
 
Samples (the code)
(version 0.9 - October 2024)
Github (zip download)Change log


 

Best Practices

 

Best Practices Presentation
(version 1.0.2 - August 2021)
Wiki
Preview PPT
Download PPT
Webinar 1h 50mins
.mp4 Preview
.mp4 Download


 

Blog posts referencing this blog post

  1. SAP Analytics Cloud – SAP SuccessFactors Import Model Security Use Case by m.ezzat
  2. Getting started with SAP Analytics Cloud, Embedded Edition (BTP service) by adugarov
  3. SAP Analytics Cloud Embedded Edition | SAP Business Technology Platform | Hands-on Video Tutorials by denys.kempen
  4. SAP Analytics Cloud User and Team Provisioning API | Hands-on Video Tutorials by denys.kempen
  5. Making manually created SAP Analytics Cloud Teams readable by the SCIM API by matthew.shaw
  6. Sample Scripts Update v0.6 – what’s new by matthew.shaw
  7. Removing Concurrent Session licenses and other updates around managing licenses with roles and teams by matthew.shaw
  8. SAP Analytics Cloud Embedded Edition Best Practices & Sample Scripts for Administration by matthew.shaw
  9. Sample Scripts Update v0.7 – what’s new by matthew.shaw
  10. SAP Analytics Cloud SCIM API version 1 and 2 high-level comparison by matthew.shaw
  11. SAP Analytics Cloud - Managing dormant users by matthew.shaw
  12. Sample Scripts Update v0.8 – what’s new by matthew.shaw


 

Feedback


I've invested a great deal of time and effort into these materials and so your feedback is very welcome and will help judge if I should continue to create these kind of resources

Please do:

  • Comment if you use these resources in anyway (or if you're shy, just hit the like button!)
  • Share which sample scripts you've used. Other customers would love to hear if you've used the scripts. It will give them a sense of how reliable they are! 😉
  • Share your experience of adopting the best practices, for example by how much did you improve your scripts' performance, or did you resolve a rare error?
  • Share how much time you saved because of these resources, would you had been as successfully without them?



Before posting any questions please:

  • Do read the contents of both articles (or watch the videos). There's a massive amount of content in each. I appreciate you may not have the time to read or watch them all. If you're looking for a quick answer and don't have the time, feel free to post a question to the community rather than here, it will help keep the number of questions here reduced and it will help others find answers easier (than searching this blogs' Q and A). You can always '@tag' me in your post so I get a notification, and you can always post a link to your question from a comment to this blog if you think that might help others.
  • If you've got a question about the sample scripts, make sure you've read the User Guide! Some of the sample scripts are highly versatile and support a great number of use-cases, so I can imagine a few good discussions here about that.


Feel free to follow this blog post for updates and also follow the wiki pages for updates there too. I'll update the version numbers in this blog post when there's one.

Many thanks

Matthew Shaw @MattShaw_on_BI
My other blog posts

 

112 Comments
mfoeken
Active Contributor
0 Kudos
Hi Matthew,

Ok, great. And as always we can rely on you sharing sample scripts, right ;-)?

Kind regards,

Martijn van Foeken | Interdobs
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert

Hi Martijn,

So no special API request needed, the regular DELETE method on a user endpoint will do the job. Existing sample scripts that delete users (by user, but or by team of users) requires no updates, they all benefit from the backend API improvements. Cool hey! All the best Matthew

deepakkg86
Participant
Hi Matthew,

We are facing issues while creating/updating accounts for SAC from SailPoint using Java code

Here are our observations:

  1. Account Operations worked fine when tried from Postman adding x-csrf-token value to header. X-csrf-token is taken from response headers of Get all users API (GET https://<Subaccount>.hcs.cloud.sap/api/v1/scim/Users?size=1&page=1)


Here is the URL used for account creation which works fine using Postman

POST https://<Subaccount>.hcs.cloud.sap/api/v1/scim/Users

 

2.   We implemented the similar logic through java code form SailPoint, it failed with 403 Forbidden error as below.

 

{

"timestamp": "2022-12-14T12:35:11.731+00:00",

"status": 403,

"error": "Forbidden",

"path": "/api/v1/scim/Users"

}

Seems x-csrf-token which we are generating via Sailpoint is not working and hence 403 error is coming - Can you please advice how we can make it working ?

As of now, we are trying to include cookies for JSESSIONID=<sessionId>; __VCAP_ID__=<vcapid>  in the modify operation by taking the values from get all users API. It gave the similar error as of now, which we are debugging still.
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Hello Deepak

The 403 will be because the x-csrf-token is not valid for the related accesstoken session. It means you can't just use an x-csrf-token from another session and re-use. The x-csrf-token needs to 'fetch'ed using a GET request. You can use the /api/v1/scim/Users as you've mentioned and is in the documentation, though I prefer /api/v1/csrf as its much quicker and has no responsebody.

I'm guessing this is what's wrong with your code. Let us know, Matthew
deepakkg86
Participant
0 Kudos
Thanks Matthew, it worked.

We encountered new issue now - In SAC to enable  SSO we are using Custom SAML User Mapping as our email address in IDP are not case sensitive.

While using create user API - I dont see any option of passing Custom SAML user mapping attribute - Can you please advice how we can update this using API ?

 

Regards

Deepak
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Deepak

For the short term you can't (when SAML SSO=email or SAML SSO=custom) to create a user with a different userName (SAML mapping) property than the userid. My scripts provide a workaround to this problem by creating the user with the wrong email or wrong custom id, before then updating it to the right one.

My user guide has it all, but I introduced this support for my samples in https://blogs.sap.com/2022/05/12/sap-analytics-cloud-user-and-team-provisioning-scim-api-sample-scri...

Having said all this, I would advise against using email as the SAML mapping. I need to write a blog on this whole topic, as there's a lot to this. But in a very few words: userID is the best way to set SAML mapping. Just because the user may authenticate with their email doesn't mean the SAML mapping needs to be email, it really doesn't. Using email or custom means the userid generated (unless you're using my scripts) will create the user with a derived userid and not necessarily the one you want. The userid is seen within the user interface and is used for data access restrictions, so its often needed to be something you tell SAC, not SAC tells you, it should be!

My samples also include scripts that update the SAML mapping property and you can identify the user by userid, email or existing saml mapping (which would also be their email if the email is the SAML mapping property).

The next version of the SCIM API for SAC will help with these issues, and I hope to write a blog soon on that too!

Hope this helps

Matthew
MarcSchweizer
Explorer
Dear Matthew,

 

thank you for this article.

Is there a way to avoid the limitation of the results for the sapanalytics.cloud/api/v1/scim/Users API.

We always get just 50 Results. But we do have more users created.

i'm happy to hear from you.

best regards

Marc
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Hello Marc

Please take a look at sample script '665-All_U-Uc-Uu-Oarrieei-Fj-Es-AdminToolKit'

This very versatile script creates teams of users by scanning all users. It can create a team of 'all' the users, or users that fulfil certain criteria. It can not only create teams that match these criteria, but it can perform 'set' operations on existing teams, like removing users from a team that have a certain criteria. My samples provide data files that create these teams:

  • AdminToolKit_All_Users

  • AdminToolKit_Users_Created_Recently

  • AdminToolKit_Users_With_BI_Concurrent_License

  • AdminToolKit_Users_With_BI_Named_User_License

  • AdminToolKit_Users_With_A_Manager.

  • AdminToolKit_Users_With_Manager_MANAGERID

  • AdminToolKit_Users_Without_A_Manager

  • AdminToolKit_Users_That_Are_Managers

  • AdminToolKit_Users_That_Are_Enabled

  • AdminToolKit_Users_That_Are_Disabled

  • AdminToolKit_Users_With_UserID_Ending__1

  • AdminToolKit_Users_With_SAP_email

  • AdminToolKit_Users_Without_SAP_email

  • AdminToolKit_Users_Without_a_Role_and_Without_a_Team

  • AdminToolKit_Users_Without_a_Team

  • AdminToolKit_Users_Without_a_Role

  • AdminToolKit_Users_With_Directly_Assigned_BIAdmin_Role

  • AdminToolKit_Users_With_Default_Settings

  • AdminToolKit_Users_Created_Over_A_Year_Ago

  • AdminToolKit_Users_That_Are_Managers_With_BI_Concurrent_License

  • AdminToolKit_Users_That_Are_Disabled_With_BI_Named_User_License

  • AdminToolKit_Users_In_Managment_Structure

  • AdminToolKit_Users_Not_In_Managment_Structure

  • AdminToolKit_Users_Without_Default_Settings


The versatility shines when you combine this with other scripts into what I call 'scenarios', and allows to complete more end-to-end tasks. I provide a few out-of-the-box for you:

  • D01 – Delete users then delete managers

  • L01 – Managers with BIconcurrent to BInamed license

  • L02 – Disabled users to BIconcurrent license

  • L03 – Convert all BIconcurrent to BInamed license

  • M01 – Reassign users of given manager to another

  • R01- Swap directly assigned role for a team role

  • S01 – Assign settings for recently created with default settings

  • S02 – Assign settings concurrent lic for recently created w default settings

  • T01 – Transport Managers then Users


It might be your requirement is already met by these. Check-out my update for more on the AdminToolKit and Scenarios here: https://blogs.sap.com/2021/11/08/sap-analytics-cloud-user-and-team-provisioning-scim-api-sample-scri...

I do plan to add a few more enhancements to the AdminToolKit soon, so stay tuned and click 'follow'!

Now, that was a long diversion from your question! So lets get to that...

...The API supports paging of users. You can ask for 200 users at a time just by using the startIndex and count parameters: https://{{SACserviceFQDN}}/api/v1/scim/Users/?startIndex={{StartUserIndex}}&count={{ReadUsersIndexSize}}

Check-out the sample 665 'Tests' and you'll see in this in the code:



const readbody                          = JSON.parse(responseBody);
const total_users_in_this_SAC_service   = readbody.totalResults;
const users_this_page                   = readbody.Resources.length;





This will help you determine if you've read all the users or not, and if you need to get another page.



Hope this helps

Matthew

deepakkg86
Participant
0 Kudos
Hi Matthew,

Many thanks for your revert, we were able to implement your suggested logic to use wrong email address and then update later with correct one.

One question - You mentioned that we shall always use user ID as SAML attribute, In our case we are using Azure AD for authentication and using user ID wont work as in our setup we dont have SAMACCOUNTNAME attribute in Azure AD - We can only use email address or employee number.

Please advice, if there is a way to do authentication basis of email address and also keeping SAML attribute as "User ID"

 

Regards

Deepak Gupta
MarcSchweizer
Explorer
0 Kudos
Thank You Matthew !

it works, well !
deepakkg86
Participant
0 Kudos
matthew.shaw Request your feedback here, appreciate your help as always.
deepakkg86
Participant
0 Kudos

mattshaw @MattShaw_on_BI We checked with SAP and tested API end points - api/v1/scim2/Users - Seems new end points are also not enabling us to assign a team directly to user account.

/scim2/Users/<ID> | SAP Help Portal

Any feedback as how I can make it work ?

 

Regards

Deepak

Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Deepak,

Which method are you using POST or PUT or PATCH please?

The thing with the v2 is you need to specify the UUID of the team, not the "teamID" we use for v1.

V1 you specify the teamID (or team name, same thing), V2 you specify the team UUID.

Thanks, Matthew
Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos

Thank you Matthew, great blog, very helpful!

Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Matthew, is there any plan to publish another collection deck for SCIM2?

Many thanks,

Wu
deepakkg86
Participant
0 Kudos
Thanks for your revert mattshaw @MattShaw_on_BI

I tried using both Put/Patch method on Users end point for assigning team - But didnt worked.

But when i use SCIM2 end point for assigning team to user via Teams end point - it works as same with V1 API end point.

 
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Dongxue

Many thanks for your feedback. Yes. I do plan to update my samples for the v2 of the SAP Analytics Cloud SCIM (v1 was already SCIM 2.0 compliant). Stay tuned! 😉

All the best, Matthew
Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Matthew,

Appreciate your reply! Looking forwards to and will keep following your updates 😊

All the best, Wu Dongxue
franziskusheep
Discoverer
0 Kudos

Hello,

I am trying to build up an teste scenario and hope someone can help me at the point i am currently stuck:
Within the coding, the result written into the variable "response" is empty. Therefore, its running into a runtime error because coding tries to access the field symbol.

      target =  |https://Firma.eu10.hcs.cloud.sap/api/v1/scim/Users/"?count=50&startIndex=   {     lv_index }|.
http_method = 'GET'.

gv_http_client->send( EXCEPTIONS http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
http_invalid_timeout = 4
OTHERS = 5 ).

IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

gv_http_client->receive( EXCEPTIONS http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).

response_data = gv_http_client->response->get_cdata( ).

 

The received Response Code is 200, but it seems as the response is empty.
I also tried to send a get request via postman to https://Firma.eu10.hcs.cloud.sap/api/v1/scim/Users/"?count=50&startIndex=   {  1  }|, but also get only an empty result. Does someone see why don't I get a list of user back here?

Kind regards,
FH

Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Looks like the request isn't valid:

https://Firma.eu10.hcs.cloud.sap/api/v1/scim/Users/"?count=50&startIndex=   {  1  }|

better would be: https://Firma.eu10.hcs.cloud.sap/api/v1/scim/Users/?count=50&startIndex=1

The sample script 665 uses the /Users/ endpoint and would be a great starting point to see a working example, then go from there.

Hope this helps, Matthew
franziskusheep
Discoverer
0 Kudos

Hello Matthew, thank you for your answer. I tested also that link. Response was 200 (with authorisation ok). It seems for me as this is okay. Just the result ist as following:

 

<html>

<head>
<link rel="shortcut icon" href="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
<script>
document.cookie="fragmentAfterLogin="+encodeURIComponent(location.hash)+";path=/;Secure;SameSite=None;";document.cookie="locationAfterLogin="+encodeURIComponent(location.href.split('#')[0].split(location.host)[1])+";path=/;Secure;SameSite=None;";document.cookie="signature=NWmnEXGGJ7hdkeQKH%2FoGMzb3Zxk%3D;path=/;Secure;SameSite=None;";location="https://companyname-1.authentication.eu10.hana.ondemand.com/oauth/authorize?response_type=code&client_id=sb-approuter-sac-saceu10!t3650&redirect_uri=https%3A%2F%2Fs-companyname-1.eu10.hcs.cloud.sap%2Fsso%2Flogin%2Fcallback"
</script>
</head>

</html>

 

It is not even JSON (I explicitly requested Content-type: application/json). For me, it looks as there as an additional Authorisation step before getting the requested JSON response. Have you ever encountered that problem?

Kind regards,
FH

Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello FH

So tricky to give you the root cause because I can't see your full request, nor if your authorisation request beforehand was really valid.

My guess is your authorisation request isn't actually valid. A 200 response when on NEO is possible if your accesstoken was empty for example. A 200 response on Cloud Foundry will always be valid, but you may not be reusing the access token correctly, or you've not got a valid csrf token beforehand either. Your request is probably badly formed too, but I can't say without viewing all the previous requests and their respective headers, body etc.

I urge you to use the sample script to see a working solution and then determine what's different between yours and the working sample.

Sorry I can't debug your code, one reason why samples are handy

All the best Matthew

 
former_member849935
Discoverer
0 Kudos
Hello Matthew,

First of all, Thank you for such an informative blog. Its very helpful.

I had a question on the PATCH capability of the SCIM API for SAP Analytics Cloud.

As per documentation , it is available https://help.sap.com/docs/SAP_ANALYTICS_CLOUD/14cac91febef464dbb1efce20e3f1613/6e4a269898b1416588365...

But i am not able to get it to work. Whatever information I pass in the body, the system returns get 400 Bad Request: Request is Unparsable.

Is there any sample documentation for Patch Requests to update user profile data / Update team Team/Role membership of a user?

Looking forward for a reply. Thanks

Regards

Arjun
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Arjun,

Many thanks for your feedback. I'm pleased the resources I've created and shared are helpful.

However, I can also see, that they need enhancing so to demonstrate the new PATCH request that was introduced in Feb2023 (Q1 QRC).

Rest assured, I have this in my list of things to do. For the meantime, you'll need to rely on the documentation. The important this to remember when using scim2 is everything is done on UUID's, not user IDs or Team IDs, otherwise you'll get an 400 response status.

All the best, Matthew
Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos

Please ignore my previous question 😁. Found the answer

Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
No worries.. stay tuned for a blog from me about changing license consumption that will be possible in a later release of SAP Analytics Cloud. Coming soon! 😉
Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Matthew, it is so kind of you and you are supportive all the time ❤️. Sure I will keep following
cgueler
Explorer
0 Kudos
Hello Matthew,

we use the propagated API of SAC called SCIM for creating and updating users in SAC. One of the parameters we do adress is a parameter for setting the license type of the SAC-User. By default a user created on SAC does get the license type "Business Intelligence".

But with our script , using the SCIM API we do override the value to "Concurrent - Business Intelligence", by setting the parameters as follows:    isConcurrent: true.

This is still implemented and in the activity log I can see , that the Parameter   IS_CONCURRENT  does get the value 1 .
But the problem is, that the license type of the newly created user is the SAP default "Business Intelligence".

 

I think, that there is a error in the API SCIM, when setting the license type by the above mentioned parameter.

The API worked without wrong behaviour until  minimum 11 of may 2023, but minimum since 15 of may 2023 this described wrong behaviour occurs. So our users are running out of license.

Best regards
Cengiz
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Cengiz

I'm out of the office on leave this week, but sounds like a defect to me. Please reproduce the issue with my sample scripts and then log an incident with SAP support. SAP support would love to see this issue reproduced with my samples, just share the sample script number, the data file, and your postman environment exported as a file, with SAP support.

I confirm you should be able to create new users with isConcurrent set to false.

Many thanks Matthew
Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi, Matthew.

This is the most active blog I have followed and I love the interaction below your blogs. I have a customer who has set up the SAC SSO, user mapping, role SAML mapping, and team SAML mapping. In this case, the SAC user attribute is always synchronized with the Azure IDP. And we have a question of overwriting: Do you know which modification method can overwrite the User attributes or Team assignment against the SAML synchronization?

Many thanks, Wu Dongxue

Matthew_Shaw
Product and Topic Expert
Product and Topic Expert

Hi Wu,

Many thanks for your feedback 🙂

I'm not entirely sure I've understood the question, but here goes...

... you are mapping attributes from SAML into SAP Analytics Cloud but you want to change what attributes are mapped so you can change them? (I think this is your question).

 

I hope this diagram I've just created will help. You can see the 'security-users' screen and it shows a 'link' icon for all the attributes that are mapped.

In my example, the email address is the property the users are identified with and you can see that by the icon on that column. If you had 'USERID' or 'CUSTOM' then that icon will be on a different column and it will match what is set in the 'menu-system-administration-Security-SAML SSO-Step 3-User Attribute'. (If you are using 'CUSTOM' then another column 'SAML MAPPING' will be shown in the menu-security-users screen).

The thing you are mapping users on, in my case email, is a property you can edit it, if and only if, its email or custom. If its USERID, then you can't edit that because USERIDs are editable.

The other things you are mapping 'First Name', 'Last Name', 'Display Name' are, by default, not editable because these are mapped from your custom IdP. That button (1) 'Map SAML User Properties' enables you to edit what is mapped, or not.

If you open that dialogue to show the 'Property Map Definitions', you can optionally delete any or all of these mappings. In my example, I've deleted the 'displayName' mapping (2) (3) and I then pressed save (4).

As the 'Display Name' is now not mapped, the 'link' icon next to the column is removed and I can also edit this value for a user unlike before (5). I can always re-map the attribute back, after I've made an ah-hoc change if I wanted to.

There's recently been a change to what can be stored in the 'Display Name' and it might mean this value isn't updated. Basically characters  < and > are now not allowed. Though there's a small bug when comma (,) and brackets and dot (.) and at sign (@) are also not allowed, but that should be resolved soon. Product Support are best to advise for your service as it depends!

Does this help?

Matthew

Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Matthew,

Very much appreciate the clear explanation. I will link your answer directly to my customer. 💙

Many thanks, Wu
nttmat1
Explorer
0 Kudos
Hi,

Thanks a lot for the blog post, it sure helped me a lot!

However I have a question, in Script Sample 001 Step 2 you get a "totalResult" with the total amount of users in the system.
Is there somehow possible to get a list of the users that has been logged in for the past couple of months? Does the API contain this information, and how can it be put to use?

 

And in SAC the OAuth token lifetime is automatically set to 720 hours, is it possible to extend it?

Once again many thanks!
Cheers
Mattias
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Hello Mattias

Thanks for your feedback.

The /activities endpoint enables you to see who logged on and when. This isn't part of the SCIM API but a separate one. For this, your best starting point is my article, which automates the activity log download via a command-line interface. I've done all the hard work for you, so you don't need to work out all the slightly weird quirks and issues when using that API. I've done it all for you.

I've coded almost precisely what you're after in a new version of the sample 665 AdminToolKit. I've yet to finalise and publish it, but it will enable you to add users to a team that have (or haven't) logged on in the last X days (or have only logged on X times). Once in a team, you can do other things like delete the users or remove other teams from the user, so they can't do anything if they did log on. The updated version will also work out if the user has personal content. I hope to publish the updated sample soon, but I think that will be in early August. So stay tuned for updates!

There is no API or supported means to automate the deactivation or re-activation of a user.

The lifetime of the OAuth token is limited, and I don't believe it can be increased; you just have to get another one. I guess this must be a security requirement. All my sample scripts automatically get a new token if the existing one expires. When using my samples, you don't need to worry about this.

Hope this helps. All the best, Matthew
nttmat1
Explorer
Hi Matthew,

Thanks for the quick response.

You're absolutely right, what I'm after is to remove users that haven't logged in for x amount days/months.
I then want to schedule the Postman "Run" so the users will automatically be removed each week/month.

Looking forward to the updated AdminToolKit.

Regards
Mattias
abhisheksingh2
Explorer
0 Kudos
Hi Matthew,

I am trying to use sample 402-U-U-Ua-Fcj-Es-Update User Active status to deactivate access of few users from a csv file. The collection runs without any problem but the users are not getting disabled for some reason in SAC portal. Any Idea where am i making a mistake.
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello

Sorry for this quick reply (on annual leave) but your question is simple.

Please visit https://blogs.sap.com/2023/07/05/sap-analytics-cloud-changes-with-managing-licenses-q3-2023/ and https://blogs.sap.com/2020/03/10/sap-analytics-cloud-managing-licenses-with-roles-and-teams/ for an faq on this exact question. I will be updating the user guide for these samples to reflect the changes in the API later.

Many thanks Matthew

abhisheksingh2
Explorer
0 Kudos
Many Thanks for prompt reply.

So as I understand from those blogs, calling API is no longer an option for mass user status update. I've exported the user list but for some reason the field IS_USER_DEACTIVATED is blank for many users. I'm bit sceptical about filling these blanks with TRUE/FALSE and then importing file back directly in the production tenant.
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello, don't worry if it's blank, it's just using the default value of FALSE. Perhaps not so obvious, you can delete all the rows in the exported file, leaving only the rows you want to change. Hope this helps, Matthew
nttmat1
Explorer
0 Kudos
Hi again Matthew,

Do you have an ETA on the new Admintoolkit? Just curious 🙂

Thanks, Mattias
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert

Hi Mattias

I'm so very keen to get this out ASAP. I've just finished a bit more testing and it seems pretty good now.

Whilst it will be a little while until I have written and updated the user guide I thought I'd share a 'BETA' version of this new sample collection.

  1. Download it now from GitHub
  2. Import the new '665 AdminToolKit' collection into Postman App
  3. Re-use an existing environment, BUT you might need to create a new OAuth client inside SAP Analytics Cloud. Why? Because this new update uses more than just the SCIM API 'service'. It also uses the 'Activities' and 'Story Listing'. So, if your existing OAuth client doesn't have these, you'll need to create a new one, with these services. It means the OAuth needs 3 services: SCIM, Activities and StoryListing. Once it has these 3, be sure to update your username/password client/secret inside your Postman Environment. (I will later create a 'test' to validate it, but not got the time for that now).
  4. Run any of the sample data files. You'll find one that does them all!

A few bits of info to share until I write it up properly:

  • It uses the SCIMv2 API to create teams, and this means the teams it creates will no longer be created with a team folder. Instead, any teams are created without a team folder.
  • There are a good number of new 'tests' and the 'master template' data file has them all. However, with so many it was annoying to list them all. So almost all the fields are now optional, only 3 fields in the data file are mandatory: file_team, file_team_displayname and file_users_action. The sample data files provide great examples of what you can now omit which makes the files so much easier to read and use.

 

The new fields and conditions you can set are:

"file_action_users_created_recently": false,
"file_users_created_recently_in_days": 8,


"file_action_users_created_more_than_days_ago": false,
"file_users_created_more_than_days": 30,


"file_action_users_with_most_recent_login_at_least_days_ago": true,
"file_users_with_with_most_recent_login_at_least_days": 30,


"file_action_users_with_most_recent_login_within_last_days": true,
"file_users_with_with_most_recent_login_within_last_days": 7,


"file_action_users_with_fewer_logins_than": false,
"file_users_with_fewer_logins_than": 10,


"file_action_users_with_greater_logins_than": false,
"file_users_with_greater_logins_than": 100,


"file_action_users_with_fewer_logins_within_last_days": false,
"file_action_users_with_greater_logins_within_last_days": false,


"file_users_with_logins_within_last_days": 7,


"file_action_users_with_private_folder_content": false,
"file_action_users_without_private_folder_content": false,


"file_action_users_that_created_public_content": false,
"file_action_users_that_did_not_create_public_content": false

 

I need to write this up properly, but in short, these should explain themselves quite well. However, a few notes:

  • if "file_action_users_with_fewer_logins_within_last_days" or "file_action_users_with_greater_logins_within_last_days" is true, then the value "file_users_with_logins_within_last_days" is used as the test for the tests "file_action_users_with_fewer_logins_than" and "file_action_users_with_greater_logins_than"

As you may expect, I've put a lot of thought into this, and these parameters allow for a great number of complex use cases, that actually are best explained and described by the sample data files. But to give you an idea, you can do things like: users that have not logged-in in the last 30 days, have 2 or fewer logins within the last 90 days, and were created over 30 days ago. You can then go on and make a more complex set of users, such as filtering out users that have public or private content.

The sample data file includes 'dormant' users:

  • 665 sample - 33 - AdminToolKit_Users_Dormant_A__Created_3_Months_No_Recent_Login_Fewer_Than_3_Logins_Last_3_Months
  • 665 sample - 34 - AdminToolKit_Users_Dormant_B__Dormant_A_Plus_No_Private_Folder_Content
  • 665 sample - 35 - AdminToolKit_Users_Dormant_C__Dormant_B_Plus_No_Public_Folder_Content
  • 665 sample - 36 - AdminToolKit_Users_Dormant_D__Dormant_C_Plus_Are_Not_Managers
  • 665 sample - 37 - AdminToolKit_Users_Dormant_E__Dormant_D_Plus_Are_Activated
  • 665 sample - 38 - AdminToolKit_Users_Dormant_F__Dormant_E_Plus_Are_Named_Licensed

You'll find the description in each of these data files provides a good summary of what they do.

It means, most can use re-use any one of these 'Domant' User sets and you'll be good to go. I've tried to do all the hard work and thinking so you don't need to.

file_action_users_that_created_public_content

When Public content is identified, it's only stories, applications, digital boardrooms, templates and insights. Sadly the API doesn't allow to models or other object types at the moment. This setting is handy, because it will identify users that created public content and could be the owner of such content. The biggest problem though, is that models are not identified.

file_action_users_with_private_folder_content

Users with Private content are identified by some logic that's not very obvious! There is no API that allows us to get the list of content from a user's personal folder.

  • So I return all the resources from the repository (but this is limited as mentioned to only stories, applications, digital boardrooms, templates and insights, but it also gets back folders)
  • Then I look at the path of that resource, not the property of the resource, there is no property that says this is public or private content, or who is the owner of it.
  • From the path, I determine if it's a personal folder or not by the top folder name. If the top folder is either 'Users' or 'WORKSPACE', then I grab the username from its subfolder. For example, I get ADMIN from '/Users/ADMIN Private' and '/WORKSPACE/Users/ADMIN Private'. It means this isn't foul proof and it might be some language or translation issues may exist. Feedback welcome! 😉

Login Activity

I use the activities API to query the number and last time users log in. It means this only works if the activities exist and aren't deleted. I test to check the oldest activity timestamp and abort the script if their entry is too recent for the test you want to run. In summary, don't delete any of these activity logs and for this sample script, it uses only LOGIN activities. For more on the activities log check out my other blog.

Until I've written it up, I may not be able to help much more, but hope these brief notes will help you and others with the updated version. I'd love to hear if you find a bug or some improvement. Just comment back here and I'll take a look.

I've got some other tasks to do before I can refocus on the documentation for this, but hope to get something out in September now. Sorry for the delay.

 

[update] Sorry forgot to mention the obvious. Once you have these teams of users created, you can then run another sample script to delete them or remove those users of that team from other teams etc. It should help manage the lifecycle of your users and in particular, help identify the users that are safe (or safer) to delete. Remember there is NO API to automatically deactivate a user. For more on the license topic and deactivating check out my updated blog 

All the very best

Matthew

nttmat1
Explorer
0 Kudos
Hi again Matthew,

 

Thanks a lot, will be digging deep into this ASAP.

Do you have any idea why the new Beta version Samples doesn't work to import into Postman? I get an error telling me it's "wrong format".

Thanks again,

Mattias
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Hi Mattias

Just double check you are trying to import the collection, not any of the sample data file please. There is just 1 collection to import, ie there is only 1 collection file in that beta folder amongst loads of sample data files. Regards Matthew
nttmat1
Explorer
0 Kudos
Hi again Matthew,

I'm reaching out with another question. 🙂

I've been experimenting with the scripts and have attempted to combine them.

I've created three teams:

- Team A: Users that has not logged in for the past 90 days.

- Team B: Users with private content.

- Team C: Users that has not logged in for past 90 days AND have private content.

My intention for Team C is for it to represent the intersection of Team A and Team B, functioning as an "AND" combination. However, it seems to add all users from both teams, using the two conditions as if they were linked by an "OR" operator (in database terms, if that analogy holds).

Here's the script I've been using:
[
{
"file_team": "MI_No_Recent_Login_with_private_content",
"file_team_displayname": "Users who have not logged in within the last 90 days and have private content",
"file_users_action": "replace",
"file_action_users_with_most_recent_login_at_least_days_ago": true,
"file_users_with_with_most_recent_login_at_least_days": 90,
"file_action_users_with_private_folder_content": true
}
]

Maybe I could create some sort of logic to remove users that is also in team B from team C, after I've done all the above.
But I’m thinking I might want to have more than two conditions in another team going forward. So it would save a lot of time and effort just being able to have it in the same script.

Could you shed some light on whether this behavior is intentional or if it can be modified? Have you encountered and resolved something similar before?

Once more, I truly appreciate all your help.

Best regards,
Mattias
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Mattias

I presume you managed to import the collection okay now.

As mentioned in my comment above, there are many sample collections already available that combine these kinds of conditions. For what you want, this one would be ideal (665 sample - 34 - AdminToolKit_Users_Dormant_B__Dormant_A_Plus_No_Private_Folder_Content)

The reason why you're experiencing an 'OR' between the statements is because you've not set them to be an 'AND'. This is explained in detail in my user guide. It's the field: file_multiple_action_users_operator_is_AND.

My user guide explains when and where the AND can be used. It can't be used with the 'users_that_are_managers', which is why when we need to exclude users that are managers, we perform an invert and OR the opposite since "X and Y = NOT( X or Y )". An example data file is provided.

 

There's no need to create 2 different teams and then do logic on them, since my AdminToolKit script supports this kind of thing in a single pass. If you want to combine teams (add, remove, replace, intersect, exclude) then you can with sample script 653-T-Uc-Utr-Oarrkie-Fcj-Es-Teams on Teams. This is explained in detail in my user guide, but as I mentioned, there's no need to do that for this use case.

 

[update 1Sep2023: Forgot to mention, perhaps the obvious. You can just add another entry into the data file to update the same or a different team. The data file samples I provide all use the 'replace' action, but as my user guide explains, there are many more that allow complex set operations and includes: add, remove, replace, intersect, exclude, excludeall and invert. See the guide for more info please!  One of my sample data file shows multiple entries and basically combines all the samples into one]

 

Kind regards, Matthew

Wu-Dongxue
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hello Matthew.

I met one problem when integrating SCIM2 PUT a request with BW using ABAP. I got the error as:

{"schemas":["urn:ietf:params:scim:api:messages:2.0:Error"],"status":"500","scimType":"","detail":"An internal error occurred."}

When I tested with Postman, everything worked fine. Have you heard of any successful cases in BW that can be integrated with SCIM2 PUT requests successfully?

Many thanks ahead!

Wu DX
abhisheksingh2
Explorer
0 Kudos
Hi Matthew,

We are trying to extract a list of teams assigned to all the SAC users in our prod tenant. I tried using 'Get READ user' without any user ID and it gives me a response however due to pagination limit it just shows first few results without giving a url or anything for next page.is there any other way to extract such information for a list of users?

 

Many Thanks,

Abhishek Singh
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Abhishek

In the latest update to the samples, version 0.8 which I published Friday, I added 2 new collections.

SCIM 1601-All_T-List all teams and SCIM 2601-All_T-List all teams. Both list all the teams. 1601 uses version 1 of the API, and 2601 uses version 2.

Both just read and no updates are performed. The updated user guide shows examples of the output made to the Postman console, which is a list of teams, each with the number of users and roles associated with them.

Both samples do all the pagination for you. Sample 1601 has code commented out which means all the users of each team are written to the console. I've commented this code out because the Postman console becomes very slow when you write a lot of text to it. But you have the option to list all the users of each team by a very simple edit. Here's a screenshot of 1601 'Tests' for the request 'READ teams page by page':

uncomment line 70 for this sample. You could do something similar with 2601.

I think this should help?

All the best, Matthew

abhisheksingh2
Explorer
0 Kudos
Many Thanks Matthew. It certainly worked like you explained.

I got the response in JSON that I'd convert into csv to get records I'm looking for. Much appreciate the excellent work you've done with SCIM APIs. It has certainly made my life easier with user/mass user provisioning work 🙂
Matthew_Shaw
Product and Topic Expert
Product and Topic Expert
Hello Abhishek

Many thanks for your feedback.

To get a csv file output you could take what I did with the export of activities and change it. You would mostly need to delete a load of code in that sample, and just move the code from this Postman 'Tests' into the JavaScript. It wouldn't be too much work in fact. I left a good number of comments in the code to help with things like this. Hope it helps, Matthew