Update core specifications, integrate ratelimit/protocol errors/authorization into core spec

This commit is contained in:
ChronosX88 2021-03-08 13:31:34 +03:00
parent 8a83844dfc
commit 4772755006
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
4 changed files with 267 additions and 261 deletions

View File

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

View File

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

View File

@ -1,18 +1,37 @@
# Protocol Core
# Cadmium Protocol core specifications
- [Protocol Core](#protocol-core)
- [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)
## 0. Table of content
## 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:
@ -26,22 +45,22 @@ Some reserved formats:
- Group Chat ID: `!<roomID>@<serverpart>`
- Single server-part: `<serverpart>`
### Server-part
### 2.1. Server-part
- 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).
- 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 `/`.
### 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.
## 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.
@ -74,14 +93,241 @@ interface BaseMessage {
*/
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)
*/
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)
}
```

View File

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