0
我試圖在URL調度應用程序中實現動態ACL(包括行級安全性)。 定義Root工廠似乎不夠,因爲我需要爲每個安全端點執行單獨的authz檢查。我的設置如下所示(我用的是pyramid docs和mmerickel's tutorials爲指導):金字塔:URL調度(混合)應用程序中的資源樹
config.py
...
settings = config.registry.settings
config = Configurator(settings=settings, root_factory=RootPermissionFactory)
config.set_authentication_policy(CustomAuthenticationPolicy(settings))
config.set_authorization_policy(ACLAuthorizationPolicy())
...
views.py
#import ...
@view_defaults(renderer='json', permission='secured')
class RecordsView(object):
...
@view_config(request_method='GET', route_name='records_by_id')
def get(self):
record = self.request.context.data
if not record:
return HTTPNotFound()
return record
@view_config(request_method='GET', route_name='records')
def get_by_owners(self):
owner_uids = self.request.params.mixed()['owner_uids']
return records_service.get_records(owner_uids=owner_uids)
def includeme(config):
config.add_route('records', '/records', factory=RecordsResource)
config.add_route('records_by_id', 'records/{record_id}', factory=RecordFactory, traverse='{record_id}')
authorization.py
class RootPermissionFactory(object):
__name__ = None
__parent__ = None
def __acl__(self):
return [
(Allow, 'authenticated_principal', 'secured'),
]
def __init__(self, request):
self.request = request
class RecordFactory(object):
def __init__(self, request):
self.request = request
def __getitem__(self, key):
record_data = records_service.get_record(key)
owner = record_data.get('owner_uid')
return RecordContext(self.request, owner, record_data)
class RecordContext(object):
def __acl__(self):
owner_principal = 'u:{owner}'.format(owner=self.owner)
return [
(Allow, owner_principal, 'secured'),
]
def __init__(self, request, owner, record_data):
self.request = request
self.owner = owner
self.data = record_data
class RecordsResource(object):
def __acl__(self):
request_params = self.request.params.mixed()
request_owner_uids = request_params['owner_uids']
authorized_owner_uids = owners_api_service.get_authorized_owners(self.request.user['auth_data'])
return [(Allow, 'authenticated_principal', 'secured')]\
if set(authorized_owner_uids) == set(request_owner_uids) else []
def __init__(self, request):
self.request = request
我的問題是以下幾點:
- 在沒有Model層的情況下利用行級安全檢查是否可以接受?即沒有爲記錄數據設置ORM,並且也沒有簡單的模型來保存數據,所以我必須使用'假'
RecordContext
類附加__acl__
規則並將數據傳遞到視圖 - 是否可以接受盡管事實上它不是來自Traversal透視圖的資源,並且依賴於查詢參數而不是路徑部分,但將端點視爲資源?