目前,Eve v0.4 通过 'auth_field' 支持用户限制资源访问,但它似乎旨在自动处理单一所有者的情况。
您将如何启用多用户受限访问,如果用户的 id 包含在允许的 id 数组中,则允许用户查看资源?可能有多个列表用于单独的读取和写入权限。
目前,Eve v0.4 通过 'auth_field' 支持用户限制资源访问,但它似乎旨在自动处理单一所有者的情况。
您将如何启用多用户受限访问,如果用户的 id 包含在允许的 id 数组中,则允许用户查看资源?可能有多个列表用于单独的读取和写入权限。
我为 EVE 写了一个小技巧,添加了这个功能。也许这有点棘手,但它确实有效。
您需要为 EVE 更新 fdec 函数 auth.py:
def fdec(f):
@wraps(f)
def decorated(*args, **kwargs):
if args:
# resource or item endpoint
resource_name = args[0]
resource = app.config['DOMAIN'][args[0]]
if endpoint_class == 'resource':
public = resource['public_methods']
roles = resource['allowed_roles']
if request.method in ['GET', 'HEAD', 'OPTIONS']:
roles += resource['allowed_read_roles']
else:
roles += resource['allowed_write_roles']
elif endpoint_class == 'item':
public = resource['public_item_methods']
roles = resource['allowed_item_roles']
if roles and isinstance(roles, str):
items = app.data.driver.db[args[0]]
item = items.find_one(kwargs)
roles = item[roles]
if request.method in ['GET', 'HEAD', 'OPTIONS']:
roles += resource['allowed_item_read_roles']
else:
roles += resource['allowed_item_write_roles']
if callable(resource['authentication']):
auth = resource['authentication']()
else:
auth = resource['authentication']
else:
# home
resource_name = resource = None
public = app.config['PUBLIC_METHODS'] + ['OPTIONS']
roles = app.config['ALLOWED_ROLES']
if request.method in ['GET', 'OPTIONS']:
roles += app.config['ALLOWED_READ_ROLES']
else:
roles += app.config['ALLOWED_WRITE_ROLES']
auth = app.auth
if auth and request.method not in public:
if not auth.authorized(roles, resource_name, request.method):
return auth.authenticate()
return f(*args, **kwargs)
return decorated
return fdec
如您所见,我添加了一个条件: if isinstance(roles, str) 想法是,当您将字符串放入 allowed_roles 而不是 list 时,这意味着您指向此项目中的一个字段,其中包含用户列表. 因此,例如,我有下一个方案和组定义:
definition = {
'url': 'groups',
'item_title': 'group',
# only admins and apps are allowed to consume this endpoint
'cache_control': '',
'cache_expires': 0,
'id_field': 'url',
'schema': _schema,
'allowed_item_roles': 'users',
'additional_lookup': {
'url': 'regex("[\w]+")', # to be unique
'field': 'url',
},
}
_schema = {
'name': required_string, # group name
'url': unique_string, # group url - unique id
'users': { # list of users, who registered for this group
'type': 'list',
'scheme': embedded_object('accounts')
},
'items': { # list of items in the group
'type': 'list',
'scheme': embedded_object('items'),
},
'owner': embedded_object('accounts'),
'secret': {'type': 'string'}
}
如您所见,我有一个用户列表,这是我帐户的嵌入对象。下一步是更新角色身份验证。现在它应该看起来像:
def check_auth(self, token, allowed_roles, resource, method):
accounts = app.data.driver.db['accounts']
lookup = {'token': token}
if allowed_roles:
# only retrieve a user if his roles match ``allowed_roles``
lookup['username'] = {'$in': allowed_roles}
account = accounts.find_one(lookup)
if account and 'username' in account:
self.set_request_auth_value(account['username'])
if account:
self.request_auth_value = account['username']
return account is not None
所以它检查用户名是否在允许的角色中。最后一步是更新 EVE 中的 flaskapp.py 以支持 allowed_roles 中的字符串
def validate_roles(self, directive, candidate, resource):
""" Validates that user role directives are syntactically and formally
adeguate.
:param directive: either 'allowed_[read_|write_]roles' or
'allow_item_[read_|write_]roles'.
:param candidate: the candidate setting to be validated.
:param resource: name of the resource to which the candidate settings
refer to.
.. versionadded:: 0.0.4
"""
roles = candidate[directive]
if not (isinstance(roles, list) or isinstance(roles, str)):
raise ConfigException("'%s' must be list"
"[%s]." % (directive, resource))
无论如何,它仍然是一种解决方法,我不确定当每个项目有数千个用户时它是否会快速可靠地运行,但对于少量用户它可以工作。
希望它会有所帮助
用户受限资源访问本质上是一种机制,用于透明地存储创建文档的用户的 ID 以及文档本身。当用户回到端点时,他只能看到/编辑他自己的文档。存储文档时如何为文档分配多个“所有者”?
您是否研究过基于角色的访问控制?它可以满足您的要求,尽管在端点(不是文档)级别。