Skip to content

权限与角色

本页是 DSH-Guild 权限模型的完整规格:每个权限位能做什么、角色怎么叠加、频道覆盖按什么顺序生效、哪些动作只有 owner 能做。想「照着配一遍」看使用指南,想查「这个功能要哪个权限」直接看下面的动作 × 权限矩阵

一、概念模型

DSH-Guild 采用 Discord 式 权限模型,三层结构:

层级作用范围说明
社区级权限整个社区挂在角色上的基础权限位,如「管理社区」「封禁成员」
频道级权限单个频道既可挂在角色上,也可作为频道覆盖(overwrite)的目标
身份用户 ↔ 社区owner / 成员 / 非成员三种状态,决定权限判定的起点

三种身份

身份判定依据权限
ownercommunities.ownerId 等于该用户恒定拥有全部权限位,忽略一切频道覆盖;删社区 / 转让所有权也 owner 可为
成员community_members 表有行基础权限 = 所持角色权限的并集,再叠加频道覆盖
非成员无成员行权限恒为 0,看不到任何频道(公开社区也不例外)

owner 不是「一个角色」

owner 是社区表上的一个字段,不占角色槽位、不可被剥夺、也不会出现在角色列表里。预置的那个「管理员」角色是普通角色,和 owner 完全是两回事 —— 详见第四节

二、权限位总表

共 11 个权限位。作用域决定了它能否作为频道覆盖的目标:channel 可以,community 只能挂在角色上。

#权限位中文名作用域能做什么
0VIEW_CHANNEL查看频道channel看不到则频道不下发、不可订阅、不可读消息
1SEND_MESSAGES发送消息channel在频道与讨论组里发言
2CREATE_THREAD创建讨论组channel在频道里开讨论组 / 话题
3MANAGE_THREADS管理讨论组channel改名 / 归档 / 删除讨论组、加人、标记解决
4MANAGE_MESSAGES管理消息channel改 / 删 / 撤回他人消息,置顶 / 取消置顶
5MANAGE_CHANNEL管理频道channel新建 / 改名 / 删除频道、调整顺序、管理频道权限覆盖
6MANAGE_COMMUNITY管理社区community改社区资料、隐私与短标识(删除 / 转让仅 owner)
7MANAGE_ROLES管理角色community增删改角色、调整层级、给成员分配角色(受层级限制)
8INVITE_MEMBERS邀请成员community邀请已注册用户加入社区
9KICK_MEMBERS移除成员community把成员移出社区(可被邀请码重新加入)
10BAN_MEMBERS封禁成员community移出并禁止重新加入、管理封禁名单

两个预设权限组合

名称内容用在哪
ALL_PERMISSIONS全部 11 个位owner 恒定拥有;建社区时预置的「管理员」角色也按它初始化
DEFAULT_EVERYONE_PERMISSIONS查看频道 + 发送消息 + 创建讨论组 + 邀请成员新建社区时 @everyone 的初始权限
位标志的实际取值

权限是 bitfield,位序为上表从左到右(VIEW_CHANNEL = 1 << 0BAN_MEMBERS = 1 << 10)。ALL_PERMISSIONS = 2047。新增权限位一律追加在末尾,不复用旧位。

三、权限解析算法

计算「某人在某频道有哪些权限」严格按以下 6 步,顺序不可调换:

1) 是 owner?          → 直接返回 ALL_PERMISSIONS(忽略后续所有覆盖)
2) 是成员?             → 否则返回 0(社区频道一律不可见)
3) 基础权限 base        = 全部持有角色的 permissions 按位或(含 @everyone)
4) @everyone 覆盖       base = (base & ~deny) | allow
5) 持有角色的覆盖      按角色 position 从低到高,逐个 base = (base & ~deny) | allow
6) 成员级覆盖          base = (base & ~deny) | allow

几个关键点:

  • 第 5 步的顺序是有意义的:高位角色的覆盖应用,所以高位的 deny 能压过低位的 allow,反之亦然。同 position 时按 targetId 字典序稳定排序。
  • 覆盖是「整体覆盖」而非「取并集」allowdeny 同时存在时,该层计算完就是 (基础 & ~deny) | allowdeny 先清掉、allow 再补上。若同一个位同时在 allow 和 deny 里,allow 胜
  • 只有 channel 作用域的位能作覆盖目标。尝试用 MANAGE_ROLES 之类的社区级位设覆盖会被直接拒绝。
  • VIEW_CHANNEL 是总闸:社区频道列表只下发 VIEW_CHANNEL 通过的频道;权限变更会实时下发,在线连接被重新校验,失去频道可见性的连接会被主动断开

频道可见性的边界

场景结果
非成员访问公开社区频道不可见(权限 0)
成员被 deny VIEW_CHANNEL该频道不下发、WS 连接断开
社区被设为私有不影响已加入成员的可见性,只影响「能否被发现 / 加入」

四、角色

@everyone

每个社区必有且仅有一个 @everyone 角色,约束如下:

属性
isEveryonetrue(每社区唯一)
position恒为 0
作用方式隐式作用于全体成员,member_roles 表不写行
可改名 / 删除 / 调层级全部不可
权限可增删权限位(初始为 DEFAULT_EVERYONE_PERMISSIONS

预置「管理员」角色

建社区时自动创建一个名字为 管理员 的角色,语义上是普通角色

  • 权限按创建当时的 ALL_PERMISSIONS 初始化 —— 后续新增的权限位不会自动补进来;
  • position 初始为 1
  • 可改名、可删除、可任意增删权限位;
  • 不会自动分配给任何人,需要 owner 手动分配;
  • 频道覆盖对它一样生效,不会绕过。

层级与 position

  • 自定义角色占 1..N唯一槽位(@everyone 恒为 0,不占槽位);
  • position 越大越靠上
  • 调整层级用整体重排语义:提交全部自定义角色、按从高到低排列,服务端据此重算槽位。

防提权三规则

这是权限体系里最容易被误解的部分:

#规则违反时
1只能操作层级严格低于自己的角色与成员403「不能操作层级不低于自己的角色」/「不能管理层级不低于自己的成员」
2不能授予自己没有的权限位403「不能授予自己没有的权限」
3频道覆盖只接受频道级权限位400「频道覆盖只支持频道级权限位(不含社区级权限)」

关于规则 1 的细节:

  • 比较基准是「我持有的最高角色 position」(@everyone 不计入;没有自定义角色则记为 0);
  • 「严格低于」意味着层级相同也不能操作;
  • 重排层级时,非 owner 只能重排层级严格低于自己的那一段,更高的角色锁在原位,且提交顺序里这段前缀的顺序必须保持不变;
  • 同样的层级判定复用于踢人 / 封禁 / 改成员角色:不能管理「当前最高角色层级不低于自己」的成员。

owner 不受这三条限制

owner 跳过所有层级与授予校验,但删社区 / 转让所有权这两件敏感操作反过来只允许 owner 执行。

五、频道权限覆盖

覆盖(overwrite)是频道维度的 allow / deny 叠加,作用对象有三类:

targetTypetargetId说明
everyone@everyone(固定常量)对全体的频道级调整
role角色 id对该角色持有者生效
member用户 id对单个成员生效,优先级最高

优先级顺序

@everyone → 角色(按 position 从低到高)→ 成员。解析细节见第三节

公告频道的自动覆盖

把频道类型切成 公告 时,系统会自动为 @everyone 写入一条只读覆盖;切回其他类型时自动撤销。这就是「公告频道默认全员只读,仅 owner 或被单独授权的角色 / 成员可发」的实现方式 —— 你也可以在此之上继续手动调整。

自锁保护

读取频道的覆盖列表走的是社区级 MANAGE_CHANNEL 校验,而不是频道级,避免管理员被自己设的频道级 deny 锁在外面无法改回来。

动作 × 权限矩阵

每个操作需要的权限,含「仅 owner」的特殊情况。

社区

操作要求
创建社区任意登录用户(受限额约束)
查看社区详情成员
改社区资料 / 隐私 / 短标识MANAGE_COMMUNITY
转让所有权仅 owner
删除社区仅 owner
退出社区成员(owner 需先转让)

频道

操作要求
新建频道MANAGE_CHANNEL(社区级校验)
改频道资料 / 类型 / 顺序MANAGE_CHANNEL(频道级校验)
删除频道MANAGE_CHANNEL(频道级校验)
查看频道列表VIEW_CHANNEL
查看 / 修改频道覆盖MANAGE_CHANNEL社区级校验,防自锁)

角色与成员

操作要求
查看角色列表成员
新建 / 改 / 删角色MANAGE_ROLES + 层级严格高于目标角色
重排角色层级MANAGE_ROLES + 只能动层级严格低于自己的段
给成员分配角色MANAGE_ROLES + 不能管理层级不低于自己的成员 + 不能授予层级不低于自己的角色
邀请用户加入INVITE_MEMBERS
移除成员(踢人)KICK_MEMBERS + 目标不是 owner / 自己 / 层级不低于自己者
封禁 / 解封 / 查封禁列表BAN_MEMBERS + 目标不是 owner / 自己 / 层级不低于自己者
查看成员 / 在线列表成员

消息

操作要求
读消息 / 置顶列表 / 已读状态 / 在线人数VIEW_CHANNEL
发消息VIEW_CHANNEL + SEND_MESSAGES
搜索消息成员(结果按可见频道过滤)
改自己的消息作者本人
改他人消息MANAGE_MESSAGES
删 / 撤回自己的消息发送后 2 分钟内;超时只能编辑
删他人消息MANAGE_MESSAGES(不受 2 分钟限制)
置顶 / 取消置顶MANAGE_MESSAGES(社区级校验)
加 / 取消表情回应VIEW_CHANNEL

讨论组(话题)

操作要求
查看讨论组列表频道 VIEW_CHANNEL
创建讨论组频道 CREATE_THREAD
改讨论组(改名 / 归档 / 删除 / 加人 / 移出 / 标记解决)MANAGE_THREADS(社区级校验)
进入私密讨论组成员 + 密码正确,或已在成员名单内
主动加入公开讨论组成员
退出讨论组成员本人
读 / 写讨论组已读状态成员

分享

操作要求
上传分享包到 R2成员
登记分享成员(校验社区成员身份)
查看分享详情成员
下载分享包成员

相关文档