10Duke Identity Provider Graph API

Overview

The Graph API offers a way to get data into and out of a 10Duke Identity Provider deployment. It's an HTTP-based API that applications can use to programmatically query or post data, and perform a wide variety of other tasks relating to managing users, groups and organisations.

The Basics

The Graph API is a representation of the information held in a 10Duke Identity Provider deployment. It is an API that models the data in terms of objects and the relationships between them and allows the client to interact with multiple nodes in a single request.

In the Graph API, there is one endpoint: /graph/

In order to access and use the graph, it is structured and accessed as follows:

API Model

In order to interact with the Graph API, it has the following key elements:

  1. Object - individual objects, such as a Profile, an Organization, or a ProfileGroup (a group of related profiles/users). Note that on the graph, each object has a unique ID.

  2. Relation - a relation between two Objects, indicating relation multiplicity and possibly carrying relation attributes.

  3. Operation - an action taken on a graph object.

Graph Selector

This is a relational path to or between an object or a set of objects on the graph. If you want to access data on the graph, you need to construct a graph selector in order to define and execute your query. A graph selector can also include conditional expressions limiting the selected object set. Parameters can be used in order to better define or articulate an individual query. For example, specifying a date range when requesting a list of all new Profile objects registered in the IdP. Request parameters are specific to each operation you may call on the Graph API.

JSON API

This is used for standard Create, Read, Update and Delete (CRUD) operations on Graph Objects and Relations, as well as for other higher level operations. The JSON API maps HTTP methods POST, GET, PUT and DELETE to the CRUD operations that are generally available for all Objects and Relations. Other operations can be selected by using operation request parameter. JSON is used for representing Objects and Relations returned by reading operations, and for submitting Object and Relation data to writing operations.

Form API

This is used for creating or updating objects directly from HTML forms. Object and Relation data is given as form input values, where input names are graph selectors describing the item to create or update, and the respective input value gives the value for the item.

Operations vs http methods

In the context of the Graph API, it is important to note that an Operation is not the same as HTTP method. There are tens of operations that can be used to query the Graph API, while there are just four HTTP methods that are relevant in the same context. The connection between the two is that if no operation is explicitly specified by giving "operation" parameter, a default operation is inferred from the used HTTP method like this:

  • HTTP POST: create
  • HTTP GET: read
  • HTTP PUT: update
  • HTTP DELETE: delete

Example Objects on the Graph

The image below depicts some of objects that you are likely to interact with on the graph most frequently. This is by no means an exhaustive list, and you can of course, create new objects on the graph, but is it meant to give you an idea of the core objects on the graph and an indication of the possible relations between them.

Identity model:

  • EmailAndPassword - stores credentials for authenticating user with email address and password
  • Membership - relation describing membership of a Profile in a ProfileGroup
  • Organization - describes an organization, typically a company whose employees use the system
  • Person - describes a real person who may or may not act in the system using a Profile
  • Profile - describes a Person acting in the system
  • ProfileGroup - describes a group having Profile members
  • Property - holds additional key-value properties that can be attached to objects like Profile and Organization
  • (Organization)ContactInformation - aggregates contact information details (email, postal address, telephone number and web address) for a Profile or and Organization
  • (Organization)EmailAddress - email address for contacting a person represented by a Profile, or for contacting an Organization
  • (Organization)PostalAddress - postal address for contacting a person represented by a Profile, or for contacting an Organization
  • (Organization)TelephoneNumber - telephone number for contacting a person represented by a Profile, or for contacting an Organization
  • (Organization)WebAddress - web address, e.g. home page or corporate site, for contacting a person represented by a Profile, or for contacting an Organization
  • TechnicalActor - describes another technical system acting in the system
  • Partnership - relation describing partnership between two Organizations

Security model:

  • ConsumerPermission - permission stored by an external system, enforced by the external system
  • ConsumerRole - role that is used for granting ConsumerPermissions to users using an external system
  • Grants - relation describing permissions granted by a role (Role, Organization, ProfileGroupRole or ConsumerRole)
  • OrganizationRole - role used for granting permissions for resources owned by an Organization
  • Permission - abstract name describing permission that may be granted to a user
  • ProfileGroupRole - role used for granting permissions for resources owned by a ProfileGroup
  • Role - role used for granting system-wide permissions

Diagram 1 Diagram 1 - 10Duke Identity Provider - Example Graph objects and object relationships

Relation types

Generally, a graph Object can exist in relation to other graph objects with the following relation multiplicities (varieties):

  • One-to-one, where the Object can be connected to maximum of one Object of another type, and the connected Object can not be connected to other Objects of this type

  • One-to-many, where multiple Objects of another type can be connected to the Object, and the connected Objects can not be connected to other Objects of this type

  • Many-to-one, where the Object can be connected to maximum of one Object of another type, and the connected object can be connected to multiple Objects of this type

  • Many-to-many, where multiple Objects of another type can be connected to the Object, and the connected object can be connected to multiple Objects of this type

The relation types can be used for building graph, even dynamically. In graph selectors, the relation types are marked with a leading tilde as follows:

  • ~OneToMany
  • ~ManyToOne
  • ~ManyToMany

One-to-one relations must be expressed as one-to-many or many-to-one in graph selectors. (Note that ~OnetoOne is not a possible relation type due to limitations of relational databases, hence the need to use one-to-many or many-to-one in order to express one-to-one relations.)

In addition to the standard, all-purpose relation objects, many-to-many relations can be extended to contain relation attributes. For instance a Membership relation is a many-to-many relation with attributes for membership validity period.

Creating a Graph Selector

When you want to query data held in the graph, you need to create your graph selector which means you need to ‘build’ a graph url or path to define the data your accessing or posting.

The structure of a graph selector is as follows:

[/ObjectPart][/~RelationPart/ObjectPart]*[SelectorParametersPart]

This can be read as:

  • first there is an optional ObjectPart
  • then there are 0-n times RelationPart followed by ObjectPart
  • then there is an optional parameter part

Within the ObjectPart there is a sub-structure as follows:

ObjectName[:CollectionName][FieldSelector]

The RelationPart starts with a tilde, but is otherwise identical to ObjectPart.

These parts can be chained ad infinitum, but:

  • the first part must be an Object part
  • when chaining more parts, there must always be both a Relation part and an Object part, i.e. a graph selector can never end with a Relation part

~OneToMany and ~ManyToOne are special cases. When they are used the relation part doesn't have anything else within it, i.e. there is no CollectionName of FieldSelector

SelectorParameterPart contains parameters for paging and sorting query results.

So if we look at an example query, you can see its composition:

GET /graph/Organization[@name=’ACME’]/~OneToMany/ProfileGroup[@type=’employees’][/ObjectPart][/~RelationPart/ObjectPart]*[SelectorParametersPart]

Key characters used

Note the use of:

  • {count} to request total size of result set instead of the objects
  • ~ in the field selector to denote a “like” condition for field value matching
  • * (asterix) in the field selector specify value starts with matching
  • {i=0,r=5} to say offset 0, limit 5
  • / (forward slash) to denote the start of a type selector
  • [] brackets to enclose a field selector
  • @ to denote a field and corresponding condition on value
  • ~ to denote a relation type

Generic Graph Operations Applicable to all Objects

Below is a list of generic graph operations that can be used with all objects on the Graph.

CRUD operation introduction / examples

Creating / Updating objects

Creating and updating object(s) is done by post / put an object graph to the graph API.

Note: Update calls to the Graph API will perform business logic closer to a merge compared update. In many case create and update work together as an object graph may consist of new objects and existing objects.

Please experiment with the client application to decide if it is more feasible to implement a full query of all data subject to update vs. just a partial query letting the server side apply default logic. Client sent data will always take priority over automated server side logic.

The below example shows creating a Company (type: Organization) with a related employees group (type: ProfileGroup):

POST /graph

{
  "__objType": "Organization",
  "type": "company",
  "name": "ACME",
  "id": "f2f7416a-eb3e-42c5-85dc-db31b3ed5613",
  "rel_Relations": [
    {
      "rel_Relation": {
        "__objType": "ObjectRelation",
        "multiplicity": "ONE_TO_MANY",
        "relatedObjectType": "com.tenduke.sdk2.objectmodel.identity.ProfileGroup"
      },
      "rel_RelatedObjectList": {
        "__objType": "RelatedObjectList",
        "rel_RelatedObjects": [
          {
            "__objType": "ProfileGroup",
            "name": "Employees",
            "referenceFields": {
              "__objType": "HashMap",
              "Entries": [
                {
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "f2f7416a-eb3e-42c5-85dc-db31b3ed5613"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_Organization_id"
                  }
                }
              ]
            },
            "id": "cfd252be-2d14-41df-a671-c9ccac857c37",
            "type": "employees"
          }
        ]
      }
    }
  ]
}

Read / Query objects

Read / query works by issuing an HTTP GET request with a selector as the Request URI. The next example shows reading back the profile group created in the above example:

GET /graph/Organization[@name=’ACME’]/~OneToMany/ProfileGroup[@type=’employees’]

Note the use of:

  • / (forward slash) to denote the start of a type selector
  • [] brackets to enclose a field selector
  • @ to denote a field and corresponding condition on value
  • ~ to denote a relation type

Extending the example slightly:

  1. GET /graph/Organization[@name~’Acme*’]/~OneToMany/ProfileGroup{count}
  2. GET /graph/Organization[@name~’Acme*’]/~OneToMany/ProfileGroup{i=0,r=5}

Delete objects

Delete works by issuing an HTTP DELETE request with a selector as the Request URI. The next example shows deleting a profile group by id:

DELETE /graph/ProfileGroup[@id=ID-HERE’]

Users

Query logged in user

Please see /userinfo under OAuth 2.0 / OpenID Connect as well. That is a limited but “standard” approach to query logged in user info.

URL Description
/graph/me() Preconfigured version of logged in user query using flat / compact response JSON.
/graph/me Generic version of logged in user query using default 10Duke SDK2 JSON format.
/graph/me.jwt This variant will query the logged in user and the response will be a signed JSON web token.

Query a user profile

A Graph query to retrieve a user profile by id.

GET /graph/Profile[@id=’profile id’]

Query user by pre-configured id query

Includes contact information and response in flat compact form.

GET 
/graph/profile(‘profile id’)

Reads user profile with related person and contact information. NOTE: this type of call variant is recommended when the client application is in a CRUD cycle. The client application may want to include more related objects depending on the case.

GET /graph/Profile[@id=’profileid’]?/~ManyToOne/Person&/~OneToMany/ContactInformation/~OneToMany/EmailAddress

Pre-configured named query to request a user profile by email address

GET /graph/emailAndProfile(‘email address’)

This query will ask for user profile including Person, all ContactInformation and Recovery EmailAddress objects as relations.

GET /graph/me?/~ManyToOne/Person&/~OneToMany/ContactInformation/~OneToMany/EmailAddress&/~OneToMany/ContactInformation/~OneToMany/TelephoneNumber&/~OneToMany/ContactInformation/~OneToMany/PostalAddress&/~OneToMany/RecoveryEmailAddress

Query user’s recovery email addresses

GET /graph/me/~OneToMany/RecoveryEmailAddress

Register a user

POST /graph?operation=RegisterUser

{
  "__objType": "Profile",
  "referenceFields": {
    "__objType": "HashMap",
    "Entries": [{
      "__objType": "KeyValue",
      "value": {
        "__objType": "UUID",
        "value": "${PERSON_ID}"
      },
      "key": {
        "__objType": "String",
        "value": "ref_Person_id"
      }
      }]
  },
  "nickname": "${NICK_NAME}",
  "id": "${PROFILE_ID}",
  "rel_Relations": [{
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "multiplicity": "MANY_TO_ONE",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.identity.Person"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "Person",
        "lastName": "${LAST_NAME}",
        "firstName": "${FIRST_NAME}",
        "id": "${PERSON_ID}",
        "rel_Relations": [{
          "rel_Relation": {
            "__objType": "ObjectRelation",
            "multiplicity": "ONE_TO_MANY",
            "relatedObjectType": "com.tenduke.sdk2.objectmodel.credential.EmailAndPassword"
              },
          "rel_RelatedObjectList": {
            "__objType": "RelatedObjectList",
            "rel_RelatedObjects": [{
              "__objType": "EmailAndPassword",
              "referenceFields": {
                "__objType": "HashMap",
                "Entries": [{
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "${PERSON_ID}"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_Person_id"
                  }
                }]
              },
              "userName": "${EMAIL}",
              "id": "${CREDENTIAL_ID}",
              "passwordPlain": "${PASSWORD}"
             }]
           }
         }]
      }]
    }
  },{
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "multiplicity": "ONE_TO_MANY",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.identity.Account"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "Account",
        "accountType": "personal",
        "referenceFields": {
          "__objType": "HashMap",
          "Entries": [{
            "__objType": "KeyValue",
            "value": {
              "__objType": "UUID",
              "value": "${PROFILE_ID}"
                  },
            "key": {
              "__objType": "String",
              "value": "ref_Profile_id"
                  }
              }]
          },
        "accountIdentifier": "${ACCOUNT_ID}",
        "id": "${ACCOUNT_ID}"
      }]
      }
    }, {
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "multiplicity": "ONE_TO_MANY",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.ContactInformation"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "ContactInformation",
        "referenceFields": {
          "__objType": "HashMap",
          "Entries": [{
            "__objType": "KeyValue",
            "value": {
              "__objType": "UUID",
              "value": "${PROFILE_ID}"
                  },
            "key": {
              "__objType": "String",
              "value": "ref_Profile_id"
            }
          }]
        },
        "id": "${CONTACT_INFO_ID}",
        "rel_Relations": [{
          "rel_Relation": {
            "__objType": "ObjectRelation",
            "multiplicity": "ONE_TO_MANY",
            "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.PostalAddress"
              },
          "rel_RelatedObjectList": {
            "__objType": "RelatedObjectList",
            "rel_RelatedObjects": [{
              "__objType": "PostalAddress",
              "referenceFields": {
                "__objType": "HashMap",
                "Entries": [{
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "${CONTACT_INFO_ID}"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_ContactInformation_id"
                  }
                }]
              },
              "countryCode": "$COUNTRY_CODE",
              "streetAddress2": "street 2",
              "streetAddress3": "street 2",
              "streetAddress": "street 1",
              "city": "Vantaa",
              "postalCode": "007",
              "id": "${POSTAL_ADDRESS_ID}"
            }]
          }
        }, {
          "rel_Relation": {
            "__objType": "ObjectRelation",
            "multiplicity": "ONE_TO_MANY",
            "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.EmailAddress"
           },
          "rel_RelatedObjectList": {
            "__objType": "RelatedObjectList",
            "rel_RelatedObjects": [{
              "__objType": "EmailAddress",
              "referenceFields": {
                "__objType": "HashMap",
                "Entries": [{
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "${CONTACT_INFO_ID}"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_ContactInformation_id"
                  }
                }]
              },
              "id": "${EMAIL_ID}",
              "value": "${EMAIL}"
            }]
          }
        }]
      }]
    }
  }]
}

Update a User

(If you missed it, check out a primer about update.)

Note: Ensure to retain object and reference identifiers logically so that updating data does not introduce duplicate objects into a graph (or switch reference from an existing object to a new one creating “ghost” objects). Look for pattern ${..._ID} in the below JSON.

PUT /graph

{
  "__objType": "Profile",
  "referenceFields": {
    "__objType": "HashMap",
    "Entries": [{
      "__objType": "KeyValue",
      "value": {
        "__objType": "UUID",
        "value": "${PERSON_ID}"
      },
      "key": {
        "__objType": "String",
        "value": "ref_Person_id"
      }
    }]
  },
  "nickname": "${NICK_NAME}",
  "id": "${PROFILE_ID}",
  "rel_Relations": [{
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "multiplicity": "MANY_TO_ONE",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.identity.Person"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "Person",
        "lastName": "${LAST_NAME}",
        "firstName": "${FIRST_NAME}",
        "id": "${PERSON_ID}",
        "rel_Relations": []
      }]
    }
  }, {
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "multiplicity": "ONE_TO_MANY",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.ContactInformation"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "ContactInformation",
        "referenceFields": {
          "__objType": "HashMap",
          "Entries": [{
            "__objType": "KeyValue",
            "value": {
              "__objType": "UUID",
              "value": "${PROFILE_ID}"
            },
            "key": {
              "__objType": "String",
              "value": "ref_Profile_id"
            }
          }]
        },
        "id": "${CONTACT_INFO_ID}",
        "rel_Relations": [{
          "rel_Relation": {
            "__objType": "ObjectRelation",
            "multiplicity": "ONE_TO_MANY",
            "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.PostalAddress"
          },
          "rel_RelatedObjectList": {
            "__objType": "RelatedObjectList",
            "rel_RelatedObjects": [{
              "__objType": "PostalAddress",
              "referenceFields": {
                "__objType": "HashMap",
                "Entries": [{
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "${CONTACT_INFO_ID}"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_ContactInformation_id"
                  }
                }]
              },
              "countryCode": "$COUNTRY_CODE",
              "id": "${POSTAL_ADDRESS_ID}"
            }]
          }
        }, {
          "rel_Relation": {
            "__objType": "ObjectRelation",
            "multiplicity": "ONE_TO_MANY",
            "relatedObjectType": "com.tenduke.sdk2.objectmodel.contact.EmailAddress"
          },
          "rel_RelatedObjectList": {
            "__objType": "RelatedObjectList",
            "rel_RelatedObjects": [{
              "__objType": "EmailAddress",
              "referenceFields": {
                "__objType": "HashMap",
                "Entries": [{
                  "__objType": "KeyValue",
                  "value": {
                    "__objType": "UUID",
                    "value": "${CONTACT_INFO_ID}"
                  },
                  "key": {
                    "__objType": "String",
                    "value": "ref_ContactInformation_id"
                  }
                }]
              },
              "id": "${EMAIL_ID}",
              "value": "${EMAIL}"
            }]
          }
        }]
      }]
    }
  }]
}

Change login email

POST /graph HTTP/1.1
Host: {IDP_HOST}
Content-Type: application/x-www-form-urlencoded

operation=ChangeLoginEmail&profileId=[PROFILE_ID]&recoveryEmailId=[EMAIL_ID]
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "__objType": "ChangeLoginEmailResult", 
  "resultCode": "Success"
}

Change contact email

POST /graph

operation=ChangeContactInfoEmail&profileId=[PROFILE_ID]&recoveryEmailId=[EMAIL_ID]

{
  "__objType": "ChangeContactInfoEmailResult", 
  "resultCode": "Success"
}

Organizations

Query all Organizations

GET /graph/Organization

Query Organization by id

GET /graph/Organization[@id=’ID_GOES_HERE’]

Query Organization by name

GET /graph/Organization[@name=’NAME_GOES_HERE’]

Query user count in an Organization

GET /graph/Organization[@id='ORG_ID']/~OneToMany/ProfileGroup/~Membership:ProfileProfileGroupMembership/Profile{count}

Query all users in an Organization

/graph/Organization[@id='ORG_ID']/~OneToMany/ProfileGroup/~Membership:ProfileProfileGroupMembership/Profile

Query users in specific range (offset, limit) in an Organization

/graph/Organization[@id='ORG_ID']/~OneToMany/ProfileGroup/~Membership:ProfileProfileGroupMembership/Profile{i=10,r=30}

Group management

Create a group and relate it to an Organization

POST /graph

{
  "__objType": "ProfileGroup",
  "name": "Employees",
  "referenceFields": {
    "__objType": "HashMap",
    "Entries": [{
      "__objType": "KeyValue",
      "value": {
        "__objType": "String",
        "value": "${ORGANIZATION_ID}"
      },
      "key": {
        "__objType": "String",
        "value": "ref_Organization_id"
      }
      }]
    },
  "id": "a99f9f51-97cb-4486-86b9-2e08de5cfcd1",
  "type": "employees"
}
/graph/Organization[@id='ORG_ID']/~OneToMany/ProfileGroup

Add a user to an Organization

Note: the intent in this example is actually adding a user to a profile group associated with an Organization

POST /graph

operation=AddToProfileGroups&profileId=$PROFILE_ID&profileGroupId=$PROFILE_GROUP_ID_1...&profileGroupId=$PROFILE_GROUP_ID_N&allowAlreadyAdded=false

Note:

  • Parameter profileGroupId may be repeated several times to define adding to several groups in one go.
  • the allowAlreadyAdded=false, which will ensure the same user is not added twice to the same group. Set the flag to true if you intentionally want to create duplicate group memberships.
  • You may use the query in “Query all ProfileGroup objects in an Organization” to determine the ProfileGroup id.

Remove a user from an Organization

POST /graph

operation=RemoveUserFromOrganization&profileId=$PROFILE_ID&organizationId=$ORGANIZATION_ID

Or alternatively manually from each profile group:

POST /graph

operation=RemoveFromProfileGroups&profileId=$PROFILE_ID&profileGroupId=$PROFILE_GROUP_ID_1...&profileGroupId=$PROFILE_GROUP_ID_N&allowAlreadyRemoved=true

Note:

  • Parameter profileGroupId may be repeated several times to define removal from several groups.
  • the allowAlreadyRemoved=true, which controls if the call returns an error or not in case the user was not a member in the group specified in the call.

Role management

Query all OrganizationRole templates

/graph/OrganizationRole[@templateFor!=null]

NOTE: Users should not be associated with template role instances. Use query “Query an Organization’s active roles” to determine OrganizationRole instances that may be assigned to users.

Query an Organization’s active roles

/graph/Organization[@id='ORG_ID']/~OneToMany/OrganizationRole

NOTE: this query provides Organization roles that may be assigned to users.

Make an Organization role available to be assigned for Organization members

NOTE: this is “how to” create an OrganizationRole that is assignable to users. The idea is that a template role functions as a single point of truth what an OrganizationRole allows users to do within an Organization’s scope. The OrganizationRole created by this call will relate to a template role by an Implies relation. The end result is that changes to a template role will immediately reflect as a change to several OrganizationRole objects that imply the edited template.

POST /graph

{
  "__objType": "OrganizationRole",
  "referenceFields": {
    "__objType": "HashMap",
    "Entries": [{
      "__objType": "KeyValue",
      "value": {
        "__objType": "String",
        "value": "${ORGANIZATION_ID}"
      },
      "key": {
        "__objType": "String",
        "value": "ref_Organization_id"
      }
      }]
    },
  "isBuiltIn": false,
  "name": "CustomerOrgAdmin in ${ORGANIZATION_NAME} (implies template)",
  "id": "${ORGANIZATION_ROLE_ID}",
  "rel_Relations": [{
    "rel_Relation": {
      "__objType": "ObjectRelation",
      "relationType": "com.tenduke.sdk2.types.object.graph.Implies",
      "relatedObjectType": "com.tenduke.sdk2.objectmodel.security.OrganizationRole"
      },
    "rel_RelatedObjectList": {
      "__objType": "RelatedObjectList",
      "rel_RelatedObjects": [{
        "__objType": "OrganizationRole",
        "relationAttributeObject": {
          "__objType": "Implies",
          "referenceFields": {
            "__objType": "HashMap",
            "Entries": [{
              "__objType": "KeyValue",
              "value": {
                "__objType": "UUID",
                "value": "${TEMPLATE_ROLE_ID}"
                      },
              "key": {
                "__objType": "String",
                "value": "ref_OrganizationRole_id2"
                      }
                  }, {
              "__objType": "KeyValue",
              "value": {
                "__objType": "UUID",
                "value": "${ORGANIZATION_ROLE_ID}"
                      },
              "key": {
                "__objType": "String",
                "value": "ref_OrganizationRole_id1"
                      }
                  }]
              },
          "implieeId": "${TEMPLATE_ROLE_ID}",
          "id": $RANDOM_UUID,
          "implierId": "${ORGANIZATION_ROLE_ID}"
          },
        "id": "${TEMPLATE_ROLE_ID}"
      }]
      }
    }]
}

Add an Organization Role to a User

POST /graph

operation=AddToOrganizationRole&organizationId=$ORGANIZATION_ID&roleName=$ROLE_NAME&profileId=$PROFILE_ID

Where $ROLE_NAME is a value from a call described in “Make an organization role available to be assigned for organization members” OR alternatively query concrete OrganizationRole names by using the example provided by “Query an Organization’s active roles”.

Example Objects and Operations

General

Login

POST /graph?operation=Login

Logins the user and establishes an authenticated session.

Parameters
Parameter In Type Required
userName - Login email address or user name query or form string true
password - Password query or form string true

Profile

Generic Operations

POST, GET, PUT, DELETE

Register user

POST /graph?operation=RegisterUser

Creates and initializes a new user in the system.

Parameters
Parameter In Type Required
body - The Profile object specifying the user to create body Profile true

Change login email

POST /graph?operation=ChangeLoginEmail

Changes the user email address used as a login name.

Parameters
Parameter In Type Required
profileId - Id of the profile for which login email is changed query or form UUID true
recoveryEmailId - query or form    

Change contact info email

POST /graph?operation=ChangeContactInfoEmail

Changes the user email address used as a contact email that may be displayed to other users.

Parameters
Parameter In Type Required
profileId - Id of the profile for which contact info email is changed query or form UUID true
recoveryEmailId - query or form    

Add user to a group or to an Organization

POST /graph?operation=AddToProfileGroups

Adds user to a ProfileGroup. When user is added to an Organization, it is done by adding the user to a ProfileGroup representing Organization members.

Parameters
Parameter In Type Required
profileId - Id of the profile to be added in the group query or form UUID true
profileGroupId - Id of the group in which the user is added query or form UUID true
allowAlreadyAdded - controls how the operation behaves if the user is already in the group. If true, operation doesn’t give an error response in this case. query or form boolean false

Remove user from a group or from an Organization

POST /graph?operation=RemoveFromProfileGroups

Removes user from a ProfileGroup. When user is removed from an Organization, it is done by removing the user from a ProfileGroup representing Organization members.

Parameters
Parameter In Type Required
profileId - Id of the profile to be removed from the group query or form UUID true
profileGroupId - Id of the group from which the user is removed query or form UUID true
allowAlreadyRemoved - controls how the operation behaves if the user is not in the group. If true, operation doesn’t give an error response in this case. query or form boolean false

Add user to an Organization role

POST /graph?operation=AddToOrganizationRole

Adds user to an OrganizationRole, i.e. to a role that is used for granting permissions in a scope of an Organization.

Parameters
Parameter In Type Required
profileId - Id of the profile to be added in the role query or form UUID true
organizationId - Id of the organization scoping the role and the attached permissions query or form UUID true
roleName - Name of the role in which the user is added query or form UUID true

~ManyToOne/Person
~OneToMany/ContactInformation
~Membership/ProfileGroup
~OneToMany/Property:ProfileProperty
~ManyToMany/Role
~ManyToMany/OrganizationRole
~ManyToMany/ConsumerRole

Organization

Generic Operations

POST, GET, PUT, DELETE

Specific Operations

GET/graph/Organization[@id=’ID_GOES_HERE’]
GET /graph/Organization[@name=’NAME_GOES_HERE’]

~OneToMany/OrganizationContactInformation
~OneToMany/OrganizationRole
~OneToMany/ProfileGroup
~OneToMany/VatNumber
~ServicePartnership/Organization

EmailAddress

Generic Operations

POST, GET, PUT, DELETE

Specific Operations,

POST /graph

operation=ChangeContactInfoEmail&profileId=[PROFILE_ID]&recoveryEmailId=[EMAIL_ID]

{
  "__objType": "ChangeContactInfoEmailResult", 
  "resultCode": "Success"
}

~ManyToOne/ContactInformation

ProfileGroup

Generic Operations

POST, GET, PUT, DELETE

~ManyToOne/Organization
~Membership/Profile
~OneToMany/ProfileGroupRole
~GroupMembership/ProfileGroup

VatNumber

Generic Operations

POST, GET, PUT, DELETE

~ManyToOne/Organization

DunsNumber

Generic Operations

POST, GET, PUT, DELETE

~ManyToOne/Organization

Person

Generic Operations

POST, GET, PUT, DELETE

~OneToMany/Profile
~OneToMany/EmailAndPassword

TechnicalActor

Generic Operations

POST, GET, PUT, DELETE

~OneToMany/EmailAndPassword