From b85f7bb24827b19c5f38e2c6021dc126767e16e5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:02:09 -0700 Subject: [PATCH 1/6] 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: ["=", "-", "~", "+", "^", "`", "@", ":"] From 56bfa7676530d4d52cf26b4acde923315e99d6af Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:03:05 -0700 Subject: [PATCH 2/6] changelog --- changelogs/client_server/newsfragments/1791.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1791.feature diff --git a/changelogs/client_server/newsfragments/1791.feature b/changelogs/client_server/newsfragments/1791.feature new file mode 100644 index 00000000..ae961ad3 --- /dev/null +++ b/changelogs/client_server/newsfragments/1791.feature @@ -0,0 +1 @@ +Add room version upgrades From 5cbfafaab73c2585c57a1703f39fa6cb8206dcee Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 9 Jan 2019 17:17:50 -0700 Subject: [PATCH 3/6] Fix link to module --- api/client-server/room_upgrades.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/room_upgrades.yaml b/api/client-server/room_upgrades.yaml index 4d6b86b4..6511d9fc 100644 --- a/api/client-server/room_upgrades.yaml +++ b/api/client-server/room_upgrades.yaml @@ -32,8 +32,8 @@ paths: 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. + data as possible over to the new room. See the `room_upgrades <#room-upgrades>`_ + module for more information on what this entails. operationId: upgradeRoom security: - accessToken: [] From 4e0533a5f34022d780bc43271d694d90f495e5a9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 13:56:48 -0700 Subject: [PATCH 4/6] Soften UX requirements --- specification/modules/room_upgrades.rst | 33 ++++++------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 81da8aaf..2015a4b1 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -29,32 +29,13 @@ Events 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. +Clients which understand ``m.room.tombstone`` events and the ``predecessor`` field on +``m.room.create`` events should communicate to the user that the room was upgraded. +One way of accomplishing this would be to hide the old room from the user's room list +and showing banners linking between the old and new room - ensuring that permalinks +work when referencing the old room. Another approach may be to virtually merge the +rooms such that the old room's timeline seamlessly continues into the new timeline +without the user having to jump between the rooms. {{room_upgrades_cs_http_api}} From 2457438f1eacb0cf26636a02df9a7e2c913586d2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 17 Jan 2019 13:57:02 -0700 Subject: [PATCH 5/6] Encourage servers to transfer whatever they can while being open-ended --- specification/modules/room_upgrades.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 2015a4b1..21a1ed2d 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -48,10 +48,14 @@ When the client requests to upgrade a known room to a known version, the server: 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. + the new room. This generally excludes membership events but may include client-specified + events and other presentation details. 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``. + +When a user joins the new room, the server may wish to automatically transfer/replicate +some of the user's personalized settings such as notifications, tags, etc. From 0dfc64a9f4f1772c5839c60fac63f15a8cc7603e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 22 Jan 2019 18:11:36 -0700 Subject: [PATCH 6/6] Improve wording --- specification/modules/room_upgrades.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/room_upgrades.rst b/specification/modules/room_upgrades.rst index 21a1ed2d..49ff4414 100644 --- a/specification/modules/room_upgrades.rst +++ b/specification/modules/room_upgrades.rst @@ -31,7 +31,7 @@ Client behaviour Clients which understand ``m.room.tombstone`` events and the ``predecessor`` field on ``m.room.create`` events should communicate to the user that the room was upgraded. -One way of accomplishing this would be to hide the old room from the user's room list +One way of accomplishing this would be hiding the old room from the user's room list and showing banners linking between the old and new room - ensuring that permalinks work when referencing the old room. Another approach may be to virtually merge the rooms such that the old room's timeline seamlessly continues into the new timeline