From 9fdd8a6f964c70689bd7451d746e96164ce8ab5f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 26 Jul 2018 14:59:43 -0600 Subject: [PATCH 1/5] Document how leaving rooms/rejecting invites over federation works Fixes https://github.com/matrix-org/matrix-doc/issues/1401 This is very similar to the joining rooms handshake, and much of it is a near copy/paste of the make_join and send_join API. The major difference is the send_leave API doesn't return anything. References: * Handling of make_leave: https://github.com/matrix-org/synapse/blob/d69decd5c78c72abef50b597a689e2bc55a39702/synapse/handlers/federation.py#L1285-L1310 * send_leave route: https://github.com/matrix-org/synapse/blob/d69decd5c78c72abef50b597a689e2bc55a39702/synapse/federation/transport/client.py#L267 * make_leave route: https://github.com/matrix-org/synapse/blob/d69decd5c78c72abef50b597a689e2bc55a39702/synapse/federation/transport/server.py#L396 * send_leave returning nothing: https://github.com/matrix-org/synapse/blob/d69decd5c78c72abef50b597a689e2bc55a39702/synapse/handlers/federation.py#L1346 --- api/server-server/leaving.yaml | 266 ++++++++++++++++++++++++++++ specification/server_server_api.rst | 20 +++ 2 files changed, 286 insertions(+) create mode 100644 api/server-server/leaving.yaml diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml new file mode 100644 index 00000000..11b0e01d --- /dev/null +++ b/api/server-server/leaving.yaml @@ -0,0 +1,266 @@ +# Copyright 2018 New Vector Ltd +# +# 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/v1 +produces: + - application/json +paths: + "/make_leave/{roomId}/{userId}": + get: + summary: Get information required to make a join event for a room + description: |- + Asks the receiving server to return information that the sending + server will need to prepare a leave event to get out of the room. + operationId: makeLeave + 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: userId + type: string + description: The user ID the leave event will be for. + required: true + x-example: "@someone:example.org" + responses: + 200: + description: |- + An unsigned event that the sending server may use as a template + for when it calls ``/send_leave``. + schema: + allOf: + - $ref: "definitions/unsigned_pdu.yaml" + - type: object + properties: + # Note: we override a bunch of parameters to change their descriptions + sender: + type: string + description: The user ID of the leaving member. + example: "@someone:example.org" + origin: + type: string + description: The name of the resident homeserver. + example: "matrix.org" + origin_server_ts: + type: integer + format: int64 + description: A timestamp added by the resident 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'] + auth_events: + type: array + description: |- + An event reference list containing the authorization events that would + allow the member to leave the room. This should normally be the + ``m.room.create``, ``m.room.power_levels``, and ``m.room.join_rules`` + events. + items: + type: array + maxItems: 2 + minItems: 2 + items: + - type: string + title: Event ID + example: "$abc123:matrix.org" + - type: object + title: Event Hash + example: { + "sha256": "abase64encodedsha256hashshouldbe43byteslong" + } + properties: + sha256: + type: string + description: The event hash. + example: abase64encodedsha256hashshouldbe43byteslong + required: ['sha256'] + redacts: + type: string + description: Not used. + required: + # Every other field is already flagged as required by the $ref + - state_key + examples: + application/json: { + "$ref": "examples/unsigned_pdu.json", + "type": "m.room.member", + "state_key": "@someone:example.org", + "content": { + "membership": "leave" + }, + "auth_events": [ + ["$room_cre4te_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], + ["$room_j0in_rul3s_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}], + ["$room_p0wer_l3vels_3vent:matrix.org", {"sha256": "abase64encodedsha256hashshouldbe43byteslong"}] + ] + } + 403: + description: |- + The request is not authorized. This could mean that the user is not in the room. + schema: + $ref: "../client-server/definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "User is not in the room." + } + "/send_leave/{roomId}/{eventId}": + put: + summary: Submit a signed leave event to a resident server + description: |- + Submits a signed leave event to the resident server for it + to accept it into the room's graph. + operationId: sendLeave + 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: + allOf: + - $ref: "definitions/pdu.yaml" + - type: object + properties: + # Note: we override a bunch of parameters to change their descriptions + 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 + auth_events: + type: array + description: |- + An event reference list containing the authorization events that would + allow the member to leave the room. + items: + type: array + maxItems: 2 + minItems: 2 + items: + - type: string + title: Event ID + example: "$abc123:matrix.org" + - type: object + title: Event Hash + example: { + "sha256": "abase64encodedsha256hashshouldbe43byteslong" + } + properties: + sha256: + type: string + description: The event hash. + example: abase64encodedsha256hashshouldbe43byteslong + required: ['sha256'] + redacts: + type: string + description: Not used. + required: + # Every other field is already flagged as required by the $ref + - state_key + example: { + "$ref": "examples/pdu.json", + "type": "m.room.member", + "state_key": "@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: array + minItems: 2 + maxItems: 2 + items: + - type: integer + description: The value ``200``. + example: 200 + - type: object + title: Empty Object + description: An empty object. + examples: + application/json: [200, {}] diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index f1825f27..32b6486f 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -881,6 +881,26 @@ Inviting to a room {{invites_ss_http_api}} +Leaving Rooms (Rejecting Invites) +--------------------------------- + +Normally homeservers can send appropriate ``m.room.member`` events to have users +leave the room, or to reject local invites. Remote invites from other homeservers +do not involve the server in the graph and therefore need another approach to +reject the invite. Joining the room and promptly leaving is not recommended as +clients and servers will interpret that as accepting the invite, then leaving the +room rather than rejecting the invite. + +Similar to the `Joining Rooms`_ handshake, the server which wishes to leave the +room starts with sending a ``/make_leave`` request to a resident server. In the +case of rejecting invites, the resident server may be the server which sent the +invite. After receiving a template event from ``/make_leave``, the leaving server +signs the event and replaces the ``event_id`` with it's own. This is then sent to +the resident server via ``/send_leave``. The resident server will then send the +event to other servers in the room. + +{{leaving_ss_http_api}} + Third-party invites ------------------- From 7679b4f1d168e4f5ab7c2e94d34923079782f234 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 30 Jul 2018 16:58:13 -0600 Subject: [PATCH 2/5] Improve documentation on how Transactions work The response is based upon various sections of the Synapse code in how it generates a response. There are no new fields added to the transaction. Originally, `previous_ids` and `pdu_failures` were to be documented however neither of these are used in the real world. --- .../definitions/transaction.yaml | 8 ++- api/server-server/transactions.yaml | 58 +++++++++++++++++-- specification/server_server_api.rst | 38 +----------- 3 files changed, 58 insertions(+), 46 deletions(-) diff --git a/api/server-server/definitions/transaction.yaml b/api/server-server/definitions/transaction.yaml index 930ddec1..7df8b646 100644 --- a/api/server-server/definitions/transaction.yaml +++ b/api/server-server/definitions/transaction.yaml @@ -25,11 +25,13 @@ properties: origin_server_ts: type: integer format: int64 - description: Timestamp in milliseconds on originating homeserver when this transaction started. - example: 1234567890 + description: |- + POSIX timestamp in milliseconds on originating homeserver when this + transaction started. + example: 1532991320875 pdus: type: array description: List of persistent updates to rooms. items: $ref: "pdu.yaml" -required: ['origin', 'origin_server_ts', 'pdus'] \ No newline at end of file +required: ['origin', 'origin_server_ts', 'pdus'] diff --git a/api/server-server/transactions.yaml b/api/server-server/transactions.yaml index 13ba6826..2a9180a1 100644 --- a/api/server-server/transactions.yaml +++ b/api/server-server/transactions.yaml @@ -30,16 +30,18 @@ paths: Push messages representing live activity to another server. The destination name will be set to that of the receiving server itself. Each embedded PDU in the transaction body will be processed. + + The sending server must wait and retry for a 200 OK response before sending a + transaction with a different ``txnId`` to the receiving server. operationId: sendTransaction parameters: - in: path name: txnId type: string - # TODO: "Overrides any ID given in the JSON body" - What does this mean? description: |- - The transaction ID. Overrides any ID given in the JSON body. + The transaction ID. required: true - x-example: TODO # No examples in the spec so far + x-example: S0meTransacti0nId - in: body name: body type: object @@ -51,7 +53,9 @@ paths: properties: edus: type: array - description: List of ephemeral messages. May be omitted if there are no ephemeral messages to be sent. + description: |- + List of ephemeral messages. May be omitted if there are no ephemeral + messages to be sent. items: $ref: "definitions/edu.yaml" example: { @@ -60,5 +64,47 @@ paths: } responses: 200: - # TODO: Spec this (and figure out what it is) - description: TODO + description: |- + The result of processing the transaction. The server is to use this response even in + the event of one or more PDUs failing to be processed. + schema: + type: array + minItems: 2 + maxItems: 2 + items: + - type: integer + description: The value ``200``. + example: 200 + - type: object + title: PDU Processing Results + description: The results for the processing of each PDU in the transaction. + properties: + pdus: + type: object + description: |- + The PDUs from the original transaction. The string key represents the ID of the + PDU (event) that was processed. + additionalProperties: + type: object + title: PDU Processing Result + description: Information about how the PDU was handled. + properties: + error: + type: string + description: |- + A human readable description about what went wrong in processing this PDU. + If no error is present, the PDU can be considered successfully handled. + example: "You are not allowed to send a message to this room." + required: ['pdus'] + examples: + application/json: [ + 200, + { + "pdus": { + "$successful_event:domain.com": {}, + "$failed_event:example.org": { + "error": "You are not allowed to send a message to this room." + } + } + } + ] diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index f1825f27..a190d9d2 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -242,41 +242,7 @@ of Transaction messages, which are encoded as JSON objects, passed over an HTTP PUT request. A Transaction is meaningful only to the pair of homeservers that exchanged it; they are not globally-meaningful. -Each transaction has: - - An opaque transaction ID, unique among transactions from the same origin. - - A timestamp (UNIX epoch time in milliseconds) generated by its origin - server. - - An origin and destination server name. - - A list of PDUs and EDUs - the actual message payload that the Transaction - carries. - -Transaction Fields -~~~~~~~~~~~~~~~~~~ - -==================== =================== ====================================== - Key Type Description -==================== =================== ====================================== -``origin`` String **Required**. ``server_name`` of homeserver sending - this transaction. -``origin_server_ts`` Integer **Required**. Timestamp in milliseconds on - originating homeserver when this - transaction started. -``pdus`` List of Objects **Required**. List of persistent updates to rooms. -``edus`` List of Objects List of ephemeral messages. May be omitted - if there are no ephemeral messages to - be sent. -==================== =================== ====================================== - -Example: - -.. code:: json - - { - "origin_server_ts": 1404835423000, - "origin": "matrix.org", - "pdus": [...], - "edus": [...] - } +{{transactions_ss_http_api}} PDUs ---- @@ -682,8 +648,6 @@ All these URLs are name-spaced within a prefix of:: /_matrix/federation/v1/... -{{transactions_ss_http_api}} - {{events_ss_http_api}} {{query_general_ss_http_api}} From 9d474bb8195b3a61b1cad0330aa3f1adec7756e7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 2 Aug 2018 12:44:54 -0600 Subject: [PATCH 3/5] Document event retrieval endpoints in more detail This also adds a previously-undocumented endpoint: /state_ids Backfill is technically not part of this section, however it is being left untouched to make the merge with #1469 easier (which moves it out of the file). Reference material: * Some calls to synapse on these endpoints with a relatively simple private room. --- api/server-server/events.yaml | 76 +++++++++++++++++++++++++++-- specification/server_server_api.rst | 12 ++++- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index d540085d..f0c3250c 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -27,7 +27,7 @@ paths: get: summary: Get all the state of a given room description: |- - Retrieves a snapshot of the entire current state of the given room. + Retrieves a snapshot of a room's state at a given event. operationId: getRoomState parameters: - in: path @@ -36,11 +36,81 @@ paths: description: The room ID to get state for. required: true x-example: "!abc123:matrix.org" + - in: query + name: event_id + type: string + description: An event ID in the room to retrieve the state at. + required: true + x-example: "$helloworld:matrix.org" responses: 200: - description: The room state for the room (kept under ``pdus``). + description: |- + The fully resolved state for the room, including the authorization + chain for the events. schema: - $ref: "definitions/transaction.yaml" + type: object + properties: + auth_chain: + type: list + description: |- + The full set of authorization events that make up the state + of the room, and their authorization events, recursively. + items: + $ref: "definitions/pdu.yaml" + example: [{"$ref": "examples/pdu.json"}] + pdus: + type: list + description: |- + The fully resolved state of the room at the given event. + items: + $ref: "definitions/pdu.yaml" + example: [{"$ref": "examples/pdu.json"}] + required: ['auth_chain', 'pdus'] + "/state_ids/{roomId}": + get: + summary: Get all the state event IDs of a given room + description: |- + Retrieves a snapshot of a room's state at a given event, in the form of + event IDs. This performs the same function as calling ``/state/{roomId}``, + however this returns just the event IDs rather than the full events. + operationId: getRoomStateIds + parameters: + - in: path + name: roomId + type: string + description: The room ID to get state for. + required: true + x-example: "!abc123:matrix.org" + - in: query + name: event_id + type: string + description: An event ID in the room to retrieve the state at. + required: true + x-example: "$helloworld:matrix.org" + responses: + 200: + description: |- + The fully resolved state for the room, including the authorization + chain for the events. + schema: + type: object + properties: + auth_chain_ids: + type: list + description: |- + The full set of authorization events that make up the state + of the room, and their authorization events, recursively. + items: + type: string + example: ["$an_event:domain.com"] + pdu_ids: + type: list + description: |- + The fully resolved state of the room at the given event. + items: + type: string + example: ["$an_event:domain.com"] + required: ['auth_chain_ids', 'pdu_ids'] "/event/{eventId}": get: summary: Get a single event diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 3bdc5b2b..4a00db98 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -606,8 +606,6 @@ All these URLs are name-spaced within a prefix of:: {{transactions_ss_http_api}} -{{events_ss_http_api}} - {{query_general_ss_http_api}} @@ -798,6 +796,16 @@ that requested by the requester in the ``v`` parameter). Specify (or remark that it is unspecified) how the server handles divergent history. DFS? BFS? Anything weirder? +Retriving events +---------------- + +In some circumstances, a homeserver may be missing a particular event or information +about the room which cannot be easily determined from backfilling. These APIs provide +homeservers with the option of getting events and the state of the room at a given +point in the timeline. + +{{events_ss_http_api}} + Inviting to a room ------------------ From 8b7bc603670c2e81c73505b0987690b6b87fa269 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 2 Aug 2018 16:42:03 -0600 Subject: [PATCH 4/5] list -> array --- api/server-server/events.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/server-server/events.yaml b/api/server-server/events.yaml index f0c3250c..11c88e8d 100644 --- a/api/server-server/events.yaml +++ b/api/server-server/events.yaml @@ -51,7 +51,7 @@ paths: type: object properties: auth_chain: - type: list + type: array description: |- The full set of authorization events that make up the state of the room, and their authorization events, recursively. @@ -59,7 +59,7 @@ paths: $ref: "definitions/pdu.yaml" example: [{"$ref": "examples/pdu.json"}] pdus: - type: list + type: array description: |- The fully resolved state of the room at the given event. items: @@ -96,7 +96,7 @@ paths: type: object properties: auth_chain_ids: - type: list + type: array description: |- The full set of authorization events that make up the state of the room, and their authorization events, recursively. @@ -104,7 +104,7 @@ paths: type: string example: ["$an_event:domain.com"] pdu_ids: - type: list + type: array description: |- The fully resolved state of the room at the given event. items: From e766606f24820f75820b1ae45c7b1a729d64ddfb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 2 Aug 2018 18:54:12 -0600 Subject: [PATCH 5/5] join -> leave --- api/server-server/leaving.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/server-server/leaving.yaml b/api/server-server/leaving.yaml index 11b0e01d..e287bf58 100644 --- a/api/server-server/leaving.yaml +++ b/api/server-server/leaving.yaml @@ -25,7 +25,7 @@ produces: paths: "/make_leave/{roomId}/{userId}": get: - summary: Get information required to make a join event for a room + summary: Get information required to make a leave event for a room description: |- Asks the receiving server to return information that the sending server will need to prepare a leave event to get out of the room.