出于本次讨论的目的,我将假设您正在使用 SQLAlchemy 与您的数据库交互。
如果您有config.add_route('pages', '/pages/{id}')
,__init__.py
您可以添加自定义工厂来替换/补充您的默认 ACL。例如:
您当前的 ACL 可能如下所示:
class RootFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'auth'),
]
def __init__(self, request):
self.request = request
这将允许经过身份验证的用户访问具有“auth”权限的任何视图,并且任何访问您的站点的人都可以访问具有“视图”权限的任何视图。
通过使用自定义工厂,您可以绕过您的 RootFactory,或对其进行补充。
要绕过,请将原来的 config.add_route 更改为-->config.add_route('pages', '/pages/{id}', factory=PageFactory)
并创建一个 PageFactory 类,如下所示:
class PageFactory(object):
__acl__ = [
(Allow, Everyone, 'view'),
(Allow, Authenticated, 'auth'),
]
def __init__(self, request):
self.request = request
from pyramid.security import authenticated_userid
user_id = authenticated_userid(self.request)
thispage = DBSession.query(Page).filter(Page.id==self.request.matchdict['id']).first()
if thispage.user_id == user_id:
## Pyramid allows Everyone, Authenticated, and authenticated_userid
## (each of these is known as a Principal) to be in the second
## position of the ACL tuple
acl.append((Allow, user_id, 'edit'))
这是假设您的视图具有permission='edit'
作为其参数之一。
现在,如果您想使用 RootFactory 并用您的自定义工厂对其进行补充,那么您不必重复自己,只需像我在本文开头所展示的那样留下 RootFactory,并从 RootFactory 类继承, 像这样:
class PageFactory(RootFactory):
@property
def __acl__(self):
acl = super(PageFactory, self).__acl__[:] ##[:] creates a copy
from pyramid.security import authenticated_userid
user_id = authenticated_userid(self.request)
thispage = DBSession.query(Page).filter(Page.id==self.request.matchdict['id']).first()
if thispage.user_id == user_id:
acl.append((Allow, user_id, 'edit'))
return acl
顺便说一下,groupfinder非常有用,因为您可以简单地将用户放在组中,例如“admin”,并且 admin 组中的所有用户都可以访问您可能想要的视图permission='whatever'
,permission='whateverelse'
并且不需要工厂,只需要一个返回当前用户的组列表的 groupfinder。唉,我离题了,因为这不是你想要做的。希望这能回答你的问题。