Coder Social home page Coder Social logo

ergo / ziggurat_foundations Goto Github PK

View Code? Open in Web Editor NEW
71.0 13.0 22.0 732 KB

Framework agnostic set of sqlalchemy classes that make building applications that require permissions an easy task.

License: BSD 3-Clause "New" or "Revised" License

Python 98.55% Mako 0.18% Shell 0.56% Dockerfile 0.71%
python pyramid flask sqlalchemy permissions mixins security permission authorization authentication

ziggurat_foundations's Introduction

Ziggurat Foundations

Build Status logo

DOCUMENTATION: http://readthedocs.org/docs/ziggurat-foundations/en/latest/

BUG TRACKER: https://github.com/ergo/ziggurat_foundations

High level mixins for adding authorization, resource ownership and permission management fast, simple and easy. In summary, Ziggurat Foundations is a set of framework agnostic set of SQLAalchemy classes, so it can be used with Flask, Pyramid or other popular frameworks. It is the perfect solution for handling complex login and user management systems, from e-commerce systems, to private intranets or large CMS systems. It can easily be extended to support any additional features you may need (explained further in the documentation)

Zigg has been used (at scale) for very large implementations (millions of real users) and has been extended for custom applications such as geo-location applications that rely on pin-point accuracy for a users location. Zigg has been designed to work for high end environments, where the user(s) are at the main focus of the application (for example Zigg could become the backbone for a social media style application).

The aim of this project is to supply set of generic models that cover the most common needs in application development when it comes to authorization - using flat and tree like data structures. We provide most commonly needed features in a "standard" application, but provide them as mixins as we understand that every implementation has its own use case and in doing so, extending the base models is very easy.

Zigg supplies extendable, robust and well tested models that include:

  • User - base for user accounts
  • Group - container for many users
  • Resource - Arbitrary database entity that can represent various object hierarchies - blogs, forums, cms documents, pages etc.

Zigg provides standard functions that let you:

  • Assign arbitrary permissions directly to users (ie. access certain views)
  • Assign users to groups
  • Assign arbitrary permissions to groups
  • Assign arbitrary resource permissions to users (ie. only user X can access private forum)
  • Assign arbitrary resource permissions to groups
  • Manage nested resources with tree service
  • Assign a user o an external identity (such as facebook/twitter)
  • Manage the sign in/sign out process
  • Change users password and generate security codes
  • Example root context factory for assigning permissions per request (framework integration)

Ziggurat Foundations is BSD Licensed

Local development using docker

docker-compose run --rm app bash
cd ../application;

To run sqlite tests:

tox

To run postgres tests:

DB_STRING="postgresql://test:test@db:5432/test" DB=postgres tox

To run mysql tests:

DB_STRING="mysql+mysqldb://test:test@db_mysql/test" DB=mysql tox

ziggurat_foundations's People

Contributors

arianmaykon avatar crooksey avatar ekarlso avatar ergo avatar fmigneault avatar gitter-badger avatar jochumdev avatar marcinkuzminski avatar peletiah avatar stevepiercy avatar tdamsma avatar themightyonyx avatar timgates42 avatar umeboshi2 avatar uralbash avatar utek avatar virhilo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ziggurat_foundations's Issues

Facing issue in Ziggurat foundation migration on MySQL 8.x

We are using ziggurat foundation (version 0.7.3) in our project for users, groups maintenance.

So when we do the setup for the first time for any developer we run the Ziggurat foundation migration script. We recently noticed that for a given user on MySQL 8.x we are facing this error

Note : One more data point this migration works fine on MySQL 5.x.

At the migration step '4c10d97c509' we get following error sqlalchemy.exc.ProgrammingError: (_mysql_exceptions.ProgrammingError) (1064, “You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘groups where groups.group_name=groups_permissions.group_name)’ at line 2”) [SQL: u’update groups_permissions set group_id = \n (select id from groups where groups.group_name=groups_permissions.group_name)’] (Background on this error at: http://sqlalche.me/e/f405).

Incorrect PermissionTuple for direct_perms_for_user in the case when user own the Resource

Hi,

When requesting user is the owner of the resource, an incorrect tuple is about to be created.

Trival steps to reproduce the error. If it will not enough I will add some more code.

user = User(...)
resource = Resource(...)
resource.owner = user
ResourceService.direct_perms_for_user(resource, user)

Causes:

        if instance.owner_user_id == user.id:
            perms.append(
>               PermissionTuple(user, ALL_PERMISSIONS, "user", None, instance, True)
            )
E           TypeError: __new__() missing 1 required positional argument: 'allowed'

I've checked tests and there is no case when this situation is tested.
Fix will be really simple because it looks like this particular condition was overlooked in some kind of refactoring:

# include all perms if user is the owner of this resource
if instance.owner_user_id == user.id:
    perms.append(
        PermissionTuple(user, ALL_PERMISSIONS, "user", None, instance, True, True) #  Missing positional argument
    )

Affected version:

ziggurat-foundations    0.8.3

0.4 version on PyPi

Hi,
I use some features from 0.4 version(master branch), but this version is not on PyPi

decrease identifiers

In oracleDB names must be from 1 to 30 bytes long.
may you decrease names to be less than 30? if you do this it is possible to use ziggurat_foundations with oracleDB.

[support] Vanilla Pyramid project - how to "get_db_session", RootFactory acl not working out of the box

I'm having trouble following the configuration and usage guide. Is it ok to ask for support here?

I've setup a Pyramid project with SQLAlchemy-scaffold and added all the configuration-changes as described in the docs.

First thing I'm running into is an issue with get_db_session:

Getting DBSession

In my models.py DBSession is defined as

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

This is the alchemy-scaffold default. Shouldn't ziggurat_foundations.models.base.get_db_session be able to find myapp.models.DBSession?
Since that didn't work for me, I can make basic login work with the other two approaches that are pointed out in the docs ("get_session_callable" and "ziggurat_foundations.models.DBSession = DBSession"). But should it work without these definitions?

Permissions not working as expected

The second issue is the view-permission. Clearly my users permissions are added to the RootFactory's acl:

log.debug(self.__acl__)
2015-12-14 19:36:30,202 DEBUG [pyramid_ziggurat_auth_demo.models:102][waitress] [('Allow', 'system.Authenticated', u'view'), ('Allow', u'editor', u'edit'), ('Allow', u'editor', u'delete')]

but it is not honored when I try to access a view with a permission (E.g. I have a "edit_note"-view with an "edit"-permission which should be accessible when user "editor" is logged in).

When I switch the permission to "view", it works for authenticated users (As expected) - but not the dynamic permission in the acl.

What am I missing?

I've uploaded the full code I'm using to https://github.com/peletiah/ziggurat_auth_demo (incl. DB-dump)

Release version for SQLAlchemy 1.4

Hi @ergo

I encountered the following error with new SQLAlchemy==1.4

>Textual column expression 'depth' should be explicitly declared with text('depth'), or use column('depth') for more specificity

when reaching the following code ziggurat_foundations.models.services.resource_tree_postgres.ResourceTreeServicePostgreSQL.from_parent_deeper

query = db_session.query(cls.model, "depth", "sorting", "path")

I see that you have already pushed the needed fix (add column()). Thanks for the quick patch!
Is it possible to have a new version released soon?

question: A way to implement roles in ziggurat_foundations

Hi Ergo,

In my app, i'll have a lot of permissions which i want to group by roles.

My first thought on howto implement that was by adding a property "is_role" to "Groups" and use that,
what do you think about that?

AND is is_role something you wanna see in ziggurat_foundations or not?

Thanks,
René

Error on alembic migrations from docs

Following
https://ziggurat-foundations.readthedocs.org/en/latest/configuration.html#configure-ziggurat-with-pyramid-framework
on the Wiki2 Pyramid Tutorial
gives some errors on the initial migration step ($VENV/bin/alembic upgrade head).

I'm using Python 3.5.1 and Pyramid 1.6.1, here's the output:

(.venv) ➜  tutorial $VENV/bin/alembic upgrade head
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 2bb1ba973f0b, initial table layout
INFO  [alembic.runtime.migration] Running upgrade 2bb1ba973f0b -> 24ab8d11f014, add external identity tables
INFO  [alembic.runtime.migration] Running upgrade 24ab8d11f014 -> 5c84d7260c5, add id/parent id to resource structure
INFO  [alembic.runtime.migration] Running upgrade 5c84d7260c5 -> 46a9c4fb9560, make password hash field bigger
INFO  [alembic.runtime.migration] Running upgrade 46a9c4fb9560 -> 264049f80948, create ordering column
INFO  [alembic.runtime.migration] Running upgrade 264049f80948 -> 2d472fe79b95, bigger identity datatypes
Traceback (most recent call last):
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context
    context)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 226, in execute
    self.errorhandler(self, exc, value)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 217, in execute
    res = self._query(query)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 378, in _query
    rowcount = self._do_query(q)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 341, in _do_query
    db.query(q)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/connections.py", line 280, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.DataError: (1171, 'All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/bin/alembic", line 9, in <module>
    load_entry_point('alembic', 'console_scripts', 'alembic')()
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/config.py", line 479, in main
    CommandLine(prog=prog).main(argv=argv)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/config.py", line 473, in main
    self.run_cmd(cfg, options)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/config.py", line 456, in run_cmd
    **dict((k, getattr(options, k)) for k in kwarg)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/command.py", line 174, in upgrade
    script.run_env()
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/script/base.py", line 397, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/util/pyfiles.py", line 93, in load_python_file
    module = load_module_py(module_id, path)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/util/compat.py", line 68, in load_module_py
    module_id, path).load_module(module_id)
  File "<frozen importlib._bootstrap_external>", line 385, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 806, in load_module
  File "<frozen importlib._bootstrap_external>", line 665, in load_module
  File "<frozen importlib._bootstrap>", line 268, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 693, in _load
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 662, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "/Users/maykon/.python-eggs/ziggurat_foundations-0.6.2-py3.5.egg-tmp/ziggurat_foundations/migrations/env.py", line 85, in <module>
    run_migrations_online()
  File "/Users/maykon/.python-eggs/ziggurat_foundations-0.6.2-py3.5.egg-tmp/ziggurat_foundations/migrations/env.py", line 78, in run_migrations_online
    context.run_migrations()
  File "<string>", line 8, in run_migrations
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/runtime/environment.py", line 797, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/runtime/migration.py", line 312, in run_migrations
    step.migration_fn(**kw)
  File "/Users/maykon/.python-eggs/ziggurat_foundations-0.6.2-py3.5.egg-tmp/ziggurat_foundations/migrations/versions/2d472fe79b95_bigger_identity_data.py", line 19, in upgrade
    type_=sa.String(255), existing_type=sa.String(50))
  File "<string>", line 8, in alter_column
  File "<string>", line 3, in alter_column
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/operations/ops.py", line 1414, in alter_column
    return operations.invoke(alt)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/operations/base.py", line 318, in invoke
    return fn(self, operation)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/operations/toimpl.py", line 53, in alter_column
    **operation.kw
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/ddl/mysql.py", line 67, in alter_column
    else existing_autoincrement
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/alembic-0.8.6-py3.5.egg/alembic/ddl/impl.py", line 118, in _exec
    return conn.execute(construct, *multiparams, **params)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 914, in execute
    return meth(self, multiparams, params)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/sql/ddl.py", line 68, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 968, in _execute_ddl
    compiled
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1146, in _execute_context
    context)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1341, in _handle_dbapi_exception
    exc_info
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 200, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 183, in reraise
    raise value.with_traceback(tb)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context
    context)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute
    cursor.execute(statement, parameters)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 226, in execute
    self.errorhandler(self, exc, value)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 217, in execute
    res = self._query(query)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 378, in _query
    rowcount = self._do_query(q)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/cursors.py", line 341, in _do_query
    db.query(q)
  File "/Users/maykon/Projects/pyramid_tutorial/.venv/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-macosx-10.11-x86_64.egg/MySQLdb/connections.py", line 280, in query
    _mysql.connection.query(self, query)
sqlalchemy.exc.DataError: (_mysql_exceptions.DataError) (1171, 'All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead') [SQL: 'ALTER TABLE external_identities MODIFY external_id VARCHAR(255) NULL']

ensure all contributors are listed in the authors file

Unable to do initial alembic migration: fails on 'groups pkey change'

Hi,

Using Python 3.5 in a virtualenv with the following distribs installed:
mysqlclient==1.3.7
bcrypt==2.0.0
ziggurat_foundations==0.6.2
SQLAlchemy==1.0.12

I'm having an error when doing the initial alembic migration:

$ alembic upgrade head
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 2bb1ba973f0b, initial table layout
[...]
INFO  [alembic.runtime.migration] Running upgrade 53927300c277 -> 3cfc41c4a5f0, groups pkey change
/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/alembic/util/langhelpers.py:122: UserWarning: Argument 'cols' is now named 'columns' for method create_primary_key().
  oldname, newname, fn_name
Traceback (most recent call last):
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/SQLAlchemy-1.0.12-py3.5.egg/sqlalchemy/engine/base.py", line 1139, in _execute_context
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/SQLAlchemy-1.0.12-py3.5.egg/sqlalchemy/engine/default.py", line 450, in do_execute
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/cursors.py", line 226, in execute
    self.errorhandler(self, exc, value)
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/cursors.py", line 217, in execute
    res = self._query(query)
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/cursors.py", line 378, in _query
    rowcount = self._do_query(q)
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/cursors.py", line 341, in _do_query
    db.query(q)
  File "/home/mike/.virtualenvs/tiime-backend/lib/python3.5/site-packages/mysqlclient-1.3.7-py3.5-linux-x86_64.egg/MySQLdb/connections.py", line 280, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1833, "Cannot change column 'group_name': used in a foreign key constraint 'fk_groups_permissions_group_name_groups' of table 'testdb.groups_permissions'")

The DB I'm doing my test on was dropped and recreated prior to the test.

Resource not found on delete branch with tree service

Using resource_tree_service = ResourceTreeService(ResourceTreeServicePostgreSQL),
I call resource_tree_service.delete_branch(resource_id=resource.resource_id, db_session=request.db),
which causes a resource to not be found after in passes:

resource = ResourceService.lock_resource_for_update(
resource_id=resource_id, db_session=db_session
)

If I use list(query.filter(cls.model.resource_id == resource_id)) instead WITHOUT the with_for_update() call, the resource is correctly retrieved. With it, it returns None.
Any idea why I might be getting this behavior suddenly?
I have been using the same method resource_tree_service.delete_branch(...) for as long as I can remember and resources where properly removed.

Warning "all => service" but no service available

When calling BaseModel.all(), we receive a deprecation warning asking to use the corresponding service, but many model types don't have such service.
I'm thinking about UserGroupMixin for instance, but there could be other.
Other services should be implemented, or adjust the warning accordingly.

Ziggurat-foundations 0.8.2 is not working with pyramid version 1.10.2

I have the following code in my init.py
config.include('ziggurat_foundations.ext.pyramid.get_user')

This line fails in Pyramid version 1.10.2 and get the following error 'AttributeError: set_request_property' and I think we need to change the file get_user.py line #47 from -
config.set_request_property(get_user, "user", reify=True)
To
config.add_request_method(get_user, "user", reify=True)

Differences when running alembic with my own versions

I run alembic with 2 different versions multi versions alembic.

My Models for RBAC looks like these:

import ziggurat_foundations.models
from ziggurat_foundations.models.base import BaseModel
from ziggurat_foundations.models.external_identity import ExternalIdentityMixin
from ziggurat_foundations.models.group import GroupMixin
from ziggurat_foundations.models.group_permission import GroupPermissionMixin
from ziggurat_foundations.models.group_resource_permission import GroupResourcePermissionMixin
from ziggurat_foundations.models.resource import ResourceMixin
from ziggurat_foundations.models.user import UserMixin
from ziggurat_foundations.models.user_group import UserGroupMixin
from ziggurat_foundations.models.user_permission import UserPermissionMixin
from ziggurat_foundations.models.user_resource_permission import UserResourcePermissionMixin
from ziggurat_foundations import ziggurat_model_init
from .meta import Base
import sqlalchemy as sa

class RbacVersion(Base):
    __tablename__ = 'alembic_ziggurat_foundations_version'

    version_num = sa.Column(sa.VARCHAR(length=32), autoincrement=False, nullable=False, primary_key=True)

# Base is sqlalchemy's Base = declarative_base() from your project
class Group(GroupMixin, Base):
    pass

class GroupPermission(GroupPermissionMixin, Base):
    pass

class UserGroup(UserGroupMixin, Base):
    pass

class GroupResourcePermission(GroupResourcePermissionMixin, Base):
    pass

class Resource(ResourceMixin, Base):
    # ... your own properties....

    # example implementation of ACLS for pyramid application
    @property
    def __acl__(self):
        acls = []

        if self.owner_user_id:
            acls.extend([(Allow, self.owner_user_id, ALL_PERMISSIONS,), ])

        if self.owner_group_id:
            acls.extend([(Allow, "group:%s" % self.owner_group_id,
                          ALL_PERMISSIONS,), ])
        return acls

class UserPermission(UserPermissionMixin, Base):
    pass

class UserResourcePermission(UserResourcePermissionMixin, Base):
    pass

class User(UserMixin, Base):
    # ... your own properties....
    pass

class ExternalIdentity(ExternalIdentityMixin, Base):
    pass

ziggurat_model_init(User, Group, UserGroup, GroupPermission, UserPermission,
               UserResourcePermission, GroupResourcePermission, Resource,
               ExternalIdentity, passwordmanager=None)

And my alembic.ini

# A generic, single database configuration.

[alembic_rbac]
script_location = ziggurat_foundations:migrations
sqlalchemy.url = postgresql://pyramid_test:[email protected]/pyramid_test

[alembic_drawstack]
script_location = drawstack:migrations
sqlalchemy.url = postgresql://pyramid_test:[email protected]/pyramid_test

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

Now alembic -n alembic_drawstack revision --autogenerate -m "Initial Commit" produces the following file.

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('uq_groups_group_name', 'groups', type_='unique')
    op.create_index(op.f('ix_resources_owner_group_id'), 'resources', ['owner_group_id'], unique=False)
    op.create_index(op.f('ix_resources_owner_user_id'), 'resources', ['owner_user_id'], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_resources_owner_user_id'), table_name='resources')
    op.drop_index(op.f('ix_resources_owner_group_id'), table_name='resources')
    op.create_unique_constraint('uq_groups_group_name', 'groups', ['group_name'])
    # ### end Alembic commands ###

Can you/we remove these?

Problem using Pylons/webtest

I'm trying to use Pylons/webtest for validation of my app.

In normal conditions, using ziggurat_foundations.ext.pyramid.sign_in with ziggurat_foundations.sign_in.sign_in_pattern = /signin_internal in my config, I can successfully route the app url using ziggurat.routes.sign_in. Login works as intended.

When using the same procedure with webtest.TestApp, the /signin_internal route returns an 500 response caused by HTTPConnectionPool with max retries exceeded, like if the path didn't exist.

Integration between pyramid and ziggurat seems to be very advanced and solid, so I'm wondering what could be the source of this problem? Any leads or suggestions where to investigate for error causes?

Documentation: how to add a permission to a view

I'm coming at Pyramid fresh (as in, I haven't learned its vanilla permission system) and I'm struggling to see how to create a view using decorators that is only for a logged in user, or one that is for a logged in user who has a certain permission, and then a certain permission for a certain object.

E.g. Django for case 1:

@login_required
def my_view(request):
    ...

Case 2:

@permission_required('polls.can_vote')
def my_view(request):
    ...

Case 3 (django-guardian syntax):

@permission_required_or_403('auth.change_object', (MyObject, 'object', 'object_name'))
def edit_object(request, object_name):
    ....

I'm sure it's just a docs issue, but can I do the same sort of decorated permissions with ziggurat_foundations?

New version for SQLAlchemy 2.0

Hi @ergo,

Enabling SQLALCHEMY_WARN_20=1 in preparation of updating it, I encountered the warnings already fixed by #72.
Will a new version be released soon to pin it in requirements?

Thanks

Inconsistency in the documentation - "login" vs. "username"

In the documentation you are using "username" in the configuration but "login" in the example-template. As a new user who hasn't fully grasped the concept it took me a while to figure out that this is the cause why my login fails.
It's obvious after the fact, but only after some clumsy debugging and sifting through ziggurat_foundations.ext.pyramid.sign_in I realized my stupid mistake.
Maybe you could homogenize that in the docs?

And rather than just routing you to ZigguratSignInBadAuth wouldn't it be nicer if an error was thrown that the respective login-keyword could not be found in the request-body?

Exception: The model should have implemented __acl__

I'm running into this exception when following the documentation regarding "resource based pyramid context factory"

It's caused by this line from the example:

# append basic resource acl that gives all permissions to owner
self.__acl__ = self.resource.__acl__

Where am I supposed to define these acl and what's the purpose? Would this be a static acl, similar to RootFactory?
DB-based permissions are not affected when I remove this line, so I'm not sure if I need to worry about it?! Please kindly clarify!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.