Flask应用程序的简单灵活的权限控制。
permission的Python项目详细描述
瓶式应用程序的简单灵活的权限控制。
功能
- simple:您只需对Rule和 Permission类。
- {STR 1 } $灵活:支持规则继承和按位操作(^ {TT3}$) 以及|)来构建自己的规则。
安装
$ pip install permission
规则
Rule有3个可重写的方法:
- base():定义基本规则。
- check():确定是否应通过此规则。
- deny():将在check()失败时执行。
重写时应始终重写check()和deny()。 base()根据需要。
权限
Permission有1个可重写的方法:
- rule():定义此权限所需的规则
您应该始终覆盖rule()。
Permission有两个实例方法可以在代码中使用:
- check():调用此项检查此权限的规则
- deny():当check()失败时调用此命令执行代码
用法
首先需要通过子类化Rule定义自己的规则,然后 覆盖check()和deny():
# rules.pyfromflaskimportsession,flash,redirect,url_forfrompermissionimportRuleclassUserRule(Rule):defcheck(self):"""Check if there is a user signed in."""return'user_id'insessiondefdeny(self):"""When no user signed in, redirect to signin page."""flash('Sign in first.')returnredirect(url_for('signin'))
然后通过子类化Permission定义权限并重写 rule():
# permissions.pyfrompermissionimportPermissionfrom.rulesimportUserRuleclassUserPermission(Permission):"""Only signin user has this permission."""defrule(self):returnUserRule()
有4种方法可以使用上面定义的UserPermission:
1。用作视图装饰符
from.permissionsimportUserPermission@app.route('/settings')@UserPermission()defsettings():"""User settings page, only accessable for sign-in user."""returnrender_template('settings.html')
2。在视图中使用代码
from.permissionsimportUserPermission@app.route('/settions')defsettings():permission=UserPermission()ifnotpermission.check()returnpermission.deny()returnrender_template('settings.html')
3。在视图中使用代码(使用“with”语句)
from.permissionsimportUserPermission@app.route('/settions')defsettings():withUserPermission():returnrender_template('settings.html')
注意:如果在权限检查时不引发异常 失败(换句话说,将调用规则的deny(), PermissionDeniedException将被筹集以停止 执行带正文代码的。顺便说一下,你可以导入这个 根据需要例外:
frompermissionimportPermissionDeniedException
^{str 1}4美元。在Jinja2模板中使用
首先,您需要将定义的权限注入模板上下文:
from.importpermissions@app.context_processordefinject_vars():returndict(permissions=permissions)
然后在模板中:
{% if permissions.UserPermission().check() %} <ahref="{{ url_for('new') }}">New</a> {% endif %}
规则继承
需要说的是,这里的继承与python类不同 继承,只是意味着您可以使用rulea作为 规则B。
我们通过重写base()来实现这一点。
假设管理员用户应该始终是用户:
# rules.pyfromflaskimportsession,abort,flash,redirect,url_forfrompermissionimportRuleclassUserRule(Rule):defcheck(self):return'user_id'insessiondefdeny(self):flash('Sign in first.')returnredirect(url_for('signin'))classAdminRule(Rule):defbase(self):returnUserRule()defcheck(self):user_id=int(session['user_id'])user=User.query.filter(User.id==user_id).first()returnuseranduser.is_admindefdeny(self):abort(403)
规则按位操作
- RuleA & RuleB表示当rulea和ruleb都被传递时 都通过了。
- RuleA | RuleB表示它将被传递rulea或ruleb is 通过。
假设我们需要用烧瓶建立一个论坛。只有主题创建者 管理员用户可以编辑主题:
首先定义规则:
# rules.pyfromflaskimportsession,abort,flash,redirect,url_forfrompermissionimportRulefrom.modelsimportUser,TopicclassUserRule(Rule):defcheck(self):"""Check if there is a user signed in."""return'user_id'insessiondefdeny(self):"""When no user signed in, redirect to signin page."""flash('Sign in first.')returnredirect(url_for('signin'))classAdminRule(Rule):defbase(self):returnUserRule()defcheck(self):user_id=int(session['user_id'])user=User.query.filter(User.id==user_id).first()returnuseranduser.is_admindefdeny(self):abort(403)classTopicCreatorRule(Rule):def__init__(self,topic):self.topic=topicsuper(TopicCreatorRule,self).__init__()defbase(self):returnUserRule()defcheck(self):returntopic.user_id==session['user_id']defdeny(self):abort(403)
然后定义权限:
# permissions.pyfrompermissionimportPermissionclassTopicAdminPermission(Permission):def__init__(self,topic):self.topic=topicsuper(TopicAdminPermission,self).__init__()defrule(self):returnAdminRule()|TopicCreatorRule(self.topic)
所以我们可以在edit_topic视图中使用TopicAdminPermission:
from.permissionsimportTopicAdminPermission@app.route('topic/<int:topic_id>/edit')defedit_topic(topic_id):topic=Topic.query.get_or_404(topic_id)permission=TopicAdminPermission(topic)ifnotpermission.check():returnpermission.deny()...
许可证
麻省理工学院