koishi-plugin-new-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/newauth.md ADDED
@@ -0,0 +1,1458 @@
1
+ # 新 权限
2
+
3
+ *Exported on 2026年5月25日 18:55:17*
4
+
5
+ **Assistant**:
6
+
7
+
8
+
9
+ 下面是一版收敛后的完整设计方案。核心原则是:
10
+
11
+ > **权限管理以“角色”为中心;指令注册后进入权限系统;Koishi 管理员决定每个角色能用哪些指令;普通群主不会天然获得 Bot 实例权限。**
12
+
13
+ ---
14
+
15
+ # 1. 设计目标
16
+
17
+ 新权限系统解决这些问题:
18
+
19
+ 1. **多群隔离**
20
+ - 同一个人在群 A 是群主,在群 B 是管理员,在群 C 是成员,权限结果不同。
21
+
22
+ 2. **角色视角管理**
23
+ - WebUI 主界面展示角色。
24
+ - 点进角色后,配置这个角色能用哪些指令。
25
+
26
+ 3. **新指令默认安全**
27
+ - 插件新增指令后,不自动开放给群主、管理员、成员。
28
+ - 默认只有 Bot 管理员可用,等待 Koishi 管理员配置。
29
+
30
+ 4. **旧 `authority` 兼容但不直接放权**
31
+ - 老插件的 `.authority(3)` 只作为“建议值”。
32
+ - 最终是否能执行,仍由新权限系统决定。
33
+
34
+ 5. **角色系统保持简单**
35
+ - 不做复杂继承。
36
+ - 不搞复杂权限树。
37
+ - 自定义角色本质上就是“用户分组 + 可用指令列表”。
38
+
39
+ 6. **群主权限和 Bot 管理权限分离**
40
+ - 群主只能代表当前群。
41
+ - 群主不能自动管理插件、文件、数据库、全局配置。
42
+
43
+ ---
44
+
45
+ # 2. 核心概念
46
+
47
+ 系统内部有四个核心对象:
48
+
49
+ ```txt
50
+ 角色 Role
51
+ 指令 Command
52
+ 作用域 Scope
53
+ 策略 Policy
54
+ ```
55
+
56
+ 它们之间的关系是:
57
+
58
+ ```txt
59
+ 某个作用域下,某个角色,能不能使用某个指令。
60
+ ```
61
+
62
+ 也就是:
63
+
64
+ ```txt
65
+ scope + role + command -> allow / deny / inherit
66
+ ```
67
+
68
+ 用户执行命令时,系统判断:
69
+
70
+ ```txt
71
+ 当前用户在当前作用域里属于哪些角色;
72
+ 这些角色是否允许使用当前指令。
73
+ ```
74
+
75
+ ---
76
+
77
+ # 3. 内置角色设计
78
+
79
+ 内置角色保持简单:
80
+
81
+ ```txt
82
+ Bot 管理员
83
+ 群主
84
+ 群管理员
85
+ 群成员
86
+ 访客
87
+ ```
88
+
89
+ ## 3.1 Bot 管理员
90
+
91
+ 这是管理 Koishi 实例的人。
92
+
93
+ 拥有:
94
+
95
+ ```txt
96
+ 插件管理
97
+ 全局配置
98
+ 数据库管理
99
+ 控制台管理
100
+ 所有未配置指令的执行权
101
+ ```
102
+
103
+ Bot 管理员只能通过 Koishi 管理员显式设置,不能由平台身份自动获得。
104
+
105
+ 也就是说:
106
+
107
+ ```txt
108
+ QQ群主 ≠ Bot 管理员
109
+ Discord 服务器 owner ≠ Bot 管理员
110
+ ```
111
+
112
+ ## 3.2 群主
113
+
114
+ 来自平台身份。
115
+
116
+ 例如:
117
+
118
+ ```txt
119
+ QQ群主
120
+ Discord 服务器拥有者
121
+ Telegram 群 owner
122
+ ```
123
+
124
+ 只在当前群作用域生效。
125
+
126
+ ```txt
127
+ 用户 A 在群 1 是群主,只代表他在群 1 里拥有“群主”角色。
128
+ ```
129
+
130
+ 不影响其他群。
131
+
132
+ ## 3.3 群管理员
133
+
134
+ 同样来自平台身份。
135
+
136
+ ```txt
137
+ QQ群管理员 -> 群管理员
138
+ Discord 有管理权限的成员 -> 群管理员
139
+ ```
140
+
141
+ 只在当前群生效。
142
+
143
+ ## 3.4 群成员
144
+
145
+ 普通群成员。
146
+
147
+ ## 3.5 访客
148
+
149
+ 用于:
150
+
151
+ ```txt
152
+ 私聊场景
153
+ 无法识别身份的用户
154
+ 未绑定用户
155
+ 非群上下文用户
156
+ ```
157
+
158
+ ---
159
+
160
+ # 4. 自定义角色设计
161
+
162
+ 自定义角色不要复杂。
163
+
164
+ 创建角色时只需要:
165
+
166
+ ```txt
167
+ 角色名称
168
+ 适用范围
169
+ 成员列表
170
+ ```
171
+
172
+ 例如:
173
+
174
+ ```txt
175
+ 角色名称:点歌管理员
176
+ 适用范围:群内
177
+ 成员:张三、李四
178
+ ```
179
+
180
+ 或者:
181
+
182
+ ```txt
183
+ 角色名称:活动管理员
184
+ 适用范围:群 A
185
+ 成员:王五
186
+ ```
187
+
188
+ 自定义角色不做继承。
189
+
190
+ 不设计:
191
+
192
+ ```txt
193
+ 高级管理员继承管理员
194
+ 点歌管理员继承群成员
195
+ 角色 A 继承角色 B
196
+ ```
197
+
198
+ 如果用户想让新角色拥有类似管理员的权限,提供一个简单操作:
199
+
200
+ ```txt
201
+ 从“群管理员”复制可用指令
202
+ ```
203
+
204
+ 复制之后两者独立,不存在继承关系。
205
+
206
+ ---
207
+
208
+ # 5. 作用域设计
209
+
210
+ 权限必须带作用域,否则多群场景一定会乱。
211
+
212
+ 作用域分为:
213
+
214
+ ```txt
215
+ global
216
+ guild:<platform>:<guildId>
217
+ ```
218
+
219
+ 可以预留频道作用域:
220
+
221
+ ```txt
222
+ channel:<platform>:<channelId>
223
+ ```
224
+
225
+ 但第一层主要用:
226
+
227
+ ```txt
228
+ global
229
+ guild
230
+ ```
231
+
232
+ ## 5.1 global
233
+
234
+ 全局默认配置。
235
+
236
+ 例如:
237
+
238
+ ```txt
239
+ 默认情况下,群成员可以用签到
240
+ 默认情况下,群管理员可以用禁言
241
+ 默认情况下,插件重载只有 Bot 管理员可用
242
+ ```
243
+
244
+ ## 5.2 guild
245
+
246
+ 单群覆盖配置。
247
+
248
+ 例如:
249
+
250
+ ```txt
251
+ 群 A:
252
+ 群成员不能用签到
253
+
254
+ 群 B:
255
+ 群成员可以用签到
256
+
257
+ 群 C:
258
+ 只有群主可以用点歌
259
+ ```
260
+
261
+ 群作用域只影响当前群,不影响其他群。
262
+
263
+ ---
264
+
265
+ # 6. 指令登记机制
266
+
267
+ 每个 Koishi 命令在注册时,都会进入权限系统的“指令登记表”。
268
+
269
+ 例如插件注册:
270
+
271
+ ```txt
272
+ sign
273
+ mute
274
+ plugin/reload
275
+ file/delete
276
+ ```
277
+
278
+ 权限系统登记为:
279
+
280
+ ```txt
281
+ command:sign
282
+ command:mute
283
+ command:plugin.reload
284
+ command:file.delete
285
+ ```
286
+
287
+ 这个 ID 是系统内部用的。
288
+
289
+ WebUI 不需要直接展示:
290
+
291
+ ```txt
292
+ command:sign
293
+ ```
294
+
295
+ 而是展示:
296
+
297
+ ```txt
298
+ 签到
299
+ 禁言
300
+ 插件重载
301
+ 删除文件
302
+ ```
303
+
304
+ ---
305
+
306
+ # 7. 指令状态
307
+
308
+ 每个指令有一个配置状态:
309
+
310
+ ```txt
311
+ 已配置
312
+ 待配置
313
+ 已禁用
314
+ ```
315
+
316
+ ## 7.1 待配置
317
+
318
+ 插件新增指令后,默认进入待配置状态。
319
+
320
+ 待配置指令默认规则:
321
+
322
+ ```txt
323
+ 只有 Bot 管理员可用。
324
+ ```
325
+
326
+ 群主、群管理员、群成员都不能直接使用。
327
+
328
+ 这样可以避免:
329
+
330
+ ```txt
331
+ 群主把 Bot 拉进群后,突然能用删除文件、重载插件、执行脚本之类的指令。
332
+ ```
333
+
334
+ ## 7.2 已配置
335
+
336
+ Koishi 管理员给某些角色勾选了这个指令后,它变成已配置。
337
+
338
+ 例如:
339
+
340
+ ```txt
341
+ 签到:
342
+ 群成员 可用
343
+ 群管理员 可用
344
+ 群主 可用
345
+
346
+ 禁言:
347
+ 群成员 不可用
348
+ 群管理员 可用
349
+ 群主 可用
350
+
351
+ 插件重载:
352
+ 只有 Bot 管理员 可用
353
+ ```
354
+
355
+ ## 7.3 已禁用
356
+
357
+ 指令存在,但被权限系统整体禁用。
358
+
359
+ 即使角色原本有权限,也不能使用。
360
+
361
+ ---
362
+
363
+ # 8. `authority` 的定位
364
+
365
+ 旧插件可能写:
366
+
367
+ ```txt
368
+ .authority(1)
369
+ .authority(2)
370
+ .authority(3)
371
+ .authority(4)
372
+ ```
373
+
374
+ 新系统里,`authority` 不再直接决定用户权限。
375
+
376
+ 它只作为指令登记时的建议值。
377
+
378
+ 例如:
379
+
380
+ ```txt
381
+ authority 0 -> 建议访客/成员可用
382
+ authority 1 -> 建议成员可用
383
+ authority 2 -> 建议群管理员可用
384
+ authority 3 -> 建议群主可用
385
+ authority 4+ -> 建议 Bot 管理员可用
386
+ ```
387
+
388
+ WebUI 里可以显示:
389
+
390
+ ```txt
391
+ 指令:禁言
392
+ 来源插件:xxx
393
+ 旧权限建议:群主可用
394
+ 当前实际配置:群管理员、群主可用
395
+ ```
396
+
397
+ 也可以提供按钮:
398
+
399
+ ```txt
400
+ 采用插件建议
401
+ ```
402
+
403
+ 但重点是:
404
+
405
+ ```txt
406
+ authority 只是建议,不是最终授权。
407
+ ```
408
+
409
+ 最终授权来自:
410
+
411
+ ```txt
412
+ 角色 + 指令配置
413
+ ```
414
+
415
+ ---
416
+
417
+ # 9. WebUI 设计
418
+
419
+ WebUI 主入口应该是角色,而不是指令矩阵。
420
+
421
+ ## 9.1 主页面:角色列表
422
+
423
+ 展示:
424
+
425
+ ```txt
426
+ 角色
427
+ - Bot 管理员
428
+ - 群主
429
+ - 群管理员
430
+ - 群成员
431
+ - 访客
432
+ - 点歌管理员
433
+ - 活动管理员
434
+ ```
435
+
436
+ 每个角色显示摘要:
437
+
438
+ ```txt
439
+ Bot 管理员 全局角色 58 个可用指令
440
+ 群主 群内角色 21 个可用指令
441
+ 群管理员 群内角色 16 个可用指令
442
+ 群成员 群内角色 8 个可用指令
443
+ 点歌管理员 自定义角色 4 个可用指令
444
+ ```
445
+
446
+ ## 9.2 角色详情页
447
+
448
+ 点进“群管理员”后,看到:
449
+
450
+ ```txt
451
+ 角色:群管理员
452
+ 当前范围:全局默认 / 群 A / 群 B
453
+ ```
454
+
455
+ 下面是指令列表:
456
+
457
+ ```txt
458
+ 基础
459
+ - 帮助 开
460
+ - 签到 开
461
+ - 天气 开
462
+
463
+ 群管理
464
+ - 禁言 开
465
+ - 踢人 关
466
+ - 撤回 开
467
+
468
+ 娱乐
469
+ - 点歌 开
470
+ - 切歌 开
471
+ - 清空歌单 关
472
+
473
+ Bot 管理
474
+ - 插件重载 不可用
475
+ - 安装插件 不可用
476
+ - 删除文件 不可用
477
+ ```
478
+
479
+ 不过普通情况下,“Bot 管理”这类不应该出现在群角色页面里。
480
+
481
+ 更推荐:
482
+
483
+ ```txt
484
+ 群角色页面只展示可以被下放/配置的群内指令。
485
+ ```
486
+
487
+ 高级审计模式下才显示不可配置指令。
488
+
489
+ ## 9.3 当前范围切换
490
+
491
+ 页面顶部有范围选择:
492
+
493
+ ```txt
494
+ 配置范围:
495
+ - 全局默认
496
+ - 群 A
497
+ - 群 B
498
+ - 群 C
499
+ ```
500
+
501
+ 选择“全局默认”时,配置默认规则。
502
+
503
+ 选择“群 A”时,配置群 A 的覆盖规则。
504
+
505
+ 例如:
506
+
507
+ ```txt
508
+ 全局默认:
509
+ 群成员可以签到
510
+
511
+ 群 A 覆盖:
512
+ 群成员不可以签到
513
+ ```
514
+
515
+ 最终群 A 里,成员不能签到。
516
+
517
+ 其他群仍然按照全局默认。
518
+
519
+ ---
520
+
521
+ # 10. 待配置指令页面
522
+
523
+ 虽然主界面是角色列表,但仍然需要一个“待配置指令”页面。
524
+
525
+ 这个页面不是主权限编辑方式,而是提醒 Koishi 管理员:
526
+
527
+ ```txt
528
+ 检测到这些新指令,还没有配置给任何角色。
529
+ ```
530
+
531
+ 例如:
532
+
533
+ ```txt
534
+ 待配置指令
535
+
536
+ - 抽奖 lottery
537
+ 来源插件:lottery
538
+ 插件建议:群成员可用
539
+
540
+ - 清空歌单 music/clear
541
+ 来源插件:music
542
+ 插件建议:群管理员可用
543
+
544
+ - 插件重载 plugin/reload
545
+ 来源插件:market
546
+ 插件建议:Bot 管理员可用
547
+ ```
548
+
549
+ 管理员可以点进去快捷分配:
550
+
551
+ ```txt
552
+ 这个指令允许哪些角色使用?
553
+ [ ] 访客
554
+ [ ] 群成员
555
+ [ ] 群管理员
556
+ [ ] 群主
557
+ [ ] Bot 管理员
558
+ [ ] 点歌管理员
559
+ ```
560
+
561
+ 但长期管理仍然推荐从角色详情页进入。
562
+
563
+ ---
564
+
565
+ # 11. 群主可配置范围
566
+
567
+ 群主不能配置所有指令。
568
+
569
+ 需要有一个概念:
570
+
571
+ ```txt
572
+ 允许群内自治
573
+ ```
574
+
575
+ 也就是说,Koishi 管理员可以决定某个指令是否允许群主在自己群里开关。
576
+
577
+ 例如:
578
+
579
+ ```txt
580
+ 签到:允许群内自治
581
+ 点歌:允许群内自治
582
+ 欢迎语:允许群内自治
583
+ 禁言:允许群内自治
584
+ 插件重载:不允许群内自治
585
+ 删除文件:不允许群内自治
586
+ 数据库管理:不允许群内自治
587
+ ```
588
+
589
+ 群主打开自己群的配置页时,只能看到:
590
+
591
+ ```txt
592
+ 允许群内自治的指令
593
+ ```
594
+
595
+ 看不到或者不能修改:
596
+
597
+ ```txt
598
+ 插件管理
599
+ 文件管理
600
+ 数据库管理
601
+ 全局广播
602
+ 重启 Bot
603
+ 执行脚本
604
+ ```
605
+
606
+ 这条很重要。
607
+
608
+ 即使某人是群主,他也只是:
609
+
610
+ ```txt
611
+ guild:<当前群> 下的群主
612
+ ```
613
+
614
+ 不是:
615
+
616
+ ```txt
617
+ global 下的 Bot 管理员
618
+ ```
619
+
620
+ ---
621
+
622
+ # 12. 权限判断流程
623
+
624
+ 用户执行命令时,流程如下:
625
+
626
+ ## 12.1 解析命令
627
+
628
+ 例如用户发送:
629
+
630
+ ```txt
631
+ /禁言 @张三
632
+ ```
633
+
634
+ Koishi 解析到命令:
635
+
636
+ ```txt
637
+ mute
638
+ ```
639
+
640
+ 权限系统找到内部指令 ID:
641
+
642
+ ```txt
643
+ command:mute
644
+ ```
645
+
646
+ ## 12.2 构建上下文
647
+
648
+ 从 session 得到:
649
+
650
+ ```txt
651
+ platform
652
+ userId
653
+ guildId
654
+ channelId
655
+ ```
656
+
657
+ 例如:
658
+
659
+ ```txt
660
+ platform = onebot
661
+ userId = 10001
662
+ guildId = 888888
663
+ ```
664
+
665
+ 当前作用域:
666
+
667
+ ```txt
668
+ guild:onebot:888888
669
+ global
670
+ ```
671
+
672
+ ## 12.3 收集用户角色
673
+
674
+ 系统从多个来源收集角色:
675
+
676
+ ```txt
677
+ 平台身份
678
+ 手动绑定角色
679
+ Bot 管理员身份
680
+ 自定义角色
681
+ ```
682
+
683
+ 例如用户在当前群是管理员:
684
+
685
+ ```txt
686
+ 群管理员
687
+ ```
688
+
689
+ 如果他同时是 Bot 管理员:
690
+
691
+ ```txt
692
+ Bot 管理员
693
+ 群管理员
694
+ ```
695
+
696
+ 如果他还被加入了“点歌管理员”:
697
+
698
+ ```txt
699
+ Bot 管理员
700
+ 群管理员
701
+ 点歌管理员
702
+ ```
703
+
704
+ ## 12.4 查找指令权限
705
+
706
+ 先查当前群覆盖配置:
707
+
708
+ ```txt
709
+ guild:onebot:888888
710
+ ```
711
+
712
+ 再查全局默认配置:
713
+
714
+ ```txt
715
+ global
716
+ ```
717
+
718
+ 如果当前群没有单独配置,则使用全局默认。
719
+
720
+ ## 12.5 得出结果
721
+
722
+ 规则:
723
+
724
+ ```txt
725
+ 只要用户拥有的任一角色允许该指令,就允许执行。
726
+ ```
727
+
728
+ 例如:
729
+
730
+ ```txt
731
+ 用户角色:群管理员、点歌管理员
732
+ 指令:清空歌单
733
+
734
+ 群管理员:不允许
735
+ 点歌管理员:允许
736
+
737
+ 最终:允许
738
+ ```
739
+
740
+ 这里的“不允许”只是表示这个角色不提供权限,不是全局封禁。
741
+
742
+ 真正的封禁应该单独做成:
743
+
744
+ ```txt
745
+ 用户黑名单
746
+ 群黑名单
747
+ 指令禁用
748
+ ```
749
+
750
+ 不要混在角色权限里。
751
+
752
+ ---
753
+
754
+ # 13. 策略状态设计
755
+
756
+ 每个角色对每个指令在某个作用域下有三种状态:
757
+
758
+ ```txt
759
+ 继承
760
+ 允许
761
+ 关闭
762
+ ```
763
+
764
+ ## 13.1 继承
765
+
766
+ 使用上级配置。
767
+
768
+ 例如群 A 没有单独设置“群成员能否签到”,就继承全局默认。
769
+
770
+ ## 13.2 允许
771
+
772
+ 当前作用域明确允许。
773
+
774
+ 例如:
775
+
776
+ ```txt
777
+ 群 A:
778
+ 群成员 可以签到
779
+ ```
780
+
781
+ ## 13.3 关闭
782
+
783
+ 当前作用域明确关闭。
784
+
785
+ 例如:
786
+
787
+ ```txt
788
+ 群 A:
789
+ 群成员 不可以签到
790
+ ```
791
+
792
+ 注意:
793
+
794
+ ```txt
795
+ 关闭只对这个角色生效。
796
+ ```
797
+
798
+ 如果这个用户还有其他角色,而其他角色允许这个指令,仍然可以执行。
799
+
800
+ 这能避免复杂的“显式拒绝优先”问题。
801
+
802
+ ---
803
+
804
+ # 14. 数据结构设计
805
+
806
+ ## 14.1 指令表
807
+
808
+ ```txt
809
+ commands
810
+ - id
811
+ - name
812
+ - commandPath
813
+ - aliases
814
+ - plugin
815
+ - description
816
+ - legacyAuthority
817
+ - status
818
+ - allowGuildOverride
819
+ - createdAt
820
+ - updatedAt
821
+ ```
822
+
823
+ 说明:
824
+
825
+ ```txt
826
+ id 内部稳定 ID,例如 command:music.clear
827
+ name WebUI 显示名,例如 清空歌单
828
+ commandPath Koishi 命令路径
829
+ aliases 别名
830
+ plugin 来源插件
831
+ legacyAuthority 旧 authority 建议
832
+ status pending/configured/disabled
833
+ allowGuildOverride 是否允许群内自治
834
+ ```
835
+
836
+ ## 14.2 角色表
837
+
838
+ ```txt
839
+ roles
840
+ - id
841
+ - name
842
+ - type
843
+ - scopeType
844
+ - builtin
845
+ - createdAt
846
+ - updatedAt
847
+ ```
848
+
849
+ 例如:
850
+
851
+ ```txt
852
+ bot-admin
853
+ guild-owner
854
+ guild-admin
855
+ guild-member
856
+ guest
857
+ custom:music-admin
858
+ ```
859
+
860
+ 字段解释:
861
+
862
+ ```txt
863
+ type:
864
+ builtin
865
+ custom
866
+
867
+ scopeType:
868
+ global
869
+ guild
870
+ ```
871
+
872
+ ## 14.3 角色成员表
873
+
874
+ ```txt
875
+ role_members
876
+ - roleId
877
+ - platform
878
+ - userId
879
+ - scope
880
+ - createdAt
881
+ ```
882
+
883
+ 用于自定义角色和 Bot 管理员。
884
+
885
+ 平台身份角色不一定需要写入数据库。
886
+
887
+ 例如 QQ 群管理员可以直接从 session 动态读取。
888
+
889
+ ## 14.4 权限策略表
890
+
891
+ ```txt
892
+ role_command_policies
893
+ - scope
894
+ - roleId
895
+ - commandId
896
+ - state
897
+ - updatedAt
898
+ ```
899
+
900
+ 其中:
901
+
902
+ ```txt
903
+ state:
904
+ inherit
905
+ allow
906
+ deny
907
+ ```
908
+
909
+ 这里的 `deny` 在 UI 上叫“关闭”,语义是:
910
+
911
+ ```txt
912
+ 这个角色在这个作用域下不拥有此指令权限。
913
+ ```
914
+
915
+ 不是全局强拒绝。
916
+
917
+ ---
918
+
919
+ # 15. 平台身份接入
920
+
921
+ Adapter 或 session 层提供当前用户在群内的平台身份。
922
+
923
+ 例如 OneBot:
924
+
925
+ ```txt
926
+ owner -> 群主
927
+ admin -> 群管理员
928
+ member -> 群成员
929
+ ```
930
+
931
+ Discord:
932
+
933
+ ```txt
934
+ server owner -> 群主
935
+ 有管理权限 -> 群管理员
936
+ 普通用户 -> 群成员
937
+ ```
938
+
939
+ 平台身份建议动态读取,不强制持久化。
940
+
941
+ 好处:
942
+
943
+ ```txt
944
+ 群管理员变更后可以自动生效
945
+ 不需要同步平台权限表
946
+ 不会出现数据库身份过期
947
+ ```
948
+
949
+ 如果平台无法提供身份,则降级为:
950
+
951
+ ```txt
952
+ 访客
953
+ ```
954
+
955
+ 或者使用手动绑定角色。
956
+
957
+ ---
958
+
959
+ # 16. Bot 管理员的来源
960
+
961
+ Bot 管理员必须由 Koishi 实例拥有者显式配置。
962
+
963
+ 来源可以是:
964
+
965
+ ```txt
966
+ 配置文件
967
+ 控制台账号
968
+ 数据库绑定
969
+ 启动时初始化账号
970
+ ```
971
+
972
+ 但不能来自:
973
+
974
+ ```txt
975
+ 群主身份
976
+ 群管理员身份
977
+ 平台频道 owner 身份
978
+ ```
979
+
980
+ 这是安全边界。
981
+
982
+ 换句话说:
983
+
984
+ ```txt
985
+ 能管理一个群 ≠ 能管理这个 Bot。
986
+ ```
987
+
988
+ ---
989
+
990
+ # 17. 命令执行接入点
991
+
992
+ 权限检查应该接在命令执行的统一入口。
993
+
994
+ 位置是:
995
+
996
+ ```txt
997
+ 命令解析完成后
998
+ action 执行前
999
+ ```
1000
+
1001
+ 此时系统已经知道:
1002
+
1003
+ ```txt
1004
+ 当前 session
1005
+ 当前命令
1006
+ 当前命令 ID
1007
+ 来源插件
1008
+ legacyAuthority
1009
+ ```
1010
+
1011
+ 然后调用权限服务:
1012
+
1013
+ ```txt
1014
+ 检查当前用户能否执行当前命令
1015
+ ```
1016
+
1017
+ 如果拒绝,直接返回统一错误:
1018
+
1019
+ ```txt
1020
+ 你没有权限使用该指令。
1021
+ ```
1022
+
1023
+ 不要让每个插件自己实现权限判断。
1024
+
1025
+ ---
1026
+
1027
+ # 18. 旧插件兼容
1028
+
1029
+ 标准旧插件写法:
1030
+
1031
+ ```txt
1032
+ ctx.command('mute').authority(3)
1033
+ ```
1034
+
1035
+ 处理方式:
1036
+
1037
+ ```txt
1038
+ 1. 命令注册时记录 legacyAuthority = 3
1039
+ 2. WebUI 显示建议:群主可用
1040
+ 3. 指令默认进入待配置
1041
+ 4. 未配置前只有 Bot 管理员可用
1042
+ 5. 管理员确认后,按新权限策略执行
1043
+ ```
1044
+
1045
+ 也就是说:
1046
+
1047
+ ```txt
1048
+ authority 不参与最终判定。
1049
+ ```
1050
+
1051
+ ## 18.1 插件内部硬编码 authority
1052
+
1053
+ 有些老插件可能自己写:
1054
+
1055
+ ```txt
1056
+ if (session.user.authority < 3) return
1057
+ ```
1058
+
1059
+ 这类无法完全优雅解决,但可以做兼容桥。
1060
+
1061
+ 设计一个 legacy authority provider(默认行为可以在web ui修改 或禁用此类硬编码插件):
1062
+
1063
+ ```txt
1064
+ 当前上下文下,根据角色反推一个近似 authority。
1065
+ ```
1066
+
1067
+ 例如:
1068
+
1069
+ ```txt
1070
+ Bot 管理员 -> 4
1071
+ 群主 -> 3
1072
+ 群管理员 -> 2
1073
+ 群成员 -> 1
1074
+ 访客 -> 0
1075
+ ```
1076
+
1077
+ 如果某个命令已经通过新权限系统放行,也可以在该命令执行上下文中临时保证:
1078
+
1079
+ ```txt
1080
+ session.user.authority >= 当前命令 legacyAuthority
1081
+ ```
1082
+
1083
+ 这样可以减少旧插件内部二次判断导致的误拒绝。
1084
+
1085
+ 但这只是兼容层,不是新权限系统核心。
1086
+
1087
+ ---
1088
+
1089
+ # 19. 缓存设计
1090
+
1091
+ 权限判断频率很高,需要缓存。
1092
+
1093
+ 缓存 key 可以包含:
1094
+
1095
+ ```txt
1096
+ platform
1097
+ userId
1098
+ guildId
1099
+ channelId
1100
+ commandId
1101
+ ```
1102
+
1103
+ 缓存内容:
1104
+
1105
+ ```txt
1106
+ 当前用户角色集合
1107
+ 当前作用域策略
1108
+ 最终权限结果
1109
+ ```
1110
+
1111
+ 需要失效的情况:
1112
+
1113
+ ```txt
1114
+ 角色成员变更
1115
+ 角色权限变更
1116
+ 指令状态变更
1117
+ 插件加载/卸载
1118
+ 群覆盖配置变更
1119
+ Bot 管理员变更
1120
+ ```
1121
+
1122
+ 平台身份缓存可以使用短 TTL。
1123
+
1124
+ 例如:
1125
+
1126
+ ```txt
1127
+ 30 秒
1128
+ 60 秒
1129
+ ```
1130
+
1131
+ 避免群管理员变更后长期不生效。
1132
+
1133
+ ---
1134
+
1135
+ # 20. 权限服务架构
1136
+
1137
+ 整体可以拆成几个服务。
1138
+
1139
+ ## 20.1 Command Registry
1140
+
1141
+ 负责收集命令。
1142
+
1143
+ 能力:
1144
+
1145
+ ```txt
1146
+ 监听命令注册
1147
+ 生成 commandId
1148
+ 记录来源插件
1149
+ 记录 legacyAuthority
1150
+ 维护 pending/configured/disabled 状态
1151
+ 提供 WebUI 查询
1152
+ ```
1153
+
1154
+ ## 20.2 Role Service
1155
+
1156
+ 负责角色。
1157
+
1158
+ 能力:
1159
+
1160
+ ```txt
1161
+ 读取内置角色
1162
+ 创建自定义角色
1163
+ 管理角色成员
1164
+ 解析用户当前角色
1165
+ ```
1166
+
1167
+ ## 20.3 Policy Service
1168
+
1169
+ 负责策略。
1170
+
1171
+ 能力:
1172
+
1173
+ ```txt
1174
+ 读取某角色可用指令
1175
+ 写入角色-指令策略
1176
+ 处理 global 和 guild 覆盖
1177
+ 判断 inherit/allow/deny
1178
+ ```
1179
+
1180
+ ## 20.4 Permission Evaluator
1181
+
1182
+ 负责最终判断。
1183
+
1184
+ 输入:
1185
+
1186
+ ```txt
1187
+ session
1188
+ commandId
1189
+ ```
1190
+
1191
+ 输出:
1192
+
1193
+ ```txt
1194
+ allow / deny
1195
+ reason
1196
+ matchedRole
1197
+ matchedScope
1198
+ ```
1199
+
1200
+ 例如:
1201
+
1202
+ ```txt
1203
+ allow:
1204
+ matchedRole = guild-admin
1205
+ matchedScope = guild:onebot:888888
1206
+ ```
1207
+
1208
+ 或者:
1209
+
1210
+ ```txt
1211
+ deny:
1212
+ reason = command_pending
1213
+ ```
1214
+
1215
+ ## 20.5 Platform Role Provider
1216
+
1217
+ 负责把平台身份转为角色。
1218
+
1219
+ 例如:
1220
+
1221
+ ```txt
1222
+ OneBotRoleProvider
1223
+ DiscordRoleProvider
1224
+ TelegramRoleProvider
1225
+ ```
1226
+
1227
+ 输出:
1228
+
1229
+ ```txt
1230
+ 当前用户在当前群是群主/管理员/成员
1231
+ ```
1232
+
1233
+ ## 20.6 Legacy Authority Bridge
1234
+
1235
+ 负责旧插件兼容。
1236
+
1237
+ 能力:
1238
+
1239
+ ```txt
1240
+ 读取命令 legacyAuthority
1241
+ 给 WebUI 提供建议
1242
+ 为 session.user.authority 提供兼容值
1243
+ ```
1244
+
1245
+ ---
1246
+
1247
+ # 21. WebUI 权限边界
1248
+
1249
+ WebUI 本身也要受权限系统控制。
1250
+
1251
+ 例如:
1252
+
1253
+ ```txt
1254
+ 查看角色列表:Bot 管理员
1255
+ 修改全局权限:Bot 管理员
1256
+ 修改所有群权限:Bot 管理员
1257
+ 修改当前群自治权限:群主,且只限 allowGuildOverride 的指令
1258
+ 创建全局自定义角色:Bot 管理员
1259
+ 创建群内自定义角色:Bot 管理员或被授权的群主
1260
+ ```
1261
+
1262
+ 群主即使进入 WebUI,也只能看到当前群可管理内容。
1263
+
1264
+ 不能看到:
1265
+
1266
+ ```txt
1267
+ 其他群配置
1268
+ Bot 全局配置
1269
+ 插件安装卸载
1270
+ 文件管理
1271
+ 数据库
1272
+ Token
1273
+ 环境变量
1274
+ ```
1275
+
1276
+ ---
1277
+
1278
+ # 22. 指令 ID 设计
1279
+
1280
+ 指令 ID 要稳定,避免重命名导致权限丢失。
1281
+
1282
+ 推荐格式:
1283
+
1284
+ ```txt
1285
+ command:<pluginName>:<commandPath>
1286
+ ```
1287
+
1288
+ 例如:
1289
+
1290
+ ```txt
1291
+ command:music:play
1292
+ command:music:clear
1293
+ command:admin:plugin.reload
1294
+ ```
1295
+
1296
+ 显示名可以变化,但 ID 尽量稳定。
1297
+
1298
+ 别名不生成新 ID。
1299
+
1300
+ 例如:
1301
+
1302
+ ```txt
1303
+ /play
1304
+ /点歌
1305
+ /music play
1306
+ ```
1307
+
1308
+ 如果它们指向同一个命令,内部都是:
1309
+
1310
+ ```txt
1311
+ command:music:play
1312
+ ```
1313
+
1314
+ 子命令可以独立成 ID:
1315
+
1316
+ ```txt
1317
+ command:plugin:install
1318
+ command:plugin:uninstall
1319
+ command:plugin:reload
1320
+ ```
1321
+
1322
+ 因为它们危险性和授权对象可能不同。
1323
+
1324
+ ---
1325
+
1326
+ # 23. 默认规则
1327
+
1328
+ 系统默认规则应当保守:
1329
+
1330
+ ```txt
1331
+ 新指令:待配置
1332
+ 待配置指令:只有 Bot 管理员可用
1333
+ Bot 管理员:默认可用所有指令
1334
+ 群主/群管理员/群成员:默认不获得新指令
1335
+ ```
1336
+
1337
+ 可以在 WebUI 里提供批量操作:
1338
+
1339
+ ```txt
1340
+ 采用插件建议
1341
+ 本插件所有指令给群成员
1342
+ 本插件所有指令给群管理员
1343
+ 本插件所有指令仅 Bot 管理员
1344
+ ```
1345
+
1346
+ 但这些必须由 Koishi 管理员确认。
1347
+
1348
+ ---
1349
+
1350
+ # 24. 最终行为示例
1351
+
1352
+ ## 24.1 签到插件
1353
+
1354
+ 插件注册:
1355
+
1356
+ ```txt
1357
+ sign
1358
+ legacyAuthority = 1
1359
+ ```
1360
+
1361
+ 进入 WebUI:
1362
+
1363
+ ```txt
1364
+ 待配置指令:签到
1365
+ 插件建议:群成员可用
1366
+ ```
1367
+
1368
+ Koishi 管理员采用建议:
1369
+
1370
+ ```txt
1371
+ 群成员:允许
1372
+ 群管理员:允许
1373
+ 群主:允许
1374
+ Bot 管理员:允许
1375
+ ```
1376
+
1377
+ 结果:
1378
+
1379
+ ```txt
1380
+ 普通成员可以签到。
1381
+ ```
1382
+
1383
+ ## 24.2 禁言插件
1384
+
1385
+ 插件注册:
1386
+
1387
+ ```txt
1388
+ mute
1389
+ legacyAuthority = 3
1390
+ ```
1391
+
1392
+ WebUI 显示:
1393
+
1394
+ ```txt
1395
+ 插件建议:群主可用
1396
+ ```
1397
+
1398
+ Koishi 管理员手动配置:
1399
+
1400
+ ```txt
1401
+ 群主:允许
1402
+ 群管理员:允许
1403
+ 群成员:关闭
1404
+ ```
1405
+
1406
+ 结果:
1407
+
1408
+ ```txt
1409
+ 群主和管理员能禁言,成员不能。
1410
+ ```
1411
+
1412
+ ## 24.3 删除文件插件
1413
+
1414
+ 插件注册:
1415
+
1416
+ ```txt
1417
+ file/delete
1418
+ legacyAuthority = 3
1419
+ ```
1420
+
1421
+ WebUI 显示:
1422
+
1423
+ ```txt
1424
+ 待配置
1425
+ 插件建议:群主可用
1426
+ ```
1427
+
1428
+ 但因为 `authority` 只是建议,不会自动生效。
1429
+
1430
+ 如果 Koishi 管理员没有配置:
1431
+
1432
+ ```txt
1433
+ 只有 Bot 管理员可用。
1434
+ ```
1435
+
1436
+ 所以普通群主把 Bot 拉进群,也不能删除文件。
1437
+
1438
+ ---
1439
+
1440
+ # 25. 一句话总结
1441
+
1442
+ 这套方案的核心是:
1443
+
1444
+ ```txt
1445
+ 指令注册后进入权限系统;
1446
+ 权限管理以角色为中心;
1447
+ 角色详情页配置可用指令;
1448
+ 新指令默认只给 Bot 管理员;
1449
+ authority 只做建议,不直接授权;
1450
+ 群主只是当前群角色,不是 Bot 管理员。
1451
+ ```
1452
+
1453
+ 这样既能兼容 Koishi 老插件,又不会让普通群主意外获得 Bot 实例级权限,同时 WebUI 也不会变成复杂难懂的权限矩阵。
1454
+
1455
+ ---
1456
+
1457
+ KOISHI侧边栏的图标不使用默认的 使用⌗
1458
+ 同时根据F:\chatluna-1.4.0-alpha.17 为指令权限限制制作一个AI自动分配