Python-eve Rest Api Framework中依赖于用户的资源过滤器

时间:2014-03-08 13:42:07

标签: python api rest authentication eve

我想基于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)
       ...

(更新)

用户限制资源访问¶(URRA)

对于 用户1:n账单 关系的情况,URRA将完成这项工作。见URRA in python eve docs

在更复杂的情况下,有必要编写自定义过滤器查询。我需要这个选项:)。

更新

我找到了解决方案,请参阅更新后的答案。

5 个答案:

答案 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,
    },
}