Flarum 权限设计详解
今天计划把 Flarum 中的权限系统重新梳理下
Flarum 中的权限系统非常简单,核心思想一个关键词 限制 ,这也就是 tags
表中 restricted
字段的缘来和作用
如果要用一句话概括,那么就是
Tag 一旦设定权限,忽略全局设置,否则使用全局权限
我们先来看看后台的权限界面,有一个大概的印象
用户组 、 用户 、权限
权限设定一般都围绕 用户组 、 用户 、权限 三者之间转开。 Flarum 也不例外
一个用户可以属于多个用户组,多个用户组可以分别拥有相同的权限,用户与权限之间没有直接关系
简单的说,就是下图这样
用户组
Flarum 中所有的权限都保存在 ez_groups
表中,字段没啥好说的,很普通
Flarum 中可以添加分组,这是肯定的,但同时也占用了 1-4
组 ID 用于内置组别
vendor/flarum/core/src/Core/Group.php
<?php const ADMINISTRATOR_ID = 1; // 管理员组 const GUEST_ID = 2; // 游客组 const MEMBER_ID = 3; // 登录用户(会员) const MODERATOR_ID = 4; // *话题管理(版主)组
前面三个都好理解,就是 MODERATOR_ID
不好理解,这个组什么意思呢?其实就是相当于大家说的 版主
但是,Flarum 中没有板块的概念,那么怎么会有版主权限呢?所以,我对它的理解,就是 话题管理者
内置组别的关系怎么样的?
-
没有登录的客户自动获得
GUEST_ID = 2
组权限,也就是会赋予一个2
组别给游客 -
登录用户自动获得
MEMBER_ID = 3
权限,同时也用于GUEST_ID = 2
权限这是什么意思呢,也就是登录用户的组别为
[2,3]
-
ADMINISTRATOR_ID
拥有所有的权限,包括登录后台,需要显示设定从后台看它是灰色的不可点击,既然拥有所有权限,那么何必设定呢
-
MODERATOR_ID
需要显式设定
为什么我们要先讲 用户组 因为它是桥梁,如果不解释清楚很难解释剩下的两个
用户
Flarum
中跟用户相关的,和权限相关的就两个表 ez_users
和 ez_users_groups
表
ez_users
ez_users
表很普通,没啥新鲜,但有两个字段值的关注 is_activated
和 suspend_until
这两个字段直接关系到登录用户是否自动获得 MEMBER_ID
会员组,一般情况下,如果你没更改,那么 is_activated==0
的情况下或者当前时间小于 suspend_until
值的情况下,那么登录用户的权限还只是游客组,对的,没有自动获得会员组
ez_users_groups
ez_users_groups
就两个字段,user_id
和 group_id
也很平常,不多说
用户这里有很多坑,如果你要改写的话,尤其是删除用户,因为涉及到删除用户的话题,用户的帖子等,所以,一般情况下,如果删除一个用户,直接把 suspend_until
值设置到 2038
年,然后把用户的密码随机化,然后一通修改所有的话题和帖子的 hide_time
属性
权限
Flarum
中跟权限相关的,就一个表 ez_permissions
,对的,它把权限和用户都放到一起了,按平时我们的设计,肯定有一个单独的权限表和一个用户组权限表
它把两者合二为一,省略了权限表,但真的省略了吗? 没有,因为用户权限表是通过代码收集起来的,举个范例,比如 flarum-ext-flags
扩展,它在文件
vendor/flarum/flarum-ext-flags/migrations/2017_07_22_000000_add_default_permissions.php
这几句代码
return Migration::addPermissions([ 'discussion.flagPosts' => Group::MEMBER_ID, 'discussion.viewFlags' => Group::MODERATOR_ID ]);
这几句代码的意思就是安装 flarum-ext-flags
扩展时自动给予两个用户组赋权限
然后 Flarum
在给其它用户组赋权限的时候就会把所有的权限列出来,一一询问是否赋于
是不是很精妙,当初我看到这个设计的时候大为赞叹
我们来看看表 ez_permissions
中的内容,这是我安装 flarum
测试上的表
如果我们把它整理一下,就是下面这样
可以看到,查看举报帖文 viewFlags
其实就只有两个用户组能看到,一个是管理员组,一个是话题管理着
标签
如果 Flarum
中的权限系统到此为止,那么太遗憾了,所以,Tags
上场了
大家可以从上图中的 ez_permissions
表中看到很多以 tag2.
开头的权限
这表示啥意思呢,这就是说可以针对每一个标签进行设置权限,它们的权限是由本来的权限名前加上 tag+tag_id
构成的
所有的标签都保存在 ez_tags
表中,数据大概就是下面这样子
其它权限
除了 ez_permissions
表中的权限设置,大家还可以从后台的第一列和第二列之间的差异上看到,有些权限在 Tag
里是没法设置的,这些权限是全局权限,保存在 ez_settings
表中,例如 allow_post_editing
是否允许用户编辑话题,这个值很简单
- 值如果小于 0 , 那么可以随意编辑
-
值如果是
reply
,那么一定被别人回复了,那么就不能编辑了,这个设定也很有意思,其实就是参与者 (participants_count
) 大于 1 的时候就不能编辑了 -
如果是大于 0 的数值,就是多少分钟后不能被编辑
判断是否有权限
理清了权限系统各个组成部分之间的关系,那么判断用户是否有具有某个权限就很简单了,直接就是判断用户组是否在权限内
<?php public function hasPermission($permission) { if ($this->isAdmin()) { return true; } if (is_null($this->permissions)) { $this->permissions = $this->getPermissions(); } return in_array($permission, $this->permissions); }
当然了,Flarum
还提供了另一个函数用于判断用户的权限
<?php public function can($ability, $arguments = []) { return static::$gate->forUser($this)->allows($ability, $arguments); }
具体上溯所有的代码,我们就不一一分析了,总之,很复杂很复杂,复杂的我都不想看了
最后,那么个,简单教程 讨论区 权限系统还没修复完毕,请大家轻拍