mirror of
https://github.com/cadmium-im/cadmium-docs-legacy.git
synced 2024-11-09 12:11:03 +00:00
Update core specifications, integrate ratelimit/protocol errors/authorization into core spec
This commit is contained in:
parent
8a83844dfc
commit
4772755006
@ -1,106 +0,0 @@
|
|||||||
# CPE#2 - In-band account login
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
This extension is intended for logging into user account on a server by username
|
|
||||||
|
|
||||||
## Message type identifiers
|
|
||||||
|
|
||||||
- `urn:cadmium:profile:login`
|
|
||||||
|
|
||||||
## Errors
|
|
||||||
|
|
||||||
- Ratelimit system: enabled
|
|
||||||
- `urn:cadmium:profile:login:invalid_creds`: user ID/password isn't valid
|
|
||||||
|
|
||||||
## Use cases
|
|
||||||
|
|
||||||
- Request:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "urn:cadmium:profile:login",
|
|
||||||
"to": ["cadmium.org"],
|
|
||||||
"payload": {
|
|
||||||
"username": "juliet",
|
|
||||||
"password": "romeo1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "urn:cadmium:profile:login",
|
|
||||||
"from": "cadmium.org",
|
|
||||||
"ok": true,
|
|
||||||
"payload": {
|
|
||||||
"authToken": "3b5135a5-aff5-4396-a629-a254f383e82f",
|
|
||||||
"deviceID": "ABCDEFG"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Error response:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "urn:cadmium:profile:login",
|
|
||||||
"from": "cadmium.org",
|
|
||||||
"ok": false,
|
|
||||||
"payload": {
|
|
||||||
"errID": "urn:cadmium:profile:login:invalid_creds",
|
|
||||||
"errText": "Username/password isn't valid"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Business Rules
|
|
||||||
|
|
||||||
None.
|
|
||||||
|
|
||||||
## JSON Schema
|
|
||||||
|
|
||||||
### Payload
|
|
||||||
|
|
||||||
- Request:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface LoginRequestPayload {
|
|
||||||
/**
|
|
||||||
* The username of account which user wants to login (can be omit if we set thirdPID)
|
|
||||||
*/
|
|
||||||
username: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Third party ID which have user (can be omit if we set username)
|
|
||||||
*/
|
|
||||||
thirdPID: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password of new account
|
|
||||||
*/
|
|
||||||
password: string
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Response:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface LoginResponsePayload {
|
|
||||||
/**
|
|
||||||
* Authentication token which required for various user actions (static SHA256 hash string from 4096 random characters)
|
|
||||||
*/
|
|
||||||
authToken: string,
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Identifier of new user device (created by this login action)
|
|
||||||
*/
|
|
||||||
deviceID: string
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,68 +0,0 @@
|
|||||||
# Basic request ratelimit system
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
This core extension is intended to limit the number of requests from clients per unit of time.
|
|
||||||
|
|
||||||
## Message type identifiers
|
|
||||||
|
|
||||||
None.
|
|
||||||
|
|
||||||
## Use cases
|
|
||||||
|
|
||||||
- Client:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "profile:register",
|
|
||||||
"to": "cadmium.org",
|
|
||||||
"payload": {
|
|
||||||
"username": "spam_spam_spam",
|
|
||||||
"thirdPIDs": [],
|
|
||||||
"password": "spam"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Server:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "profile:register",
|
|
||||||
"from": "cadmium.org",
|
|
||||||
"ok": false,
|
|
||||||
"payload": {
|
|
||||||
"errID": "ratelimit_exceed",
|
|
||||||
"errText": "Request ratelimit exceed! Please, try again later!",
|
|
||||||
"errPayload": {
|
|
||||||
"retryAfter": 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Errors
|
|
||||||
|
|
||||||
### Global errors
|
|
||||||
|
|
||||||
- `ratelimit_exceed`
|
|
||||||
|
|
||||||
## Business Rules
|
|
||||||
|
|
||||||
- Server MUST count number of requests per unit of time and drop new requests after specified number of made requests with Protocol Error message.
|
|
||||||
- Number of requests and used unit of time SHOULD be configurable on server
|
|
||||||
|
|
||||||
## JSON Schema
|
|
||||||
|
|
||||||
### Error payload
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface RatelimitExceedErrorPayload {
|
|
||||||
/**
|
|
||||||
* How long after the client can retry the request (in millis)
|
|
||||||
*/
|
|
||||||
retryAfter: number
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,18 +1,37 @@
|
|||||||
# Protocol Core
|
# Cadmium Protocol core specifications
|
||||||
|
|
||||||
- [Protocol Core](#protocol-core)
|
## 0. Table of content
|
||||||
- [Transport](#transport)
|
|
||||||
- [Federated Entity ID](#federated-entity-id)
|
|
||||||
- [Server-part](#server-part)
|
|
||||||
- [Username/Room alias/RoomID](#usernameroom-aliasroomid)
|
|
||||||
- [Special business rules](#special-business-rules)
|
|
||||||
- [BaseMessage](#basemessage)
|
|
||||||
|
|
||||||
## Transport
|
- [Cadmium Protocol core specifications](#cadmium-protocol-core-specifications)
|
||||||
|
- [0. Table of content](#0-table-of-content)
|
||||||
|
- [1. Transport](#1-transport)
|
||||||
|
- [2. Federated Entity ID](#2-federated-entity-id)
|
||||||
|
- [2.1. Server-part](#21-server-part)
|
||||||
|
- [2.2. Username/Room alias/RoomID](#22-usernameroom-aliasroomid)
|
||||||
|
- [2.3. Special business rules](#23-special-business-rules)
|
||||||
|
- [3. BaseMessage model](#3-basemessage-model)
|
||||||
|
- [4. Protocol Errors](#4-protocol-errors)
|
||||||
|
- [4.1. Use cases](#41-use-cases)
|
||||||
|
- [4.2. JSON Schema](#42-json-schema)
|
||||||
|
- [4.2.1. Payload](#421-payload)
|
||||||
|
- [5. Basic request ratelimit system](#5-basic-request-ratelimit-system)
|
||||||
|
- [5.1. Use cases](#51-use-cases)
|
||||||
|
- [5.2. Error types](#52-error-types)
|
||||||
|
- [5.2.1. Global error types](#521-global-error-types)
|
||||||
|
- [5.3. Business Rules](#53-business-rules)
|
||||||
|
- [5.4. JSON Schema](#54-json-schema)
|
||||||
|
- [5.4.1. Error payload](#541-error-payload)
|
||||||
|
- [6. User authorization](#6-user-authorization)
|
||||||
|
- [6.1. Message Type Identifier](#61-message-type-identifier)
|
||||||
|
- [6.2. Authorization types](#62-authorization-types)
|
||||||
|
- [6.3. Common Flow](#63-common-flow)
|
||||||
|
- [6.4. JSON Schema](#64-json-schema)
|
||||||
|
|
||||||
For starting we simply use JSON + Websockets.
|
## 1. Transport
|
||||||
|
|
||||||
## Federated Entity ID
|
We are using Websockets for underlying connections and JSON for message serialization format.
|
||||||
|
|
||||||
|
## 2. Federated Entity ID
|
||||||
|
|
||||||
Some reserved formats:
|
Some reserved formats:
|
||||||
|
|
||||||
@ -26,22 +45,22 @@ Some reserved formats:
|
|||||||
- Group Chat ID: `!<roomID>@<serverpart>`
|
- Group Chat ID: `!<roomID>@<serverpart>`
|
||||||
- Single server-part: `<serverpart>`
|
- Single server-part: `<serverpart>`
|
||||||
|
|
||||||
### Server-part
|
### 2.1. Server-part
|
||||||
|
|
||||||
- hostname: `IPv4 / [IPv6] / dns-domain:<port (1-65535)>` (for end-users use)
|
- hostname: `IPv4 / [IPv6] / dns-domain:<port (1-65535)>` (for end-users use)
|
||||||
- server ID: static SHA256 hash string from 4096 characters (for internal protocol use).
|
- server ID: static SHA256 hash string from 4096 characters (for internal protocol use).
|
||||||
- Generation example (using Linux): `echo -n $(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 4096 | head -n 1) | sha256sum`
|
- Generation example (using Linux): `echo -n $(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 4096 | head -n 1) | sha256sum`
|
||||||
|
|
||||||
### Username/Room alias/RoomID
|
### 2.2. Username/Room alias/RoomID
|
||||||
|
|
||||||
MUST NOT be empty, and MUST contain only the characters `a-z`, `0-9`, `.`, `_`, `=`, `-`, and `/`.
|
MUST NOT be empty, and MUST contain only the characters `a-z`, `0-9`, `.`, `_`, `=`, `-`, and `/`.
|
||||||
|
|
||||||
### Special business rules
|
### 2.3. Special business rules
|
||||||
|
|
||||||
- RoomID SHOULD be UUID identifier.
|
- Room ID MUST be UUID identifier.
|
||||||
- Servers MUST use server ID in internal purposes instead of normal server-part with hostname. Only end-users MUST use normal server-part with hostname. This is done for easy multi-domain serving.
|
- Servers MUST use server ID in internal purposes instead of normal server-part with hostname. Only end-users MUST use normal server-part with hostname. This is done for easy multi-domain serving.
|
||||||
|
|
||||||
## BaseMessage
|
## 3. BaseMessage model
|
||||||
|
|
||||||
BaseMessage is a basic message model, basis of the whole protocol. It is used for a very easy protocol extension process.
|
BaseMessage is a basic message model, basis of the whole protocol. It is used for a very easy protocol extension process.
|
||||||
|
|
||||||
@ -74,14 +93,241 @@ interface BaseMessage {
|
|||||||
*/
|
*/
|
||||||
ok: boolean,
|
ok: boolean,
|
||||||
|
|
||||||
/**
|
|
||||||
* Authentication token string (can be omit if the action does not require user authentication) - MUST be only in request messages from client
|
|
||||||
*/
|
|
||||||
authToken?: string,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message payload (used to store extra information in message, list of permissible fields in the payload depends on "type" field)
|
* Message payload (used to store extra information in message, list of permissible fields in the payload depends on "type" field)
|
||||||
*/
|
*/
|
||||||
payload: Map<K,V>
|
payload: Map<K,V>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 4. Protocol Errors
|
||||||
|
|
||||||
|
Mechanism of error processing is included into protocol.
|
||||||
|
Adds into any response message `ok` variable. If `ok` is true - we have no errors, if `ok` is false - we have an error.
|
||||||
|
|
||||||
|
### 4.1. Use cases
|
||||||
|
|
||||||
|
Client:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "incorrectMessageType",
|
||||||
|
"from": "@juliet@cadmium.im",
|
||||||
|
"to": "cadmium.im",
|
||||||
|
"payload": {
|
||||||
|
"test": "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Server:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "incorrectMessageType",
|
||||||
|
"from": "cadmium.im",
|
||||||
|
"to": "@juliet@cadmium.im",
|
||||||
|
"ok": false,
|
||||||
|
"payload": {
|
||||||
|
"errID": "unhandled",
|
||||||
|
"errText": "Incorrect type of message (type isn't implemented in the server)",
|
||||||
|
"errPayload": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2. JSON Schema
|
||||||
|
|
||||||
|
#### 4.2.1. Payload
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface ErrorPayload {
|
||||||
|
/**
|
||||||
|
* Error identifier (defined in extensions, maybe same per extensions)
|
||||||
|
*/
|
||||||
|
errID: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explanation of error in human-readable view
|
||||||
|
*/
|
||||||
|
errText: string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advanced error information (fields defined in extensions)
|
||||||
|
*/
|
||||||
|
errPayload: Map<K,V>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 5. Basic request ratelimit system
|
||||||
|
|
||||||
|
This system is intended to limit the number of requests from clients per unit of time.
|
||||||
|
|
||||||
|
### 5.1. Use cases
|
||||||
|
|
||||||
|
- Client:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "profile:register",
|
||||||
|
"to": "cadmium.org",
|
||||||
|
"payload": {
|
||||||
|
"username": "spam_spam_spam",
|
||||||
|
"thirdPIDs": [],
|
||||||
|
"password": "spam"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Server:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "profile:register",
|
||||||
|
"from": "cadmium.org",
|
||||||
|
"ok": false,
|
||||||
|
"payload": {
|
||||||
|
"errID": "ratelimit_exceed",
|
||||||
|
"errText": "Request ratelimit exceed! Please, try again later!",
|
||||||
|
"errPayload": {
|
||||||
|
"retryAfter": 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2. Error types
|
||||||
|
|
||||||
|
#### 5.2.1. Global error types
|
||||||
|
|
||||||
|
- `ratelimit_exceed`
|
||||||
|
|
||||||
|
### 5.3. Business Rules
|
||||||
|
|
||||||
|
- Server MUST count number of requests per unit of time and drop new requests after specified number of made requests with Protocol Error message.
|
||||||
|
- Number of requests and used unit of time SHOULD be configurable on server
|
||||||
|
|
||||||
|
### 5.4. JSON Schema
|
||||||
|
|
||||||
|
#### 5.4.1. Error payload
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface RatelimitExceedErrorPayload {
|
||||||
|
/**
|
||||||
|
* How long after the client can retry the request (in millis)
|
||||||
|
*/
|
||||||
|
retryAfter: number
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. User authorization
|
||||||
|
|
||||||
|
Authorization has multiple types which described in this document. Auth flow can vary depending on selected type of authentication. Common flow of auth is described in this document. When authorization was passed successfully, server must mark current session as authorized.
|
||||||
|
|
||||||
|
### 6.1. Message Type Identifier
|
||||||
|
|
||||||
|
`urn:cadmium:auth`
|
||||||
|
|
||||||
|
### 6.2. Authorization types
|
||||||
|
|
||||||
|
- `urn:cadmium:auth:types:login_password` - simple login/pass authorization
|
||||||
|
- `urn:cadmium:auth:types:token` - authorization by token
|
||||||
|
|
||||||
|
### 6.3. Common Flow
|
||||||
|
|
||||||
|
Flow for user authorization (in this example type of auth is `login_password` and `token`):
|
||||||
|
|
||||||
|
1. User obtains correct user/pass pair.
|
||||||
|
2. User sends this pair to server:
|
||||||
|
|
||||||
|
C->S:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "urn:cadmium:auth",
|
||||||
|
"to": ["cadmium.org"],
|
||||||
|
"payload": {
|
||||||
|
"type": "urn:cadmium:auth:types:login_password",
|
||||||
|
"fields": {
|
||||||
|
"username": "juliet",
|
||||||
|
"password": "romeo1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
S->C:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "urn:cadmium:auth",
|
||||||
|
"from": "cadmium.org",
|
||||||
|
"ok": true,
|
||||||
|
"payload": {
|
||||||
|
"token": "3b5135a5-aff5-4396-a629-a254f383e82f",
|
||||||
|
"deviceID": "ABCDEFG"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Afterwards, user uses obtained auth token for every new session to authorize it:
|
||||||
|
|
||||||
|
C->S:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "urn:cadmium:auth",
|
||||||
|
"to": ["cadmium.org"],
|
||||||
|
"payload": {
|
||||||
|
"type": "urn:cadmium:auth:types:token",
|
||||||
|
"fields": {
|
||||||
|
"token": "3b5135a5-aff5-4396-a629-a254f383e82f",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
S->C:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "abcd",
|
||||||
|
"type": "urn:cadmium:auth",
|
||||||
|
"from": "cadmium.org",
|
||||||
|
"ok": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.4. JSON Schema
|
||||||
|
|
||||||
|
Request:
|
||||||
|
```typescript
|
||||||
|
interface AuthReq {
|
||||||
|
type: string; // type of authorization
|
||||||
|
fields: AuthFields; // auth fields (depends on type of auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AuthFields {}
|
||||||
|
|
||||||
|
interface LoginPassFields : AuthFields {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TokenFields : AuthFields {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```typescript
|
||||||
|
interface AuthResp {
|
||||||
|
token: string; // newly created authorization token
|
||||||
|
deviceID: string; // ID of newly created device (session id in other words)
|
||||||
|
}
|
||||||
|
```
|
@ -1,66 +0,0 @@
|
|||||||
# Protocol Errors
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Mechanism of error processing included into protocol.
|
|
||||||
Adds into any response message `ok` variable. If `ok` is true - we have no errors, if `ok` is false - we have an error.
|
|
||||||
|
|
||||||
## Message type identifiers
|
|
||||||
|
|
||||||
None.
|
|
||||||
|
|
||||||
## Use cases
|
|
||||||
|
|
||||||
*Request*:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "incorrectMessageType",
|
|
||||||
"from": "@juliet@cadmium.im",
|
|
||||||
"to": "cadmium.im",
|
|
||||||
"payload": {
|
|
||||||
"test": "test"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
*Response*:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "abcd",
|
|
||||||
"type": "incorrectMessageType",
|
|
||||||
"from": "cadmium.im",
|
|
||||||
"to": "@juliet@cadmium.im",
|
|
||||||
"ok": false,
|
|
||||||
"payload": {
|
|
||||||
"errID": "unhandled",
|
|
||||||
"errText": "Incorrect type of message (type isn't implemented in the server)",
|
|
||||||
"errPayload": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## JSON Schema
|
|
||||||
|
|
||||||
### Payload
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
interface ErrorPayload {
|
|
||||||
/**
|
|
||||||
* Error identifier (defined in extensions, maybe same per extensions)
|
|
||||||
*/
|
|
||||||
errID: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Explanation of error in human-readable view
|
|
||||||
*/
|
|
||||||
errText: string,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advanced error information (fields defined in extensions)
|
|
||||||
*/
|
|
||||||
errPayload: Map<K,V>
|
|
||||||
}
|
|
||||||
```
|
|
Loading…
Reference in New Issue
Block a user