2013-04-23 68 views
4

我有一個簡單的根資源工廠:金字塔:多個資源工廠 - 如何

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__充分的宗旨,它應設置爲。

此外,金字塔何時會遍歷__parent__鏈,何時不會?對於這樣的觀點的配置:

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

將金字塔 '收集' 這兩種權限(special_editedit),或只是一個(special_edit)?

請詳細解釋計算權限的「流程」。

回答

12

__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,所以遍歷不會去任何地方,它只會返回根對象作爲上下文。查找上下文對象是遍歷運算的整個目標。

所以,現在我們有一個上下文。好極了。

金字塔的授權通過將用戶的「有效原則」與「上下文」和「許可」結合起來。這三件事是您的授權策略將用於確定操作是被允許還是被拒絕。

「有效負責人」來自身份驗證策略,代表請求背後的用戶。

「上下文」和「許可」是你想要的。在大多數情況下,它們是request.context和視圖的權限,但是pyramid.security.has_permission()可以接受任何上下文對象和任何權限並返回給您允許或拒絕結果。

所以,我們已經得到了3個需要的授權內容。現在,如何授權?那是由授權政策決定的。默認情況下,ACLAuthorizationPolicy。那麼它是怎樣工作的?

ACLAuthorizationPolicy開始在context並通過對象的「血統」後退。 「血統」被定義爲通過追溯每個對象的__parent__創建的列表,其中不再有__parent__。因此,在您的示例中,上下文將是SpecialFactory的實例,並且上下文的「譜系」是列表[ SpecialFactory(request), Root(request) ]

ACL匹配工作方式(在ACLAuthorizationPolicy中)的方式是它沿着上下文中的每個對象從上下文返回到根,按順序搜索每個對象的__acl__。它發現的第一場比賽是勝利者。 ACL中的條目由「(AllowDeny,principal,permission)」定義,並且match是包含我們正在查找的相同許可的ACL中的條目,因爲委託人與我們的列表中的一個委託人匹配爲當前用戶提供有效的校長。一旦找到匹配,搜索停止並返回結果。

如果此算法不適用於您,請替換授權策略。它具有高度的可插拔性,默認的實現很容易理解(總共只有幾行代碼)。你甚至可以制定自己的策略,根本不關心上下文,在這一點上,你可以忽略所有這些遍歷的廢話。隨你便。