Merge pull request #1828 from matrix-org/travis/spec/rooms-v3
Add specification for room version 3: Event IDs as hashes
This commit is contained in:
commit
df01acc6e2
12 changed files with 633 additions and 352 deletions
|
@ -13,7 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
type: object
|
type: object
|
||||||
title: Persistent Data Unit
|
title: Persistent Data Unit
|
||||||
description: A persistent data unit (event)
|
description: A persistent data unit (event) for room versions 1 and 2.
|
||||||
example:
|
example:
|
||||||
$ref: "../examples/pdu.json"
|
$ref: "../examples/pdu.json"
|
||||||
allOf:
|
allOf:
|
||||||
|
@ -26,13 +26,13 @@ allOf:
|
||||||
description: |-
|
description: |-
|
||||||
Content hashes of the PDU, following the algorithm specified in `Signing Events`_.
|
Content hashes of the PDU, following the algorithm specified in `Signing Events`_.
|
||||||
example: {
|
example: {
|
||||||
"sha256": "thishashcoversallfieldsincasethisisredacted"
|
"sha256": "ThisHashCoversAllFieldsInCaseThisIsRedacted"
|
||||||
}
|
}
|
||||||
properties:
|
properties:
|
||||||
sha256:
|
sha256:
|
||||||
type: string
|
type: string
|
||||||
description: The hash.
|
description: The hash.
|
||||||
example: thishashcoversallfieldsincasthisisredacted
|
example: ThisHashCoversAllFieldsInCaseThisIsRedacted
|
||||||
required: ['sha256']
|
required: ['sha256']
|
||||||
signatures:
|
signatures:
|
||||||
type: object
|
type: object
|
||||||
|
@ -40,7 +40,7 @@ allOf:
|
||||||
Signatures for the PDU, following the algorithm specified in `Signing Events`_.
|
Signatures for the PDU, following the algorithm specified in `Signing Events`_.
|
||||||
example: {
|
example: {
|
||||||
"example.com": {
|
"example.com": {
|
||||||
"ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
|
"ed25519:key_version:": "86BytesOfSignatureOfTheRedactedEvent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
|
|
73
api/server-server/definitions/pdu_v3.yaml
Normal file
73
api/server-server/definitions/pdu_v3.yaml
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# 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.
|
||||||
|
type: object
|
||||||
|
title: Persistent Data Unit
|
||||||
|
description: A persistent data unit (event) for room version 3 and beyond.
|
||||||
|
example:
|
||||||
|
$ref: "../examples/pdu_v3.json"
|
||||||
|
allOf:
|
||||||
|
- $ref: "unsigned_pdu_base.yaml"
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
auth_events:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: Event ID.
|
||||||
|
description: |-
|
||||||
|
Event IDs for the authorization events that would
|
||||||
|
allow this event to be in the room.
|
||||||
|
example: ["$base64EncodedHash", "$AnotherEvent"]
|
||||||
|
prev_events:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: Event ID.
|
||||||
|
description: |-
|
||||||
|
Event IDs for the most recent events in the room
|
||||||
|
that the homeserver was aware of when it made this event.
|
||||||
|
example: ["$base64EncodedHash", "$AnotherEvent"]
|
||||||
|
hashes:
|
||||||
|
type: object
|
||||||
|
title: Event Hash
|
||||||
|
description: |-
|
||||||
|
Content hashes of the PDU, following the algorithm specified in `Signing Events`_.
|
||||||
|
example: {
|
||||||
|
"sha256": "ThisHashCoversAllFieldsInCaseThisIsRedacted"
|
||||||
|
}
|
||||||
|
properties:
|
||||||
|
sha256:
|
||||||
|
type: string
|
||||||
|
description: The hash.
|
||||||
|
example: ThisHashCoversAllFieldsInCaseThisIsRedacted
|
||||||
|
required: ['sha256']
|
||||||
|
signatures:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Signatures for the PDU, following the algorithm specified in `Signing Events`_.
|
||||||
|
example: {
|
||||||
|
"example.com": {
|
||||||
|
"ed25519:key_version:": "86BytesOfSignatureOfTheRedactedEvent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
title: Server Signatures
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- auth_events
|
||||||
|
- prev_events
|
||||||
|
- hashes
|
||||||
|
- signatures
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright 2018 New Vector Ltd
|
# Copyright 2018-2019 New Vector Ltd
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -16,140 +16,13 @@ title: Unsigned Persistent Data Unit
|
||||||
description: An unsigned persistent data unit (event)
|
description: An unsigned persistent data unit (event)
|
||||||
example:
|
example:
|
||||||
$ref: "../examples/unsigned_pdu.json"
|
$ref: "../examples/unsigned_pdu.json"
|
||||||
properties:
|
allOf:
|
||||||
event_id:
|
- $ref: "unsigned_pdu_base.yaml"
|
||||||
type: string
|
- type: object
|
||||||
description: The event ID for the PDU.
|
|
||||||
example: "$a4ecee13e2accdadf56c1025:example.com"
|
|
||||||
room_id:
|
|
||||||
type: string
|
|
||||||
description: Room identifier.
|
|
||||||
example: "!abc123:matrix.org"
|
|
||||||
sender:
|
|
||||||
type: string
|
|
||||||
description: The ID of the user sending the event.
|
|
||||||
example: "@someone:matrix.org"
|
|
||||||
origin:
|
|
||||||
type: string
|
|
||||||
description: The ``server_name`` of the homeserver that created this event.
|
|
||||||
example: "matrix.org"
|
|
||||||
origin_server_ts:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: Timestamp in milliseconds on origin homeserver when this event was created.
|
|
||||||
example: 1234567890
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
description: Event type
|
|
||||||
example: "m.room.message"
|
|
||||||
state_key:
|
|
||||||
type: string
|
|
||||||
description: |-
|
|
||||||
If this key is present, the event is a state event, and it will replace previous events
|
|
||||||
with the same ``type`` and ``state_key`` in the room state.
|
|
||||||
example: "my_key"
|
|
||||||
content:
|
|
||||||
type: object
|
|
||||||
description: The content of the event.
|
|
||||||
example: {"key": "value"}
|
|
||||||
prev_events:
|
|
||||||
type: array
|
|
||||||
description: |-
|
|
||||||
Event IDs and reference hashes for the most recent events in the room
|
|
||||||
that the homeserver was aware of when it made this event.
|
|
||||||
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']
|
|
||||||
depth:
|
|
||||||
type: integer
|
|
||||||
description: |-
|
|
||||||
The maximum depth of the ``prev_events``, plus one. Must be less than the
|
|
||||||
maximum value for an integer (2^63 - 1). If the room's depth is already at
|
|
||||||
the limit, the depth must be set to the limit.
|
|
||||||
example: 12
|
|
||||||
auth_events:
|
|
||||||
type: array
|
|
||||||
description: |-
|
|
||||||
Event IDs and reference hashes for the authorization events that would
|
|
||||||
allow this event to be in 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: For redaction events, the ID of the event being redacted.
|
|
||||||
example: "$def456:matrix.org"
|
|
||||||
unsigned:
|
|
||||||
type: object
|
|
||||||
title: Example Unsigned Data
|
|
||||||
description: |-
|
|
||||||
Additional data added by the origin server but not covered by the ``signatures``. More
|
|
||||||
keys than those defined here may be used.
|
|
||||||
example: {"key": "value"}
|
|
||||||
properties:
|
properties:
|
||||||
age:
|
event_id:
|
||||||
type: integer
|
|
||||||
description: The number of milliseconds that have passed since this message was sent.
|
|
||||||
example: 4612
|
|
||||||
replaces_state:
|
|
||||||
type: string
|
type: string
|
||||||
description: The event ID of the state event this event replaces.
|
description: The event ID for the PDU.
|
||||||
example: "$state_event:example.org"
|
example: "$a4ecee13e2accdadf56c1025:example.com"
|
||||||
prev_sender:
|
required:
|
||||||
type: string
|
- event_id
|
||||||
description: The sender of the replaced state event.
|
|
||||||
example: "@someone:example.org"
|
|
||||||
prev_content:
|
|
||||||
type: object
|
|
||||||
description: The content of the replaced state event.
|
|
||||||
example: {
|
|
||||||
"membership": "join",
|
|
||||||
"displayname": "Bob"
|
|
||||||
}
|
|
||||||
redacted_because:
|
|
||||||
type: string
|
|
||||||
description: A reason for why the event was redacted.
|
|
||||||
example: "Inappropriate content"
|
|
||||||
required:
|
|
||||||
- event_id
|
|
||||||
- room_id
|
|
||||||
- sender
|
|
||||||
- origin
|
|
||||||
- origin_server_ts
|
|
||||||
- type
|
|
||||||
- content
|
|
||||||
- prev_events
|
|
||||||
- depth
|
|
||||||
- auth_events
|
|
||||||
|
|
151
api/server-server/definitions/unsigned_pdu_base.yaml
Normal file
151
api/server-server/definitions/unsigned_pdu_base.yaml
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
# 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.
|
||||||
|
type: object
|
||||||
|
title: Unsigned Persistent Data Unit
|
||||||
|
description: An unsigned persistent data unit (event)
|
||||||
|
example:
|
||||||
|
$ref: "../examples/unsigned_pdu_base.json"
|
||||||
|
properties:
|
||||||
|
room_id:
|
||||||
|
type: string
|
||||||
|
description: Room identifier.
|
||||||
|
example: "!abc123:matrix.org"
|
||||||
|
sender:
|
||||||
|
type: string
|
||||||
|
description: The ID of the user sending the event.
|
||||||
|
example: "@someone:matrix.org"
|
||||||
|
origin:
|
||||||
|
type: string
|
||||||
|
description: The ``server_name`` of the homeserver that created this event.
|
||||||
|
example: "matrix.org"
|
||||||
|
origin_server_ts:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
description: Timestamp in milliseconds on origin homeserver when this event was created.
|
||||||
|
example: 1234567890
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
description: Event type
|
||||||
|
example: "m.room.message"
|
||||||
|
state_key:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
If this key is present, the event is a state event, and it will replace previous events
|
||||||
|
with the same ``type`` and ``state_key`` in the room state.
|
||||||
|
example: "my_key"
|
||||||
|
content:
|
||||||
|
type: object
|
||||||
|
description: The content of the event.
|
||||||
|
example: {"key": "value"}
|
||||||
|
prev_events:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
Event IDs and reference hashes for the most recent events in the room
|
||||||
|
that the homeserver was aware of when it made this event.
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
maxItems: 2
|
||||||
|
minItems: 2
|
||||||
|
items:
|
||||||
|
- type: string
|
||||||
|
title: Event ID
|
||||||
|
example: "$abc123:matrix.org"
|
||||||
|
- type: object
|
||||||
|
title: Event Hash
|
||||||
|
example: {
|
||||||
|
"sha256": "Base64EncodedSha256HashesShouldBe43BytesLong"
|
||||||
|
}
|
||||||
|
properties:
|
||||||
|
sha256:
|
||||||
|
type: string
|
||||||
|
description: The event hash.
|
||||||
|
example: Base64EncodedSha256HashesShouldBe43BytesLong
|
||||||
|
required: ['sha256']
|
||||||
|
depth:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
The maximum depth of the ``prev_events``, plus one. Must be less than the
|
||||||
|
maximum value for an integer (2^63 - 1). If the room's depth is already at
|
||||||
|
the limit, the depth must be set to the limit.
|
||||||
|
example: 12
|
||||||
|
auth_events:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
Event IDs and reference hashes for the authorization events that would
|
||||||
|
allow this event to be in 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": "Base64EncodedSha256HashesShouldBe43BytesLong"
|
||||||
|
}
|
||||||
|
properties:
|
||||||
|
sha256:
|
||||||
|
type: string
|
||||||
|
description: The event hash.
|
||||||
|
example: Base64EncodedSha256HashesShouldBe43BytesLong
|
||||||
|
required: ['sha256']
|
||||||
|
redacts:
|
||||||
|
type: string
|
||||||
|
description: For redaction events, the ID of the event being redacted.
|
||||||
|
example: "$def456:matrix.org"
|
||||||
|
unsigned:
|
||||||
|
type: object
|
||||||
|
title: Example Unsigned Data
|
||||||
|
description: |-
|
||||||
|
Additional data added by the origin server but not covered by the ``signatures``. More
|
||||||
|
keys than those defined here may be used.
|
||||||
|
example: {"key": "value"}
|
||||||
|
properties:
|
||||||
|
age:
|
||||||
|
type: integer
|
||||||
|
description: The number of milliseconds that have passed since this message was sent.
|
||||||
|
example: 4612
|
||||||
|
replaces_state:
|
||||||
|
type: string
|
||||||
|
description: The event ID of the state event this event replaces.
|
||||||
|
example: "$state_event:example.org"
|
||||||
|
prev_sender:
|
||||||
|
type: string
|
||||||
|
description: The sender of the replaced state event.
|
||||||
|
example: "@someone:example.org"
|
||||||
|
prev_content:
|
||||||
|
type: object
|
||||||
|
description: The content of the replaced state event.
|
||||||
|
example: {
|
||||||
|
"membership": "join",
|
||||||
|
"displayname": "Bob"
|
||||||
|
}
|
||||||
|
redacted_because:
|
||||||
|
type: string
|
||||||
|
description: A reason for why the event was redacted.
|
||||||
|
example: "Inappropriate content"
|
||||||
|
required:
|
||||||
|
- event_id
|
||||||
|
- room_id
|
||||||
|
- sender
|
||||||
|
- origin
|
||||||
|
- origin_server_ts
|
||||||
|
- type
|
||||||
|
- content
|
||||||
|
- prev_events
|
||||||
|
- depth
|
||||||
|
- auth_events
|
19
api/server-server/examples/pdu_v3.json
Normal file
19
api/server-server/examples/pdu_v3.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"$ref": "unsigned_pdu_base.json",
|
||||||
|
"hashes": {
|
||||||
|
"sha256": "thishashcoversallfieldsincasethisisredacted"
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"example.com": {
|
||||||
|
"ed25519:key_version:": "these86bytesofbase64signaturecoveressentialfieldsincludinghashessocancheckredactedpdus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"auth_events": [
|
||||||
|
"$base64encodedeventid",
|
||||||
|
"$adifferenteventid"
|
||||||
|
],
|
||||||
|
"prev_events": [
|
||||||
|
"$base64encodedeventid",
|
||||||
|
"$adifferenteventid"
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,27 +1,4 @@
|
||||||
{
|
{
|
||||||
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
|
"$ref": "unsigned_pdu_base.json",
|
||||||
"sender": "@alice:example.com",
|
"event_id": "$a4ecee13e2accdadf56c1025:example.com"
|
||||||
"origin": "example.com",
|
}
|
||||||
"event_id": "$a4ecee13e2accdadf56c1025:example.com",
|
|
||||||
"origin_server_ts": 1404838188000,
|
|
||||||
"depth": 12,
|
|
||||||
"auth_events": [
|
|
||||||
[
|
|
||||||
"$af232176:example.org",
|
|
||||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"type": "m.room.message",
|
|
||||||
"prev_events": [
|
|
||||||
[
|
|
||||||
"$af232176:example.org",
|
|
||||||
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"content": {
|
|
||||||
"key": "value"
|
|
||||||
},
|
|
||||||
"unsigned": {
|
|
||||||
"age": 4612
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
26
api/server-server/examples/unsigned_pdu_base.json
Normal file
26
api/server-server/examples/unsigned_pdu_base.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"room_id": "!UcYsUzyxTGDxLBEvLy:example.org",
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"origin": "example.com",
|
||||||
|
"origin_server_ts": 1404838188000,
|
||||||
|
"depth": 12,
|
||||||
|
"auth_events": [
|
||||||
|
[
|
||||||
|
"$af232176:example.org",
|
||||||
|
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"type": "m.room.message",
|
||||||
|
"prev_events": [
|
||||||
|
[
|
||||||
|
"$af232176:example.org",
|
||||||
|
{"sha256": "abase64encodedsha256hashshouldbe43byteslong"}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"key": "value"
|
||||||
|
},
|
||||||
|
"unsigned": {
|
||||||
|
"age": 4612
|
||||||
|
}
|
||||||
|
}
|
|
@ -484,6 +484,7 @@ The available room versions are:
|
||||||
|
|
||||||
* `Version 1 <rooms/v1.html>`_ - **Stable**. The current version of most rooms.
|
* `Version 1 <rooms/v1.html>`_ - **Stable**. The current version of most rooms.
|
||||||
* `Version 2 <rooms/v2.html>`_ - **Stable**. Implements State Resolution Version 2.
|
* `Version 2 <rooms/v2.html>`_ - **Stable**. Implements State Resolution Version 2.
|
||||||
|
* `Version 3 <rooms/v3.html>`_ - **Stable**. Introduces events whose IDs are the event's hash.
|
||||||
|
|
||||||
Specification Versions
|
Specification Versions
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -77,7 +77,7 @@ results of the resolution so far.
|
||||||
* Add the first event in the list to :math:`R`.
|
* Add the first event in the list to :math:`R`.
|
||||||
|
|
||||||
* For each subsequent event in the list, check that the event would be
|
* For each subsequent event in the list, check that the event would be
|
||||||
allowed by the `authorization rules`_ for a room in state :math:`R`. If the
|
allowed by the authorization rules for a room in state :math:`R`. If the
|
||||||
event would be allowed, then update :math:`R` with the event and continue
|
event would be allowed, then update :math:`R` with the event and continue
|
||||||
with the next event in the list. If it would not be allowed, stop and
|
with the next event in the list. If it would not be allowed, stop and
|
||||||
continue below with ``m.room.join_rules`` events.
|
continue below with ``m.room.join_rules`` events.
|
||||||
|
@ -95,4 +95,200 @@ A *conflict* occurs between states where those states have different
|
||||||
affected are said to be *conflicting* events.
|
affected are said to be *conflicting* events.
|
||||||
|
|
||||||
|
|
||||||
.. _`authorization rules`: ../server_server/unstable.html#authorization-rules
|
Authorization rules
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The types of state events that affect authorization are:
|
||||||
|
|
||||||
|
- ``m.room.create``
|
||||||
|
- ``m.room.member``
|
||||||
|
- ``m.room.join_rules``
|
||||||
|
- ``m.room.power_levels``
|
||||||
|
- ``m.room.third_party_invite``
|
||||||
|
|
||||||
|
The rules are as follows:
|
||||||
|
|
||||||
|
1. If type is ``m.room.create``:
|
||||||
|
|
||||||
|
a. If it has any previous events, reject.
|
||||||
|
b. If the domain of the ``room_id`` does not match the domain of the
|
||||||
|
``sender``, reject.
|
||||||
|
c. If ``content.room_version`` is present and is not a recognised version,
|
||||||
|
reject.
|
||||||
|
d. If ``content`` has no ``creator`` field, reject.
|
||||||
|
e. Otherwise, allow.
|
||||||
|
|
||||||
|
#. Reject if event has ``auth_events`` that:
|
||||||
|
|
||||||
|
a. have duplicate entries for a given ``type`` and ``state_key`` pair
|
||||||
|
#. have entries whose ``type`` and ``state_key`` don't match those
|
||||||
|
specified by the `auth events selection`_ algorithm described in the
|
||||||
|
server specification.
|
||||||
|
|
||||||
|
#. If event does not have a ``m.room.create`` in its ``auth_events``, reject.
|
||||||
|
|
||||||
|
#. 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.member``:
|
||||||
|
|
||||||
|
a. If no ``state_key`` key or ``membership`` key in ``content``, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``join``:
|
||||||
|
|
||||||
|
i. If the only previous event is an ``m.room.create``
|
||||||
|
and the ``state_key`` is the creator, allow.
|
||||||
|
|
||||||
|
#. If the ``sender`` does not match ``state_key``, reject.
|
||||||
|
|
||||||
|
#. If the ``sender`` is banned, reject.
|
||||||
|
|
||||||
|
#. If the ``join_rule`` is ``invite`` then allow if membership state
|
||||||
|
is ``invite`` or ``join``.
|
||||||
|
|
||||||
|
#. If the ``join_rule`` is ``public``, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``invite``:
|
||||||
|
|
||||||
|
i. If ``content`` has ``third_party_invite`` key:
|
||||||
|
|
||||||
|
#. If *target user* is banned, reject.
|
||||||
|
|
||||||
|
#. If ``content.third_party_invite`` does not have a
|
||||||
|
``signed`` key, reject.
|
||||||
|
|
||||||
|
#. If ``signed`` does not have ``mxid`` and ``token`` keys, reject.
|
||||||
|
|
||||||
|
#. If ``mxid`` does not match ``state_key``, reject.
|
||||||
|
|
||||||
|
#. If there is no ``m.room.third_party_invite`` event in the
|
||||||
|
current room state with ``state_key`` matching ``token``, reject.
|
||||||
|
|
||||||
|
#. If ``sender`` does not match ``sender`` of the
|
||||||
|
``m.room.third_party_invite``, reject.
|
||||||
|
|
||||||
|
#. If any signature in ``signed`` matches any public key in the
|
||||||
|
``m.room.third_party_invite`` event, allow. The public keys are
|
||||||
|
in ``content`` of ``m.room.third_party_invite`` as:
|
||||||
|
|
||||||
|
#. A single public key in the ``public_key`` field.
|
||||||
|
#. A list of public keys in the ``public_keys`` field.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If *target user*'s current membership state is ``join`` or ``ban``,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *invite
|
||||||
|
level*, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``leave``:
|
||||||
|
|
||||||
|
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
|
||||||
|
current membership state is ``invite`` or ``join``.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If the *target user*'s current membership state is ``ban``, and the
|
||||||
|
``sender``'s power level is less than the *ban level*, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *kick
|
||||||
|
level*, and the *target user*'s power level is less than the
|
||||||
|
``sender``'s power level, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. If ``membership`` is ``ban``:
|
||||||
|
|
||||||
|
i. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s power level is greater than or equal to the *ban
|
||||||
|
level*, and the *target user*'s power level is less than the
|
||||||
|
``sender``'s power level, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. Otherwise, the membership is unknown. Reject.
|
||||||
|
|
||||||
|
#. If the ``sender``'s current membership state is not ``join``, reject.
|
||||||
|
|
||||||
|
#. If type is ``m.room.third_party_invite``:
|
||||||
|
|
||||||
|
a. Allow if and only if ``sender``'s current power level is greater than
|
||||||
|
or equal to the *invite level*.
|
||||||
|
|
||||||
|
#. If the event type's *required power level* is greater than the ``sender``'s power
|
||||||
|
level, reject.
|
||||||
|
|
||||||
|
#. If the event has a ``state_key`` that starts with an ``@`` and does not match
|
||||||
|
the ``sender``, reject.
|
||||||
|
|
||||||
|
#. If type is ``m.room.power_levels``:
|
||||||
|
|
||||||
|
a. If ``users`` key in ``content`` is not a dictionary with keys that are
|
||||||
|
valid user IDs with values that are integers (or a string that is an
|
||||||
|
integer), reject.
|
||||||
|
|
||||||
|
#. If there is no previous ``m.room.power_levels`` event in the room, allow.
|
||||||
|
|
||||||
|
#. For each of the keys ``users_default``, ``events_default``,
|
||||||
|
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
|
||||||
|
each entry being changed under the ``events`` or ``users`` keys:
|
||||||
|
|
||||||
|
i. If the current value is higher than the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. If the new value is higher than the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. For each entry being changed under the ``users`` key, other than the
|
||||||
|
``sender``'s own entry:
|
||||||
|
|
||||||
|
i. If the current value is equal to the ``sender``'s current power level,
|
||||||
|
reject.
|
||||||
|
|
||||||
|
#. Otherwise, allow.
|
||||||
|
|
||||||
|
#. If type is ``m.room.redaction``:
|
||||||
|
|
||||||
|
a. If the ``sender``'s power level is greater than or equal to the *redact
|
||||||
|
level*, allow.
|
||||||
|
|
||||||
|
#. If the domain of the ``event_id`` of the event being redacted is the same
|
||||||
|
as the domain of the ``event_id`` of the ``m.room.redaction``, allow.
|
||||||
|
|
||||||
|
#. Otherwise, reject.
|
||||||
|
|
||||||
|
#. Otherwise, allow.
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
Some consequences of these rules:
|
||||||
|
|
||||||
|
* Unless you are a member of the room, the only permitted operations (apart
|
||||||
|
from the intial create/join) are: joining a public room; accepting or
|
||||||
|
rejecting an invitation to a room.
|
||||||
|
|
||||||
|
* To unban somebody, you must have power level greater than or equal to both
|
||||||
|
the kick *and* ban levels, *and* greater than the target user's power
|
||||||
|
level.
|
||||||
|
|
||||||
|
Event format
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Events in version 1 rooms have the following structure:
|
||||||
|
|
||||||
|
{{definition_ss_pdu}}
|
||||||
|
|
||||||
|
|
||||||
|
.. _`auth events selection`: ../../server_server/unstable.html#auth-events-selection
|
||||||
|
.. _`Signing Events`: ../../server_server/unstable.html#signing-events
|
||||||
|
|
121
specification/rooms/v3.rst
Normal file
121
specification/rooms/v3.rst
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
.. Copyright 2018-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 Version 3
|
||||||
|
==============
|
||||||
|
|
||||||
|
This room version builds on `version 2 <v2.html>`_ with an improved event format.
|
||||||
|
|
||||||
|
.. note:
|
||||||
|
All requirements listed in this room version specification are scoped to rooms
|
||||||
|
which actually use this room version. For example, a requirement of "all APIs must
|
||||||
|
accept the new event format" does in fact apply to all APIs, but only so much as
|
||||||
|
where the contextual room of the request is using this room version. Rooms using
|
||||||
|
other room versions should not be affected by these sweeping requirements.
|
||||||
|
|
||||||
|
|
||||||
|
Client considerations
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This room version changes the format for event IDs sent to clients. Clients should be
|
||||||
|
aware that these event IDs may contain slashes and other potentially problematic
|
||||||
|
characters. Clients should be treating event IDs as opaque identifiers and should not
|
||||||
|
be attempting to parse them into a usable form, just like with other room versions.
|
||||||
|
|
||||||
|
Clients should expect to see event IDs changed from the format of ``$randomstring:example.org``
|
||||||
|
to something like ``$acR1l0raoZnm60CBwAVgqbZqoO/mYU81xysh1u7XcJk`` (note the lack of
|
||||||
|
domain and the potentially problematic slash).
|
||||||
|
|
||||||
|
|
||||||
|
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 3 uses the state resolution algorithm defined in `room version 2 <v2.html>`_,
|
||||||
|
and the event format defined here.
|
||||||
|
|
||||||
|
Event IDs
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
.. admonition:: Rationale
|
||||||
|
|
||||||
|
In other room versions (namely version 1 and 2) the event ID is a distinct field
|
||||||
|
from the remainder of the event, which must be tracked as such. This leads to
|
||||||
|
complications where servers receive multiple events with the same ID in either the
|
||||||
|
same or different rooms where the server cannot easily keep track of which event it
|
||||||
|
should be using. By removing the use of a dedicated event ID, servers are required
|
||||||
|
to track the hashes on an event to determine its ID.
|
||||||
|
|
||||||
|
The event ID is the `reference hash`_ of the event encoded using `Unpadded Base64`_,
|
||||||
|
prefixed with ``$``. A resulting event ID using this approach should look similar to
|
||||||
|
``$CD66HAED5npg6074c6pDtLKalHjVfYb2q4Q3LZgrW6o``.
|
||||||
|
|
||||||
|
Event IDs should not be sent over federation to servers when the room uses
|
||||||
|
this room version. On the receiving end of an event, the server should compute
|
||||||
|
the relevant event ID for itself.
|
||||||
|
|
||||||
|
Additionally, the ``auth_events`` and ``prev_events`` have had a format change
|
||||||
|
compared to other room versions to make it easier to handle. Instead of a tuple
|
||||||
|
of values, they are now plain lists of events.
|
||||||
|
|
||||||
|
{{definition_ss_pdu_v3}}
|
||||||
|
|
||||||
|
Changes to APIs
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Due to the event ID being removed from the event, some APIs need to change. All
|
||||||
|
APIs which currently accept an event ID must do so with the new format. Servers
|
||||||
|
must append the calculated event ID to all events sent to clients where an event
|
||||||
|
ID would normally be expected.
|
||||||
|
|
||||||
|
Because the format of events has changed, servers must be aware of the room version
|
||||||
|
where the event resides so that the server may parse and handle the event. The
|
||||||
|
federation API has taken this concern into consideration by ensuring that servers
|
||||||
|
are aware of (or can find) the room version during a request.
|
||||||
|
|
||||||
|
Authorization rules for events
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The authorization rules for a given event have changed in this room version due
|
||||||
|
to the change in event format:
|
||||||
|
|
||||||
|
* The event no longer needs to be signed by the domain of the event ID (as there
|
||||||
|
is no domain in the event ID), but still needs to be signed by the sender's
|
||||||
|
domain.
|
||||||
|
|
||||||
|
* In past room versions, redactions were only permitted to enter the DAG if the
|
||||||
|
sender's domain matched the domain in the event ID being redacted, or the sender
|
||||||
|
had appropriate permissions per the power levels. Due to servers now not being
|
||||||
|
able to determine where an event came from during event authorization, redaction
|
||||||
|
events are always accepted (provided the event is allowed by ``events`` and
|
||||||
|
``events_default`` in the power levels). However, servers should not apply or send
|
||||||
|
redactions to clients until both the redaction event and original event have been
|
||||||
|
seen, and are valid. Servers should only apply redactions to events where the
|
||||||
|
sender's domains match, or the sender of the redaction has the appropriate
|
||||||
|
permissions per the power levels.
|
||||||
|
|
||||||
|
|
||||||
|
The remaining rules are the same as `room version 1 <v1.html#authorization-rules>`_.
|
||||||
|
|
||||||
|
|
||||||
|
.. _`Unpadded Base64`: ../../appendices.html#unpadded-base64
|
||||||
|
.. _`Canonical JSON`: ../../appendices.html#canonical-json
|
||||||
|
.. _`Signing Events`: ../../server_server/unstable.html#signing-events
|
||||||
|
.. _`reference hash`: ../../server_server/unstable.html#reference-hashes
|
|
@ -281,6 +281,8 @@ Transactions are limited in size; they can have at most 50 PDUs and 100 EDUs.
|
||||||
|
|
||||||
{{transactions_ss_http_api}}
|
{{transactions_ss_http_api}}
|
||||||
|
|
||||||
|
.. _`Persistent Data Unit schema`:
|
||||||
|
|
||||||
PDUs
|
PDUs
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -327,7 +329,7 @@ following subset of the room state:
|
||||||
``m.room.third_party_invite`` event with ``state_key`` matching
|
``m.room.third_party_invite`` event with ``state_key`` matching
|
||||||
``content.third_party_invite.signed.token``, if any.
|
``content.third_party_invite.signed.token``, if any.
|
||||||
|
|
||||||
{{definition_ss_pdu}}
|
For a full schema of what a PDU looks like, see the `room version specification`_.
|
||||||
|
|
||||||
Checks performed on receipt of a PDU
|
Checks performed on receipt of a PDU
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -379,189 +381,9 @@ Authorization rules
|
||||||
|
|
||||||
The rules governing whether an event is authorized depends on a set of state. A
|
The rules governing whether an event is authorized depends on a set of state. A
|
||||||
given event is checked multiple times against different sets of state, as
|
given event is checked multiple times against different sets of state, as
|
||||||
specified above. The types of state events that affect authorization are:
|
specified above. Each room version can have a different algorithm for how the
|
||||||
|
rules work, and which rules are applied. For more detailed information, please
|
||||||
- ``m.room.create``
|
see the `room version specification`_.
|
||||||
- ``m.room.member``
|
|
||||||
- ``m.room.join_rules``
|
|
||||||
- ``m.room.power_levels``
|
|
||||||
- ``m.room.third_party_invite``
|
|
||||||
|
|
||||||
The rules are as follows:
|
|
||||||
|
|
||||||
1. If type is ``m.room.create``:
|
|
||||||
|
|
||||||
a. If it has any previous events, reject.
|
|
||||||
b. If the domain of the ``room_id`` does not match the domain of the
|
|
||||||
``sender``, reject.
|
|
||||||
c. If ``content.room_version`` is present and is not a recognised version,
|
|
||||||
reject.
|
|
||||||
d. If ``content`` has no ``creator`` field, reject.
|
|
||||||
e. Otherwise, allow.
|
|
||||||
|
|
||||||
#. Reject if event has ``auth_events`` that:
|
|
||||||
|
|
||||||
a. have duplicate entries for a given ``type`` and ``state_key`` pair
|
|
||||||
#. have entries whose ``type`` and ``state_key`` don't match those
|
|
||||||
specified by the `auth events selection`_ algorithm described above.
|
|
||||||
|
|
||||||
#. If event does not have a ``m.room.create`` in its ``auth_events``, reject.
|
|
||||||
|
|
||||||
#. 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.member``:
|
|
||||||
|
|
||||||
a. If no ``state_key`` key or ``membership`` key in ``content``, reject.
|
|
||||||
|
|
||||||
#. If ``membership`` is ``join``:
|
|
||||||
|
|
||||||
i. If the only previous event is an ``m.room.create``
|
|
||||||
and the ``state_key`` is the creator, allow.
|
|
||||||
|
|
||||||
#. If the ``sender`` does not match ``state_key``, reject.
|
|
||||||
|
|
||||||
#. If the ``sender`` is banned, reject.
|
|
||||||
|
|
||||||
#. If the ``join_rule`` is ``invite`` then allow if membership state
|
|
||||||
is ``invite`` or ``join``.
|
|
||||||
|
|
||||||
#. If the ``join_rule`` is ``public``, allow.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. If ``membership`` is ``invite``:
|
|
||||||
|
|
||||||
i. If ``content`` has ``third_party_invite`` key:
|
|
||||||
|
|
||||||
#. If *target user* is banned, reject.
|
|
||||||
|
|
||||||
#. If ``content.third_party_invite`` does not have a
|
|
||||||
``signed`` key, reject.
|
|
||||||
|
|
||||||
#. If ``signed`` does not have ``mxid`` and ``token`` keys, reject.
|
|
||||||
|
|
||||||
#. If ``mxid`` does not match ``state_key``, reject.
|
|
||||||
|
|
||||||
#. If there is no ``m.room.third_party_invite`` event in the
|
|
||||||
current room state with ``state_key`` matching ``token``, reject.
|
|
||||||
|
|
||||||
#. If ``sender`` does not match ``sender`` of the
|
|
||||||
``m.room.third_party_invite``, reject.
|
|
||||||
|
|
||||||
#. If any signature in ``signed`` matches any public key in the
|
|
||||||
``m.room.third_party_invite`` event, allow. The public keys are
|
|
||||||
in ``content`` of ``m.room.third_party_invite`` as:
|
|
||||||
|
|
||||||
#. A single public key in the ``public_key`` field.
|
|
||||||
#. A list of public keys in the ``public_keys`` field.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
|
||||||
|
|
||||||
#. If *target user*'s current membership state is ``join`` or ``ban``,
|
|
||||||
reject.
|
|
||||||
|
|
||||||
#. If the ``sender``'s power level is greater than or equal to the *invite
|
|
||||||
level*, allow.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. If ``membership`` is ``leave``:
|
|
||||||
|
|
||||||
i. If the ``sender`` matches ``state_key``, allow if and only if that user's
|
|
||||||
current membership state is ``invite`` or ``join``.
|
|
||||||
|
|
||||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
|
||||||
|
|
||||||
#. If the *target user*'s current membership state is ``ban``, and the
|
|
||||||
``sender``'s power level is less than the *ban level*, reject.
|
|
||||||
|
|
||||||
#. If the ``sender``'s power level is greater than or equal to the *kick
|
|
||||||
level*, and the *target user*'s power level is less than the
|
|
||||||
``sender``'s power level, allow.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. If ``membership`` is ``ban``:
|
|
||||||
|
|
||||||
i. If the ``sender``'s current membership state is not ``join``, reject.
|
|
||||||
|
|
||||||
#. If the ``sender``'s power level is greater than or equal to the *ban
|
|
||||||
level*, and the *target user*'s power level is less than the
|
|
||||||
``sender``'s power level, allow.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. Otherwise, the membership is unknown. Reject.
|
|
||||||
|
|
||||||
#. If the ``sender``'s current membership state is not ``join``, reject.
|
|
||||||
|
|
||||||
#. If type is ``m.room.third_party_invite``:
|
|
||||||
|
|
||||||
a. Allow if and only if ``sender``'s current power level is greater than
|
|
||||||
or equal to the *invite level*.
|
|
||||||
|
|
||||||
#. If the event type's *required power level* is greater than the ``sender``'s power
|
|
||||||
level, reject.
|
|
||||||
|
|
||||||
#. If the event has a ``state_key`` that starts with an ``@`` and does not match
|
|
||||||
the ``sender``, reject.
|
|
||||||
|
|
||||||
#. If type is ``m.room.power_levels``:
|
|
||||||
|
|
||||||
a. If ``users`` key in ``content`` is not a dictionary with keys that are
|
|
||||||
valid user IDs with values that are integers (or a string that is an
|
|
||||||
integer), reject.
|
|
||||||
|
|
||||||
#. If there is no previous ``m.room.power_levels`` event in the room, allow.
|
|
||||||
|
|
||||||
#. For each of the keys ``users_default``, ``events_default``,
|
|
||||||
``state_default``, ``ban``, ``redact``, ``kick``, ``invite``, as well as
|
|
||||||
each entry being changed under the ``events`` or ``users`` keys:
|
|
||||||
|
|
||||||
i. If the current value is higher than the ``sender``'s current power level,
|
|
||||||
reject.
|
|
||||||
|
|
||||||
#. If the new value is higher than the ``sender``'s current power level,
|
|
||||||
reject.
|
|
||||||
|
|
||||||
#. For each entry being changed under the ``users`` key, other than the
|
|
||||||
``sender``'s own entry:
|
|
||||||
|
|
||||||
i. If the current value is equal to the ``sender``'s current power level,
|
|
||||||
reject.
|
|
||||||
|
|
||||||
#. Otherwise, allow.
|
|
||||||
|
|
||||||
#. If type is ``m.room.redaction``:
|
|
||||||
|
|
||||||
a. If the ``sender``'s power level is greater than or equal to the *redact
|
|
||||||
level*, allow.
|
|
||||||
|
|
||||||
#. If the domain of the ``event_id`` of the event being redacted is the same
|
|
||||||
as the domain of the ``event_id`` of the ``m.room.redaction``, allow.
|
|
||||||
|
|
||||||
#. Otherwise, reject.
|
|
||||||
|
|
||||||
#. Otherwise, allow.
|
|
||||||
|
|
||||||
.. NOTE::
|
|
||||||
|
|
||||||
Some consequences of these rules:
|
|
||||||
|
|
||||||
* Unless you are a member of the room, the only permitted operations (apart
|
|
||||||
from the intial create/join) are: joining a public room; accepting or
|
|
||||||
rejecting an invitation to a room.
|
|
||||||
|
|
||||||
* To unban somebody, you must have power level greater than or equal to both
|
|
||||||
the kick *and* ban levels, *and* greater than the target user's power
|
|
||||||
level.
|
|
||||||
|
|
||||||
|
|
||||||
Rejection
|
Rejection
|
||||||
+++++++++
|
+++++++++
|
||||||
|
@ -1230,6 +1052,24 @@ been given a redacted version of the event. To enforce this, the receiving
|
||||||
server should use the redacted copy it calculated rather than the full copy it
|
server should use the redacted copy it calculated rather than the full copy it
|
||||||
received.
|
received.
|
||||||
|
|
||||||
|
.. _`reference hashes`:
|
||||||
|
|
||||||
|
Calculating the reference hash for an event
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The *reference hash* of an event covers the essential fields of an event,
|
||||||
|
including content hashes. It is calculated as follows.
|
||||||
|
|
||||||
|
1. The event is put through the redaction algorithm.
|
||||||
|
|
||||||
|
2. The ``signatures``, ``age_ts``, and ``unsigned`` properties are removed
|
||||||
|
from the event, if present.
|
||||||
|
|
||||||
|
3. The event is converted into `Canonical JSON`_.
|
||||||
|
|
||||||
|
4. A sha256 hash is calculed on the resulting JSON object.
|
||||||
|
|
||||||
|
|
||||||
Calculating the content hash for an event
|
Calculating the content hash for an event
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ targets:
|
||||||
files:
|
files:
|
||||||
- rooms/v2.rst
|
- rooms/v2.rst
|
||||||
version_label: v2
|
version_label: v2
|
||||||
|
rooms@v3: # this is translated to be rooms/v3.html
|
||||||
|
files:
|
||||||
|
- rooms/v3.rst
|
||||||
|
version_label: v3
|
||||||
appendices:
|
appendices:
|
||||||
files:
|
files:
|
||||||
- appendices.rst
|
- appendices.rst
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue