REST Identity store

January 11, 2019 ยท View on GitHub

The REST backend allows you to query identity data in existing webapps, like:

  • Forums (phpBB, Discourse, etc.)
  • Custom Identity stores (Keycloak, ...)
  • CRMs (Wordpress, ...)
  • Self-hosted clouds (Nextcloud, ownCloud, ...)

To integrate this backend with your webapp, you will need to implement the REST endpoints described below.

Features

NameSupported?
AuthenticationYes
DirectoryYes
IdentityYes
ProfileYes

Configuration

KeyDefaultDescription
rest.enabledfalseGlobally enable/disable the REST backend
rest.hostNoneDefault base URL to use for the different endpoints.
rest.endpoints.auth/_mxisd/backend/api/v1/auth/loginValidate credentials and get user profile
rest.endpoints.directory/_mxisd/backend/api/v1/directory/user/searchSearch for users by arbitrary input
rest.endpoints.identity.single/_mxisd/backend/api/v1/identity/singleEndpoint to query a single 3PID
rest.endpoints.identity.bulk/_mxisd/backend/api/v1/identity/bulkEndpoint to query a list of 3PID
rest.endpoints.profile.displayName/_mxisd/backend/api/v1/profile/displayNameQuery the display name for a Matrix ID
rest.endpoints.profile.threepids/_mxisd/backend/api/v1/profile/threepidsQuery the 3PIDs for a Matrix ID
rest.endpoints.profile.roles/_mxisd/backend/api/v1/profile/rolesQuery the Roles for a Matrix ID

Endpoint values can handle two formats:

  • URL Path starting with / that gets happened to the rest.host
  • Full URL, if you want each endpoint to go to a specific server/protocol/port

If an endpoint value is configured as an empty string, it will disable that specific feature, essentially bypassing the Identity store for that specific query.

rest.host is mandatory if at least one endpoint is not a full URL.

Endpoints

Authentication

  • Method: POST
  • Content-Type: application/json (JSON)
  • Encoding: UTF8

Request Body

{
  "auth": {
    "mxid": "@john.doe:example.org",
    "localpart": "john.doe",
    "domain": "example.org",
    "password": "passwordOfTheUser"
  }
}

Response Body

If the authentication fails:

{
  "auth": {
    "success": false
  }
}

If the authentication succeed:

  • auth.id supported values: localpart, mxid
  • auth.profile and any sub-member are all optional
{
  "auth": {
    "success": true,
    "id": {
      "type": "localpart",
      "value": "john"
    },
    "profile": {
      "display_name": "John Doe",
      "three_pids": [
        {
          "medium": "email",
          "address": "john.doe@example.org"
        },
        {
          "medium": "msisdn",
          "address": "123456789"
        }
      ]
    }
  }
}

Directory

  • Method: POST
  • Content-Type: application/json (JSON)
  • Encoding: UTF8

Request Body

{
  "by": "<search type>",
  "search_term": "doe"
}

by can be:

  • name
  • threepid

Response Body:

If users found:

{
  "limited": false,
  "results": [
    {
      "avatar_url": "http://domain.tld/path/to/avatar.png",
      "display_name": "John Doe",
      "user_id": "UserIdLocalpart"
    },
    {
      "...": "..."
    }
  ]
}

If no user found:

{
  "limited": false,
  "results": []
}

Identity

Single 3PID lookup

  • Method: POST
  • Content-Type: application/json (JSON)
  • Encoding: UTF8
Request Body
{
  "lookup": {
    "medium": "email",
    "address": "john.doe@example.org"
  }
}
Response Body

If a match was found:

  • lookup.id.type supported values: localpart, mxid
{
  "lookup": {
    "medium": "email",
    "address": "john.doe@example.org",
    "id": {
      "type": "mxid",
      "value": "@john:example.org"
    }
  }
}

If no match was found:

{}

Bulk 3PID lookup

  • Method: POST
  • Content-Type: application/json (JSON)
  • Encoding: UTF8
Request Body
{
  "lookup": [
    {
      "medium": "email",
      "address": "john.doe@example.org"
    },
    {
      "medium": "msisdn",
      "address": "123456789"
    }
  ]
}
Response Body

For all entries where a match was found:

  • lookup[].id.type supported values: localpart, mxid
{
  "lookup": [
    {
      "medium": "email",
      "address": "john.doe@example.org",
      "id": {
        "type": "localpart",
        "value": "john"
      }
    },
    {
      "medium": "msisdn",
      "address": "123456789",
      "id": {
        "type": "mxid",
        "value": "@jane:example.org"
      }
    }
  ]
}

If no match was found:

{
  "lookup": []
}

Profile

Request Body

For all requests, the values are the same:

  • Method: POST
  • Content-Type: application/json (JSON)
  • Encoding: UTF8

With body (example values):

Request Body
{
    "mxid": "@john.doe:example.org",
    "localpart": "john.doe",
    "domain": "example.org"
}

Response Body

For all responses, the same object structure will be parsed, making the non-relevant fields as optional.

Structure with example values:

{
  "profile": {
    "display_name": "John Doe",
    "threepids": [
      {
        "medium": "email",
        "address": "john.doe@example.org"
      },
      {
        "...": "..."
      }
    ],
    "roles": [
      "DomainUsers",
      "SalesOrg",
      "..."
    ]
  }
}

The base profile key is mandatory. display_name, threepids and roles are only to be returned on the relevant request.

If there is no profile, the following response is expected:

{
  "profile": {}
}