# #1: Suggestion on a Telodendria Admin API. This is a suggestion of how the admin API should work; it is subject to heavy changes. It also acts as a suggestion on how suggestions should be written. It might not be accepted, or the format might be changed heavily. ## "Admin" users. Like in Synapse, there should be a field dictating if the user is an admin, and unlike Synapse, there should be privilege levels. In the `[dataroot]/users/[user].json` file, there should be a field called `"privileges"` which contains a list of strings. ```json { "devices": { "foobar": { ... } }, "salt": "salt goes here", "deactivated": false, "createdOn": 1700000000000, "password": "hash goes here", "privileges": [ "DEACTIVATE", "ISSUE_TOKENS" ] } ``` ## Privileges list Here are all of the admin privileges a user can have: - DEACTIVATE: This allows an user to deactivate/reactivate any users using the DELETE /_telodendria/admin/disable/[localpart] endpoint - ISSUE_TOKENS: This allows users to create, modify and delete registration tokens. - CREATE_USERS: Allows users with such privilege to create new users even if registration is completely turned off. - ALL: Users with this privilege can use *any* admin endpoint(and some others) **THIS PRIVILEGE SHOULD ONLY BE USED WITH *TRUSTED* USERS.** ## Admin endpoints ### GET `/_telodendria/admin/privileges` |Requires token|Rate limited| |--------------|------------| |YES |YES | |Error response|Description | |--------------|------------------------| |200 |User was sucessfully | | |deactivated. | 200 Response JSON Format: |Field |Type |Description | |-----------|-----------|-------------------------------------------------| |privileges |list |The same data structure as in `users/[user].json`| 200 Response Example: ```json { "privileges": [ "DEACTIVATE", "REMOVE_DEVICES" ] } ``` ### DELETE `/_telodendria/admin/deactivate/[localpart]` |Requires token|Rate limited|Permissions| |--------------|------------|-----------| |YES |YES |DEACTIVATE | Description: Deactivates a local user, optionally with a reason. Request JSON Format: |Field |Type |Description |Required| |-----------|-----------|---------------------|--------| |reason |string |A reason why the |NO | | | |user was deactivated.| | Request Example: ```json { "reason": "Being mean in a lot of rooms." } ``` |Error response|Description | |--------------|------------------------| |200 |User was sucessfully | | |deactivated. | |--------------|------------------------| |403 |User does not have the | | |DEACTIVATE permission | 200 Response JSON Format: |Field |Type |Description | |-----------|-----------|-----------------------| |user |localpart |The deactivated user's | | | |localpart | |-----------|-----------|-----------------------| |reason |string |The reason the user | | | |was deactivacted. | | | |Defaults to: | | | |"Deactivated by admin" | |-----------|-----------|-----------------------| |banned_by |localpart |The localpart of the | | | |admin who deactivated | | | |the user. 403 Response JSON Format: |Field |Type |Description | |-----------|-----------|-----------------------| |errcode |string |Set to "M_FORBIDDEN" | |-----------|-----------|-----------------------| |error |string |Human-readable explain-| | | |ation of the privilege | | | |issue. | 200 Response Example: ```json { "user": "evan", "reason": "Being mean in a lot of rooms", "banned_by": "alice" } ``` 403 Response Example: ``` { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ``` ### PUT `/_telodendria/admin/deactivate/[localpart]` |Requires token|Rate limited|Permissions| |--------------|------------|-----------| |YES |YES |DEACTIVATE | Description: Reactivates a local user. |Error response|Description | |--------------|------------------------| |204 |User was sucessfully | | |reactivated. | |--------------|------------------------| |403 |User does not have the | | |DEACTIVATE permission | 403 Response JSON Format: |Field |Type |Description | |-----------|-----------|-----------------------| |errcode |string |Set to "M_FORBIDDEN" | |-----------|-----------|-----------------------| |error |string |Human-readable explain-| | | |ation of the privilege | | | |issue. | 403 Response Example: ``` { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ``` ### GET `/_telodendria/admin/tokens` |Requires token|Rate limited|Permissions | |--------------|------------|------------| |YES |YES |ISSUE_TOKENS| Description: Gets a list of *all* tokens present, and additional information. |Error response|Description | |--------------|---------------------------| |200 |Token list was sucessfully | | |retrieved | |--------------|---------------------------| |403 |User does not have the | | |ISSUE_TOKENS permission. | 200 Response JSON Format: |Field |Type |Description | |-----------|----------------------|-----------------------| |tokens |list[`TokenInfo`] |A list of tokens and | | | |other information. | `TokenInfo` JSON Format: |Field |Type |Description | |-----------|----------------------|-------------------------| |name |string |The token's name. | |-----------|----------------------|-------------------------| |created_by |localpart |The user who has created | | | |the token's localpart | |-----------|----------------------|-------------------------| |created_on |timestamp |The creation date of the | | | |token. | |-----------|----------------------|-------------------------| |expires_on |timestamp |The token's expiry date | | | |NOTE: If token does not | | | |expire, it is set to 0 | |-----------|----------------------|-------------------------| |used |integer |The number of times the | | | |token was used | |-----------|----------------------|-------------------------| |uses |integer |The number of uses for a | | | |token. | | | |NOTE: If token has unli- | | | |mited mumber of uses, | | | |set to 0 | 403 Response JSON Format: |Field |Type |Description | |-----------|-----------|-----------------------| |errcode |string |Set to "M_FORBIDDEN" | |-----------|-----------|-----------------------| |error |string |Human-readable explain-| | | |ation of the privilege | | | |issue. | 200 Response Example: ```json { "tokens": [ { "name": "forbob", "created_by": "alice", "created_on": 1234567890123, "expires_on": 2147483647000, "used": 1, "uses": 3 } ] } ``` 403 Response JSON Format: ```json { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ``` ### GET `/_telodendria/admin/tokens/[token]` |Requires token|Rate limited|Permissions | |--------------|------------|------------| |YES |YES |ISSUE_TOKENS| Description: Returns information about a specific registration token. |error response|description | |--------------|---------------------------| |200 |token info was sucessfully | | |retrieved | |--------------|---------------------------| |403 |user does not have the | | |ISSUE_TOKENS permission. | |--------------|---------------------------| |404 |Token does not exist. | 200 Response JSON Format: |Field |Type |Description | |-----------|----------------------|-------------------------| |name |string |The token's name. | |-----------|----------------------|-------------------------| |created_by |localpart |The user who has created | | | |the token's localpart | |-----------|----------------------|-------------------------| |created_on |timestamp |The creation date of the | | | |token. | |-----------|----------------------|-------------------------| |expires_on |timestamp |The token's expiry date | | | |NOTE: If token does not | | | |expire, it is not set. | |-----------|----------------------|-------------------------| |used |integer |The number of times the | | | |token was used | |-----------|----------------------|-------------------------| |uses |integer |The number of uses for | | | |the token. | | | |NOTE: If token has unli- | | | |mited mumber of uses, it | | | |is not set. | 200 Response Example: ```json { "name": "forbob", "created_by": "alice", "created_on": 1234567890123, "used": 1, "uses": 3 } ``` ### POST `/_telodendria/admin/tokens` |Requires token|Rate limited|Permissions | |--------------|------------|------------| |YES |YES |ISSUE_TOKENS| Description: Adds a registration token, and setup expiry date and max uses. Request JSON Format: |Field |Type |Description |Required| |-----------|-----------|----------------------|--------| |expires |timestamp |The timestamp for this|NO | | | |token's expiry. | | |-----------|-----------|----------------------|--------| |max_uses |integer |The maximum number of |NO | | | |uses for this token | | |-----------|-----------|----------------------|--------| |name |string |A name for the token. |NO | | | |If none is set, a ran-| | | | |domly generated string| | | | |is made. | | Request Example: ```json { "name": "OnlyClownsM7iAhUJD", "expires": 2147484637000, "max_uses": 5 } ``` |Error response|Description | |--------------|---------------------------| |200 |Token was sucessfully crea-| | |ted | |--------------|---------------------------| |403 |User does not have the | | |ISSUE_TOKENS permission. | 200 Response JSON Format: |Field |Type |Description | |-----------|----------------------|-------------------------| |name |string |The token's name. | |-----------|----------------------|-------------------------| |created_by |localpart |The user who has created | | | |the token's localpart | |-----------|----------------------|-------------------------| |created_on |timestamp |The creation date of the | | | |token. | |-----------|----------------------|-------------------------| |expires_on |timestamp |The token's expiry date | | | |NOTE: If token does not | | | |expire, it is not set. | |-----------|----------------------|-------------------------| |used |integer |The number of times the | | | |token was used | |-----------|----------------------|-------------------------| |uses |integer |The number of uses for | | | |the token. | | | |NOTE: If token has unli- | | | |mited mumber of uses, it | | | |is not set. | 200 Response Example: ```json { "name": "OnlyClownsM7iAhUJD", "created_by": "donald", "created_on": 1234567890123, "expires_on": 2147484637000, "used": 0, "uses": 5 } ``` 403 Response JSON Format: ```json { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ``` ### DELETE /_telodendria/admin/tokens/[tokenname] |Requires token|Rate limited|Permissions | |--------------|------------|------------| |YES |YES |ISSUE_TOKENS| Description: Deletes an existing registration token. |Error response|Description | |--------------|---------------------------| |204 |Token was sucessfully dele-| | |ted | |--------------|---------------------------| |403 |User does not have the | | |ISSUE_TOKENS permission. | 403 Response JSON Format: ```json { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ``` ### POST /_telodendria/admin/user/create |Requires token|Rate limited|Permissions | |--------------|------------|------------| |YES |YES |CREATE_USERS| Description: Creates a new user with password login. **NOTE**: This does not make the user login. Request JSON Format: |Field |Type |Description |Required| |-------------|-----------|----------------------|--------| |name |localpart |The created user's lo-|YES | | | |calpart. | | |-------------|-----------|----------------------|--------| |password |string |The created user's |YES | | | |password. | | Request Example: ```json { "name": "edward", "password": "verysecurepassworddontworryaboutittoomuch" } ``` |Error response|Description | |--------------|-----------------------------| |204 |User was sucessfully created.| |--------------|-----------------------------| |403 |User does not have the | | |CREATE_USERS permission. | 403 Response JSON Format: ```json { "errcode": "M_FORBIDDEN", "error": "Forbidden access. Bad permissions or not authenticated." } ```