5

我有一个简单的根资源工厂:

class Root:
    __acl__ = [
        (Allow, Authenticated, 'edit')
    ]

现在对于一些“特殊”路线,我需要创建另一个资源工厂

config.add_route('special', '/special/test', factory=SpecialFactory)

class SpecialFactory:
    __acl__ = [
        (Allow, Authenticated, 'special_edit')
    ]

现在,我想让Root--SpecialFactory我应该怎么做?

这是正确的方法吗...

class SpecialFactory:
    def __init__(self, request):
        self.request = request
        self.__parent__ = Root(request)
        self.__name__ = 'special'

    __acl__ = [
        (Allow, Authenticated, 'special_edit')
    ]

我也不完全理解它的目的__name__以及应该设置什么。

此外,Pyramid 什么时候会遍历__parent__链条,什么时候不会?对于这样的视图配置:

@view_config(route_name='special', permission='special_edit')
def something(req):
    pass

Pyramid 会“收集”两个权限(special_editedit)还是只收集一个(special_edit)?

请详细解释计算权限的“流程”。

4

1 回答 1

14

__name__只有在通过遍历生成 url 时才会考虑,所以不用担心。

首先,工厂参数是工厂。意思是,它是“某个对象”,它接受一个request对象,并期望接收一个实际上是树根的对象。

class Root:
    def __init__(self, request):
        self.request = request

def resource_factory(request):
    return Root(request)

add_route(..., factory=resource_factory)

请注意,在这里,工厂是显而易见的。一种常用的捷径是利用构造对象实例实际上返回自身这一事实。所以Root(request)从外面看完全一样,并返回与 . 相同的对象resource_factory(request)

太好了,所以现在我们有了一个“根”对象,我们可以从中开始遍历。当然这不一定是树的实际根,它只是遍历应该开始的地方。

您还没有在 中添加traverse参数add_route,因此遍历不会去任何地方,它只会返回根对象作为上下文。找到上下文对象是遍历练习的全部目标。

所以,现在我们有了一个上下文。耶。

Pyramid 的授权通过将用户的“有效主体”与“上下文”和“权限”相结合来工作。这 3 件事是您的授权策略将用于确定允许或拒绝操作的内容。

“有效主体”来自身份验证策略,代表请求背后的用户。

“上下文”和“权限”是你想要的。在大多数情况下,它们是request.context视图的权限,但pyramid.security.has_permission()可以接受任何上下文对象和任何权限,并向您返回允许或拒绝结果。

所以,我们已经获得了授权所需的 3 件东西。现在,如何授权?好吧,这取决于授权策略。默认情况下,ACLAuthorizationPolicy. 那么它是怎样工作的?

ACLAuthorizationPolicy开始context并向后通过该对象的“血统”。“血统”被定义为通过跟踪每个对象的__parent__最后创建的列表,没有更多__parent__可以遵循的。因此,在您的示例中,上下文将是 的实例SpecialFactory,而上下文的“沿袭”是 list [ SpecialFactory(request), Root(request) ]

ACL 匹配的工作方式(在 中ACLAuthorizationPolicy)是它遍历沿袭中的每个对象,从上下文回到根,__acl__按顺序搜索每个对象。它找到的第一场比赛就是获胜者。ACL 中的条目由“(AllowDeny, principal, permission)”定义,并且 match 是 ACL 中的条目,它包含我们正在寻找的相同权限,因为主体与我们的有效主体列表中的一个主体匹配当前用户。一旦找到匹配项,搜索就会停止并返回结果。

如果此算法对您不起作用,请更换授权策略。它是高度可插拔的,默认实现很容易理解(总共只有几行代码)。您甚至可以制定自己的策略,根本不关心上下文,此时您可以忽略所有这些遍历废话。由你决定。

于 2013-04-23T16:08:20.037 回答