--- title: 房间版本 10 type: docs weight: 100 version: 10 --- {{< boxes/warning >}} 本页面的翻译未经核对,可能存在翻译质量不佳、错翻、漏翻等情况。您可以在 Forgejo 存储库 打开 Issue、提交 Pull Request 或邮件联系我们提出改进建议和参与翻译与核对。 {{< /boxes/warning >}} 该房间版本基于[版本 9](/rooms/v9),强制要求权限等级(power level)值为整数,并引入了新的 `knock_restricted` 加入规则,使潜在成员更容易加入此类房间。 ## 客户端注意事项 此房间版本增加了新的 `knock_restricted` 加入规则,允许房间的潜在成员通过敲门(在[房间版本 7](/rooms/v7)中引入)或“加入限制”(在[房间版本 8](/rooms/v8)中引入并在[房间版本 9](/rooms/v9)中细化)两种方式加入房间。 客户端应针对具备该规则的房间做出相应渲染。例如: ``` 该房间为: [ ] 公开 [x] 私有 加入规则(公开时禁用): [x] 允许 `#space:example.org` 的成员加入 [x] 允许敲门 ``` 本地实现事件修订(redaction)算法的客户端,应参考下文的[修订](#redactions)章节以获得完整概览。 ## 服务器实现要素 {{% boxes/warning %}} 本节内容仅适用于服务器实现者。使用客户端-服务器 API 的应用通常不受此处细节影响。有关客户端注意事项的部分才是客户端-服务器 API 用例应参考的资料。 {{% /boxes/warning %}} [房间版本 7](/rooms/v7) 增加了“敲门”,[房间版本 8](/rooms/v8) 增加了“加入限制”(并被 [房间版本 9](/rooms/v9) 进一步细化)——两者都为潜在成员提供了加入方式,但过去无法将两种机制结合使用。该房间版本引入了一种新的 `knock_restricted` 加入规则,混合了两种行为,允许用户只要满足 `restricted` 或 `knock` 加入规则之一即可加入房间。 此外,该房间版本还要求权限等级事件中的数值必须为整数类型,而不能是其它房间版本为兼容性允许的字符串表示形式。 房间版本 10 基于房间版本 9,具体变化如下所述。 ### 事件格式 该房间版本未对事件格式进行修改。详见[下文](#event-format-1)当前事件格式的详细信息。 #### 已弃用事件内容模式 虽然本房间版本未专门改变事件格式,但某些已弃用行为被严格禁止支持。 ##### `m.room.power_levels` 事件的值必须为整数 在其它房间版本中,例如 [v9](/rooms/v9/#mroompower_levels-events-accept-values-as-strings),权限等级可以为兼容性目的用字符串表示。 本房间版本移除了此项兼容——权限等级在本版本中**不得**用字符串表示。结构不正确的权限等级将按照下述授权规则被拒绝。 ### 授权规则 事件必须由 `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. 若 `content` 有 `join_authorised_via_users_server` 键: 1. 若事件未由该键指向的用户的 homeserver 有效签名,则拒绝。 3. 若 `membership` 为 `join`: 1. 如果唯一的先前事件为 `m.room.create` 且 `state_key` 为创建者,则允许。 2. 若 `sender` 不等于 `state_key`,则拒绝。 3. 若 `sender` 被封禁,则拒绝。 4. 若 `join_rule` 为 `invite` 或 `knock`,且成员状态为 `invite` 或 `join`,则允许。 5. {{% changed-in v=10 %}} 若 `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` 事件中的任何公钥匹配,则允许。公钥包含于 `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. {{% changed-in v=10 %}} 若 `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. {{% added-in v=10 %}} 若 `content` 中 `users_default`、`events_default`、`state_default`、`ban`、`redact`、`kick` 或 `invite` 属性存在且类型不是整数,则拒绝。 2. {{% added-in v=10 %}} 若 `content` 中 `events` 或 `notifications` 属性存在,且不是值为整数的对象,则拒绝。 3. 若 `content` 中的 `users` 属性不是 key 为有效用户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. 对于除 `sender` 自身外,变更或移除的 `users` 属性每个条目: 1. 若当前值大于等于 `sender` 当前权限等级,则拒绝。 9. 对于新增或变更的 `users` 属性每个条目: 1. 若新值大于 `sender` 当前权限等级,则拒绝。 10. 否则,允许。 10. 否则,允许。 {{% boxes/note %}} 这些规则的一些后果: - 除非你是该房间的成员,否则仅允许的操作(除初始创建/加入外)为:加入公开房间;接受或拒绝房间邀请。 - 若想为某人解除封禁,你必须拥有大于等于踢人和封禁等级的权限,并且高于目标用户的权限等级。 {{% /boxes/note %}} ## 与 v9 保持一致内容 以下章节自 v9 起未改动,为资料完整起见在此列出。 ### 修订(Redactions) {{% rver-fragment name="v9-redactions" %}} ### 处理修订 {{% rver-fragment name="v3-handling-redactions" %}} ### 事件ID {{% rver-fragment name="v4-event-ids" %}} ### 事件格式 {{% rver-fragment name="v6-event-format" %}} ### 状态解析 {{% rver-fragment name="v2-state-res" %}} ### 规范 JSON {{% rver-fragment name="v6-canonical-json" %}} ### 签名密钥有效期 {{% rver-fragment name="v5-signing-requirements" %}}