金字塔:多个资源工厂——如何 [英] Pyramid: multiple resource factories -- how to

查看:45
本文介绍了金字塔:多个资源工厂——如何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a simple root resource factory:

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

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

Now for some "special" routes, I need to create another resource factory

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

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

现在,我想让 Root 成为 SpecialFactory 的父级 -- 我该怎么做?

Now, I want to make Root the parent of SpecialFactory -- how should I do it?

这是正确的方法吗...

Is this the right way...

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

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

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

I also don't understand the purpose of __name__ fully and what it should be set to.

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

Also, when will Pyramid traverse the __parent__ chain and when not? For a view config like this:

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

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

will Pyramid 'collect' both permissions (special_edit and edit) or just one (special_edit)?

请详细解释计算权限的流程".

Please explain the "flow" of calculating the permissions extensively.

推荐答案

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

__name__ only comes into account when generating urls via traversal, so don't worry about it.

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

First off, the factory argument is a factory. Meaning, it's "some object" that accepts a request object, and expects to receive back an object that is actually the root of the tree.

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) 相同的对象.

Notice how, here, the factory is obvious. A shortcut that is commonly used is to use the fact that constructing an instance of an object actually returns itself. So Root(request) looks exactly the same from the outside and returns the same object as resource_factory(request).

太好了,现在我们有了一个可以开始遍历的根"对象.当然,这不一定是树的实际根,它只是应该从哪里开始遍历.

Great, so now we have a "root" object from which we can begin traversal. Of course this doesn't have to be the actual root of the tree, it's just where traversal should begin from.

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

You haven't added a traverse argument to your add_route, so traversal won't go anywhere, it will just return the root object as the context. Finding the context object is the whole goal of the traversal exercise.

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

So, now we have a context. Yay.

Pyramid 的授权通过将用户的有效委托人"与上下文"和权限"相结合来工作.这 3 件事是您的授权策略将用于确定是允许还是拒绝操作的内容.

Pyramid's authorization works by combining the "effective principals" of the user, with the "context" and a "permission". These 3 things are what your authorization policy will use to determine if an operation is allowed or denied.

有效委托人"来自身份验证策略,代表请求背后的用户.

The "effective principals" come from the authentication policy, and are representative of the user behind the request.

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

The "context" and "permission" are whatever you want. In most scenarios they are request.context and the view's permission, but pyramid.security.has_permission() can accept any context object and any permission and return you an allow or deny result.

因此,我们已获得授权所需的 3 项内容.现在,如何授权?那么这取决于授权政策.默认情况下,ACLAuthorizationPolicy.那么它是如何工作的?

So, we've got the 3 required things for authorization. Now, how to authorize? Well that is up to the authorization policy. By default, the ACLAuthorizationPolicy. So how does it work?

ACLAuthorizationPolicycontext 开始,然后向后遍历该对象的世系".谱系"被定义为通过跟随每个对象的 __parent__ 回到最后创建的列表,在那里没有更多的 __parent__ 跟随.因此,在您的示例中,上下文将是 SpecialFactory 的实例,上下文的沿袭"是列表 [ SpecialFactory(request), Root(request) ].

The ACLAuthorizationPolicy starts at the context and goes backward through the "lineage" that object. The "lineage" is defined as the list created by following each object's __parent__ back to the end, where there is no more __parent__ to follow. So in your example, the context would be an instance of SpecialFactory, and the "lineage" of the context is the list [ SpecialFactory(request), Root(request) ].

ACL 匹配的工作方式(在 ACLAuthorizationPolicy 中)是它从上下文到根遍历沿袭中的每个对象,搜索每个对象的 __acl__命令.它找到的第一场比赛是赢家.ACL 中的条目由(Allow or Deny, principal, permission)"定义,匹配项为ACL 中包含我们正在寻找的相同权限的条目,因为主体与当前用户的有效主体列表中的主体之一相匹配.一旦找到匹配项,搜索就会停止并返回结果.

The way ACL matching works (in the ACLAuthorizationPolicy) is that it goes through each object in the lineage from the context back to the root, searching each object's __acl__ in order. The first match it finds is the winner. An entry in the ACL is defined by "(Allow or Deny, principal, permission)" and match is an entry in the ACL that contains the same permission we are looking for, as the the principal matches one of the principals in our list of effective principals for the current user. Once a match is found, searching stops and the result is returned.

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

If this algorithm doesn't work for you, replace the authorization policy. It's highly pluggable and the default implementation is easy to understand (totaling only a few lines of code). You could even make your own policy that doesn't care about the context at all, at which point you can ignore all this traversal nonsense. It's up to you.

这篇关于金字塔:多个资源工厂——如何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆