--- title: 房间版本 7 type: docs weight: 70 version: 7 --- {{< boxes/warning >}} 本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 Forgejo 存储库 打开 Issue、提交 Pull Request 或邮件联系我们提出改进建议和参与翻译与核对。 {{< /boxes/warning >}} 本房间版本在 [版本 6](/rooms/v6) 的基础上,新增了敲门作为一种可选的加入规则和成员状态。 ## 客户端注意事项 这是首个完全支持敲门(knocking)的房间版本。因此,用户无法在非 v7 版本为基础的房间发起敲门请求。 虽然本房间版本相关的部分没有变动,实现本地化撤回算法的客户端应参考下方的[撤回](#redactions)章节了解完整细节。 ## 服务器实现要点 {{% boxes/warning %}} 本节内容仅面向服务器实现者。使用客户端-服务器 API 的应用一般无需关心此处的细节。关于客户端应注意事项,请参考前文相关章节。 {{% /boxes/warning %}} 房间版本 7 新增了支持敲门的事件认证规则。[房间版本 6](/rooms/v6) 及其所基于的版本中包含了其他认证规则变更的细节。 ### 认证规则 {{% added-in v=7 %}} 对于对 `m.room.member` 事件执行的检查,新增了针对 `membership=knock` 的处理分支。 事件必须由其 `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` 事件设定了权限要求,否则一般都允许撤回事件参与验证。需要特别注意,_撤回等级_ **不会**被认证规则使用。 有权发送撤回事件并不意味着撤回操作会被执行。接收端服务器还必须执行额外检查,详见[撤回处理](#handling-redactions)章节。 {{% /boxes/note %}} 认证规则如下: 1. 若事件类型为 `m.room.create`: 1. 若存在任何 `prev_events`,拒绝。 2. 若 `room_id` 的域名与 `sender` 域名不一致,拒绝。 3. 若 `content.room_version` 存在且不为已知版本,拒绝。 4. 若 `content` 无 `creator` 属性,拒绝。 5. 其他情况,允许。 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. 若 `membership` 为 `join`: 1. 如仅有的上一个事件为 `m.room.create` 且 `state_key` 为创建者,允许。 2. 若 `sender` 与 `state_key` 不同,拒绝。 3. 若 `sender` 已被禁言(banned),拒绝。 4. {{% changed-in v=7 %}} 若 `join_rule` 为 `invite` 或 `knock`,则当成员状态为 `invite` 或 `join` 时允许。 5. 若 `join_rule` 为 `public`,允许。 6. 其他情况,拒绝。 3. 若 `membership` 为 `invite`: 1. 如果 `content` 有 `third_party_invite` 属性: 1. 若*目标用户*被 ban,拒绝。 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` 事件中的任一公钥匹配,允许。公钥位于 `m.room.third_party_invite` 事件的 `content` 中: 1. `public_key` 属性中的单个公钥; 2. `public_keys` 属性中的公钥列表。 8. 其他情况,拒绝。 2. 若 `sender` 当前成员状态不是 `join`,拒绝。 3. 若*目标用户*当前成员状态为 `join` 或 `ban`,拒绝。 4. 若 `sender` 权限等级大于等于 *invite level*,允许。 5. 其他情况,拒绝。 4. 若 `membership` 为 `leave`: 1. {{% changed-in v=7 %}} 若 `sender` 等于 `state_key`,仅当该用户当前成员状态为 `invite`、`join` 或 `knock` 时允许。 2. 若 `sender` 当前成员状态不是 `join`,拒绝。 3. 若*目标用户*当前成员状态为 `ban`,且 `sender` 权限小于 *ban level*,拒绝。 4. 若 `sender` 权限等级大于等于 *kick level*,并且 *目标用户* 权限低于 `sender`,允许。 5. 其他情况,拒绝。 5. 若 `membership` 为 `ban`: 1. 若 `sender` 当前成员状态不是 `join`,拒绝。 2. 若 `sender` 权限等级大于等于 *ban level*,且*目标用户*权限等级低于 `sender`,允许。 3. 其他情况,拒绝。 6. {{% added-in v=7 %}} 若 `membership` 为 `knock`: 1. 若 `join_rule` 不为 `knock`,拒绝。 2. 若 `sender` 与 `state_key` 不同,拒绝。 3. 若 `sender` 当前成员状态不是 `ban`、`invite` 或 `join`,允许。 4. 其他情况,拒绝。 7. 其他未知成员状态,拒绝。 5. 若 `sender` 当前成员状态不是 `join`,拒绝。 6. 若事件类型为 `m.room.third_party_invite`: 1. 仅当 `sender` 当前权限等级大于等于 *invite level* 时允许。 7. 若事件类型所需*权限等级*大于 `sender` 的当前权限等级,拒绝。 8. 若事件有以 `@` 开头的 `state_key` 且不等于 `sender`,拒绝。 9. 若事件类型为 `m.room.power_levels`: 1. 若 `content` 的 `users` 属性不是仅包含有效用户 ID 的对象,值为整数(或可解释为整数的字符串),拒绝。 2. 若房间内无之前的 `m.room.power_levels` 事件,允许。 3. 对 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick`、`invite` 这些属性,如有新增、变更或移除,逐项检查: 1. 若当前值高于 `sender` 的当前权限等级,拒绝。 2. 若新值高于 `sender` 当前权限等级,拒绝。 4. 对 `events` 或 `notifications` 属性中被变更或移除的条目逐项检查: 1. 若当前值高于 `sender` 当前权限等级,拒绝。 5. 对 `events` 或 `notifications` 属性中被新增或变更的条目逐项检查: 1. 若新值高于 `sender` 当前权限等级,拒绝。 6. 对除 `sender` 自己以外的、`users` 属性中被变更或移除的条目逐项检查: 1. 若当前值大于等于 `sender` 当前权限等级,拒绝。 7. 对 `users` 属性中被新增或变更的条目逐项检查: 1. 若新值高于 `sender` 当前权限等级,拒绝。 8. 其他情况,允许。 10. 其他情况,允许。 {{% boxes/note %}} 这些规则的部分后果如下: - 除非你是房间成员,否则仅允许的操作(除首次创建/加入外)有:加公共房、接受或拒绝邀请。 - 若要解除对某人的封禁(unban),你必须拥有大于等于踢人(kick)*和*禁言(ban)等级的权限,*且*高于目标用户的权限等级。 {{% /boxes/note %}} ## 与 v6 保持一致的内容 下列章节自 v6 起未做更改,为保障文档完整性此处附上。 ### 撤回 {{% rver-fragment name="v6-redactions" %}} ### 撤回处理 {{% rver-fragment name="v3-handling-redactions" %}} ### 事件 ID {{% rver-fragment name="v4-event-ids" %}} ### 事件格式 {{% rver-fragment name="v6-event-format" %}} #### 已弃用事件内容模式 {{% rver-fragment name="v1-deprecated-formatting-off-spec" %}} {{% rver-fragment name="v1-stringy-power-levels" %}} ### 状态解析 {{% rver-fragment name="v2-state-res" %}} ### 规范化 JSON {{% rver-fragment name="v6-canonical-json" %}} ### 签名密钥有效期 {{% rver-fragment name="v5-signing-requirements" %}}