Metadata-Version: 1.1
Name: sqlalchemy-auth
Version: 1.2.2
Summary: Provides authorization mechanisms for SQLAlchemy
Home-page: https://github.com/dhiltonp/sqlalchemy_auth
Author: David P Hilton
Author-email: david.hilton.p@gmail.com
License: mit
Description-Content-Type: UNKNOWN
Description: Overview
        ========
        
        sqlalchemy\_auth provides authorization mechanisms for SQLAlchemy DB
        access.
        
        It is easy to use, and easy to bypass.
        
        1. You set a ``badge`` on a session, and receive a ``badge`` within a
           query.
        2. All mapped classes can add implicit filters on queries and implicit
           data on inserts.
        3. All mapped classes can selectively block attribute access.
        
        Your ``badge`` is shared between all queries and mapped class instances
        within a session.
        
        Getting Started
        ===============
        
        Session
        ~~~~~~~
        
        Create a session using the AuthSession and AuthQuery classes:
        
        .. code:: python
        
            Session = sessionmaker(bind=engine, class_=AuthSession, query_cls=AuthQuery, badge=DENY)
            session = Session()
        
        By default you don't need no stinking ``badge``. It is set to ``ALLOW``,
        bypassing all auth mechanisms. Change ``badge`` from ``ALLOW`` to enable
        authorization:
        
        .. code:: python
        
            session.badge=badge
        
        Temporarily switch ``badge``:
        
        .. code:: python
        
            with session.switch_badge(badge):
                ...
        
        ``badge`` can be anything (the current user, their role, etc.), and will
        be passed in to ``add_auth_filters`` or ``add_auth_insert_data`` (unless
        it's ``ALLOW`` or ``DENY``).
        
        Filters
        ~~~~~~~
        
        To add filters, define ``add_auth_filters``:
        
        .. code:: python
        
            class Data(Base):
                __tablename__ = "data"
        
                id = Column(Integer, primary_key=True)
                owner = Column(Integer)
                data = Column(String)
        
                @classmethod
                def add_auth_filters(cls, query, badge):
                    return query.filter_by(owner=badge.user_id)
        
        Inserts
        ~~~~~~~
        
        To add data on insert, define ``add_auth_insert_data``
        
        .. code:: python
        
            class Data(Base):
                __tablename__ = "data"
        
                id = Column(Integer, primary_key=True)
                owner = Column(Integer)
                data = Column(String)
        
                def add_auth_insert_data(self, badge):
                    self.owner = badge.user_id
        
        Default Filters and Inserts
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        If your ``Base`` inherits from ``AuthBase``, you will inherit no-op
        ``add_auth_filters`` and ``add_auth_insert_data`` methods.
        
        Attribute Blocking
        ~~~~~~~~~~~~~~~~~~
        
        To block attributes, inherit from the ``BlockBase`` class (you can also
        use mixins instead of ``declarative_base(cls=BlockBase)``):
        
        .. code:: python
        
            Base = declarative_base(cls=BlockBase)
        
            class AttributeCheck(Base):
                __tablename__ = "attributecheck"
        
                id = Column(Integer, primary_key=True)
                owner = Column(String)
                data = Column(String)
                secret = Column(String)
        
                def _blocked_read_attributes(self, badge):
                    if self.owner == badge.user_id:
                        return []
                    return ["secret"]
        
                def _blocked_write_attributes(self, badge):
                    return ["id", "owner"]
        
        Four convenience methods are defined: ``readable_attrs()``,
        ``read_blocked_attrs()`` and ``writable_attrs()``,
        ``write_blocked_attrs()``. Only public attributes are returned.
        
        Attribute blocking is only effective for instances of the mapped class.
        
        Gotchas
        =======
        
        One Badge per Session/Query/Objects Group
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        Only one badge exists between a session, its queries and returned
        objects. For example:
        
        .. code:: python
        
            session.badge = ALLOW
            query = session.query(Data)
            unfiltered = query.all()
        
            session.badge = badge
            filtered = query.all()
        
        In this example, ``unfiltered`` will contain all Data objects, but the
        same query later would return a ``filtered`` subset.
        
        Scoped Session Usage
        ~~~~~~~~~~~~~~~~~~~~
        
        To support ``scoped_session.query`` style syntax with ``badge`` and
        ``switch_badge``, you must run ``instrument_scoped_session`` on the
        value returned by ``sqlalchemy.orm.scoped_session()``.
        
        If you do not, setting ``badge`` will have no effect and calling
        ``switch_badge`` will raise
        ``AttributeError: 'scoped_session' object has no attribute 'switch_badge'``.
        
        Attribute Blocking Limitations
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        Attribute blocking relies on the object being an instance of the class
        with blocks. In the following example, ``add_auth_filters`` is applied,
        but blocks are not:
        
        .. code:: python
        
            obj = session.query(Class.attr, Class.blocked_attr).first()
            obj.blocked_attr = "foo"
        
        Similarly, ``update`` bypasses attribute blocks:
        
        .. code:: python
        
            query = session.query(Class.blocked).update({Class.blocked: "unchecked write"})
        
        --------------
        
        See auth\_query\_test.py for end-to-end examples.
        
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Database
Classifier: Operating System :: OS Independent
