Skip to content

Latest commit

 

History

History
 
 

rest

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

REST or JSON-RPC authenticator

This authenticator permits authentication of Tinode users and creation of Tinode accounts using a separate process as a source of truth. For instance, if accounts are managed by corporate LDAP, this service allows handling of Tinode authentication using the same LDAP service.

This authenticator calls a designated authentication service over HTTP(S) POST. A skeleton implementation of a server is provided for reference at rest-auth. The requests may be handled either by a single endpoint or by separate per-request endpoints.

Request and response payloads are formatted as JSON. Some of the request or response fields are context-dependent and may be skipped.

Configuration

Add the following section to the auth_config in tinode.conf:

...
"auth_config": {
  ...
  "rest": {
    // ServerUrl is the URL of the authentication server to call. The URL must be absolute:
    // it must include the scheme, such as http or https, and the host name.
    "server_url": "http://127.0.0.1:5000/",
    // Authentication server is allowed to create new accounts.
    "allow_new_accounts": true,
    // Use separate endpoints, i.e. add request name to serverUrl path when making requests:
    // http://127.0.0.1:5000/add
    "use_separate_endpoints": true
  },
  ...
},

If you want to use your authenticator instead of stock basic (login-password) authentication, add a logical renaming:

...
"auth_config": {
  "logical_names": ["basic:rest"],
  "rest": { ... },
  ...
},
...

Request

{
  "endpoint": "auth",       // string, one of the endpoints as described below, optional.
  "secret": "Ym9iOmJvYjEyMw==", // authentication secret as provided by the client,
                            // base64-encoded bytes, optional.
  "addr": "2001:0db8:85a3:0000:0000:8a2e:0370:7334", // string, IPv4 or IPv6 address of
                            // the client making the request, optional.
  "rec": {    // authentication record, optional.
    {
      "uid": "LELEQHDWbgY", // user ID, int64 base64-encoded
      "authlvl": "auth",    // authentication level
      "lifetime": "10000s", // lifetime of this record in seconds or as time.Duration string;
                            // see https://golang.org/pkg/time/#Duration for format.
       "features": 1,       // bitmap of features as integer or as a string of feature characters:
                            // "validated" (V) or "no login" (L)".
       "tags": ["email:[email protected]"], // Tags associated with this authentication record.
       "state": "ok",       // optional account state.
    }
  }
}

Response

{
  "err": "internal", // string, error message in case of an error.
  "rec": {           // authentication record.
    ...              // the same as `request.rec`
  },
  "byteval": "Ym9iOmJvYjEyMw==",    // array of bytes, optional
  "ts": "2018-12-04T15:17:02.627Z", // time stamp, optional
  "boolval": true,                  // boolean value, optional
  "strarr": ["abc", "def"],         // array of strings, optoional
  "newacc": {        // data to use for creating a new account.
    // Default access mode
    "auth": "JRWPS",
    "anon": "N",
    "public": {...}, // user's public data, see /docs/API.md#public-and-private-fields
    "private": {...} // user's private data, see /docs/API.md#public-and-private-fields
  }
}

Recognized error responses

The error is returned as json:

{ "err": "error-message" }

See here for an up to date list of supported error messages.

  • "internal": database failure or other internal catch-all failure.
  • "malformed": request cannot be parsed or otherwise wrong.
  • "failed": authentication failed (wrong login or password, etc).
  • "duplicate value": duplicate credential, i.e. attempt to create a record with a non-unique login.
  • "unsupported": the operation is not supported.
  • "expired": the secret has expired.
  • "policy": policy violation, e.g. password too weak.
  • "credentials": credentials like email or captcha must be validated.
  • "not found": the object was not found.
  • "denied": the operation is not permitted.

The server must implement the following endpoints:

add Add new authentication record

This endpoint requests server to add a new authentication record. This endpoint is generally used for account creation. If accounts are managed externally, it's likely to be unused and should generally return an error "unsupported".

Sample request

{
  "endpoint": "add",
  "secret": "Ym9iOmJvYjEyMw==",
  "addr": "111.22.33.44",
  "rec": {
    "uid": "LELEQHDWbgY",
    "lifetime": "10000s",
    "features": 2,
    "tags": ["email:[email protected]"]
  }
}

Sample response (rec values may change)

{
  "rec": {
    "uid": "LELEQHDWbgY",
    "authlvl": "auth",
    "lifetime": "5000s",
    "features": 1,
    "tags": ["email:[email protected]", "uname:alice"]
  }
}

auth Request for authentication

Request to authenticate a user. Client (Tinode) provides a secret, authentication server responds with a user record. If this is a very first login and the server manages the accounts, the server may return newacc object which will be used by client (Tinode) to create the account. The server may optionally return a challenge as byteval.

Sample request

{
  "endpoint": "auth",
  "secret": "Ym9iOmJvYjEyMw==",
  "addr": "111.22.33.44"
}

Sample response when the account already exists (optional challenge included)

{
  "rec": {
    "uid": "LELEQHDWbgY",
    "authlvl": "auth",
    "state": "ok"
  },
  "byteval": "9X6m3tWeBEMlDxlcFAABAAEAbVs"
}

Sample response when the account needs to be created by Tinode

{
  "rec": {
    "state": "suspended", // Or "ok".
    "authlvl": "auth",
    "lifetime": "5000s",
    "features": 1,
    "tags": ["email:[email protected]", "uname:alice"]
  },
  "newacc": {
    "auth": "JRWPS",
    "anon": "N",
    "public": {/* see /docs/API.md#public-and-private-fields */},
    "private": {/* see /docs/API.md#public-and-private-fields */}
  }  
}

checkunique Checks if provided authentication record is unique.

Request is used for account creation. If accounts are managed by the server, the server should respond with an error "unsupported".

Sample request

{
  "endpoint": "checkunique",
  "secret": "Ym9iOmJvYjEyMw==",
  "addr": "111.22.33.44"
}

Sample response

{
  "boolval": true
}

del Requests to delete authentication record.

If accounts are managed by the server, the server should respond with an error "unsupported".

Sample request

{
  "endpoint": "del",
  "rec": {
    "uid": "LELEQHDWbgY",
  }
}

Sample response

{}

gen Generate authentication secret.

If accounts are managed by the server, the server should respond with an error "unsupported".

Sample request

{
  "endpoint": "gen",
  "rec": {
    "uid": "LELEQHDWbgY",
    "authlvl": "auth",
  }
}

Sample response

{
  "byteval": "9X6m3tWeBEMlDxlcFAABAAEAbVs",
  "ts": "2018-12-04T15:17:02.627Z",
}

link Requests server to link new account ID to authentication record.

If server requested Tinode to create a new account, this endpoint is used to link the new Tinode user ID with the server's authentication record. If linking is successful, the server should respond with a non-empty json.

Sample request

{
  "endpoint": "link",
  "secret": "Ym9iOmJvYjEyMw==",
  "rec": {
    "uid": "LELEQHDWbgY",
    "authlvl": "auth",
  },
}

Sample response

{}

upd Update authentication record.

If accounts are managed by the server, the server should respond with an error "unsupported".

Sample request

{
  "endpoint": "upd",
  "secret": "Ym9iOmJvYjEyMw==",
  "addr": "111.22.33.44",
  "rec": {
    "uid": "LELEQHDWbgY",
    "authlvl": "auth",
  }
}

Sample response

{}

rtagns Get a list of restricted tag namespaces.

Server may enforce certain tag namespaces (tag prefixes) to be restricted, i.e. not editable by the user. These are also used in Tinode discovery mechanism (e.g. searching for users, contact sync). See API docs for details.

The server may optionally provide a regular expression to validate search tokens before rewriting them as prefixed tags. I.e. if server allows only logins of 3-8 ASCII letters and numbers then the regexp could be ^[a-z0-9_]{3,8}$ which is base64-encoded as XlthLXowLTlfXXszLDh9JA==.

Sample request

{
  "endpoint": "rtagns",
}

Sample response

{
  "strarr": ["basic", "email", "tel"],
  "byteval": "XlthLXowLTlfXXszLDh9JA=="
}