Python访问控制库。
项目描述
Balrog是一个Python库,帮助您在项目中构建授权系统
You shall not pass!
Balrog适用于具有静态定义角色的系统,这些角色启用了某些工作流程。每个身份在特定上下文中只能有一个角色。这种方法允许根据这些角色执行的工作流程来覆盖您的系统,进行功能测试。可以将对系统的流程中定义角色的正式要求应用于工作流程。
这些角色在代码中静态定义,并且这种方式可以正确地版本控制和进行测试。可以进行某些权限组的组合并在角色之间共享,但在语义上,当其中一个角色禁止某些操作而另一个角色允许这些操作时,一个身份不能拥有两个相互矛盾的角色。相反,可以提取具有允许的权限的正确角色。
安装
pip install balrog
用法
需要权限才能访问资源或执行操作。权限分组在角色中,角色分组在策略中。
检查权限的入口点是策略。定义一个策略实例并指定与其一起工作的角色列表。
项目可以包含多个用于不同目的的策略。
权限声明
import balrog
from flask import request
def get_identity(*args, **kwargs):
"""Get current user."""
# Flask request wrapper implements the ``user`` property
return request.user
def get_role(identity, *args, **kwargs):
"""Get current identity role."""
# User.role is a property of the ORM User model
return identity.role
read = balrog.Permissions(name="article.read")
post = balrog.Permissions(name="article.post")
comment = balrog.Permissions(name="article.comment")
anonymous = balrog.Role(
name="anonymous",
permissions=[read],
)
"""Anonymous visitors can read articles."""
user = balrog.Role(
name="user",
permissions=[read, comment],
)
"""User accounts can read and comment articles."""
author = balrog.Role(
name="author",
permissions=[read, post, comment],
)
"""Author accounts can read, create and comment articles."""
policy = balrog.Policy(
roles=[anonymous, user, author],
get_identity=get_identity,
get_role=get_role,
permissions=[read, post, comment]
)
权限检查
# ...
policy = balrog.Policy(roles=[anonymous, user, author], get_identity=get_identity, get_role=get_role)
policy.check("article.comment")
过滤集合
articles = session.query(Article)
my_articles = policy.filter("article.view", objects=articles)
每个角色都是一组权限的集合。除了包含在角色权限之外,权限还可以实现更详细的检查和过滤逻辑。
权限
权限具有唯一的名称(在角色内),反映了您想要对此资源执行的操作。
import balrog
eat = balrog.Permission(name="cucumber.eat")
happy = balrog.Permission(name="be-happy")
名称只是一个字符串标识符,您使用它来请求策略进行权限检查。名称格式规范可以由每个项目自行决定。
权限有两个方法:check 和 filter。默认情况下,check 方法实现为 True,filter 方法简单地绕过对象。这些方法是控制对某些上下文、您的资源实例、检查白名单、从集合中过滤出当前认证身份无法查看的对象等额外机会。
角色
角色在策略内具有唯一的名称。角色名称由认证身份确定,并在策略权限检查中隐式使用。
角色是一组权限的集合,用于定义角色并启用系统中的某些工作流程。
当系统很大并且声明了大量的特定权限时,有时从角色中授予所有权限而不是子类化角色类更容易。
import balrog
class Admin(balrog.Role):
def check(self, identity, permission, *args, **kwargs):
return True
策略
策略用作项目中权限检查的入口点。它封装了定义工作流程的角色。项目中可能存在多个策略实例。
除了角色外,策略还需要一些配置和后端实现。
get_identity
一个回调,返回当前认证身份。项目必须实现此后端并从Flask请求对象等恢复身份实例(例如,用户对象)。
from flask import request
def get_identity(*args, **kwargs):
"""Get current user."""
# Flask request wrapper implements the ``user`` property
return request.user
get_role
一个回调,返回当前身份在上下文中的角色。在简单情况下,角色与数据库中的用户相关联。
def get_role(identity, *args, **kwargs):
"""Get current identity role."""
# User.role is a property of the ORM User model
return identity.role
check
权限检查。您传递给此函数的所有参数都通过 Role.check 传递,最终传递到 Permission.check。
if not policy.check("article.read", article=a):
flask.abort("You can't access the article `{0}`".format(a.id))
filter
如果身份没有权限访问给定的对象,该函数将过滤掉这些对象。
articles = session.query(Article).filter_by(is_published=True)
my_articles = policy.filter("article.read", objects=articles)
实现自己的过滤
import balrog
class ViewArticle(balrog.Permission);
def filter(self, identity, objects, *args, **kwargs):
"""Filter out articles of the other users.
:param identity: User object.
:param objects: SQLAlchemy query.
:returns: SQLAlchemy query with applied filtering.
"""
return objects.filter_by(user_id=identity.id)
当在角色中没有这样的权限时,过滤函数可以抛出异常。在这种情况下,库不能确定返回表示空对象集合的类型的类型。一些项目会期望一个空列表,一些会期望一个假的ORM查询等。相反,应该处理此异常。
try:
my_articles = policy.filter("article.read", objects=articles)
except balrog.PermissionNotFound:
my_articles = []
上下文
您传递给 check 或 filter 函数的所有额外内容都将传递到相关的 Role 和 Permission 方法。您可以使用白名单来传递您控制的某些对象实例的访问权限。
policy.check("message.send", ip=ip_addr)
Policy.check 方法可以比较 IP 地址是否在白名单中。
联系
如果您有任何问题、错误报告、建议等,请在该 GitHub 项目页面 上创建问题。
许可证
本软件受 MIT 许可证 许可。
见 许可证 更新日志 =========
1.1.0
Policy 会跟踪所有权限,并在调用未知权限时引发 PermissionNotFound(hvdklauw)。
1.0.1
将上下文传递给 get_identity(olegpidsadnyi)
1.0.0
初始公共版本
项目详情
下载文件
下载您平台对应的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。
源分发
构建分发
balrog-1.1.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 456e08cdb028d02f19cb61cd45fe06a51cd988ff45018cb5398da34cfcab336a |
|
MD5 | b46db514ae4ee7fb3d96bd1b2fc09347 |
|
BLAKE2b-256 | c36f87977bd309d0f69a8a2c138077a172477fa17fc15fe2ac880fa079b70ea4 |
balrog-1.1.0-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e773c3bb51d19c867e1faefdd88b3718045a49e01e4ff3ee3d4edc66b4287870 |
|
MD5 | dda2d93030a6f9f8307560e0e776e0e2 |
|
BLAKE2b-256 | 8d75cb48d2836682f1574c95d0e481efe83372030c385ad9844b9bc5544676cb |