# #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.

    - 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`

Get the priviledges of the user that owns the provided access token.

|Requires token|Rate limited|
|--------------|------------|
|YES           |YES         |


|Error response|Description             |
|--------------|------------------------|
|200           |Privileges successfully |
|              |returned.               |

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]`

Deactivates a local user, optionally with a reason.

|Requires token|Rate limited|Permissions|
|--------------|------------|-----------|
|YES           |YES         |DEACTIVATE |

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`

Gets a list of *all* tokens present, and additional information.

|Requires token|Rate limited|Permissions |
|--------------|------------|------------|
|YES           |YES         |ISSUE_TOKENS|

|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]`

Returns information about a specific registration token.

|Requires token|Rate limited|Permissions |
|--------------|------------|------------|
|YES           |YES         |ISSUE_TOKENS|  

|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`

Adds a registration token, and setup expiry date and max uses.

|Requires token|Rate limited|Permissions |
|--------------|------------|------------|
|YES           |YES         |ISSUE_TOKENS|  

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."
}
```