在第五章数据库的时候, 我们创建了Role表,并创建了不同的角色。
不同的角色要有不同的权限, 本节我们来为角色划分权限。
————————————————————————————————
一.为我们的角色划分权限
我们知道, 社交博客应该具有以下权限:
操作 | 位值 |
关注用户 | 0x00000001 (0x01) |
在他人文章发表评论 | 0x00000010 (0x02) |
写文章 | 0x00000100 (0x04) |
管理他人发表的评论 | 0x00001000 (0x08) |
管理员权限 | 0x10000000 (0x80) |
我们用不同的位值来表示不同的权限, 代码实现如下:
class Permission():
FOLLOW = 0x01
COMMIT = 0x02
WRITE_ARTICLE = 0x04
MODERATE_COMMIT = 0x08
ADMINISTER = 0x80
class Role(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True)
#只有角色为用户时default属性值才为True, 表示在注册时, 默认角色为用户。
default = db.Column(db.Boolean, default=False, index=True)
permissions = db.Column(db.Integer) #每个用户的permissions值, 表示他具有的权限
users = db.relationship('User', backref='role', dynamic='lazy')
@staticmethod
def insert_roles():
#定义角色字典, 键为角色名, 值为权限和默认值组成的元组, 这样一个角色的所有属性都包括在字典里了
roles = {
'User':(Permission.Follow|
Permission.Commit|
Permission.WRITE_ARTICLE, True),
'Moderator':(Permission.FOLLOW|
Permission.Commit|
Permission.WRITE_ARTICLE|
Permission.MODERATE_COMMIT, False),
'Administrator':(0xff, False)
}
for r in roles: #遍历字典, 得到的r为角色名
#在数据库中搜索该角色, 没有的话创建该角色
role = Role.query.filter_by(name=r).first()
if not role:
role = Role(name=r)
#设置permissions和default属性值
role.permissions = roles[r][0]
role.default = roles[r][1]
#把改动添加到会话
db.session.add(role)
#提交会话
db.session.commit()
此处我们添加了一个往数据库的Role表添加角色的函数insert_role, 字典会使添加新用户和改变用户权限变得更加灵活, 下面我们演示添加角色:
数据库的变化更加直观:
————————————————————————————————————————————
二.赋予角色:
class User(UserMixin, db.Model):
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
if self.role is None:
if self.email == current_app.config['FLASKY_ADMIN']:
self.role = Role.query.filter_by(permissions=0xff).first()
else:
self.role = Role.query.filter_by(default=True).first()
#...
我们为User表增加了一个构造函数, 先调用父类构造函数创建角色;
创建用户的代码在auth.register视图函数中:
u = User(email=form.email.data, username=form.username.data, password=form.password.data)
并没有指定角色, 所以构造函数中又加了个判断条件, 如果角色没有指定, 如果该注册用户的email是config字典中存储的管理员email的话, 把该用户的角色设置为管理员, 否则默认设置为用户。