【功能前瞻】Koishi 4.14 权限系统

权限的依赖关系

Koishi 中的权限不仅存在继承关系,还存在依赖关系。它的基本写法如下:

ctx.permissions.depend(A, B)

如果权限 A 依赖了权限 B,那么要执行权限 A 的操作时必须同时检查权限 B(换句话说就是 A 需要 B)。

例 6:foo 指令的代码中调用了 bar 指令,因此 foo 指令依赖 bar 指令。

command.foo -> command.bar

如果用户只拥有 foo 的权限,没有调用 bar 的权限,他依然无法调用 foo 指令。

例 7:foo 指令的代码中使用了 bot.muteChannel()

command.foo -> bot.channel.mute

如果机器人没有实现此 API,用户就无法在该机器人上调用 foo 指令。

由此可见,权限的依赖与继承不同。继承更多的是一种管理上的考虑,而依赖则关乎具体的功能实现。

3 个赞

权限访问器

在上面的介绍中,如果要定义新的权限,就必须手动分配给用户或用户组后才能使用。有没有方法自动为一个会话分配权限呢?这就是权限访问器的功能。

ctx.permissions.provide('onebot.admin', async (session) => {
  return session.onebot?.sender?.role === 'admin'
})

上面的代码的作用是:当某个会话处于 onebot 平台,并且发送者是群内管理员时,自动附加一个 onebot.admin 权限。利用这种技术,我们就可以为特定平台提供权限能力了。

每个权限可以定义多个访问器函数。在运行时必须通过每一个访问器函数的检查才能视为拥有权限。

一个权限要么是普通权限,要么是访问器权限。下面是一些区别:

普通权限 访问器权限
手动分配给用户 (组) 自动分配给会话
可以被其他权限继承 不能被其他权限继承
3 个赞

权限国际化

普通权限要被用于指令和控制台中显示,因此需要做国际化。具体的做法也很简单:

  1. 通过 API 定义:使用 permission.{name} 提供翻译文本
  2. 通过指令定义:定义时提供文本 (自动视为当前用户语言),或通过 --locale 指定特定语言的文本
  3. 通过控制台定义:可以在控制台「用户管理」界面中配置用户组文本

访问器权限由于其不能被其他权限继承,因此不需要做国际化。

3 个赞

提供网络服务

这部分功能可能不会在 4.14 实装,但是作为权限系统的一部分,这里一并介绍。

未来将会提供基于权限系统的 Router API,允许部分网络服务经过权限认证。应用场景包括:

  1. 将 Koishi 直接提供网络服务,其他应用可以调用 Koishi 的功能
  2. 用户可以独立配置每一个控制台页面、功能的访问权限
  3. 用户可以为自己生成具有细粒度权限的个人令牌 (PAT),用于网络调用
5 个赞

到底是什么版本 :thinking:

3 个赞

超时空是 Koishi 传统艺能,不可不品尝(其实是 typo

6 个赞

好好好!!!

1 个赞

好好好!!
快进到 KoishiLang KoishiOS MineKoi

2 个赞

万物基于 Koishi (x

2 个赞


忍不住了家人们

3 个赞

补充:条件权限

权限的继承和依赖关系都可以是有条件的,可以传入第三个参数:

ctx.permissions.inherit(A, B, condition)
ctx.permissions.extend(A, B, condition)

这里的 condition 可以是一个接受会话对象,返回布尔值的同步函数,也可以通过 Schema.computed() 让用户提供,实现过滤器与权限的联动。

在控制台中,commands 插件同样支持指令配置条件权限,用法与其他要用到过滤器的地方差不多。

目前暂时不支持用户和用户组条件继承其他权限。

1 个赞

补充:频道权限

同用户一样,频道和群组也是可以有权限的。因此你可以限制某些功能只能在特定频道和群组中触发(当然过滤器也可以实现这一点)。

而过滤器不能实现的在于,权限系统实际上允许你将频道编组(类似用户组)。当我们需要发送广播消息的时候就可以只对部分频道发送了。例如,你可以利用权限系统设置若干广播频道,并只在这些频道中发送订阅信息。

1 个赞

看完之后 赶去重写了权限分配功能 看来以后要多逛逛论坛了

2 个赞

20230808 更新:权限系统相关功能将加入 admin 插件,不会创建专门的 permissions 插件了。

2 个赞

我觉得可以做一个一键控制指令在help里显示和隐藏的功能,会很舒服,然后就是想要一个可以一键控制指令权限设置的功能,就是我想所有指令在大于3级权限下可以无限制调用,低于3级统一限制调用次数,超nice的。

1 个赞

非常棒的想法!这些想法可以通过插件实现,请在下方的「求插件」版块创建一个新的帖子,这样感兴趣的开发者看到后会制作的。

2 个赞

之后的功能更新会移至官方文档中继续:

本话题依然可以用作答疑。

2 个赞

请问 koishi.yml 文件中如何配置指定指令的 permission 呢?

1 个赞

默认指令权限为 command.指令名称
如果是注册了 指令1/子指令1
那么用户同时需要 command.指令1 权限和 command.子指令1

1 个赞

这是预期的,子指令依赖父指令。

2 个赞