我正在尝试为我正在构建的应用程序工具箱创建一个安全系统。我之前有一个acl,但问题是我无法控制基于应用程序的级别。
基本上,我认为我需要的是将应用程序GUID传递给groupfinder()
function,我不知道应该怎么做。
有人有什么想法吗?
答案 0 :(得分:4)
金字塔中的groupfinder
和context factory
旨在单独操作并单独运行。前者用于定义当前用户"后者用于定义当前资源"。这两项最终通过授权政策permission
功能与permits
合并,以确定当前用户是否为"有"许可"对这个"资源进行操作"。
groupfinder
负责识别用户。这意味着将它们转换为一组可以在以后使用的主体。
context factory
确定当前资源(上下文)...因此每个网址通常应该不同(请记住URL中的R是资源),因此网址通常定义资源。
附加到网址的视图定义了所需的permission
(对于视图正在执行的操作)。
这里的第二步是人们在来到金字塔时最难以理解的。如何为每个URL定义此资源?它包含在网址发送教程[1]中,但我会在这里快速解释。
如上所述,每条路由通常代表一个资源,因此我们可以通过为该路由定义一个对象将其放入代码中。这是通过factory
的{{1}}参数完成的,它可以通过路径做很多事情来确定当前资源是什么。
config.add_route(..., factory=...)
此代码段定义了一个包含页面工厂的路径,并且附加到此路径的每个视图都将该页面作为上下文(def page_factory(request):
# I'm attached to a page so I can grab the matchdict
pageid = request.matchdict['pageid']
page = request.db.query(Page).get(pageid)
if page is None:
raise HTTPNotFound
return page
config.add_route('page', '/pages/{pageid}', factory=page_factory)
)。
这里的request.context
对象有一个ACL,用于定义允许哪些用户/组(主体)对其执行操作(权限)。
Page
假设此页面附加到app1,我们可以轻松定义一个groupfinder,说app1中的任何人都可以读取它:
class Page(Base):
__tablename__ = 'page'
# a bunch of columns
def __acl__(self):
return [
(Allow, f'app:{self.app.id} user:{self.owner_id}', 'edit'),
(Allow, f'app:{self.app.id}', 'read'),
]
组查找器不了解页面,但它描述的用户具有足够的粒度,以便页面可以与它们允许的操作相匹配。
[1] https://docs.pylonsproject.org/projects/pyramid/en/1.9-branch/tutorials/wiki2/authorization.html