我想基于Python eve restframework中用户的访问权限实现“更复杂”的过滤器。
我们有令牌身份验证,用户帐户是在TokenAuth
类中提取的。
用户有一些合同,每个合同都有账单。我想实施一个显示合同账单的终点/账单。我们使用mongodb
。
为了更好地理解,有些像SQL语句"SELECT * FROM bills WHERE bills.contract IN user.contracts"
user { contracts : ["a","b","c"] }
bills { contract: "a" }
class TokenAuth(TokenAuthBase):
def check_auth(self, token, allowed_roles, resource, method):
users = app.data.driver.db['users']
TokenAuth.account = users.find_one(lookup)
...
(更新)
对于 用户1:n账单 关系的情况,URRA将完成这项工作。见URRA in python eve docs。
在更复杂的情况下,有必要编写自定义过滤器查询。我需要这个选项:)。
我找到了解决方案,请参阅更新后的答案。
答案 0 :(得分:2)
那么Predefined Database Filters呢?
bills = {
'datasource': {
'source': 'bills',
'filter': {'field1': 'value1', 'field2': 'value2'}
}
}
source
是一个mongodb集合; filter
是一个mongodb查询。它将透明地应用于命中端点的任何请求(在客户端查询之前)。
答案 1 :(得分:2)
感谢Nicola Iaorcci,我找到了解决方案。
首先,我为每个端点使用自定义身份验证类。
class MyCreditNoteAuth(TokenAuthBase):
def check_auth(self, token, allowed_roles, resource, method):
account = app.data.driver.db['users'].find_one({'api_access_token': token})
此方法从mongodb获取用户的帐户,现在我可以访问他的合同ID。
第二,仍然在上面的方法中,我在每个请求上更新数据源的过滤器:
mynotes['datasource']['filter']['contract'] = { '$in': account['contracts'] }
现在,客户在给定的端点上只能看到自己的“笔记”。
答案 2 :(得分:1)
我认为在每个请求的基础上执行此操作可能会更好。修改'DOMAIN'
可能会导致多个人登录并同时发送请求,并且域之间的域发生变化,具体取决于您实现这类事情的方式。像这样的Mayby会起作用:
from eve import Eve
from eve.auth import BasicAuth
def pre_get_api_stuff(resource, request, lookup):
username = request.authorization['username']
accounts = app.data.driver.db['accounts']
account = accounts.find_one({'username': username})
if resource == 'notes':
lookup.update({'username': username})
app = Eve(auth=BasicAuth)
app.on_pre_GET += pre_get_api_stuff
答案 3 :(得分:0)
你有没有找到User-Restricted Resource Access?
快速浏览一下,我会说通过将您的帐单文档存储用户令牌(或ID,或任何标识您设置中的用户),然后在bills
端点启用URRA,就可以了
答案 4 :(得分:0)
更完整的示例如下,假设我们在settings.py
中有以下内容var info = client.Inbox.Fetch (new [] { 4442 }, MessageSummaryItems.Flags | MessageSummaryItems.GMailLabels);
if (info[0].Flags.Value.HasFlag (MessageFlags.Flagged)) {
// this message is starred
}
if (info[0].Flags.Value.HasFlag (MessageFlags.Draft)) {
// this is a draft
}
if (info[0].GMailLabels.Contains ("Important")) {
// the message is Important
}
auth附带了一个基于用户名的过滤器,过滤器的逻辑在这里很简单,但你可以在过滤器中添加任何你想要的东西
note_schema = {
'user_id': {
'type': 'objectid',
'required': True,
'readonly': True
}
}
user_schema = {
'username': {
'type': 'string',
'required': True,
'unique': True,
},
'password': {
'type': 'string',
'required': True,
},
'token': {
'type': 'string',
'required': True,
}
}
DOMAIN = {
'user': {
'schema': user_schema,
},
'note': {
'schema': note_schema,
},
}