From b85f7bb24827b19c5f38e2c6021dc126767e16e5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:02:09 -0700 Subject: [PATCH] Add room version upgrades Implements https://github.com/matrix-org/matrix-doc/issues/1501 --- api/client-server/room_upgrades.yaml | 95 +++++++++++++++++++++++++ event-schemas/examples/m.room.create | 6 +- event-schemas/examples/m.room.tombstone | 9 +++ event-schemas/schema/m.room.create | 12 ++++ event-schemas/schema/m.room.tombstone | 27 +++++++ proposals/1501-room-version-upgrades.md | 2 +- specification/modules/room_upgrades.rst | 76 ++++++++++++++++++++ specification/targets.yaml | 1 + 8 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 api/client-server/room_upgrades.yaml create mode 100644 event-schemas/examples/m.room.tombstone create mode 100644 event-schemas/schema/m.room.tombstone create mode 100644 specification/modules/room_upgrades.rst diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml new file mode 100644 index 00000000..4d6b86b4 --- /dev/null +++ b/api/client-server/room_upgrades.yaml @@ -0,0 +1,95 @@ +# Copyright 2019 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 Client-Server Room Upgrades 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: + "/rooms/{roomId}/upgrade": + post: + summary: Upgrades a room to a new room version. + description: |- + Upgrades the given room to a particular room version, migrating as much + data as possible over to the new room. See the `room_upgrades`_ module + for more information on what this entails. + operationId: upgradeRoom + security: + - accessToken: [] + parameters: + - in: path + type: string + name: roomId + required: true + description: The ID of the room to upgrade. + x-example: "!oldroom:example.org" + - in: body + name: body + required: true + description: The request body + schema: + type: object + properties: + new_version: + type: string + description: The new version for the room. + example: {"new_version": "2"} + required: [new_version] + responses: + 200: + description: The room was successfully upgraded. + examples: + application/json: { + "replacement_room": "!newroom:example.org" + } + schema: + type: object + properties: + replacement_room: + type: string + description: The ID of the new room. + required: [replacement_room] + 400: + description: |- + The request was invalid. One way this can happen is if the room version + requested is not supported by the homeserver. + examples: + application/json: { + "errcode": "M_UNSUPPORTED_ROOM_VERSION", + "error": "This server does not support that room version" + } + schema: + "$ref": "definitions/errors/error.yaml" + 403: + description: |- + The user is not permitted to upgrade the room. + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "You cannot upgrade this room" + } + schema: + "$ref": "definitions/errors/error.yaml" + tags: + - Room ugprades diff --git a/event-schemas/examples/m.room.create b/event-schemas/examples/m.room.create index 29b6237a..e33dbc3b 100644 --- a/event-schemas/examples/m.room.create +++ b/event-schemas/examples/m.room.create @@ -5,6 +5,10 @@ "content": { "creator": "@example:example.org", "room_version": "1", - "m.federate": true + "m.federate": true, + "predecessor": { + "event_id": "$something:example.org", + "room_id": "!oldroom:example.org" + } } } diff --git a/event-schemas/examples/m.room.tombstone b/event-schemas/examples/m.room.tombstone new file mode 100644 index 00000000..b6224476 --- /dev/null +++ b/event-schemas/examples/m.room.tombstone @@ -0,0 +1,9 @@ +{ + "$ref": "core/state_event.json", + "type": "m.room.tombstone", + "state_key": "", + "content": { + "body": "This room has been replaced", + "replacement_room": "!newroom:example.org" + } +} diff --git a/event-schemas/schema/m.room.create b/event-schemas/schema/m.room.create index d12b9ccd..a6fe331e 100644 --- a/event-schemas/schema/m.room.create +++ b/event-schemas/schema/m.room.create @@ -14,6 +14,18 @@ properties: room_version: description: The version of the room. Defaults to ``"1"`` if the key does not exist. type: string + predecessor: + description: A reference to the room this room replaces, if the previous room was upgraded. + type: object + title: Previous Room + properties: + room_id: + type: string + description: The ID of the old room. + event_id: + type: string + description: The event ID of the last known event in the old room. + required: [room_id, event_id] required: - creator type: object diff --git a/event-schemas/schema/m.room.tombstone b/event-schemas/schema/m.room.tombstone new file mode 100644 index 00000000..0fd8ba45 --- /dev/null +++ b/event-schemas/schema/m.room.tombstone @@ -0,0 +1,27 @@ +--- +allOf: + - $ref: core-event-schema/state_event.yaml +description: 'A state event signifying that a room has been upgraded to a different room version, and that clients should go there.' +properties: + content: + properties: + body: + type: string + description: A server-defined message. + replacement_room: + type: string + description: The new room the client should be visiting. + required: + - replacement_room + - body + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: + - m.room.tombstone + type: string +title: Indication that the room has been upgraded. +type: object diff --git a/proposals/1501-room-version-upgrades.md b/proposals/1501-room-version-upgrades.md index 3a726250..7bd310ea 100644 --- a/proposals/1501-room-version-upgrades.md +++ b/proposals/1501-room-version-upgrades.md @@ -48,7 +48,7 @@ When this is called, the server: "state_key": "", "room_id": "!QtykxKocfsgujksjgd:matrix.org", "content": { - "version": "2", + "room_version": "2", "predecessor": { "room_id": "!cURbaf:matrix.org", "event_id": "$1235135aksjgdkg:matrix.org" diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst new file mode 100644 index 00000000..81da8aaf --- /dev/null +++ b/specification/modules/room_upgrades.rst @@ -0,0 +1,76 @@ +.. Copyright 2019 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. + +Room Upgrades +============= + +.. _module:room-upgrades: + +From time to time, a room may need to be upgraded to a different room version for a +variety for reasons. This module defines a way for rooms to upgrade to a different +room version when needed. + +Events +------ + +{{m_room_tombstone_event}} + +Client behaviour +---------------- + +Clients which understand ``m.room.tombstone`` events MUST: + +* Hide the old room from the user's list of rooms. Permalinks, backlinks, etc should + still be accessible to this room, however. +* At the very bottom of the old room's timeline/message view, display a message which + indicates the room has been upgraded with a permalink to the new room. When the user + accesses the permalink, they are to be joined to the new room. + + * Note that if the homeserver doesn't support the room version that the user may + receive an error upon trying to join. + * If the replacement room has a tombstone event, the client may automatically follow + the chain until it finds a room which does not have a tombstone in it. + +* Optionally, the client may wish to improve the presentation of unread messages when + the user is in both the old and new rooms. For example, if the user was not active + during the upgrade and had unread messages in the old room, the new room may have an + indicator which shows the sum of unread notifications between the rooms. + +Clients which understand ``m.room.tombstone`` events must also understand the ``predecessor`` +field on ``m.room.create`` events such that: + +* At the top of the scrollback/message view for the new room a message is displayed + indicating that the room is a continuation of a previous room, with a permalink to + the old room. +* Optionally supporting search and other functions of the room to span across the old + and new rooms. + +{{room_upgrades_cs_http_api}} + +Server behaviour +---------------- + +When the client requests to upgrade a known room to a known version, the server: + +1. Checks that the user has permission to send ``m.room.tombstone`` events in the room. +2. Creates a replacement room with a ``m.room.create`` event containing a ``predecessor`` + field and the applicable ``room_version``. +3. Replicates the power levels, privacy, topic, and other transferable state events to + the new room. This generally excludes membership events. +4. Moves any local aliases to the new room. +5. Sends a ``m.room.tombstone`` event to the old room to indicate that it is not intended + to be used any further. +6. If possible, the power levels in the old room should also be modified to prevent sending + of events and inviting new users. For example, setting ``events_default`` and ``invite`` + to the greater of ``50`` and ``users_default + 1``. diff --git a/specification/targets.yaml b/specification/targets.yaml index 93e1b8a6..60da93cd 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -70,6 +70,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/openid.rst - modules/server_acls.rst - modules/mentions.rst + - modules/room_upgrades.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]