Add page content as raw Pandoc output
This commit is contained in:
parent
ebc6db233b
commit
c924b3246f
13 changed files with 6469 additions and 0 deletions
|
@ -3,3 +3,287 @@ title: Room Version 1
|
|||
type: docs
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# Room Version 1
|
||||
|
||||
This room version is the first ever version for rooms, and contains the
|
||||
building blocks for other room versions.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## Client considerations
|
||||
|
||||
Clients may need to consider some algorithms performed by the server for
|
||||
their own implementation.
|
||||
|
||||
### Redactions
|
||||
|
||||
Upon receipt of a redaction event, the server must strip off any keys
|
||||
not in the following list:
|
||||
|
||||
- `event_id`
|
||||
- `type`
|
||||
- `room_id`
|
||||
- `sender`
|
||||
- `state_key`
|
||||
- `content`
|
||||
- `hashes`
|
||||
- `signatures`
|
||||
- `depth`
|
||||
- `prev_events`
|
||||
- `prev_state`
|
||||
- `auth_events`
|
||||
- `origin`
|
||||
- `origin_server_ts`
|
||||
- `membership`
|
||||
|
||||
The content object must also be stripped of all keys, unless it is one
|
||||
of one of the following event types:
|
||||
|
||||
- `m.room.member` allows key `membership`.
|
||||
- `m.room.create` allows key `creator`.
|
||||
- `m.room.join_rules` allows key `join_rule`.
|
||||
- `m.room.power_levels` allows keys `ban`, `events`, `events_default`,
|
||||
`kick`, `redact`, `state_default`, `users`, `users_default`.
|
||||
- `m.room.aliases` allows key `aliases`.
|
||||
- `m.room.history_visibility` allows key `history_visibility`.
|
||||
|
||||
## 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.
|
||||
|
||||
The algorithms defined here should only apply to version 1 rooms. Other
|
||||
algorithms may be used by other room versions, and as such servers
|
||||
should be aware of which version room they are dealing with prior to
|
||||
executing a given algorithm.
|
||||
|
||||
Warning
|
||||
|
||||
Although there are many rooms using room version 1, it is known to have
|
||||
undesirable effects. Servers implementing support for room version 1
|
||||
should be aware that restrictions should be generally relaxed and that
|
||||
inconsistencies may occur.
|
||||
|
||||
### State resolution
|
||||
|
||||
Warning
|
||||
|
||||
Room version 1 is known to have bugs that can cause the state of rooms
|
||||
to reset to older versions of the room's state. For example this could
|
||||
mean that users who had joined the room may be removed from the room,
|
||||
admins and moderators could lose their power level, and users who have
|
||||
been banned from the room may be able to rejoin. Other state events such
|
||||
as the the room's name or topic could also reset to a previous version.
|
||||
|
||||
This is fixed in the state resolution algorithm introduced in room
|
||||
version 2.
|
||||
|
||||
The room state *S*′(*E*) after an event *E* is defined in terms of the
|
||||
room state *S*(*E*) before *E*, and depends on whether *E* is a state
|
||||
event or a message event:
|
||||
|
||||
- If *E* is a message event, then *S*′(*E*) = *S*(*E*).
|
||||
- If *E* is a state event, then *S*′(*E*) is *S*(*E*), except that its
|
||||
entry corresponding to *E*'s `event_type` and `state_key` is
|
||||
replaced by *E*'s `event_id`.
|
||||
|
||||
The room state *S*(*E*) before *E* is the *resolution* of the set of
|
||||
states {*S*′(*E*′), *S*′(*E*″), …} consisting of the states after each
|
||||
of *E*'s `prev_event`s {*E*′, *E*″, …}.
|
||||
|
||||
The *resolution* of a set of states is defined as follows. The resolved
|
||||
state is built up in a number of passes; here we use *R* to refer to the
|
||||
results of the resolution so far.
|
||||
|
||||
- Start by setting *R* to the union of the states to be resolved,
|
||||
excluding any *conflicting* events.
|
||||
- First we resolve conflicts between `m.room.power_levels` events. If
|
||||
there is no conflict, this step is skipped, otherwise:
|
||||
- Assemble all the `m.room.power_levels` events from the states to
|
||||
be resolved into a list.
|
||||
- Sort the list by ascending `depth` then descending
|
||||
`sha1(event_id)`.
|
||||
- Add the first event in the list to *R*.
|
||||
- For each subsequent event in the list, check that the event
|
||||
would be allowed by the authorization rules for a room in state
|
||||
*R*. If the event would be allowed, then update *R* with the
|
||||
event and continue with the next event in the list. If it would
|
||||
not be allowed, stop and continue below with `m.room.join_rules`
|
||||
events.
|
||||
- Repeat the above process for conflicts between `m.room.join_rules`
|
||||
events.
|
||||
- Repeat the above process for conflicts between `m.room.member`
|
||||
events.
|
||||
- No other events affect the authorization rules, so for all other
|
||||
conflicts, just pick the event with the highest depth and lowest
|
||||
`sha1(event_id)` that passes authentication in *R* and add it to
|
||||
*R*.
|
||||
|
||||
A *conflict* occurs between states where those states have different
|
||||
`event_ids` for the same `(event_type, state_key)`. The events thus
|
||||
affected are said to be *conflicting* events.
|
||||
|
||||
### 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`
|
||||
|
||||
Note
|
||||
|
||||
Power levels are inferred from defaults when not explicitly supplied.
|
||||
For example, mentions of the `sender`'s power level can also refer to
|
||||
the default power level for users in the room.
|
||||
|
||||
The rules are as follows:
|
||||
|
||||
1. If type is `m.room.create`:
|
||||
1. If it has any previous events, reject.
|
||||
2. If the domain of the `room_id` does not match the domain of the
|
||||
`sender`, reject.
|
||||
3. If `content.room_version` is present and is not a recognised
|
||||
version, reject.
|
||||
4. If `content` has no `creator` field, reject.
|
||||
5. Otherwise, allow.
|
||||
2. Reject if event has `auth_events` that:
|
||||
1. have duplicate entries for a given `type` and `state_key` pair
|
||||
2. have entries whose `type` and `state_key` don't match those
|
||||
specified by the [auth events
|
||||
selection](../server_server/%SERVER_RELEASE_LABEL%.html#auth-events-selection)
|
||||
algorithm described in the server specification.
|
||||
3. If event does not have a `m.room.create` in its `auth_events`,
|
||||
reject.
|
||||
4. If type is `m.room.aliases`:
|
||||
1. If event has no `state_key`, reject.
|
||||
2. If sender's domain doesn't matches `state_key`, reject.
|
||||
3. Otherwise, allow.
|
||||
5. If type is `m.room.member`:
|
||||
1. If no `state_key` key or `membership` key in `content`, reject.
|
||||
2. If `membership` is `join`:
|
||||
1. If the only previous event is an `m.room.create` and the
|
||||
`state_key` is the creator, allow.
|
||||
2. If the `sender` does not match `state_key`, reject.
|
||||
3. If the `sender` is banned, reject.
|
||||
4. If the `join_rule` is `invite` then allow if membership
|
||||
state is `invite` or `join`.
|
||||
5. If the `join_rule` is `public`, allow.
|
||||
6. Otherwise, reject.
|
||||
3. If `membership` is `invite`:
|
||||
1. If `content` has `third_party_invite` key:
|
||||
1. If *target user* is banned, reject.
|
||||
2. If `content.third_party_invite` does not have a `signed`
|
||||
key, reject.
|
||||
3. If `signed` does not have `mxid` and `token` keys,
|
||||
reject.
|
||||
4. If `mxid` does not match `state_key`, reject.
|
||||
5. If there is no `m.room.third_party_invite` event in the
|
||||
current room state with `state_key` matching `token`,
|
||||
reject.
|
||||
6. If `sender` does not match `sender` of the
|
||||
`m.room.third_party_invite`, reject.
|
||||
7. 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:
|
||||
1. A single public key in the `public_key` field.
|
||||
2. A list of public keys in the `public_keys` field.
|
||||
8. Otherwise, reject.
|
||||
2. If the `sender`'s current membership state is not `join`,
|
||||
reject.
|
||||
3. If *target user*'s current membership state is `join` or
|
||||
`ban`, reject.
|
||||
4. If the `sender`'s power level is greater than or equal to
|
||||
the *invite level*, allow.
|
||||
5. Otherwise, reject.
|
||||
4. If `membership` is `leave`:
|
||||
1. If the `sender` matches `state_key`, allow if and only if
|
||||
that user's current membership state is `invite` or `join`.
|
||||
2. If the `sender`'s current membership state is not `join`,
|
||||
reject.
|
||||
3. If the *target user*'s current membership state is `ban`,
|
||||
and the `sender`'s power level is less than the *ban level*,
|
||||
reject.
|
||||
4. 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.
|
||||
5. Otherwise, reject.
|
||||
5. If `membership` is `ban`:
|
||||
1. If the `sender`'s current membership state is not `join`,
|
||||
reject.
|
||||
2. 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.
|
||||
3. Otherwise, reject.
|
||||
6. Otherwise, the membership is unknown. Reject.
|
||||
6. If the `sender`'s current membership state is not `join`, reject.
|
||||
7. If type is `m.room.third_party_invite`:
|
||||
1. Allow if and only if `sender`'s current power level is greater
|
||||
than or equal to the *invite level*.
|
||||
8. If the event type's *required power level* is greater than the
|
||||
`sender`'s power level, reject.
|
||||
9. If the event has a `state_key` that starts with an `@` and does not
|
||||
match the `sender`, reject.
|
||||
10. If type is `m.room.power_levels`:
|
||||
1. 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.
|
||||
2. If there is no previous `m.room.power_levels` event in the room,
|
||||
allow.
|
||||
3. For the keys `users_default`, `events_default`, `state_default`,
|
||||
`ban`, `redact`, `kick`, `invite` check if they were added,
|
||||
changed or removed. For each found alteration:
|
||||
1. If the current value is higher than the `sender`'s current
|
||||
power level, reject.
|
||||
2. If the new value is higher than the `sender`'s current power
|
||||
level, reject.
|
||||
4. For each entry being added, changed or removed in both the
|
||||
`events` and `users` keys:
|
||||
1. If the current value is higher than the `sender`'s current
|
||||
power level, reject.
|
||||
2. If the new value is higher than the `sender`'s current power
|
||||
level, reject.
|
||||
5. For each entry being changed under the `users` key, other than
|
||||
the `sender`'s own entry:
|
||||
1. If the current value is equal to the `sender`'s current
|
||||
power level, reject.
|
||||
6. Otherwise, allow.
|
||||
11. If type is `m.room.redaction`:
|
||||
1. If the `sender`'s power level is greater than or equal to the
|
||||
*redact level*, allow.
|
||||
2. 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.
|
||||
3. Otherwise, reject.
|
||||
12. Otherwise, allow.
|
||||
|
||||
Note
|
||||
|
||||
Some consequences of these rules:
|
||||
|
||||
- Unless you are a member of the room, the only permitted operations
|
||||
(apart from the initial 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}}
|
||||
|
||||
### Canonical JSON
|
||||
|
||||
Servers MUST NOT strictly enforce the JSON format specified in the
|
||||
[appendices](../appendices.html#canonical-json) for the reasons
|
||||
described there.
|
||||
|
|
|
@ -3,3 +3,190 @@ title: Room Version 2
|
|||
type: docs
|
||||
weight: 20
|
||||
---
|
||||
|
||||
# Room Version 2
|
||||
|
||||
This room version builds off of [version 1](v1.html) with an improved
|
||||
state resolution algorithm.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## 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 details contained here, and can safely ignore their
|
||||
presence.
|
||||
|
||||
Room version 2 uses the base components of [room version 1](v1.html),
|
||||
changing only the state resolution algorithm.
|
||||
|
||||
### State resolution
|
||||
|
||||
The room state *S*′(*E*) after an event *E* is defined in terms of the
|
||||
room state *S*(*E*) before *E*, and depends on whether *E* is a state
|
||||
event or a message event:
|
||||
|
||||
- If *E* is a message event, then *S*′(*E*) = *S*(*E*).
|
||||
- If *E* is a state event, then *S*′(*E*) is *S*(*E*), except that its
|
||||
entry corresponding to *E*'s `event_type` and `state_key` is
|
||||
replaced by *E*'s `event_id`.
|
||||
|
||||
The room state *S*(*E*) before *E* is the *resolution* of the set of
|
||||
states {*S*′(*E*<sub>1</sub>), *S*′(*E*<sub>2</sub>), …} consisting of
|
||||
the states after each of *E*'s `prev_event`s
|
||||
{*E*<sub>1</sub>, *E*<sub>2</sub>, …}, where the resolution of a set of
|
||||
states is given in the algorithm below.
|
||||
|
||||
#### Definitions
|
||||
|
||||
The state resolution algorithm for version 2 rooms uses the following
|
||||
definitions, given the set of room states
|
||||
{*S*<sub>1</sub>, *S*<sub>2</sub>, …}:
|
||||
|
||||
Power events
|
||||
A *power event* is a state event with type `m.room.power_levels` or
|
||||
`m.room.join_rules`, or a state event with type `m.room.member` where
|
||||
the `membership` is `leave` or `ban` and the `sender` does not match the
|
||||
`state_key`. The idea behind this is that power events are events that
|
||||
might remove someone's ability to do something in the room.
|
||||
|
||||
Unconflicted state map and conflicted state set
|
||||
The *unconflicted state map* is the state where the value of each key
|
||||
exists and is the same in each state *S*<sub>*i*</sub>. The *conflicted
|
||||
state set* is the set of all other state events. Note that the
|
||||
unconflicted state map only has one event per `(event_type, state_key)`,
|
||||
whereas the conflicted state set may have multiple events.
|
||||
|
||||
Auth difference
|
||||
The *auth difference* is calculated by first calculating the full auth
|
||||
chain for each state *S*<sub>*i*</sub>, that is the union of the auth
|
||||
chains for each event in *S*<sub>*i*</sub>, and then taking every event
|
||||
that doesn't appear in every auth chain. If *C*<sub>*i*</sub> is the
|
||||
full auth chain of *S*<sub>*i*</sub>, then the auth difference is
|
||||
∪ *C*<sub>*i*</sub> − ∩ *C*<sub>*i*</sub>.
|
||||
|
||||
Full conflicted set
|
||||
The *full conflicted set* is the union of the conflicted state set and
|
||||
the auth difference.
|
||||
|
||||
Reverse topological power ordering
|
||||
The *reverse topological power ordering* of a set of events is the
|
||||
lexicographically smallest topological ordering based on the DAG formed
|
||||
by auth events. The reverse topological power ordering is ordered from
|
||||
earliest event to latest. For comparing two topological orderings to
|
||||
determine which is the lexicographically smallest, the following
|
||||
comparison relation on events is used: for events *x* and *y*,
|
||||
*x* < *y* if
|
||||
|
||||
1. *x*'s sender has *greater* power level than *y*'s sender, when
|
||||
looking at their respective `auth_event`s; or
|
||||
2. the senders have the same power level, but *x*'s `origin_server_ts`
|
||||
is *less* than *y*'s `origin_server_ts`; or
|
||||
3. the senders have the same power level and the events have the same
|
||||
`origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
|
||||
`event_id`.
|
||||
|
||||
The reverse topological power ordering can be found by sorting the
|
||||
events using Kahn's algorithm for topological sorting, and at each step
|
||||
selecting, among all the candidate vertices, the smallest vertex using
|
||||
the above comparison relation.
|
||||
|
||||
Mainline ordering
|
||||
Given an `m.room.power_levels` event *P*, the *mainline of* *P* is the
|
||||
list of events generated by starting with *P* and recursively taking the
|
||||
`m.room.power_levels` events from the `auth_events`, ordered such that
|
||||
*P* is last. Given another event *e*, the *closest mainline event to*
|
||||
*e* is the first event encountered in the mainline when iteratively
|
||||
descending through the `m.room.power_levels` events in the `auth_events`
|
||||
starting at *e*. If no mainline event is encountered when iteratively
|
||||
descending through the `m.room.power_levels` events, then the closest
|
||||
mainline event to *e* can be considered to be a dummy event that is
|
||||
before any other event in the mainline of *P* for the purposes of
|
||||
condition 1 below.
|
||||
|
||||
The *mainline ordering based on* *P* of a set of events is the ordering,
|
||||
from smallest to largest, using the following comparison relation on
|
||||
events: for events *x* and *y*, *x* < *y* if
|
||||
|
||||
1. the closest mainline event to *x* appears *before* the closest
|
||||
mainline event to *y*; or
|
||||
2. the closest mainline events are the same, but *x*'s
|
||||
`origin_server_ts` is *less* than *y*'s `origin_server_ts`; or
|
||||
3. the closest mainline events are the same and the events have the
|
||||
same `origin_server_ts`, but *x*'s `event_id` is *less* than *y*'s
|
||||
`event_id`.
|
||||
|
||||
Iterative auth checks
|
||||
The *iterative auth checks algorithm* takes as input an initial room
|
||||
state and a sorted list of state events, and constructs a new room state
|
||||
by iterating through the event list and applying the state event to the
|
||||
room state if the state event is allowed by the [authorization
|
||||
rules](../server_server/%SERVER_RELEASE_LABEL%.html#authorization-rules).
|
||||
If the state event is not allowed by the authorization rules, then the
|
||||
event is ignored. If a `(event_type, state_key)` key that is required
|
||||
for checking the authorization rules is not present in the state, then
|
||||
the appropriate state event from the event's `auth_events` is used if
|
||||
the auth event is not rejected.
|
||||
|
||||
#### Algorithm
|
||||
|
||||
The *resolution* of a set of states is obtained as follows:
|
||||
|
||||
1. Take all *power events* and any events in their auth chains,
|
||||
recursively, that appear in the *full conflicted set* and order them
|
||||
by the *reverse topological power ordering*.
|
||||
2. Apply the *iterative auth checks algorithm*, starting from the
|
||||
*unconflicted state map*, to the list of events from the previous
|
||||
step to get a partially resolved state.
|
||||
3. Take all remaining events that weren't picked in step 1 and order
|
||||
them by the mainline ordering based on the power level in the
|
||||
partially resolved state obtained in step 2.
|
||||
4. Apply the *iterative auth checks algorithm* on the partial resolved
|
||||
state and the list of events from the previous step.
|
||||
5. Update the result by replacing any event with the event with the
|
||||
same key from the *unconflicted state map*, if such an event exists,
|
||||
to get the final resolved state.
|
||||
|
||||
#### Rejected events
|
||||
|
||||
Events that have been rejected due to failing auth based on the state at
|
||||
the event (rather than based on their auth chain) are handled as usual
|
||||
by the algorithm, unless otherwise specified.
|
||||
|
||||
Note that no events rejected due to failure to auth against their auth
|
||||
chain should appear in the process, as they should not appear in state
|
||||
(the algorithm only uses events that appear in either the state sets or
|
||||
in the auth chain of the events in the state sets).
|
||||
|
||||
Rationale
|
||||
|
||||
This helps ensure that different servers' view of state is more likely
|
||||
to converge, since rejection state of an event may be different. This
|
||||
can happen if a third server gives an incorrect version of the state
|
||||
when a server joins a room via it (either due to being faulty or
|
||||
malicious). Convergence of state is a desirable property as it ensures
|
||||
that all users in the room have a (mostly) consistent view of the state
|
||||
of the room. If the view of the state on different servers diverges it
|
||||
can lead to bifurcation of the room due to e.g. servers disagreeing on
|
||||
who is in the room.
|
||||
|
||||
Intuitively, using rejected events feels dangerous, however:
|
||||
|
||||
1. Servers cannot arbitrarily make up state, since they still need to
|
||||
pass the auth checks based on the event's auth chain (e.g. they
|
||||
can't grant themselves power levels if they didn't have them
|
||||
before).
|
||||
2. For a previously rejected event to pass auth there must be a set of
|
||||
state that allows said event. A malicious server could therefore
|
||||
produce a fork where it claims the state is that particular set of
|
||||
state, duplicate the rejected event to point to that fork, and send
|
||||
the event. The duplicated event would then pass the auth checks.
|
||||
Ignoring rejected events would therefore not eliminate any potential
|
||||
attack vectors.
|
||||
|
||||
Rejected auth events are deliberately excluded from use in the iterative
|
||||
auth checks, as auth events aren't re-authed (although non-auth events
|
||||
are) during the iterative auth checks.
|
||||
|
|
|
@ -3,3 +3,102 @@ title: Room Version 3
|
|||
type: docs
|
||||
weight: 30
|
||||
---
|
||||
|
||||
# Room Version 3
|
||||
|
||||
This room version builds on [version 2](v2.html) with an improved event
|
||||
format.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## 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
|
||||
|
||||
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](../server_server/%SERVER_RELEASE_LABEL%.html#reference-hashes) of
|
||||
the event encoded using [Unpadded
|
||||
Base64](../appendices.html#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).
|
||||
|
|
|
@ -3,3 +3,63 @@ title: Room Version 4
|
|||
type: docs
|
||||
weight: 40
|
||||
---
|
||||
|
||||
# Room Version 4
|
||||
|
||||
This room version builds on [version 3](v3.html) using a different
|
||||
encoding for event IDs.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## Client considerations
|
||||
|
||||
This room version changes the format form event IDs sent to clients.
|
||||
Clients should already be treating event IDs as opaque identifiers, and
|
||||
should not be concerned with the format of them. Clients should still
|
||||
encode the event ID when including it in a request path.
|
||||
|
||||
Clients should expect to see event IDs changed from the format of
|
||||
`$randomstring:example.org` to something like
|
||||
`$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg` (note the lack of
|
||||
domain).
|
||||
|
||||
## 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 4 uses the same algorithms defined in [room version
|
||||
3](v3.html), however using URL-safe base64 to generate the event ID.
|
||||
|
||||
### Event IDs
|
||||
|
||||
Rationale
|
||||
|
||||
Room version 3 generated event IDs that were difficult for client
|
||||
implementations which were not encoding the event ID to function in
|
||||
those rooms. It additionally raised concern due to the `/` character
|
||||
being interpretted differently by some reverse proxy software, and
|
||||
generally made administration harder.
|
||||
|
||||
The event ID is the [reference
|
||||
hash](../server_server/%SERVER_RELEASE_LABEL%.html#reference-hashes) of
|
||||
the event encoded using a variation of [Unpadded
|
||||
Base64](../appendices.html#unpadded-base64) which replaces the 62nd and
|
||||
63rd characters with `-` and `_` instead of using `+` and `/`. This
|
||||
matches [RFC4648's definition of URL-safe
|
||||
base64](https://tools.ietf.org/html/rfc4648#section-5). Event IDs are
|
||||
still prefixed with `$` and may result in looking like
|
||||
`$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg`.
|
||||
|
||||
Just like in room version 3, 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. Room version 3 also changes the format of `auth_events`
|
||||
and `prev_events` in a PDU.
|
||||
|
||||
{{definition\_ss\_pdu\_v4}}
|
||||
|
|
|
@ -3,3 +3,47 @@ title: Room Version 5
|
|||
type: docs
|
||||
weight: 50
|
||||
---
|
||||
|
||||
# Room Version 5
|
||||
|
||||
This room version builds on [version 4](v4.html) while enforcing signing
|
||||
key validity periods for events.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## Client considerations
|
||||
|
||||
There are no specific requirements for clients in this room version.
|
||||
Clients should be aware of event ID changes in [room version
|
||||
4](v4.html), however.
|
||||
|
||||
## 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 5 uses the same algorithms defined in [room version
|
||||
4](v4.html), ensuring that signing key validity is respected.
|
||||
|
||||
### Signing key validity period
|
||||
|
||||
When validating event signatures, servers MUST enforce the
|
||||
`valid_until_ts` property from a key request is at least as large as the
|
||||
`origin_server_ts` for the event being validated. Servers missing a copy
|
||||
of the signing key MUST try to obtain one via the [GET
|
||||
/\_matrix/key/v2/server](../server_server/%SERVER_RELEASE_LABEL%.html#get-matrix-key-v2-server-keyid)
|
||||
or [POST
|
||||
/\_matrix/key/v2/query](../server_server/%SERVER_RELEASE_LABEL%.html#post-matrix-key-v2-query)
|
||||
APIs. When using the `/query` endpoint, servers MUST set the
|
||||
`minimum_valid_until_ts` property to prompt the notary server to attempt
|
||||
to refresh the key if appropriate.
|
||||
|
||||
Servers MUST use the lesser of `valid_until_ts` and 7 days into the
|
||||
future when determining if a key is valid. This is to avoid a situation
|
||||
where an attacker publishes a key which is valid for a significant
|
||||
amount of time without a way for the homeserver owner to revoke it.
|
||||
|
|
|
@ -3,3 +3,86 @@ title: Room Version 6
|
|||
type: docs
|
||||
weight: 60
|
||||
---
|
||||
|
||||
# Room Version 6
|
||||
|
||||
This room version builds on [version 5](v5.html) while changing various
|
||||
authorization rules performed on events.
|
||||
|
||||
Table of Contents
|
||||
|
||||
## Client considerations
|
||||
|
||||
The redaction algorithm has changed from [room version 1](v1.html) to
|
||||
remove all rules against events of type `m.room.aliases`. Room versions
|
||||
2, 3, 4, and 5 all use v1's redaction algorithm. The algorithm is
|
||||
otherwise unchanged.
|
||||
|
||||
## Server implementation components
|
||||
|
||||
Warning
|
||||
|
||||
The information contained in this section is strictly for server
|
||||
implementors. Applications which use the Client-Server API are generally
|
||||
unaffected by the intricacies contained here. The section above
|
||||
regarding client considerations is the resource that Client-Server API
|
||||
use cases should reference.
|
||||
|
||||
Room version 6 makes the following alterations to algorithms described
|
||||
in [room version 5](v5.html).
|
||||
|
||||
### Redactions
|
||||
|
||||
As mentioned in the client considerations portion of this specification,
|
||||
all special meaning has been removed for events of type
|
||||
`m.room.aliases`. The algorithm is otherwise unchanged.
|
||||
|
||||
### Authorization rules for events
|
||||
|
||||
Like redactions, all rules relating specifically to events of type
|
||||
`m.room.aliases` are removed. They must still pass authorization checks
|
||||
relating to state events.
|
||||
|
||||
Additionally, the authorization rules for events of type
|
||||
`m.room.power_levels` now include the content key `notifications`. This
|
||||
new rule takes the place of the rule which checks the `events` and
|
||||
`users` keys.
|
||||
|
||||
For completeness, the changes to the auth rules can be represented as
|
||||
follows:
|
||||
|
||||
...
|
||||
|
||||
-If type is `m.room.aliases`:
|
||||
-
|
||||
- a. If event has no `state_key`, reject.
|
||||
- b. If sender's domain doesn't matches `state_key`, reject.
|
||||
- c. Otherwise, allow.
|
||||
|
||||
...
|
||||
|
||||
If type is `m.room.power_levels`:
|
||||
|
||||
...
|
||||
|
||||
- * For each entry being added, changed or removed in both the `events` and `users` keys:
|
||||
+ * For each entry being added, changed or removed in the `events`, `users`, and `notifications` keys:
|
||||
|
||||
i. If the current value is higher than the `sender`'s current power level, reject.
|
||||
|
||||
ii. If the new value is higher than the `sender`'s current power level, reject.
|
||||
|
||||
...
|
||||
|
||||
The remaining rules are the same as in [room version
|
||||
3](v3.html#authorization-rules-for-events) (the last inherited room
|
||||
version to specify the authorization rules).
|
||||
|
||||
### Canonical JSON
|
||||
|
||||
Servers MUST strictly enforce the JSON format specified in the
|
||||
[appendices](../appendices.html#canonical-json). This translates to a
|
||||
400 `M_BAD_JSON` error on most endpoints, or discarding of events over
|
||||
federation. For example, the Federation API's `/send` endpoint would
|
||||
discard the event whereas the Client Server API's `/send/{eventType}`
|
||||
endpoint would return a `M_BAD_JSON` error.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue