sqlalchemy - 如何为 Sqlalchemy 查询预筛选用户访问的最佳方式?

  显示原文与译文双语对照的内容
0 0

我一直不停的在sql alchemy配方在他们的wiki,但是不知道哪个又是最好的实现我想要做什么。

在我的表中的每一行都有一个与之关联user_id 。 现在,对于每一个查询,而用户当前登录的id,然后查询的条件进行查询的我对自己做的 我担心的是,开发人员可能会忘记将此过滤器添加到查询( 一个巨大的安全风险) 。 所以,我想设置一个全局过滤器* * * * * 根据当前用户为admin权限登录的用户能看到的内容。

感谢你的帮助。 谢谢

时间: 原作者:

0 0

下面是简化的重定义查询构造函数筛选所有模型查询( 包括关系) 。 可以将其传递到为 query_cls参数设置为 sessionmaker. 用户ID参数无需全局至于会话构造时已经可用。

class HackedQuery(Query):

    def get(self, ident):
        # Use default implementation when there is no condition
        if not self._criterion:
            return Query.get(self, ident)
        # Copied from Query implementation with some changes.
        if hasattr(ident, '__composite_values__'):
            ident = ident.__composite_values__()
        mapper = self._only_mapper_zero(
                    "get() can only be used against a single mapped class.")
        key = mapper.identity_key_from_primary_key(ident)
        if ident is None:
            if key is not None:
                ident = key[1]
        else:
            from sqlalchemy import util
            ident = util.to_list(ident)
        if ident is not None:
            columns = list(mapper.primary_key)
            if len(columns)!=len(ident):
                raise TypeError("Number of values doen't match number "
                                'of columns in primary key')
            params = {}
            for column, value in zip(columns, ident):
                params[column.key] = value
            return self.filter_by(**params).first()


def QueryPublic(entities, session=None):
    # It's not directly related to the problem, but is useful too.
    query = HackedQuery(entities, session).with_polymorphic('*')
    # Version for several entities needs thorough testing, so we 
    # don't use it yet.
    assert len(entities)==1, entities
    cls = _class_to_mapper(entities[0]).class_
    public_condition = getattr(cls, 'public_condition', None)
    if public_condition is not None:
        query = query.filter(public_condition)
    return query

它只适用于单个模型查询和有很多工作,使其适用于其他情况。 我想看到一个版本,因为它是必须功能对于大多数Web应用程序发生。 它使用固定条件存储在每个模型类中,所以你要对其进行修改以满足你的需求。

原作者:
0 0

这里有个非常naive 实现假定有attribute/property self.current_user登录用户具有存储。

class YourBaseRequestHandler(object):

    @property
    def current_user(self):
        """The current user logged in."""
        pass

    def query(self, session, entities):
        """Use this method instead of :method:`Session.query()
        <sqlalchemy.orm.session.Session.query>`.

        """
        return session.query(entities).filter_by(user_id=self.current_user.id)
原作者:
0 0

我写了一个SQLAlchemy扩展我认为确实如你可以描述: https://github .com/mwhite/multialchemy

它是通过代理方式更改 Query._from_objQueryContext._froms属性,这正是表格中进行选择最终得到设置。

原作者:
...