202 lines
11 KiB
Markdown
202 lines
11 KiB
Markdown
---
|
||
title: 房间版本 11
|
||
type: docs
|
||
weight: 100
|
||
version: 11
|
||
---
|
||
|
||
{{< boxes/warning >}}
|
||
本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 <a href="https://codeberg.org/wholetrans/docs-matrix-spec">Forgejo 存储库</a> 打开 Issue、提交 Pull Request 或<a href="mailto:errata@wholetrans.org">邮件联系</a>我们提出改进建议和参与翻译与核对。
|
||
{{< /boxes/warning >}}
|
||
|
||
|
||
本房间版本基于[版本 10](/rooms/v10) ,并进一步明确了撤回(redaction)规则。
|
||
|
||
## 客户端注意事项
|
||
|
||
### 撤回
|
||
|
||
{{% added-in v=11 %}} 顶层的 `origin`、`membership` 和 `prev_state` 属性不再受到撤回保护。[`m.room.create`](/client-server-api#mroomcreate) 事件现在会保留整个 `content` 属性。[`m.room.redaction`](/client-server-api#mroomredaction) 事件保留 `content` 下的 `redacts` 属性。[`m.room.power_levels`](/client-server-api#mroompower_levels) 事件保留 `content` 下的 `invite` 属性。
|
||
|
||
完整的撤回算法如下。
|
||
|
||
{{% rver-fragment name="v11-redactions" %}}
|
||
|
||
### 事件格式
|
||
|
||
客户端不应再依赖 [`m.room.create`](/client-server-api#mroomcreate) 事件的 `content` 中的 `creator` 属性。在所有房间版本中,客户端可以通过 `sender` 属性来确定房间的创建者。
|
||
|
||
[`m.room.redaction`](/client-server-api#mroomredaction) 事件的格式已被修改。客户端应当在 `content` 下查找 `redacts` 键,而不是顶层属性。
|
||
|
||
[`m.room.member`](/client-server-api#mroommember) 事件的 `third_party_invite` 键不再被撤回,但撤回后仅包含 `signed` 键。
|
||
|
||
## 服务端实现组件
|
||
|
||
{{% boxes/warning %}}
|
||
本部分内容仅供服务端实现者参考。使用 Client-Server API 的应用通常不受此处细节影响。上面“客户端注意事项”部分才是 Client-Server API 使用场景应关注的内容。
|
||
{{% /boxes/warning %}}
|
||
|
||
本房间版本更新了撤回算法,并修改了服务端应如何创建 `m.room.create` 和 `m.room.redaction` 事件。
|
||
|
||
房间版本 11 以版本 10 为基础,并有以下要点。
|
||
|
||
### 撤回
|
||
|
||
[见上文](#redactions)。
|
||
|
||
### 事件格式
|
||
|
||
核心事件格式与[房间版本 10](/rooms/v10#event-format) 相同。不过,该房间版本改变了某些事件类型的部分属性。
|
||
|
||
{{% rver-fragment name="v11-event-format" %}}
|
||
|
||
#### 移除 `m.room.create` 事件的 `creator` 属性
|
||
|
||
`m.room.create` 事件的 `content` 不再包含 `creator` 属性,此前它总是与事件的 `sender` 属性等同。
|
||
|
||
#### 将 `m.room.redaction` 事件的 `redacts` 属性移入 `content`
|
||
|
||
`m.room.redaction` 事件的 `redacts` 属性已从事件的顶层属性移到事件的 `content` 属性下。
|
||
|
||
为向后兼容旧版客户端,服务端在通过 Client-Server API 提供此类事件时,应在顶层添加 `redacts` 属性。
|
||
|
||
为更好兼容新版客户端,服务端在向*旧版*房间版本提供此类事件时,应在 `content` 下添加 `redacts` 属性。
|
||
|
||
### 授权规则
|
||
|
||
事件必须由 `sender` 属性指定的服务器签名。
|
||
|
||
影响授权的状态事件类型有:
|
||
|
||
- [`m.room.create`](/client-server-api#mroomcreate)
|
||
- [`m.room.member`](/client-server-api#mroommember)
|
||
- [`m.room.join_rules`](/client-server-api#mroomjoin_rules)
|
||
- [`m.room.power_levels`](/client-server-api#mroompower_levels)
|
||
- [`m.room.third_party_invite`](/client-server-api#mroomthird_party_invite)
|
||
|
||
{{% boxes/note %}}
|
||
未显式设置时,权限级别会采用默认值。例如,提及 `sender` 的权限级别,也可以指代房间内用户的默认权限级别。
|
||
{{% /boxes/note %}}
|
||
|
||
{{% boxes/note %}}
|
||
`m.room.redaction` 事件与其它事件一样受到授权规则约束。实际上,除非 `m.room.power_levels` 事件通过 `events` 或 `events_default` 属性对 `m.room.redaction` 事件设置了权限要求,否则这些事件通常会被允许。特别注意,撤回权限(_redact level_)**不会**被授权规则考虑。
|
||
|
||
具有发送撤回事件的能力,并不意味着该撤回一定会被执行。接收服务器必须按[撤回处理](#handling-redactions)部分所述进行额外检查。
|
||
{{% /boxes/note %}}
|
||
|
||
规则如下:
|
||
|
||
1. {{% changed-in v=11 %}}
|
||
如果类型为 `m.room.create`:
|
||
1. 如果有任何 `prev_events`,则拒绝。
|
||
2. 如果 `room_id` 的域名与 `sender` 的域名不一致,则拒绝。
|
||
3. 如果 `content.room_version` 存在且不是已知版本,则拒绝。
|
||
4. 其他情况,允许。
|
||
2. 针对事件的 `auth_events`:
|
||
1. 如果某一对 `type` 和 `state_key` 存在重复项,则拒绝。
|
||
2. 如果有 `type` 和 `state_key` 未按[授权事件选择](/server-server-api#auth-events-selection)算法选取,拒绝。
|
||
3. 如果有条目在[PDU接收时的检查](/server-server-api/#checks-performed-on-receipt-of-a-pdu)中被拒绝,则拒绝。
|
||
4. 如果没有 `m.room.create` 事件,被拒绝。
|
||
3. 如果房间状态下 `m.room.create` 事件的 `content` 的 `m.federate` 属性为 `false`,且当前事件的 `sender` 域与创建事件的 `sender` 域不一致,则拒绝。
|
||
4. 如果类型为 `m.room.member`:
|
||
1. 如果没有 `state_key` 属性,或 `content` 中没有 `membership` 属性,拒绝。
|
||
2. 如果 `content` 包含 `join_authorised_via_users_server`:
|
||
1. 如果事件未被该属性指定用户的 homeserver 合法签名,则拒绝。
|
||
3. 如果 `membership` 为 `join`:
|
||
1. {{% changed-in v=11 %}}
|
||
若唯一的前序事件是 `m.room.create` 且 `state_key` 为 `m.room.create` 的 sender,则允许。
|
||
2. 如果 `sender` 不等于 `state_key`,拒绝。
|
||
3. 如果 `sender` 被禁言,拒绝。
|
||
4. 若 `join_rule` 为 `invite` 或 `knock`,且会员状态为 `invite` 或 `join`,则允许。
|
||
5. 若 `join_rule` 为 `restricted` 或 `knock_restricted`:
|
||
1. 若会员状态为 `join` 或 `invite`,允许。
|
||
2. 如果 `content` 中的 `join_authorised_via_users_server` 不是有权邀请用户的用户,拒绝。
|
||
3. 其他情况,允许。
|
||
6. 若 `join_rule` 为 `public`,允许。
|
||
7. 其他情况,拒绝。
|
||
4. 如果 `membership` 为 `invite`:
|
||
1. 如果 `content` 有 `third_party_invite` 属性:
|
||
1. 如目标用户已被禁言,拒绝。
|
||
2. 如果 `content.third_party_invite` 缺少 `signed` 属性,拒绝。
|
||
3. 如果 `signed` 不包含 `mxid` 和 `token` 属性,拒绝。
|
||
4. 如果 `mxid` 不等于 `state_key`,拒绝。
|
||
5. 若当前房间状态没有 `state_key` 匹配 `token` 的 `m.room.third_party_invite` 事件,拒绝。
|
||
6. 如果 `sender` 不等于 `m.room.third_party_invite` 的 sender,拒绝。
|
||
7. 若 `signed` 中任何签名匹配 `m.room.third_party_invite` 事件中的公钥,则允许。公钥位于 `content` 的如下属性中:
|
||
1. `public_key` 属性内的单个公钥;
|
||
2. `public_keys` 属性内的公钥列表。
|
||
8. 否则,拒绝。
|
||
2. 如果 `sender` 当前会员状态不是 `join`,拒绝。
|
||
3. 如果目标用户当前会员状态为 `join` 或 `ban`,拒绝。
|
||
4. 如果 `sender` 的权限级别大于等于邀请级别,允许。
|
||
5. 否则,拒绝。
|
||
5. 如果 `membership` 为 `leave`:
|
||
1. 若 `sender` 等于 `state_key`,仅当此用户当前会员状态为 `invite`、`join` 或 `knock` 时允许。
|
||
2. 如果 `sender` 的当前会员状态不是 `join`,拒绝。
|
||
3. 若目标用户当前会员状态为 `ban`,且 `sender` 权限小于禁言级别,拒绝。
|
||
4. 若 `sender` 权限大于等于踢出级别,且目标用户权限低于 `sender` 权限,允许。
|
||
5. 否则,拒绝。
|
||
6. 如果 `membership` 为 `ban`:
|
||
1. 若 `sender` 当前会员状态不是 `join`,拒绝。
|
||
2. 若 `sender` 权限大于等于禁言级别,且目标用户权限低于 `sender` 权限,允许。
|
||
3. 否则,拒绝。
|
||
7. 如果 `membership` 为 `knock`:
|
||
1. 若 `join_rule` 不是 `knock` 或 `knock_restricted`,拒绝。
|
||
2. 若 `sender` 不等于 `state_key`,拒绝。
|
||
3. 若 `sender` 当前会员状态不是 `ban`、`invite` 或 `join`,允许。
|
||
4. 否则,拒绝。
|
||
8. 其他未知会员状态,拒绝。
|
||
5. 如果 `sender` 当前会员状态不是 `join`,拒绝。
|
||
6. 若类型为 `m.room.third_party_invite`:
|
||
1. 仅当 `sender` 当前权限大于等于邀请级别时允许。
|
||
7. 如事件类型所需权限级别大于 `sender` 权限级别,拒绝。
|
||
8. 如果事件有 `state_key` 以 `@` 开头,且不等于 `sender`,拒绝。
|
||
9. 若类型为 `m.room.power_levels`:
|
||
1. 如果 `content` 内的 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick` 或 `invite` 属性存在且不是整数,拒绝。
|
||
2. 如果 `content` 内的 `events` 或 `notifications` 属性存在,且不是值为整数的对象,拒绝。
|
||
3. 如果 `content` 内的 `users` 属性不是键为合法用户ID、值为整数的对象,拒绝。
|
||
4. 如果房间中不存在先前的 `m.room.power_levels` 事件,允许。
|
||
5. 对于 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick`、`invite`,如有添加、变更或删除,每项需检查:
|
||
1. 当前值大于 `sender` 当前权限,拒绝。
|
||
2. 新值大于 `sender` 当前权限,拒绝。
|
||
6. 对于 `events` 或 `notifications` 属性中被更改或移除的每一项:
|
||
1. 当前值大于 `sender` 当前权限,拒绝。
|
||
7. 对于 `events` 或 `notifications` 中被添加或更改的每一项:
|
||
1. 新值大于 `sender` 当前权限,拒绝。
|
||
8. 对于除自身外的 `users` 属性中被更改或移除的每一项:
|
||
1. 当前值大于等于 `sender` 当前权限,拒绝。
|
||
9. 对于 `users` 属性中被添加或更改的每一项:
|
||
1. 新值大于 `sender` 当前权限,拒绝。
|
||
10. 其他情况,允许。
|
||
10. 其他情况,允许。
|
||
|
||
{{% boxes/note %}}
|
||
这些规则的部分结果:
|
||
|
||
- 除非你是房间成员,唯一允许的操作(除初始创建/加入外)只有加入公开房间,以及接受或拒绝房间邀请。
|
||
- 取消禁言某人,你必须同时具有不小于踢出和禁言级别的权限,且权限要高于目标用户。
|
||
{{% /boxes/note %}}
|
||
|
||
## 与 v10 一致
|
||
|
||
以下章节自 v10 起未修改,为完整性而保留。
|
||
|
||
### 撤回处理
|
||
|
||
{{% rver-fragment name="v3-handling-redactions" %}}
|
||
|
||
### 事件 ID
|
||
|
||
{{% rver-fragment name="v4-event-ids" %}}
|
||
|
||
### 状态解析
|
||
|
||
{{% rver-fragment name="v2-state-res" %}}
|
||
|
||
### 规范化 JSON
|
||
|
||
{{% rver-fragment name="v6-canonical-json" %}}
|
||
|
||
### 签名密钥有效期
|
||
|
||
{{% rver-fragment name="v5-signing-requirements" %}}
|