跳转到主要内容

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 (7.2 kB 查看哈希值)

上传时间

构建分发

balrog-1.1.0-py2.py3-none-any.whl (8.0 kB 查看哈希值)

上传时间 Python 2 Python 3

由以下支持