OTDS REST API - Creating users - getting an error

Options

Hi hope you can help.

I need to build a service which will bulk create users in a non-sync partition in OTDS (10.5). So, in the first instance, I am trying to create a user through the REST API examples via http://:8080/otdsws/api/?rest and also via http://:8080/otdsws/api/?v1

In either case, I try the following example body and both fail:

{
       "user_partition_id": "ONLINESERVICES",
       "name": "asmith",
       "location": "cn=asmith,ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net",
       "id": "asmith@ONLINESERVICES",
       "description": "OpenText Engineer 2",
       "values": [
         {
           "name": "schemaType",
           "values": [
             3
           ]
         },
         {
           "name": "oTExternalID4",
           "values": [
             "ONLINESERVICES\\asmith"
           ]
         },
         {
           "name": "oTExternalID3",
           "values": [
             "asmith@ONLINESERVICES"
           ]
         },
         {
           "name": "oTExternalID2",
           "values": [
             "asmith@ONLINESERVICES"
           ]
         },
         {
           "name": "oTExternalID1",
           "values": [
             "asmith"
           ]
         },
         {
           "name": "oTGroupOfResources",
           "values": [
             "cn=OTAG,ou=Resources,dc=identity,dc=opentext,dc=net",
             "cn=Portal 8.5,ou=Resources,dc=identity,dc=opentext,dc=net",
             "cn=Content Server 10,ou=Resources,dc=identity,dc=opentext,dc=net"
           ]
         },
         {
           "name": "givenName",
           "values": [
             "Alfonso"
           ]
         },
         {
           "name": "sn",
           "values": [
             "Smith"
           ]
         },
         {
           "name": "cn",
           "values": [
             "asmith"
           ]
         },
         {
           "name": "oTUserID4",
           "values": [
             "ONLINESERVICES\\asmith"
           ]
         },
         {
           "name": "description",
           "values": [
             "OpenText Engineer 2"
           ]
         },
         {
           "name": "oTUserID3",
           "values": [
             "asmith@ONLINESERVICES"
           ]
         },
         {
           "name": "oTUserID2",
           "values": [
             "asmith@ONLINESERVICES"
           ]
         },
         {
           "name": "oTUserID1",
           "values": [
             "asmith"
           ]
         },
         {
           "name": "entryDN",
           "values": [
             "cn=asmith,ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net"
           ]
         },
         {
           "name": "oTDeleteFromResource",
           "values": [
             "cn=Collab,ou=Resources,dc=identity,dc=opentext,dc=net"
           ]
         },
         {
           "name": "oTObjectGUID",
           "values": [
             "jKPvKssXT3uN0ByE7Kaf5A=="
           ]
         }
       ],
       "object_class": "oTPerson",
       "url_id": "asmith@ONLINESERVICES",
       "url_location": "cn=asmith,ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net"
     }

Using the v1 url I get the following error:

{
   "status": 2001,
   "error": "com.opentext.otds.ds.repositoryhandler.repoconnector.impl.jndiconnector.LdapException: JNDIConnector::doCreate: [LDAP: error code 32 - Entry cn=asmith,cn=asmith,ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net cannot be added because its parent entry cn=asmith,ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net does not exist in the server]" }

and using the 'rest' url I get this error:

{
   "status": -1,
   "error": "com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"user_partition_id\" (class com.opentext.otds.usergroup.data.User), not marked as ignorable (9 known properties: , \"values\", \"urlLocation\", \"urlId\", \"name\", \"location\", \"objectClass\", \"userPartitionID\", \"id\", \"description\"])\n at [Source: org.apache.catalina.connector.CoyoteInputStream@1836cb4b; line: 2, column: 29] (through reference chain: com.opentext.otds.usergroup.data.User[\"user_partition_id\"])" }

In either case, I'm stuck!

Perhaps the format of the body is incorrect, but this seems to follow the schema and more over I created a user manually in OTDS, then did a '/users' call and got back the body that I then used for the template which matched the schema.

Can you point me in the right direction.

Thanks,

Anthony

P.S. Currently using the swagger integrated javadocs on my server

Tagged:

Comments

  • Hi Anthony
    Please set the "location" parameter to:
    "ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net"

    If you have OTDS 10.5 patch 5 you can omit "location" altogether.

    Also, do not specify any of the "values" (user attributes) that you have shown above (e.g. oTGroupOfResources, oTExternalID1-4, etc.). These are all set automatically by the server.

  • Hi Peter,

    Super that worked as follows (Just for those interested):

    {
          "user_partition_id": "ONLINESERVICES",
          "name": "asmith",
          "location": "ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net",
          "id": "asmith@ONLINESERVICES",
          "description": "OpenText Engineer 2",
          "values": [
          ],
          "object_class": "oTPerson",
          "url_id": "asmith@ONLINESERVICES",
          "url_location": "ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net"
        }
    

    Following on from this, I need to wrap this into a client app (java most probably). Thus far I've used the swagger interface to the API's so I am already authenticated via the browser. I am unclear as to whether this has an OTDSTicket (OTDS) or an OTCSTicket in the header. I've tried to look at this using POSTMAN but for some reason I'm failing to get the syntax right to validate.

    I think I need to use a OTDSTICKET using the /authentication/ticketforresource which I'm hoping I can do just using the resourceid parameter only.

    Any advice enourmously welcome.

    Thanks,

    Anthony

  • You need to obtain an OTDS ticket by invoking /authentication/credentials. You only have to provide the username and password fields. The ticket will be in the 'ticket' field of the response. Then you use this ticket to make all subsequent requests by including it in an HTTP header called "OTDSTicket".

    Also, you don't need to include any of the following to create the user:
    id
    url_id
    url_location
    object_class

    These fields are ignored on creation.

  • Excellent, thanks again Peter.

  • Hi Anthony and Peter
    We have to created around 250 users in non sync partition in OTDS. I am trying to use this thread to create them, but unfortunately, I have stuck up with invoking /authentication/credentials to obtain OTDS ticket. I am getting an error

    Below is my code;
    *{
    "tokenBinary": [
    ],
    "continuationContext": [

    ],
    "clientData": [

    ],
    "headersList": [
    {
    "name": "string",
    "values": [

      ]
    }
    

    ],
    "cookiesList": [
    {
    "name": "string",
    "values": [

      ]
    }
    

    ],
    "remoteAddr": "string",
    "remoteHost": "string",
    "authenticator": [

    ],
    "secureSecret": [

    ],
    "userName": "otadmin@otds.admin",
    "password": "xxxxxx",
    "code": "string",
    "targetResourceId": "string",
    "sourceResourceId": "string"
    }*

    If i try to pass only user and id password, it is throwing an error as "Bad Request". Kindly guide me.

    Thanks
    Praveen

  • Most of the parameters are optional, for more complex use cases. You just need to POST the following to /otdsws/v1/authentication/credentials:

    {
    "user_name":"otadmin@otds.admin",
    "password":"xxxxxx"
    }

  • Hi Praveen,

    Having now solved this and is working very nicely I'm happy to share how I solved this. This requires a couple of steps.

    1. Get a otdsticket and a token from a /otdsws/v1/authentication/credentials call passing in the username and password as a JSON object. The form of the JSON object will depend on the version of the API you re using so you will need to pass in either:

      {
      "user_name": "your username",
      "password": "your password"
      }

    or

    { 
    "user_name":<your username>,
    "password":<your password>
    }
    
    1. Extract your otdsticket and token from the resulting JSON object.

    2. In what ever way you are storing your list of users (mine were in a CSV file which I read in line by line), for each user formulate a JSON object. Use the /otdsws/v1/users This should look something like this

      {
      "user_partition_id": "ONLINESERVICES",
      "name": "asmith",
      "location": "ou=Root,ou=ONLINESERVICES,ou=IdentityProviders,dc=identity,dc=opentext,dc=net",
      "description": "OpenText",
      "values": [
      ]
      }

    Add additional name/value pairs depending on what you want to set for your users
    4. Now add a password for this user using the /otdsws/v1/users//password (Note this has to be called by otdadmin user and that this is a PUT not a POST

    Again, this needs to be a JSON request in the following form

    {
    "new_password":"<password to set>"
    }
    

    Hope this helps.

    Anthony

  • Hi Anthony

    Thanks a lot for your help. Now I can create users using this API.

    My issues is now, do I need to run for each user at one time, because http://url:port/otdsws/v1/users, it allows only one user.
    Kindly let me know the steps, how to generate the json file to create multiple users with one shot. Really appreciate your help because I have to create these users in 3 more systems.

    Do you have any idea, how to assign these users to usergroups instead of selecting and assigning tedious process.

    One more thing I want tell you, I am passing the password in the creation file it self, by using attribute "ownPassword".

    Thanks a lot.

    Regards
    Praveen

    • The attribute for sending the password on creation is "userPassword"

    • REST semantics for object creation mandate creating a user one at a time. You should be able to simply create a loop in your client application to create all the users you wish.

    To add members to a group,
    POST /groups/{group_id}/members
    the body needs to contain a list of strings containing the DNs of the users, e.g.:
    {
    "string_list": [
    "cn=user1,ou=Root,ou=partitionName,ou=IdentityProviders,dc=identity,dc=opentext,dc=net",
    "cn=user2,ou=Root,ou=partitionName,ou=IdentityProviders,dc=identity,dc=opentext,dc=net",
    "cn=user3,ou=Root,ou=partitionName,ou=IdentityProviders,dc=identity,dc=opentext,dc=net"
    ]
    }

  • I echo Peters response. In my case I had the list of users in a CSV file. I then looped over the CSV file, getting each name that I wanted to create in turn from the CSV file, then created the JSON string for the user then made the REST call.

    To do the group bit, do as Peter has suggested and build an array list of strings. I would do this by adding the users string "cn=user1,ou=Root,ou=partitionName,ou=IdentityProviders,dc=identity,dc=opentext,dc=net", to the array list as I looped around the users (wait until you get a positive response from the JSON returned).

    Keep adding to the ArrayList until you have looped over all the users, and then pass this to another function to create the group. (I'm using Java so I would use a List<String> userList = new ArrayList<String>();).

    Pass the entire ArrayList to a new function e.g.

    private void addUsersToGroup(List<String> userList) {
        // Now loop over the arrayList using an enhanced for loop
        // and build a JSON string ...
    }
    

    Then make the REST call.

    I hope this makes sense.

    Once again, thanks to Peter for his initial insight in solving my own problem from a few days ago.

    Thanks,

    Anthony

  • Hi Peter and Anthony

    What do you mean by client system. Is it in OTDS or in content server. Actually I am new to this area and this technology. Kindly help me where to store this csv file and what yo write in the script.

    Million Thanks
    Praveen

  • Hi Peter and Anthony

    Kindly advise me how to write and where to write the script, I am waiting for your reply. One more thing, if I add the group information while creating users, in the users area it is displaying the groups, but when you go to groups tab, I could not see any users under the group. Any idea why it is not getting updated in user groups.

    Thanks in advance
    Regards
    Praveen

  • The 'client system' is wherever you're running your code/script from. I can't tell you how and where to write the script - that's your decision. Maybe 'script' is the wrong terminology --- I'm just referring to your application/code.

    You can't specify the group membership as part of creating the users. That's not currently working, as you noticed. You will need to explicitly add the new user to the group by calling
    POST /groups/{group_id}/members to add the new user to the group.

  • Anthony,
    Did you ever get this fully working? If you did it with Java, would you mind sharing? I'm trying to save some time and I'm betting somebody already has Java program to create user in bulk for a non-synchronized partition using the OTDS REST APIs. (at least I'm hoping:))

  • Hi Don,

    If I can find it, I'll happily share it. I'm sure it's not the most efficient code in the world, but it does the trick. I'll comment back here if I find it - wish me luck :-)

    Thanks,

    Anthony

  • Anthony,
    Thank you, that would be extremely helpful :)

  • Hi Don and any other interested parties,

    I have uploaded the example code - and please bear in mind that it is example code and not production ready - to github. You can find the link and a little more detail via my website here:

    http://www.contentsciences.com/2017/04/24/directory-services-bulk-uploader/

    Code is here:
    https://github.com/contentsciences/OTDS-User-Loader

    Thanks

    Anthony

  • Hi Antony,

    How to invoke OTDS's /authentication/resource/validation endpoint?

    here ticket, sourceResourceId, secureSecret/authenticator are required. but I am unable to find out from where I can get the authenticator. please share what is mean of authenticator or secureSecret here.