Merge remote-tracking branch 'origin/master' into kitsune/cleanup
commit
8e7c0dfb93
@ -0,0 +1,50 @@
|
|||||||
|
# Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
type: object
|
||||||
|
title: KeyBackupData
|
||||||
|
description: "The key data"
|
||||||
|
properties:
|
||||||
|
first_message_index:
|
||||||
|
description: |-
|
||||||
|
The index of the first message in the session that the key can decrypt.
|
||||||
|
type: integer
|
||||||
|
example: 1
|
||||||
|
forwarded_count:
|
||||||
|
description: |-
|
||||||
|
The number of times this key has been forwarded via key-sharing between devices.
|
||||||
|
type: integer
|
||||||
|
example: 0
|
||||||
|
is_verified:
|
||||||
|
description: |-
|
||||||
|
Whether the device backing up the key verified the device that the key
|
||||||
|
is from.
|
||||||
|
type: boolean
|
||||||
|
example: false
|
||||||
|
session_data:
|
||||||
|
description: |-
|
||||||
|
Algorithm-dependent data. See the documentation for the backup
|
||||||
|
algorithms in `Server-side key backups`_ for more information on the
|
||||||
|
expected format of the data.
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"ephemeral": "base64+ephemeral+key",
|
||||||
|
"ciphertext": "base64+ciphertext+of+JSON+data",
|
||||||
|
"mac": "base64+mac+of+ciphertext"
|
||||||
|
}
|
||||||
|
required:
|
||||||
|
- first_message_index
|
||||||
|
- forwarded_count
|
||||||
|
- is_verified
|
||||||
|
- session_data
|
@ -0,0 +1,940 @@
|
|||||||
|
# Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server Key Backup API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
"/room_keys/version":
|
||||||
|
post:
|
||||||
|
summary: Create a new backup.
|
||||||
|
description: |-
|
||||||
|
Creates a new backup.
|
||||||
|
operationId: postRoomKeysVersion
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: version
|
||||||
|
description: "The backup configuration."
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
description: The algorithm used for storing backups.
|
||||||
|
type: string
|
||||||
|
enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
|
||||||
|
example: "m.megolm_backup.v1.curve25519-aes-sha2"
|
||||||
|
auth_data:
|
||||||
|
description: |-
|
||||||
|
Algorithm-dependent data. See the documentation for the backup
|
||||||
|
algorithms in `Server-side key backups`_ for more information on the
|
||||||
|
expected format of the data.
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"public_key": "abcdefg",
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.org": {
|
||||||
|
"ed25519:deviceid": "signature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- auth_data
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description:
|
||||||
|
The version id of the new backup.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
description: The backup version. This is an opaque string.
|
||||||
|
example: "1"
|
||||||
|
required:
|
||||||
|
- version
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
get:
|
||||||
|
summary: Get information about the latest backup version.
|
||||||
|
description: |-
|
||||||
|
Get information about the latest backup version.
|
||||||
|
operationId: getRoomKeysVersionCurrent
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description:
|
||||||
|
The information about the backup.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
description: The algorithm used for storing backups.
|
||||||
|
enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
|
||||||
|
example: "m.megolm_backup.v1.curve25519-aes-sha2"
|
||||||
|
auth_data:
|
||||||
|
description: |-
|
||||||
|
Algorithm-dependent data. See the documentation for the backup
|
||||||
|
algorithms in `Server-side key backups`_ for more information on the
|
||||||
|
expected format of the data.
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"public_key": "abcdefg",
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.org": {
|
||||||
|
"ed25519:deviceid": "signature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup.
|
||||||
|
type: integer
|
||||||
|
example: 42
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
An opaque string representing stored keys in the backup.
|
||||||
|
Clients can compare it with the ``etag`` value they received
|
||||||
|
in the request of their last key storage request. If not
|
||||||
|
equal, another client has modified the backup.
|
||||||
|
type: string
|
||||||
|
example: "anopaquestring"
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
description: The backup version
|
||||||
|
example: "1"
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- auth_data
|
||||||
|
- count
|
||||||
|
- etag
|
||||||
|
- version
|
||||||
|
404:
|
||||||
|
description:
|
||||||
|
No backup exists.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "No current backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
"/room_keys/version/{version}":
|
||||||
|
get:
|
||||||
|
summary: Get information about an existing backup.
|
||||||
|
description: |-
|
||||||
|
Get information about an existing backup.
|
||||||
|
operationId: getRoomKeysVersion
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup version to get, as returned in the ``version`` parameter
|
||||||
|
of the response in `POST /_matrix/client/r0/room_keys/version`_ or
|
||||||
|
this endpoint.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description:
|
||||||
|
The information about the requested backup.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
description: The algorithm used for storing backups.
|
||||||
|
enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
|
||||||
|
example: "m.megolm_backup.v1.curve25519-aes-sha2"
|
||||||
|
auth_data:
|
||||||
|
description: |-
|
||||||
|
Algorithm-dependent data. See the documentation for the backup
|
||||||
|
algorithms in `Server-side key backups`_ for more information on the
|
||||||
|
expected format of the data.
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"public_key": "abcdefg",
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.org": {
|
||||||
|
"ed25519:deviceid": "signature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup.
|
||||||
|
type: integer
|
||||||
|
example: 42
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
An opaque string representing stored keys in the backup.
|
||||||
|
Clients can compare it with the ``etag`` value they received
|
||||||
|
in the request of their last key storage request. If not
|
||||||
|
equal, another client has modified the backup.
|
||||||
|
type: string
|
||||||
|
example: "anopaquestring"
|
||||||
|
version:
|
||||||
|
type: string
|
||||||
|
description: The backup version
|
||||||
|
example: "1"
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- auth_data
|
||||||
|
- count
|
||||||
|
- etag
|
||||||
|
- version
|
||||||
|
404:
|
||||||
|
description:
|
||||||
|
The backup specified does not exist.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
put:
|
||||||
|
summary: Update information about an existing backup.
|
||||||
|
description: |-
|
||||||
|
Update information about an existing backup. Only ``auth_data`` can be modified.
|
||||||
|
operationId: putRoomKeysVersion
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup version to update, as returned in the ``version``
|
||||||
|
parameter in the response of `POST
|
||||||
|
/_matrix/client/r0/room_keys/version`_ or `GET
|
||||||
|
/_matrix/client/r0/room_keys/version/{version}`_.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: body
|
||||||
|
name: version
|
||||||
|
description: "The backup configuration"
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
description: |-
|
||||||
|
The algorithm used for storing backups. Must be the same as
|
||||||
|
the algorithm currently used by the backup.
|
||||||
|
type: string
|
||||||
|
enum: ["m.megolm_backup.v1.curve25519-aes-sha2"]
|
||||||
|
example: "m.megolm_backup.v1.curve25519-aes-sha2"
|
||||||
|
auth_data:
|
||||||
|
description: |-
|
||||||
|
Algorithm-dependent data. See the documentation for the backup
|
||||||
|
algorithms in `Server-side key backups`_ for more information on the
|
||||||
|
expected format of the data.
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"public_key": "abcdefg",
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.org": {
|
||||||
|
"ed25519:deviceid": "signature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version:
|
||||||
|
description: |-
|
||||||
|
The backup version. If present, must be the same as the
|
||||||
|
version in the path parameter.
|
||||||
|
type: string
|
||||||
|
example: "1"
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- auth_data
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties: {}
|
||||||
|
400:
|
||||||
|
description: |-
|
||||||
|
A parameter was incorrect. For example, the ``algorithm`` does not
|
||||||
|
match the current backup algorithm, or the ``version`` in the body
|
||||||
|
does not match the ``version`` in the path.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_INVALID_PARAM",
|
||||||
|
"error": "Algorithm does not match"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
404:
|
||||||
|
description: The backup specified does not exist.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
delete:
|
||||||
|
summary: Delete an existing key backup.
|
||||||
|
description: |-
|
||||||
|
Delete an existing key backup. Both the information about the backup,
|
||||||
|
as well as all key data related to the backup will be deleted.
|
||||||
|
operationId: deleteRoomKeysVersion
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup version to delete, as returned in the ``version``
|
||||||
|
parameter in the response of `POST
|
||||||
|
/_matrix/client/r0/room_keys/version`_ or `GET
|
||||||
|
/_matrix/client/r0/room_keys/version/{version}`_.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |-
|
||||||
|
The delete succeeded, or the specified backup was previously
|
||||||
|
deleted.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties: {}
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup specified does not exist. If the backup was previously
|
||||||
|
deleted, the call should succeed rather than returning an error.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
"/room_keys/keys/{roomId}/{sessionId}":
|
||||||
|
put:
|
||||||
|
summary: Store a key in the backup.
|
||||||
|
description: |-
|
||||||
|
Store a key in the backup.
|
||||||
|
operationId: postRoomKeysKeyRoomIdSessionId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup in which to store the key. Must be the current backup.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: sessionId
|
||||||
|
description: The ID of the megolm session that the key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "sessionid"
|
||||||
|
- in: body
|
||||||
|
name: data
|
||||||
|
description: "The key data."
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/key_backup_data.yaml"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
403:
|
||||||
|
description: |-
|
||||||
|
The version specified does not match the current backup version.
|
||||||
|
The current version will be included in the ``current_version``
|
||||||
|
field.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_WRONG_ROOM_KEYS_VERSION",
|
||||||
|
"error": "Wrong backup version.",
|
||||||
|
"current_version": "42"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
get:
|
||||||
|
summary: Retrieve a key from the backup
|
||||||
|
description: |-
|
||||||
|
Retrieve a key from the backup.
|
||||||
|
operationId: getRoomKeysKeyRoomIdSessionId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to retrieve the key
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the requested key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: sessionId
|
||||||
|
description: The ID of the megolm session whose key is requested.
|
||||||
|
required: true
|
||||||
|
x-example: "sessionid"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The key data
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/key_backup_data.yaml"
|
||||||
|
404:
|
||||||
|
description: The key or backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Key not found."
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
delete:
|
||||||
|
summary: Delete a key from the backup
|
||||||
|
description: |-
|
||||||
|
Delete a key from the backup.
|
||||||
|
operationId: deleteRoomKeysKeyRoomIdSessionId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to delete the key
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the specified key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: sessionId
|
||||||
|
description: The ID of the megolm session whose key is to be deleted.
|
||||||
|
required: true
|
||||||
|
x-example: "sessionid"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
"/room_keys/keys/{roomId}":
|
||||||
|
put:
|
||||||
|
summary: Store several keys in the backup for a given room.
|
||||||
|
description: |-
|
||||||
|
Store a key in the backup.
|
||||||
|
operationId: postRoomKeysKeyRoomId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup in which to store the keys. Must be the current backup.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the keys are for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
- in: body
|
||||||
|
description: "The backup data"
|
||||||
|
name: backupData
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sessions:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
A map of session IDs to key data.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: "definitions/key_backup_data.yaml"
|
||||||
|
example: {
|
||||||
|
"sessionid1": {
|
||||||
|
"ephemeral": "base64+ephemeral+key",
|
||||||
|
"ciphertext": "base64+ciphertext+of+JSON+data",
|
||||||
|
"mac": "base64+mac+of+ciphertext"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
403:
|
||||||
|
description: |-
|
||||||
|
The version specified does not match the current backup version.
|
||||||
|
The current version will be included in the ``current_version``
|
||||||
|
field.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_WRONG_ROOM_KEYS_VERSION",
|
||||||
|
"error": "Wrong backup version.",
|
||||||
|
"current_version": "42"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
get:
|
||||||
|
summary: Retrieve the keys from the backup for a given room
|
||||||
|
description: |-
|
||||||
|
Retrieve the keys from the backup for a given room
|
||||||
|
operationId: getRoomKeysKeyRoomId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to retrieve the key
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the requested key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |-
|
||||||
|
The key data. If no keys are found, then an object with an empty
|
||||||
|
``sessions`` property will be returned (``{"sessions": {}}``).
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sessions:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
A map of session IDs to key data.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: "definitions/key_backup_data.yaml"
|
||||||
|
example: {
|
||||||
|
"sessionid1": {
|
||||||
|
"ephemeral": "base64+ephemeral+key",
|
||||||
|
"ciphertext": "base64+ciphertext+of+JSON+data",
|
||||||
|
"mac": "base64+mac+of+ciphertext"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
delete:
|
||||||
|
summary: Delete a key from the backup
|
||||||
|
description: |-
|
||||||
|
Delete a key from the backup.
|
||||||
|
operationId: deleteRoomKeysKeyRoomId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to delete the key
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: path
|
||||||
|
type: string
|
||||||
|
name: roomId
|
||||||
|
description: The ID of the room that the specified key is for.
|
||||||
|
required: true
|
||||||
|
x-example: "!roomid:example.org"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
"/room_keys/keys":
|
||||||
|
put:
|
||||||
|
summary: Store several keys in the backup.
|
||||||
|
description: |-
|
||||||
|
Store several keys in the backup.
|
||||||
|
operationId: postRoomKeysKey
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup in which to store the keys. Must be the current backup.
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
- in: body
|
||||||
|
description: "The backup data"
|
||||||
|
name: backupData
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
rooms:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
A map of room IDs to session IDs to key data.
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: "definitions/key_backup_data.yaml"
|
||||||
|
example: {
|
||||||
|
"!room:example.org": {
|
||||||
|
"sessions": {
|
||||||
|
"sessionid1": {
|
||||||
|
"ephemeral": "base64+ephemeral+key",
|
||||||
|
"ciphertext": "base64+ciphertext+of+JSON+data",
|
||||||
|
"mac": "base64+mac+of+ciphertext"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
403:
|
||||||
|
description: |-
|
||||||
|
The version specified does not match the current backup version.
|
||||||
|
The current version will be included in the ``current_version``
|
||||||
|
field.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_WRONG_ROOM_KEYS_VERSION",
|
||||||
|
"error": "Wrong backup version.",
|
||||||
|
"current_version": "42"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
tags:
|
||||||
|
- End-to-end encryption
|
||||||
|
get:
|
||||||
|
summary: Retrieve the keys from the backup for a given room
|
||||||
|
description: |-
|
||||||
|
Retrieve the keys from the backup for a given room
|
||||||
|
operationId: getRoomKeysKeyRoomId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to retrieve the keys. If omitted, the keys are
|
||||||
|
retrieved from the current backup.
|
||||||
|
x-example: "1"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |-
|
||||||
|
The key data. If no keys are found, then an object with an empty
|
||||||
|
``rooms`` property will be returned (``{"rooms": {}}``).
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
rooms:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
A map of room IDs to session IDs to key data.
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: "definitions/key_backup_data.yaml"
|
||||||
|
example: {
|
||||||
|
"!room:example.org": {
|
||||||
|
"sessions": {
|
||||||
|
"sessionid1": {
|
||||||
|
"ephemeral": "base64+ephemeral+key",
|
||||||
|
"ciphertext": "base64+ciphertext+of+JSON+data",
|
||||||
|
"mac": "base64+mac+of+ciphertext"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
404:
|
||||||
|
description: The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version."
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
||||||
|
delete:
|
||||||
|
summary: Delete a key from the backup
|
||||||
|
description: |-
|
||||||
|
Delete a key from the backup.
|
||||||
|
operationId: deleteRoomKeysKeyRoomId
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
type: string
|
||||||
|
name: version
|
||||||
|
description: |-
|
||||||
|
The backup from which to delete the key
|
||||||
|
required: true
|
||||||
|
x-example: "1"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The update succeeded
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
etag:
|
||||||
|
description: |-
|
||||||
|
The new etag value representing stored keys in the backup.
|
||||||
|
See ``GET /room_keys/version/{version}`` for more details.
|
||||||
|
type: string
|
||||||
|
example: "abcdefg"
|
||||||
|
count:
|
||||||
|
description: The number of keys stored in the backup
|
||||||
|
type: integer
|
||||||
|
example: 10
|
||||||
|
required:
|
||||||
|
- etag
|
||||||
|
- count
|
||||||
|
404:
|
||||||
|
description: |-
|
||||||
|
The backup was not found.
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"errcode": "M_NOT_FOUND",
|
||||||
|
"error": "Unknown backup version"
|
||||||
|
}
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/error.yaml"
|
||||||
|
429:
|
||||||
|
description: This request was rate-limited.
|
||||||
|
schema:
|
||||||
|
"$ref": "definitions/errors/rate_limited.yaml"
|
@ -0,0 +1,58 @@
|
|||||||
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
type: object
|
||||||
|
title: Room State
|
||||||
|
description: The state for the room.
|
||||||
|
properties:
|
||||||
|
origin:
|
||||||
|
type: string
|
||||||
|
description: The resident server's DNS name.
|
||||||
|
auth_chain:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
The auth chain for the entire current room state prior to the join event.
|
||||||
|
|
||||||
|
Note that events have a different format depending on the room version - check the
|
||||||
|
`room version specification`_ for precise event formats.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
title: PDU
|
||||||
|
description: |-
|
||||||
|
The `PDUs <#pdus>`_ that make up the auth chain. The event format varies depending
|
||||||
|
on the room version - check the `room version specification`_ for precise event formats.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties: []
|
||||||
|
example:
|
||||||
|
$ref: "../examples/minimal_pdu.json"
|
||||||
|
state:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
The resolved current room state prior to the join event.
|
||||||
|
|
||||||
|
The event format varies depending on the room version - check the `room version specification`_
|
||||||
|
for precise event formats.
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
title: PDU
|
||||||
|
description: |-
|
||||||
|
The `PDUs <#pdus>`_ for the fully resolved state of the room. The event format varies depending
|
||||||
|
on the room version - check the `room version specification`_ for precise event formats.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties: []
|
||||||
|
example:
|
||||||
|
$ref: "../examples/minimal_pdu.json"
|
||||||
|
required: ["auth_chain", "state", "origin"]
|
@ -0,0 +1,136 @@
|
|||||||
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Federation Join Room API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8448
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
basePath: /_matrix/federation/v2
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
# Note: there is no v2 of make_join (yet)
|
||||||
|
"/send_join/{roomId}/{eventId}":
|
||||||
|
put:
|
||||||
|
summary: Submit a signed join event to a resident server
|
||||||
|
description: |-
|
||||||
|
.. Note::
|
||||||
|
This API is nearly identical to the v1 API with the
|
||||||
|
exception of the response format being fixed.
|
||||||
|
|
||||||
|
This endpoint is preferred over the v1 API as it provides
|
||||||
|
a more standarised response format. Senders which receive
|
||||||
|
a 400, 404, or other status code which indicates this endpoint
|
||||||
|
is not available should retry using the v1 API instead.
|
||||||
|
|
||||||
|
Submits a signed join event to the resident server for it
|
||||||
|
to accept it into the room's graph. Note that events have
|
||||||
|
a different format depending on the room version - check
|
||||||
|
the `room version specification`_ for precise event formats.
|
||||||
|
**The request and response body here describe the common
|
||||||
|
event fields in more detail and may be missing other required
|
||||||
|
fields for a PDU.**
|
||||||
|
operationId: sendJoinV2
|
||||||
|
security:
|
||||||
|
- signedRequest: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: roomId
|
||||||
|
type: string
|
||||||
|
description: The room ID that is about to be joined.
|
||||||
|
required: true
|
||||||
|
x-example: "!abc123:matrix.org"
|
||||||
|
- in: path
|
||||||
|
name: eventId
|
||||||
|
type: string
|
||||||
|
description: The event ID for the join event.
|
||||||
|
required: true
|
||||||
|
x-example: "$abc123:example.org"
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
type: object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sender:
|
||||||
|
type: string
|
||||||
|
description: The user ID of the joining member.
|
||||||
|
example: "@someone:example.org"
|
||||||
|
origin:
|
||||||
|
type: string
|
||||||
|
description: The name of the joining homeserver.
|
||||||
|
example: "matrix.org"
|
||||||
|
origin_server_ts:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: A timestamp added by the joining homeserver.
|
||||||
|
example: 1234567890
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
description: The value ``m.room.member``.
|
||||||
|
example: "m.room.member"
|
||||||
|
state_key:
|
||||||
|
type: string
|
||||||
|
description: The user ID of the joining member.
|
||||||
|
example: "@someone:example.org"
|
||||||
|
content:
|
||||||
|
type: object
|
||||||
|
title: Membership Event Content
|
||||||
|
description: The content of the event.
|
||||||
|
example: {"membership": "join"}
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
type: string
|
||||||
|
description: The value ``join``.
|
||||||
|
example: "join"
|
||||||
|
required: ['membership']
|
||||||
|
required:
|
||||||
|
- state_key
|
||||||
|
- sender
|
||||||
|
- origin
|
||||||
|
- origin_server_ts
|
||||||
|
- type
|
||||||
|
- content
|
||||||
|
example: {
|
||||||
|
"$ref": "examples/minimal_pdu.json",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@someone:example.org",
|
||||||
|
"origin": "example.org",
|
||||||
|
"origin_server_ts": 1549041175876,
|
||||||
|
"sender": "@someone:example.org",
|
||||||
|
"content": {
|
||||||
|
"membership": "join"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |-
|
||||||
|
The full state for the room, having accepted the join event.
|
||||||
|
schema:
|
||||||
|
$ref: "./definitions/send_join_response.yaml"
|
||||||
|
examples:
|
||||||
|
application/json: {
|
||||||
|
"origin": "matrix.org",
|
||||||
|
"auth_chain": [{"$ref": "examples/minimal_pdu.json"}],
|
||||||
|
"state": [{"$ref": "examples/minimal_pdu.json"}]
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Federation Leave Room API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8448
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
basePath: /_matrix/federation/v2
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
# Note: there is no v2 of make_leave (yet)
|
||||||
|
"/send_leave/{roomId}/{eventId}":
|
||||||
|
put:
|
||||||
|
summary: Submit a signed leave event to a resident server
|
||||||
|
description: |-
|
||||||
|
.. Note::
|
||||||
|
This API is nearly identical to the v1 API with the
|
||||||
|
exception of the response format being fixed.
|
||||||
|
|
||||||
|
This endpoint is preferred over the v1 API as it provides
|
||||||
|
a more standarised response format. Senders which receive
|
||||||
|
a 400, 404, or other status code which indicates this endpoint
|
||||||
|
is not available should retry using the v1 API instead.
|
||||||
|
|
||||||
|
Submits a signed leave event to the resident server for it
|
||||||
|
to accept it into the room's graph. Note that events have
|
||||||
|
a different format depending on the room version - check
|
||||||
|
the `room version specification`_ for precise event formats.
|
||||||
|
**The request and response body here describe the common
|
||||||
|
event fields in more detail and may be missing other required
|
||||||
|
fields for a PDU.**
|
||||||
|
operationId: sendLeaveV2
|
||||||
|
security:
|
||||||
|
- signedRequest: []
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: roomId
|
||||||
|
type: string
|
||||||
|
description: The room ID that is about to be left.
|
||||||
|
required: true
|
||||||
|
x-example: "!abc123:matrix.org"
|
||||||
|
- in: path
|
||||||
|
name: eventId
|
||||||
|
type: string
|
||||||
|
description: The event ID for the leave event.
|
||||||
|
required: true
|
||||||
|
x-example: "$abc123:example.org"
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
type: object
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
sender:
|
||||||
|
type: string
|
||||||
|
description: The user ID of the leaving member.
|
||||||
|
example: "@someone:example.org"
|
||||||
|
origin:
|
||||||
|
type: string
|
||||||
|
description: The name of the leaving homeserver.
|
||||||
|
example: "matrix.org"
|
||||||
|
origin_server_ts:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: A timestamp added by the leaving homeserver.
|
||||||
|
example: 1234567890
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
description: The value ``m.room.member``.
|
||||||
|
example: "m.room.member"
|
||||||
|
state_key:
|
||||||
|
type: string
|
||||||
|
description: The user ID of the leaving member.
|
||||||
|
example: "@someone:example.org"
|
||||||
|
content:
|
||||||
|
type: object
|
||||||
|
title: Membership Event Content
|
||||||
|
description: The content of the event.
|
||||||
|
example: {"membership": "leave"}
|
||||||
|
properties:
|
||||||
|
membership:
|
||||||
|
type: string
|
||||||
|
description: The value ``leave``.
|
||||||
|
example: "leave"
|
||||||
|
required: ['membership']
|
||||||
|
depth:
|
||||||
|
type: integer
|
||||||
|
description: This field must be present but is ignored; it may be 0.
|
||||||
|
example: 12
|
||||||
|
required:
|
||||||
|
- state_key
|
||||||
|
- sender
|
||||||
|
- origin
|
||||||
|
- origin_server_ts
|
||||||
|
- type
|
||||||
|
- depth
|
||||||
|
- content
|
||||||
|
example: {
|
||||||
|
"$ref": "examples/minimal_pdu.json",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@someone:example.org",
|
||||||
|
"origin": "example.org",
|
||||||
|
"origin_server_ts": 1549041175876,
|
||||||
|
"sender": "@someone:example.org",
|
||||||
|
"content": {
|
||||||
|
"membership": "leave"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: |-
|
||||||
|
An empty response to indicate the event was accepted into the graph by
|
||||||
|
the receiving homeserver.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
title: Empty Object
|
||||||
|
description: An empty object.
|
||||||
|
examples:
|
||||||
|
application/json: {}
|
@ -0,0 +1 @@
|
|||||||
|
Add key backup (``/room_keys/*``) endpoints.
|
@ -1 +0,0 @@
|
|||||||
List available enum values for the room versions capability.
|
|
@ -1 +0,0 @@
|
|||||||
Fix various spelling errors throughout the specification.
|
|
@ -1 +0,0 @@
|
|||||||
Minor clarifications to token-based User-Interactive Authentication.
|
|
@ -1 +0,0 @@
|
|||||||
Minor clarification for what the user directory searches.
|
|
@ -1 +0,0 @@
|
|||||||
Fix various spelling errors throughout the specification.
|
|
@ -1 +0,0 @@
|
|||||||
Fix key export format example to match the specification.
|
|
@ -1 +0,0 @@
|
|||||||
Added data structures for defining moderation policies in rooms per `MSC2313 <https://github.com/matrix-org/matrix-doc/pull/2313>`_.
|
|
@ -1 +0,0 @@
|
|||||||
Fix various spelling errors throughout the specification.
|
|
@ -1 +0,0 @@
|
|||||||
Clarify the IV data type for encrypted files.
|
|
@ -0,0 +1 @@
|
|||||||
|
Fix issues with ``age`` and ``unsigned`` being shown in the wrong places.
|
@ -0,0 +1 @@
|
|||||||
|
Fix definitions for room version capabilities.
|
@ -0,0 +1 @@
|
|||||||
|
Fix various typos throughout the specification.
|
@ -0,0 +1 @@
|
|||||||
|
Fix various typos throughout the specification.
|
@ -0,0 +1 @@
|
|||||||
|
Clarify link to OpenID Connect specification.
|
@ -0,0 +1 @@
|
|||||||
|
Clarify the behaviour of SSO login and UI-Auth.
|
@ -1 +0,0 @@
|
|||||||
Add new ``POST /publicRooms`` endpoint for filtering the room directory.
|
|
@ -1 +0,0 @@
|
|||||||
Move auth event selection to a more obvious location.
|
|
@ -1 +0,0 @@
|
|||||||
Remove the unused ``query_auth`` API per `MSC2451 <https://github.com/matrix-org/matrix-doc/pull/2451>`_.
|
|
@ -1 +0,0 @@
|
|||||||
Fix typo in Request Authentication python example.
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"$ref": "core/state_event.json",
|
|
||||||
"state_key": "example.org",
|
|
||||||
"type": "m.room.aliases",
|
|
||||||
"content": {
|
|
||||||
"aliases": ["#somewhere:example.org", "#another:example.org"]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,10 @@
|
|||||||
{
|
{
|
||||||
"age": 242352,
|
"$ref": "core/state_event.json",
|
||||||
|
"type": "m.room.server_acl",
|
||||||
|
"state_key": "",
|
||||||
"content": {
|
"content": {
|
||||||
"allow_ip_literals": false,
|
"allow_ip_literals": false,
|
||||||
"allow": ["*"],
|
"allow": ["*"],
|
||||||
"deny": ["*.evil.com", "evil.com"]
|
"deny": ["*.evil.com", "evil.com"]
|
||||||
},
|
}
|
||||||
"state_key": "",
|
|
||||||
"origin_server_ts": 1431961217939,
|
|
||||||
"event_id": "$WLGTSEFSEF:localhost",
|
|
||||||
"type": "m.room.server_acl",
|
|
||||||
"room_id": "!Cuyf34gef24t:localhost",
|
|
||||||
"sender": "@example:localhost"
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
title: UnsignedData
|
||||||
|
type: object
|
||||||
|
description: Contains optional extra information about the event.
|
||||||
|
properties:
|
||||||
|
age:
|
||||||
|
description: The time in milliseconds that has elapsed since the event was
|
||||||
|
sent. This field is generated by the local homeserver, and may be incorrect
|
||||||
|
if the local time on at least one of the two servers is out of sync, which can
|
||||||
|
cause the age to either be negative or greater than it actually is.
|
||||||
|
type: integer
|
||||||
|
redacted_because:
|
||||||
|
description: The event that redacted this event, if any.
|
||||||
|
title: Event
|
||||||
|
type: object
|
||||||
|
transaction_id:
|
||||||
|
description: |
|
||||||
|
The client-supplied transaction ID, for example, provided via
|
||||||
|
``PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}``,
|
||||||
|
if the client being given the event is the same one which sent it.
|
||||||
|
type: string
|
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
allOf:
|
|
||||||
- $ref: core-event-schema/state_event.yaml
|
|
||||||
description: 'This event is sent by a homeserver directly to inform of changes to the list of aliases it knows about for that room. The ``state_key`` for this event is set to the homeserver which owns the room alias. The entire set of known aliases for the room is the union of all the ``m.room.aliases`` events, one for each homeserver. Clients **should** check the validity of any room alias given in this list before presenting it to the user as trusted fact. The lists given by this event should be considered simply as advice on which aliases might exist, for which the client can perform the lookup to confirm whether it receives the correct room ID.'
|
|
||||||
properties:
|
|
||||||
content:
|
|
||||||
properties:
|
|
||||||
aliases:
|
|
||||||
description: A list of room aliases.
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- aliases
|
|
||||||
type: object
|
|
||||||
state_key:
|
|
||||||
description: The homeserver domain which owns these room aliases.
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
enum:
|
|
||||||
- m.room.aliases
|
|
||||||
type: string
|
|
||||||
title: Informs the room about what room aliases it has been given.
|
|
||||||
type: object
|
|
@ -0,0 +1,77 @@
|
|||||||
|
# Update auth rules to check notifications key in m.room.power_levels
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The key `notifications` was added to the `m.room.power_levels` event after the
|
||||||
|
finalisation of the auth rules specified in room version 1. This leads to the
|
||||||
|
fact, that this dictionary is not subject to the same validation as other
|
||||||
|
dictionaries in the event, such as `users` or `events`. This especially means
|
||||||
|
that Alice is able to alter any entry within the dictionary including ones,
|
||||||
|
that are above her own power level, which is inconsistent with the behaviour
|
||||||
|
for the other two dictionaries.
|
||||||
|
|
||||||
|
[m.room.power_levels](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-power-levels)
|
||||||
|
[room version 1](https://matrix.org/docs/spec/rooms/v1)
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
The auth rules regarding `m.room.power_levels` have been established in room
|
||||||
|
version 1. The general idea here was that creators of a new `m.room.power_levels`
|
||||||
|
event are only able to make changes to something that is equal to or lower than
|
||||||
|
their own power level.
|
||||||
|
So, assuming a room with Alice (50), Bob (100), `m.room.power_levels` at 50,
|
||||||
|
`m.room.name` at 75 and `m.room.topic` at 25 would mean the following:
|
||||||
|
|
||||||
|
* Alice CAN alter `m.room.topic` to any power level up to her own, in this case 50
|
||||||
|
* Alice is NOT able to alter `m.room.name` since the current value is higher than
|
||||||
|
her own (75 > 50)
|
||||||
|
* Alice is NOT able to alter the power level of Bob, since his current value is
|
||||||
|
higher than her own (100 > 50)
|
||||||
|
* Alice is free to set the level for anything that has not been defined such as
|
||||||
|
`org.alice.message` up to a maximum of 50
|
||||||
|
|
||||||
|
Later on the key `notifications` was added to the `m.room.power_levels` event.
|
||||||
|
It contains a mapping of notification keys to a power level, that is required
|
||||||
|
for a user to trigger the specific notification. The most famous notification
|
||||||
|
type is the `@room` notification.
|
||||||
|
|
||||||
|
Going back to the original example because this key was added later on, the auth
|
||||||
|
rules make no mention of it, which enables the following behaviour. *It is assumed
|
||||||
|
that `@room` is at 75*
|
||||||
|
|
||||||
|
* Alice can add any key to the dictionary and set the value to any value she wants,
|
||||||
|
including ones higher than her own.
|
||||||
|
* Alice can alter the value for `@room` to any value she wants, including ones that
|
||||||
|
are higher than her own, even though her own value is lower.
|
||||||
|
|
||||||
|
The proposed solution is to alter the auth rules and add the `notifications` dictionary
|
||||||
|
to the same rules that handle `events` and `users`.
|
||||||
|
|
||||||
|
So the rule [10.d](https://matrix.org/docs/spec/rooms/v1.html) of the auth rules in
|
||||||
|
room version 1 would be updated in a new room version to:
|
||||||
|
|
||||||
|
|
||||||
|
> For each entry being added, changed or removed in events, users __and notifications__
|
||||||
|
>keys:
|
||||||
|
|
||||||
|
|
||||||
|
## Tradeoffs
|
||||||
|
|
||||||
|
The proposed solution would be a breaking change with current room versions and
|
||||||
|
the alternative would be to leave the `notifications` key without any checks.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
This is likely to improve security because it prevents malicious users that were
|
||||||
|
only given the right to emit `m.room.power_levels` so that they could alter a very
|
||||||
|
specific key, such as `invite`, from altering the rules established for triggering
|
||||||
|
notifications.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The current spec conform behaviour regarding `notifications` is inconsistent with
|
||||||
|
behaviour shown by the other dictionaries and room administrators are very likely
|
||||||
|
expecting the `notifications` to work the same as them. The required change is minimal
|
||||||
|
is and also in line with the general spirit of the auth rules regarding the
|
||||||
|
`m.room.power_levels` event. A new room version is, however, required. This can be
|
||||||
|
done with other pending changes.
|
@ -0,0 +1,14 @@
|
|||||||
|
# MSC2240: Room Version 6
|
||||||
|
|
||||||
|
A new room version, `6`, is proposed using [room version 5](https://matrix.org/docs/spec/rooms/v5.html) as a base
|
||||||
|
and incorporating the following MSCs:
|
||||||
|
|
||||||
|
* [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209) - Including notifications in power level auth rules.
|
||||||
|
* [MSC2432](https://github.com/matrix-org/matrix-doc/pull/2432) - Alias event authorisation and redaction.
|
||||||
|
* [MSC2540](https://github.com/matrix-org/matrix-doc/pull/2540) - Integers in canonical JSON compliance.
|
||||||
|
|
||||||
|
Though other MSCs are capable of being included in this version, they do not have sufficient implementation to be
|
||||||
|
considered stable enough for v6 rooms. A future room version may still include them.
|
||||||
|
|
||||||
|
Room version 6 upon being added to the specification shall be considered stable. No other room versions are affected
|
||||||
|
by this MSC.
|
@ -0,0 +1,101 @@
|
|||||||
|
# Proposal for mandating case folding when processing e-mail addresses
|
||||||
|
|
||||||
|
[RFC822](https://tools.ietf.org/html/rfc822#section-3.4.7) mandates that
|
||||||
|
localparts in e-mail addresses must be processed with the original case
|
||||||
|
preserved. [The Matrix spec](https://matrix.org/docs/spec/appendices#pid-types)
|
||||||
|
doesn't mandate anything about processing e-mail addresses, other than the fact
|
||||||
|
that the domain part must be converted to lowercase, as domain names are case
|
||||||
|
insensitive.
|
||||||
|
|
||||||
|
On the other hand, most major e-mail providers nowadays process the localparts
|
||||||
|
of e-mail addresses as case insensitive. Therefore, most users expect localparts
|
||||||
|
to be treated case insensitively, and get confused when it's not. Some users,
|
||||||
|
for example, get confused over the fact that registering a 3PID association for
|
||||||
|
`john.doe@example.com` doesn't mean that the association is valid for
|
||||||
|
`John.Doe@example.com`, and don't expect to have to remember the exact
|
||||||
|
case they used to initially register the association (and sometimes get locked
|
||||||
|
out of their account because of that). So far we've seen that confusion occur
|
||||||
|
and lead to troubles of various degrees over several deployments of Synapse and
|
||||||
|
Sydent.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
This proposal suggests changing the specification of the e-mail 3PID type in
|
||||||
|
[the Matrix spec appendices](https://matrix.org/docs/spec/appendices#pid-types)
|
||||||
|
to mandate that, before any processing, e-mail addresses must go through a full
|
||||||
|
case folding based on [the unicode mapping
|
||||||
|
file](https://www.unicode.org/Public/8.0.0/ucd/CaseFolding.txt), on top of
|
||||||
|
having their domain lowercased.
|
||||||
|
|
||||||
|
This means that `Strauß@Example.com` must be considered as being the same e-mail
|
||||||
|
address as `strauss@example.com`.
|
||||||
|
|
||||||
|
## Other considered solutions
|
||||||
|
|
||||||
|
A first look at this issue concluded that there was no need to add such a
|
||||||
|
mention to the spec, and that it can be considered an implementation detail.
|
||||||
|
However, [MSC2134](https://github.com/matrix-org/matrix-doc/pull/2134) changes
|
||||||
|
this: because hashing functions are case sensitive, we need both clients and
|
||||||
|
identity servers to follow the same policy regarding case sensitivity.
|
||||||
|
|
||||||
|
An initial version of this proposal proposed to mandate lowercasing e-mail
|
||||||
|
addresses instead of case folding them, however it was pointed out that this
|
||||||
|
solution might not be the best and most future-proof one.
|
||||||
|
|
||||||
|
Unicode normalisation was also looked at but judged unnecessary.
|
||||||
|
|
||||||
|
## Tradeoffs
|
||||||
|
|
||||||
|
Implementing this MSC in identity servers and homeservers might require the
|
||||||
|
databases of existing instances to be updated in a large part to case fold the
|
||||||
|
email addresses of existing associations, in order to avoid conflicts. However,
|
||||||
|
most of this update can usually be done by a background job running at startup,
|
||||||
|
so the UX improvement outweighs this trouble.
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
### Conflicts with existing associations
|
||||||
|
|
||||||
|
Some users might already have two different accounts associated with the same
|
||||||
|
e-mail address but with different cases. This appears to happen in a small
|
||||||
|
number of cases, however, and can be dealt with by the identity server's or the
|
||||||
|
homeserver's maintainer.
|
||||||
|
|
||||||
|
For example, with Sydent, the process of dealing with such cases could look
|
||||||
|
like:
|
||||||
|
|
||||||
|
1. list all MXIDs associated with a variant of the email address, and the
|
||||||
|
timestamp of that association
|
||||||
|
2. delete all associations except for the most recent one [0]
|
||||||
|
3. inform the user of the deletion by sending them an email notice to the email
|
||||||
|
address
|
||||||
|
|
||||||
|
### Storing and querying
|
||||||
|
|
||||||
|
Most database engines don't support case folding, therefore querying all
|
||||||
|
e-mail addresses matching a case folded e-mail address might not be trivial,
|
||||||
|
e.g. an identity server querying all associations for `strauss@example.com` when
|
||||||
|
processing a `/lookup` request would be expected to also get associations for
|
||||||
|
`Strauß@Example.com`.
|
||||||
|
|
||||||
|
To address this issue, implementation maintainers are strongly encouraged to
|
||||||
|
make e-mail addresses go through a full case folding before storing them.
|
||||||
|
|
||||||
|
### Implementing case folding
|
||||||
|
|
||||||
|
The need for case folding in services on the Internet doesn't seem to be very
|
||||||
|
large currently (probably due to its young age), therefore there seem to be only
|
||||||
|
a few third-party implementation librairies out there. However, both
|
||||||
|
[Go](https://godoc.org/golang.org/x/text/cases#Fold), [Python
|
||||||
|
2](https://docs.python.org/2/library/stringprep.html#stringprep.map_table_b3)
|
||||||
|
and [Python 3](https://docs.python.org/3/library/stdtypes.html#str.casefold)
|
||||||
|
support it natively, and [a third-party JavaScript
|
||||||
|
implementation](https://github.com/ar-nelson/foldcase) exists which, although
|
||||||
|
young, seems to be working.
|
||||||
|
|
||||||
|
## Footnotes
|
||||||
|
|
||||||
|
[0]: This is specific to Sydent because of a bug it has where v1 lookups are
|
||||||
|
already processed case insensitively, which means it will return the most recent
|
||||||
|
association for any case of the given email address, therefore keeping only this
|
||||||
|
association won't change the result of v1 lookups.
|
@ -0,0 +1,230 @@
|
|||||||
|
# User-Interactive Authentication for SSO-backed homeserver
|
||||||
|
|
||||||
|
Certain endpoints, such as `DELETE /_matrix/client/r0/devices/{deviceId}` and
|
||||||
|
`POST /_matrix/client/r0/account/3pid/add`, require the user to reconfirm their
|
||||||
|
identity, as a guard against a leaked access token being used to take over an
|
||||||
|
entire account.
|
||||||
|
|
||||||
|
On a normal homeserver, this is done by prompting the user to enter their
|
||||||
|
password. However, on a homeserver where users authenticate via a single-sign-on
|
||||||
|
system, the user doesn't have a password registered with the homeserver. Instead
|
||||||
|
we need to delegate that check to the SSO system.
|
||||||
|
|
||||||
|
At the protocol level, this means adding support for SSO to the
|
||||||
|
[user-interactive authentication API](https://matrix.org/docs/spec/client_server/r0.6.0#user-interactive-authentication-api).
|
||||||
|
|
||||||
|
In theory, once SSO is added as a possible flow for authentication, any clients
|
||||||
|
that already implement the [fallback process for unknown authentication types](https://matrix.org/docs/spec/client_server/r0.6.0#fallback)
|
||||||
|
will work fine without modification. It is unknown whether this is widely
|
||||||
|
supported among clients.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
An [additional authentication type](https://matrix.org/docs/spec/client_server/r0.6.0#authentication-types)
|
||||||
|
of `m.login.sso` is added to the user-interactive authentication specification.
|
||||||
|
|
||||||
|
There are no additional parameters as part of this authentication type. As per
|
||||||
|
the user-interactive authentication specification, the only parameter included in
|
||||||
|
the `auth` dictionary should be the session ID from the homeserver, e.g.:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"session": "<session ID>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Detailed fallback authentication flow:
|
||||||
|
|
||||||
|
The following is a re-iteration of the [fallback authentication flow](https://matrix.org/docs/spec/client_server/r0.6.0#fallback),
|
||||||
|
but with details filled in for the proposed new authentication type.
|
||||||
|
|
||||||
|
When choosing this authentication flow, the following should occur:
|
||||||
|
|
||||||
|
1. If the client wants to complete authentication using SSO, it opens a browser
|
||||||
|
window for `/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`
|
||||||
|
with session set to the UI-Auth session id (from the "auth" dict).
|
||||||
|
|
||||||
|
The homeserver returns a page which asks for the user's confirmation before
|
||||||
|
proceeding. See the security considerations section below for why this is
|
||||||
|
necessary. For example, the page could say words to the effect of:
|
||||||
|
|
||||||
|
> A client is trying to remove a device/add an email address/take over your
|
||||||
|
> account. To confirm this action, **re-authenticate with single sign-on**.
|
||||||
|
> If you did not expect this, your account may be compromised!
|
||||||
|
2. The link, once the user clicks on it, goes to the SSO provider's page.
|
||||||
|
3. The SSO provider validates the user, and redirects the browser back to the
|
||||||
|
homeserver.
|
||||||
|
4. The homeserver validates the response from the SSO provider, updates the
|
||||||
|
user-interactive auth session to show that the SSO has completed, and
|
||||||
|
[serves the fallback auth completion page as specced](https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
|
||||||
|
5. The client resubmits its original request, with its original session id,
|
||||||
|
which now should complete.
|
||||||
|
|
||||||
|
Note that the post-SSO URL on the homeserver is left up to the homeserver
|
||||||
|
implementation rather than forming part of the specification, choices might be
|
||||||
|
limited by the chosen SSO implementation, for example:
|
||||||
|
|
||||||
|
* SAML2 servers typically only support one URL per service provider, so in
|
||||||
|
practice it will need to be the same as that already used for the login flow
|
||||||
|
(for synapse, it's `/_matrix/saml2/authn_response`) - and the server needs to
|
||||||
|
be able to figure out if it's doing SSO for a login attempt or an SSO
|
||||||
|
attempt.
|
||||||
|
* CAS doesn't have the same restriction.
|
||||||
|
|
||||||
|
### Example flow:
|
||||||
|
|
||||||
|
A more complete example is provided below in which a user attempts to delete
|
||||||
|
a device and is pushed into the user interactive authentication process with
|
||||||
|
SSO being the only possible flow.
|
||||||
|
|
||||||
|
0. Client submits the request, which the server says requires SSO:
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /_matrix/client/r0/delete_devices HTTP/1.1
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer xyzzy
|
||||||
|
|
||||||
|
{
|
||||||
|
"devices": ["FSVVTZRRAA"]
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTP/1.1 401 Unauthorized
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"flows": [
|
||||||
|
{
|
||||||
|
"stages": [
|
||||||
|
"m.login.sso"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {},
|
||||||
|
"session": "dTKfsLHSAJeAhqfxUsvrIVJd"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Client opens a browser window for the fallback endpoint:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /_matrix/client/r0/auth/m.login.sso/fallback/web
|
||||||
|
?session=dTKfsLHSAJeAhqfxUsvrIVJd HTTP/1.1
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
|
||||||
|
<body>
|
||||||
|
A client is trying to remove a device from your account. To confirm this
|
||||||
|
action, <a href="https://sso_provider/validate?SAMLRequest=...">re-authenticate with single sign-on</a>.
|
||||||
|
If you did not expect this, your account may be compromised!
|
||||||
|
</body>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. The user clicks the confirmation link which goes to the SSO provider's site:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET https://sso_provider/validate?SAMLRequest=<etc> HTTP/1.1
|
||||||
|
|
||||||
|
<SAML/CAS or other SSO data>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. The SSO provider validates the user and ends up redirecting the browser back
|
||||||
|
to the homeserver. The example below shows a 302 for simplicity, this might
|
||||||
|
vary based on SSO implementation.
|
||||||
|
|
||||||
|
```
|
||||||
|
HTTP/1.1 302 Moved
|
||||||
|
Location: https://homeserver/_matrix/saml2/authn_response?
|
||||||
|
SAMLResponse=<etc>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. The browser sends the SSO response to the homeserver, which validates it and
|
||||||
|
shows the fallback auth completion page:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /_matrix/saml2/authn_response?SAMLResponse=<etc>
|
||||||
|
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
|
||||||
|
<script>
|
||||||
|
if (window.onAuthDone) {
|
||||||
|
window.onAuthDone();
|
||||||
|
} else if (window.opener && window.opener.postMessage) {
|
||||||
|
window.opener.postMessage("authDone", "*");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>Thank you.</p>
|
||||||
|
<p>You may now close this window and return to the application.</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
5. The client closes the browser popup if it is still open, and resubmits its
|
||||||
|
original request, which now succeeds:
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /_matrix/client/r0/delete_devices HTTP/1.1
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer xyzzy
|
||||||
|
|
||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"session": "dTKfsLHSAJeAhqfxUsvrIVJd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
An alternative client flow where the fallback auth ends up redirecting to a
|
||||||
|
given URI, instead of doing JavaScript `postMessage` foo could be considered.
|
||||||
|
This is probably an orthogonal change to the fallback auth though.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
### Why we need user to confirm before the SSO flow
|
||||||
|
|
||||||
|
Recall that the thing we are trying to guard against here is a single leaked
|
||||||
|
access-token being used to take over an entire account. So let's assume the
|
||||||
|
attacker has got hold of an access token for your account. What happens if the
|
||||||
|
confirmation step is skipped?
|
||||||
|
|
||||||
|
The attacker, who has your access token, starts a UI Authentication session to
|
||||||
|
add their email address to your account.
|
||||||
|
|
||||||
|
They then sends you a link "hey, check out this cool video!"; the link leads (via
|
||||||
|
an innocent-looking URL shortener or some other phishing technique) to
|
||||||
|
`/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`, with the ID of
|
||||||
|
the session that he just created.
|
||||||
|
|
||||||
|
Since there is no confirmation step, the server redirects directly to the SSO
|
||||||
|
provider.
|
||||||
|
|
||||||
|
It's common for SSO providers to redirect straight back to the app if you've
|
||||||
|
recently authenticated with them; even in the best case, the SSO provider shows
|
||||||
|
an innocent message along the lines of "Confirm that you want to sign in to
|
||||||
|
\<your Matrix homeserver>".
|
||||||
|
|
||||||
|
After redirecting back to the homeserver, the SSO is completed and the
|
||||||
|
attacker's session is validated. They are now able to make their malicious
|
||||||
|
change to your account.
|
||||||
|
|
||||||
|
This problem can be mitigated by clearly telling the user what is about to happen.
|
||||||
|
|
||||||
|
### Reusing User Interactive Authentication sessions
|
||||||
|
|
||||||
|
The security of this relies on User Interactive Authentication sessions only
|
||||||
|
being used for the same request as they were initiated for. This security is not
|
||||||
|
only a concern for the proposed SSO authentication type. It is not believed
|
||||||
|
that this is currently enforced in implementations.
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
A vendor prefix of `org.matrix.login.sso` is proposed (instead of `m.login.sso`)
|
||||||
|
until this is part of the specification.
|
@ -0,0 +1,56 @@
|
|||||||
|
# Invalidating devices during password modification
|
||||||
|
|
||||||
|
There are multiple use cases for why a user might want to modify their password:
|
||||||
|
|
||||||
|
* Adopting a password manager (to use a unique password or more secure password).
|
||||||
|
* Password rotation.
|
||||||
|
* Re-secure a compromised account.
|
||||||
|
* ... probably tons of others ...
|
||||||
|
|
||||||
|
These can be summarized into two groups:
|
||||||
|
|
||||||
|
1. "My account has been compromised and I need to re-secure it."
|
||||||
|
2. "I just want to change my password."
|
||||||
|
|
||||||
|
The [current Matrix specification](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password)
|
||||||
|
does not provide a way to differentiate between these use cases. It currently
|
||||||
|
specifies behavior that fits well into the first use-case above: that the
|
||||||
|
sessions except the current session should be revoked.
|
||||||
|
|
||||||
|
It is reasonable for a client to want to specify this behavior to offer two
|
||||||
|
different workflows:
|
||||||
|
|
||||||
|
1. Modify a password and log all other devices out (for use when an account has
|
||||||
|
been compromised).
|
||||||
|
2. Modify a password and do not touch any session data (for use in a
|
||||||
|
non-malicious situations).
|
||||||
|
|
||||||
|
Alternately a client may default to whichever workflow is best for their users.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
An optional field is added to the JSON body of the [password reset endpoint](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password)
|
||||||
|
called `logout_devices`. This is a boolean flag (defaulting to `true`) that
|
||||||
|
signals to whether other devices and sessions should be invalidated after
|
||||||
|
modifying the password.
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
The specification states:
|
||||||
|
|
||||||
|
> The homeserver SHOULD NOT revoke the access token provided in the request,
|
||||||
|
> however all other access tokens for the user should be revoked if the request
|
||||||
|
> succeeds.
|
||||||
|
|
||||||
|
Defaulting `logout_devices` to `true` should be backwards compatible.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
A new endpoint could be provided in a future version of the specification that
|
||||||
|
supports an additional field (as described above).
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
By defaulting to invalidating devices and sessions the security considerations
|
||||||
|
of this endpoint should remain intact. A client will need to be modified to
|
||||||
|
choose to keep other devices active.
|
@ -0,0 +1,88 @@
|
|||||||
|
# Symmetric SSSS
|
||||||
|
|
||||||
|
[MSC1946 (Secure Secret Storage and
|
||||||
|
Sharing)](https://github.com/matrix-org/matrix-doc/pull/1946) proposed a way of
|
||||||
|
storing encrypted secrets on the server. In the proposal, secrets were
|
||||||
|
encrypted using a Curve25519 key, which was chosen to allow easier migration
|
||||||
|
from key backups that we created before the backup key was stored using it.
|
||||||
|
|
||||||
|
However this does not provide any guarantees that data stored using the
|
||||||
|
proposal came from a trusted source. To remedy this, we propose to change the
|
||||||
|
encryption to use AES with a MAC to ensure that only someone who knows the key
|
||||||
|
is able to store data.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
* The `m.secret_storage.v1.curve25519-aes-sha2` method proposed in MSC1946 is
|
||||||
|
removed.
|
||||||
|
|
||||||
|
* A new method, `m.secret_storage.v1.aes-hmac-sha2`, is added. With this
|
||||||
|
method, the Secret Storage key may be any size (though 256 bits is
|
||||||
|
recommended), and data is encrypted as follows:
|
||||||
|
|
||||||
|
1. Given the secret storage key, generate 64 bytes by performing an HKDF with
|
||||||
|
SHA-256 as the hash, a salt of 32 bytes of 0, and with the secret name as
|
||||||
|
the info. The first 32 bytes are used as the AES key, and the next 32 bytes
|
||||||
|
are used as the MAC key
|
||||||
|
2. Generate 16 random bytes, set bit 63 to 0 (in order to work around
|
||||||
|
differences in AES-CTR implementations), and use this as the AES
|
||||||
|
initialization vector. This becomes the `iv` property, encoded using base64.
|
||||||
|
3. Encrypt the data using AES-CTR-256 using the AES key generated above. This
|
||||||
|
encrypted data, encoded using base64, becomes the `ciphertext` property.
|
||||||
|
4. Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256
|
||||||
|
using the MAC key generated above. The resulting MAC is base64-encoded and
|
||||||
|
becomes the `mac` property.
|
||||||
|
|
||||||
|
(We use AES-CTR to match file encryption and key exports.)
|
||||||
|
|
||||||
|
If the key Secret Storage key is generated from a passphrase, information
|
||||||
|
about how to generate the key is stored in the `passphrase` property of the
|
||||||
|
key's account-data in a similar manner to what was done with the original
|
||||||
|
`m.secret_storage.v1.curve25519-aes-sha2` method, except that there is an
|
||||||
|
optional `bits` parameter that defaults to 256, and indicates the number of
|
||||||
|
bits that should be generated from PBKDF2 (in other words, the size of the
|
||||||
|
key).
|
||||||
|
|
||||||
|
* For the purposes of allowing clients to check whether a user has correctly
|
||||||
|
entered the key, clients should:
|
||||||
|
|
||||||
|
1. encrypt and MAC a message consisting of 32 bytes of 0 as described above,
|
||||||
|
using the empty string as the info parameter to the HKDF in step 1.
|
||||||
|
2. store the `iv` and `mac` in the `m.secret_storage.key.[key ID]`
|
||||||
|
account-data.
|
||||||
|
|
||||||
|
* The `passthrough` property specified in the "Enconding the recovery key for
|
||||||
|
server-side storage via MSC1946" section of MSC1219 is removed. The primary
|
||||||
|
purpose of that property was to allow easy migration of pre-MSC1946 backups,
|
||||||
|
so that users could reuse the backup recovery key as the Secret Storage key
|
||||||
|
without needing to re-enter the recovery key. However, since we are now
|
||||||
|
using a symmetric encryption algorithm, the client needs to know the key that
|
||||||
|
is used to encrypt, so the purpose of the field cannot be fulfilled.
|
||||||
|
|
||||||
|
* Signing the Secret Storage key with the user's master cross-signing key is no
|
||||||
|
longer required. The key is trusted on the basis of the user entering the
|
||||||
|
key/passphrase.
|
||||||
|
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
Users who have data stored using the old encryption algorithm will need their
|
||||||
|
data migrated. Clients that support the old algorithm but not the new
|
||||||
|
algorithm will not be able to use the migrated secrets until they are updated
|
||||||
|
with the new algorithms. This should not be a major problem because the only
|
||||||
|
clients that are known to have implemented the old algorithm are Riot
|
||||||
|
Web/Android/iOS, and they have been upgraded to implement the new algorithm.
|
||||||
|
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
Rather than switching to a symmetric encryption algorithm, we could stay with
|
||||||
|
an asymmetric encryption algorithm, and add on a method to authenticate the
|
||||||
|
data. However, it is much safer to use well-known cryptographic methods rather
|
||||||
|
than trying to invent something new. Since the main reason for using an
|
||||||
|
asymmetric scheme was to ease migration from older key backups without
|
||||||
|
requiring the user to re-enter the key, but this is no longer possible due to
|
||||||
|
the need to authenticate the data using the Secret Storage key, there is no
|
||||||
|
reason to stay with an asymmetric algorithm. It is also better to use
|
||||||
|
cryptographic methods already used in Matrix where possible, rather than
|
||||||
|
introducing something new.
|
@ -0,0 +1,14 @@
|
|||||||
|
# MSC2526: Add ability to delete key backups
|
||||||
|
|
||||||
|
[MSC1219](https://github.com/matrix-org/matrix-doc/issues/1219) defined a
|
||||||
|
mechanism for key backups. However, it inadvertently omitted the endpoint to
|
||||||
|
delete an entire key backup. This proposal adds the endpoint.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
An endpoint is added, `DELETE /room_keys/version/{version}`, that deletes a
|
||||||
|
backup version. Both the information about the key backup, as well as all keys
|
||||||
|
associated with the backup should be deleted. If the specified version was
|
||||||
|
previously deleted, the endpoint succeeds, returning an HTTP code of 200. If
|
||||||
|
the specified version never existed, the endpoint returns an HTTP code of 404
|
||||||
|
with a Matrix `errcode` of `M_NOT_FOUND`.
|
@ -0,0 +1,65 @@
|
|||||||
|
# MSC2540: Stricter event validation: JSON compliance
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
There has been [prior discussions](https://github.com/matrix-org/matrix-doc/issues/1646)
|
||||||
|
about validating events more strictly. This MSC proposes fixing a small piece of
|
||||||
|
this: JSON compliance.
|
||||||
|
|
||||||
|
The [Canonical JSON](https://matrix.org/docs/spec/appendices#canonical-json)
|
||||||
|
specification requires that numbers that are serialized in JSON are integers in
|
||||||
|
the inclusive range of `[-(2^53) + 1, (2^53) - 1]`, which matches the requirements of
|
||||||
|
[section 6 of RFC 7159](https://tools.ietf.org/html/rfc7159). Note that it is
|
||||||
|
not explicit, but all floats are invalid.
|
||||||
|
|
||||||
|
It is worth mentioning that there are common extensions to JSON which produce
|
||||||
|
invalid JSON according to the Matrix specification; some programming langauges
|
||||||
|
even support these by default. One common additional feature is handling
|
||||||
|
"special" float values: `Infinity`, `-Infinity`, and `NaN`.
|
||||||
|
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
In a future room version, homeserver implementations are to strictly enforce
|
||||||
|
the JSON compliance of the Canonical JSON specification for events.
|
||||||
|
Non-compliant events should be treated like any other malformed event,
|
||||||
|
for example by rejecting the request with an HTTP 400 error with `M_BAD_JSON`,
|
||||||
|
or by discarding the event.
|
||||||
|
|
||||||
|
The rationale for doing this in a future room version is to avoid a split brain
|
||||||
|
room -- where some federated servers believe an event is valid and others reject
|
||||||
|
it as invalid. Rooms will be able to opt into this behavior as part of a room
|
||||||
|
version upgrade.
|
||||||
|
|
||||||
|
Homeserver implementations are not to strictly enforce this JSON compliance in
|
||||||
|
[room versions 1, 2, 3, 4, and 5](https://matrix.org/docs/spec/#complete-list-of-room-versions).
|
||||||
|
The rationale is essentially the same as why a future room version is necessary:
|
||||||
|
this ensures that all federated servers treat the same events as valid.
|
||||||
|
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
Homeserver implementations might include JSON parsers which are stricter than
|
||||||
|
others. It may not be worthwhile or reasonable to loosen those restrictions for
|
||||||
|
stable room versions.
|
||||||
|
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
It could be argued that this MSC is unnecessary since it does not add any new
|
||||||
|
requirements for handling of JSON data. Unfortunately starting to enforce these
|
||||||
|
requirements in current rooms could cause federation to break as homeservers
|
||||||
|
will disagree on whether events are valid.
|
||||||
|
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
A room version of `org.matrix.strict_canonicaljson` until a future room version
|
||||||
|
is available. This room version will use
|
||||||
|
[room version 5](https://matrix.org/docs/spec/rooms/v5) as base and include the
|
||||||
|
above modifications.
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Original styles generated from:
|
||||||
|
pygmentize -f html -S colorful -a pre.code > ./scripts/css/pygments.css
|
||||||
|
|
||||||
|
Rules for which we don't want the syntax highlighter to kick in are commented
|
||||||
|
out at the bottom.
|
||||||
|
|
||||||
|
Windows users: if you regenerate this file, you'll need to re-save it as utf-8
|
||||||
|
to make docutils happy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* DIFFS */
|
||||||
|
pre.code .gd { color: #A00000 } /* Generic.Deleted */
|
||||||
|
pre.code .gi { color: #00A000 } /* Generic.Inserted */
|
||||||
|
|
||||||
|
/* UNUSED */
|
||||||
|
/*pre.code .hll { background-color: #ffffcc }*/
|
||||||
|
/*pre.code { background: #ffffff; }*/
|
||||||
|
/*pre.code .c { color: #888888 } !* Comment *!*/
|
||||||
|
/*pre.code .err { color: #FF0000; background-color: #FFAAAA } !* Error *!*/
|
||||||
|
/*pre.code .k { color: #008800; font-weight: bold } !* Keyword *!*/
|
||||||
|
/*pre.code .o { color: #333333 } !* Operator *!*/
|
||||||
|
/*pre.code .ch { color: #888888 } !* Comment.Hashbang *!*/
|
||||||
|
/*pre.code .cm { color: #888888 } !* Comment.Multiline *!*/
|
||||||
|
/*pre.code .cp { color: #557799 } !* Comment.Preproc *!*/
|
||||||
|
/*pre.code .cpf { color: #888888 } !* Comment.PreprocFile *!*/
|
||||||
|
/*pre.code .c1 { color: #888888 } !* Comment.Single *!*/
|
||||||
|
/*pre.code .cs { color: #cc0000; font-weight: bold } !* Comment.Special *!*/
|
||||||
|
/*pre.code .ge { font-style: italic } !* Generic.Emph *!*/
|
||||||
|
/*pre.code .gr { color: #FF0000 } !* Generic.Error *!*/
|
||||||
|
/*pre.code .gh { color: #000080; font-weight: bold } !* Generic.Heading *!*/
|
||||||
|
/*pre.code .go { color: #888888 } !* Generic.Output *!*/
|
||||||
|
/*pre.code .gp { color: #c65d09; font-weight: bold } !* Generic.Prompt *!*/
|
||||||
|
/*pre.code .gs { font-weight: bold } !* Generic.Strong *!*/
|
||||||
|
/*pre.code .gu { color: #800080; font-weight: bold } !* Generic.Subheading *!*/
|
||||||
|
/*pre.code .gt { color: #0044DD } !* Generic.Traceback *!*/
|
||||||
|
/*pre.code .kc { color: #008800; font-weight: bold } !* Keyword.Constant *!*/
|
||||||
|
/*pre.code .kd { color: #008800; font-weight: bold } !* Keyword.Declaration *!*/
|
||||||
|
/*pre.code .kn { color: #008800; font-weight: bold } !* Keyword.Namespace *!*/
|
||||||
|
/*pre.code .kp { color: #003388; font-weight: bold } !* Keyword.Pseudo *!*/
|
||||||
|
/*pre.code .kr { color: #008800; font-weight: bold } !* Keyword.Reserved *!*/
|
||||||
|
/*pre.code .kt { color: #333399; font-weight: bold } !* Keyword.Type *!*/
|
||||||
|
/*pre.code .m { color: #6600EE; font-weight: bold } !* Literal.Number *!*/
|
||||||
|
/*pre.code .s { background-color: #fff0f0 } !* Literal.String *!*/
|
||||||
|
/*pre.code .na { color: #0000CC } !* Name.Attribute *!*/
|
||||||
|
/*pre.code .nb { color: #007020 } !* Name.Builtin *!*/
|
||||||
|
/*pre.code .nc { color: #BB0066; font-weight: bold } !* Name.Class *!*/
|
||||||
|
/*pre.code .no { color: #003366; font-weight: bold } !* Name.Constant *!*/
|
||||||
|
/*pre.code .nd { color: #555555; font-weight: bold } !* Name.Decorator *!*/
|
||||||
|
/*pre.code .ni { color: #880000; font-weight: bold } !* Name.Entity *!*/
|
||||||
|
/*pre.code .ne { color: #FF0000; font-weight: bold } !* Name.Exception *!*/
|
||||||
|
/*pre.code .nf { color: #0066BB; font-weight: bold } !* Name.Function *!*/
|
||||||
|
/*pre.code .nl { color: #997700; font-weight: bold } !* Name.Label *!*/
|
||||||
|
/*pre.code .nn { color: #0e84b5; font-weight: bold } !* Name.Namespace *!*/
|
||||||
|
/*pre.code .nt { color: #007700 } !* Name.Tag *!*/
|
||||||
|
/*pre.code .nv { color: #996633 } !* Name.Variable *!*/
|
||||||
|
/*pre.code .ow { color: #000000; font-weight: bold } !* Operator.Word *!*/
|
||||||
|
/*pre.code .w { color: #bbbbbb } !* Text.Whitespace *!*/
|
||||||
|
/*pre.code .mb { color: #6600EE; font-weight: bold } !* Literal.Number.Bin *!*/
|
||||||
|
/*pre.code .mf { color: #6600EE; font-weight: bold } !* Literal.Number.Float *!*/
|
||||||
|
/*pre.code .mh { color: #005588; font-weight: bold } !* Literal.Number.Hex *!*/
|
||||||
|
/*pre.code .mi { color: #0000DD; font-weight: bold } !* Literal.Number.Integer *!*/
|
||||||
|
/*pre.code .mo { color: #4400EE; font-weight: bold } !* Literal.Number.Oct *!*/
|
||||||
|
/*pre.code .sa { background-color: #fff0f0 } !* Literal.String.Affix *!*/
|
||||||
|
/*pre.code .sb { background-color: #fff0f0 } !* Literal.String.Backtick *!*/
|
||||||
|
/*pre.code .sc { color: #0044DD } !* Literal.String.Char *!*/
|
||||||
|
/*pre.code .dl { background-color: #fff0f0 } !* Literal.String.Delimiter *!*/
|
||||||
|
/*pre.code .sd { color: #DD4422 } !* Literal.String.Doc *!*/
|
||||||
|
/*pre.code .s2 { background-color: #fff0f0 } !* Literal.String.Double *!*/
|
||||||
|
/*pre.code .se { color: #666666; font-weight: bold; background-color: #fff0f0 } !* Literal.String.Escape *!*/
|
||||||
|
/*pre.code .sh { background-color: #fff0f0 } !* Literal.String.Heredoc *!*/
|
||||||
|
/*pre.code .si { background-color: #eeeeee } !* Literal.String.Interpol *!*/
|
||||||
|
/*pre.code .sx { color: #DD2200; background-color: #fff0f0 } !* Literal.String.Other *!*/
|
||||||
|
/*pre.code .sr { color: #000000; background-color: #fff0ff } !* Literal.String.Regex *!*/
|
||||||
|
/*pre.code .s1 { background-color: #fff0f0 } !* Literal.String.Single *!*/
|
||||||
|
/*pre.code .ss { color: #AA6600 } !* Literal.String.Symbol *!*/
|
||||||
|
/*pre.code .bp { color: #007020 } !* Name.Builtin.Pseudo *!*/
|
||||||
|
/*pre.code .fm { color: #0066BB; font-weight: bold } !* Name.Function.Magic *!*/
|
||||||
|
/*pre.code .vc { color: #336699 } !* Name.Variable.Class *!*/
|
||||||
|
/*pre.code .vg { color: #dd7700; font-weight: bold } !* Name.Variable.Global *!*/
|
||||||
|
/*pre.code .vi { color: #3333BB } !* Name.Variable.Instance *!*/
|
||||||
|
/*pre.code .vm { color: #996633 } !* Name.Variable.Magic *!*/
|
||||||
|
/*pre.code .il { color: #0000DD; font-weight: bold } !* Literal.Number.Integer.Long *!*/
|
@ -0,0 +1,100 @@
|
|||||||
|
.. Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
|
..
|
||||||
|
.. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
.. you may not use this file except in compliance with the License.
|
||||||
|
.. You may obtain a copy of the License at
|
||||||
|
..
|
||||||
|
.. http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
..
|
||||||
|
.. Unless required by applicable law or agreed to in writing, software
|
||||||
|
.. distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
.. See the License for the specific language governing permissions and
|
||||||
|
.. limitations under the License.
|
||||||
|
|
||||||
|
Room Version 6
|
||||||
|
==============
|
||||||
|
|
||||||
|
This room version builds on `version 5 <v5.html>`_ while changing various
|
||||||
|
authorization rules performed on events.
|
||||||
|
|
||||||
|
.. contents:: Table of Contents
|
||||||
|
.. sectnum::
|
||||||
|
|
||||||
|
|
||||||
|
Client considerations
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The redaction algorithm has changed from `room version 1 <v1.html>`_ to remove
|
||||||
|
all rules against events of type ``m.room.aliases``. Room versions 2, 3, 4, and
|
||||||
|
5 all use v1's redaction algorithm. The algorithm is otherwise unchanged.
|
||||||
|
|
||||||
|
|
||||||
|
Server implementation components
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
.. WARNING::
|
||||||
|
The information contained in this section is strictly for server implementors.
|
||||||
|
Applications which use the Client-Server API are generally unaffected by the
|
||||||
|
intricacies contained here. The section above regarding client considerations
|
||||||
|
is the resource that Client-Server API use cases should reference.
|
||||||
|
|
||||||
|
|
||||||
|
Room version 6 makes the following alterations to algorithms described in `room version 5 <v5.html>`_.
|
||||||
|
|
||||||
|
Redactions
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
As mentioned in the client considerations portion of this specification, all
|
||||||
|
special meaning has been removed for events of type ``m.room.aliases``. The
|
||||||
|
algorithm is otherwise unchanged.
|
||||||
|
|
||||||
|
Authorization rules for events
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Like redactions, all rules relating specifically to events of type ``m.room.aliases``
|
||||||
|
are removed. They must still pass authorization checks relating to state events.
|
||||||
|
|
||||||
|
Additionally, the authorization rules for events of type ``m.room.power_levels``
|
||||||
|
now include the content key ``notifications``. This new rule takes the place of the
|
||||||
|
rule which checks the ``events`` and ``users`` keys.
|
||||||
|
|
||||||
|
For completeness, the changes to the auth rules can be represented as follows:
|
||||||
|
|
||||||
|
.. code:: diff
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
-If type is `m.room.aliases`:
|
||||||
|
-
|
||||||
|
- a. If event has no `state_key`, reject.
|
||||||
|
- b. If sender's domain doesn't matches `state_key`, reject.
|
||||||
|
- c. Otherwise, allow.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
If type is `m.room.power_levels`:
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
- * For each entry being added, changed or removed in both the `events` and `users` keys:
|
||||||
|
+ * For each entry being added, changed or removed in the `events`, `users`, and `notifications` keys:
|
||||||
|
|
||||||
|
i. If the current value is higher than the `sender`'s current power level, reject.
|
||||||
|
|
||||||
|
ii. If the new value is higher than the `sender`'s current power level, reject.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
The remaining rules are the same as in `room version 3 <v3.html#authorization-rules-for-events>`_
|
||||||
|
(the last inherited room version to specify the authorization rules).
|
||||||
|
|
||||||
|
Canonical JSON
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Servers MUST strictly enforce the JSON format specified in the
|
||||||
|
`appendices <../appendices.html#canonical-json>`_. This translates to a 400 ``M_BAD_JSON`` error
|
||||||
|
on most endpoints, or discarding of events over federation. For example, the Federation API's
|
||||||
|
``/send`` endpoint would discard the event whereas the Client Server API's ``/send/{eventType}``
|
||||||
|
endpoint would return a ``M_BAD_JSON`` error.
|
Loading…
Reference in New Issue