Fully specify room versions (#3432)

* Fully specify room versions

* Misc typo clarifications

* Try to clarify redactions a bit

* Update content/client-server-api/_index.md

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update content/rooms/v6.md

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update content/rooms/v6.md

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Better describe client considerations

* Doc template params

* Move redaction "new stuff" to v3

* Remove unhelpful sentences about "here follows unchanged stuff"

* Simplify event signing text

* Clean up handling redactions sections

* Move v4's event schema to unchanged section

* Update content/rooms/v4.md

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Travis Ralston 2021-11-01 08:49:15 -06:00 committed by GitHub
parent b873ba984c
commit 241e01c332
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1082 additions and 439 deletions

View file

@ -12,6 +12,10 @@ as a possible join rule and membership state.
This is the first room version to support knocking completely. As such,
users will not be able to knock on rooms which are not based off v7.
Though unchanged in this room version, clients which implement the
redaction algorithm locally should refer to the [redactions](#redactions)
section below for a full overview.
## Server implementation components
{{% boxes/warning %}}
@ -26,27 +30,183 @@ Room version 7 adds new authorization rules for events to support knocking.
[Room version 6](/rooms/v6) has details of other authorization rule changes,
as do the versions v6 is based upon.
{{% added-in this=true %}} For checks perfomed upon `m.room.member` events, the following conditions
are added in context:
### Authorization rules
If type is `m.room.member`:
{{% added-in this=true %}} For checks perfomed upon `m.room.member` events, a
new point for `membership=knock` is added.
...
Events must be signed by the server denoted by the `sender` key.
* If `membership` is `ban`:
`m.room.redaction` events are not explicitly part of the auth rules.
They are still subject to the minimum power level rules, but should always
fall into "10. Otherwise, allow". Instead of being authorized at the time
of receipt, they are authorized at a later stage: see the
[Redactions](#redactions) section below for more information.
...
The types of state events that affect authorization are:
* If `membership` is `knock`:
- `m.room.create`
- `m.room.member`
- `m.room.join_rules`
- `m.room.power_levels`
- `m.room.third_party_invite`
i. If the `join_rule` is anything other than `knock`, reject.
{{% boxes/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.
{{% /boxes/note %}}
ii. If `sender` does not match `state_key`, reject.
The rules are as follows:
iii. If the `sender`'s current membership is not `ban`, `invite`, or `join`, allow.
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-api#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.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. If `membership` is `knock`:
1. If the `join_rule` is anything other than `knock`, reject.
2. If `sender` does not match `state_key`, reject.
3. If the `sender`'s current membership is not `ban`, `invite`,
or `join`, allow.
7. Otherwise, the membership is unknown. Reject.
5. If the `sender`'s current membership state is not `join`, reject.
6. 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*.
7. If the event type's *required power level* is greater than the
`sender`'s power level, reject.
8. If the event has a `state_key` that starts with an `@` and does not
match the `sender`, reject.
9. 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`, `users`, and `notifications` 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.
10. Otherwise, allow.
iv. Otherwise, reject.
{{% boxes/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.
{{% /boxes/note %}}
The remaining rules are the same as in [room version 6](/rooms/v6#authorization-rules-for-events).
## Unchanged from v6
The following sections have not been modified since v6, but are included for
completeness.
### State resolution
{{% rver-fragment name="v2-state-res" %}}
### Event format
{{% rver-fragment name="v4-event-explainer" %}}
{{% definition path="api/server-server/definitions/pdu_v4" %}}
### Canonical JSON
{{% rver-fragment name="v6-canonical-json" %}}
### Signing key validity period
{{% rver-fragment name="v5-signing-requirements" %}}
### Redactions
{{% rver-fragment name="v3-handling-redactions" %}}
{{% rver-fragment name="v6-redactions" %}}