2013-04-23 4 views
4

У меня есть простой корень ресурса завод:Pyramid: несколько заводов ресурсов - как

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_edit и edit) или только один (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 определяется как «(Allow или Deny, principal, permission)», а совпадение - это запись в ACL, которая содержит то же разрешение, которое мы ищем, так как руководитель соответствует одному из принципов в нашем списке эффективные принципы для текущего пользователя. Как только совпадение найдено, поиск останавливается и результат возвращается.

Если этот алгоритм не работает для вас, замените политику авторизации. Он очень подключен, и реализация по умолчанию легко понять (всего лишь несколько строк кода). Вы даже можете сделать свою собственную политику, которая не заботится о контексте вообще, и в этот момент вы можете игнорировать всю эту обходную глупость. Тебе решать.