django的授权库,带有acl,不依赖于模型。
django-keeper的Python项目详细描述
django守门员
Django的授权库,不依赖于模型。
- 不会依赖于型号
- 不会将工作分配/权限保存到数据存储中
支持的版本:
- python 3.6
- Python3.7
- Django 1.10
- Django 1.11
- Django 2.0
- Django 2.1
- Django 2.2
安装
$ pip install django-keeper
并添加到已安装的应用程序中
INSTALLED_APPS=[...'keeper',]
一目了然
模型的声明性权限映射。
fromdjango.confimportsettingsfromkeeper.securityimportAllowfromkeeper.operatorsimportEveryone,Authenticated,IsUserclassIssue(models.Model):author=models.ForeignKey(settings.AUTH_USER_MODEL)...def__acl__(self):return[(Allow,Everyone,'view'),(Allow,Authenticated,'add_comment'),(Allow,IsUser(self.author),'edit'),]
模型实例允许:
- 每次查看请求
- 添加评论的授权请求
- 编辑是作者
然后,对视图应用@keeper
。
fromkeeper.viewsimportkeeper# Model Permissions@keeper('view',model=Issue,mapper=lambdarequest,issue_id:{'id':issue_id},)defissue_detail(request,issue_id):""" View requires 'view' permission of Issue model * An issue object will be retrieved * keeper will check whether the rquests has 'view' permission for the issue The third argument function can return keyword argument to retrieve the issue object. """request.k_context# Will be instance of the issue object...@keeper('add_comment',model=Issue,mapper=lambdarequest,issue_id:{'id':issue_id},)defadd_comment(request,issue_id):...
全局权限
不仅仅是模型权限django-keeper
可以处理全局权限。
首先,在models.py中编写具有__acl__
方法的类。
classRoot:def__acl__(self):return[(Allow,Authenticated,'view_dashboard'),(Allow,Authenticated,'add_issue'),]
没必要把它放进models.py
,
但很容易理解。
并具体说明。
KEEPER_GLOBAL_CONTEXT=myapp.models.Root'
然后可以在视图中使用全局权限。
只需应用@keeper
和权限名称。
@keeper('add_issue')defissue_list(request):""" View requires 'add_issue' permission of Root Context """
运算符
运算符只是Callable[[HttpRequest], bool]
。
默认情况下,django keeper有以下运算符:
keeper.operators.Everyone
keeper.operators.Authenticated
keeper.operators.IsUser
keeper.operators.Staff
也可以轻松创建自己的运算符。
fromkeeper.operatorsimportAuthenticated,OperatorclassIsIP(Operator):def__init__(self,ip):self.ip=ipdef__call__(self,request):returnrequest.META.get('REMOTE_ADDR')==self.ipclassBelongsTeam(Authenticated):def__init__(self,team,role):self.team=teamdef__call__(self,request):ifnotsuper().__call__(request):returnFalsereturnrequest.user.team==self.team
在acl中使用它
classArticle(models.Model):team=models.ForeignKey(Team)def__acl__(self):return[(Allow,Everyone,'view'),(Allow,BelongsTeam(self.team),'edit'),(Allow,IsIP(settings.COMPANY_IP_ADDRESS),'edit'),]
组合运算符
可以使用按位运算符组合多个“运算符”。
classArticle(models.Model):def__acl__(self):return[(Allow,Authenticated()&IsIP(settings.COMPANY_IP_ADDRESS),'view'),]
可以使用运算符
a & b
a | b
a ^ b
~a
失败时的操作
当请求无法传递acl时,可以更改操作。
fromkeeper.viewsimportkeeper,login_required@keeper('view_articles',on_fail=login_required(),)defdashboard(request):...
这个视图的行为就像django的decorator 当请求没有“查看”权限时。
也可以使用其他操作。
keeper.views.login_required
keeper.views.permission_denied
keeper.views.not_found
keeper.views.redirect
在模板中使用
还支持在模板中处理权限。
{%loadkeeper%}{%has_permissionissue'edit'ascan_edit%}{%ifcan_edit%} <a href="...">Edit</a>{%endif%}
检查全局权限时,请使用has_global_permission
。
{%loadkeeper%}{%has_global_permission'add_issue'ascan_add_issue%}{%ifcan_add_issue%} <a href="...">New Issue</a>{%endif%}
带django core
添加身份验证后端:
AUTHENTICATION_BACKENDS=('keeper.permissions.ObjectPermissionBackend','django.contrib.auth.backends.ModelBackend',)
现在User.has_perm
方法将考虑django keeper的权限。
备选方案
- django-guardian
- 这取决于数据库
- 不是处理全局权限的方法,不仅仅是针对模型
- django-rules
常见问题解答
- 我能用acl过滤模型吗?
- 不支持