Search code examples
pythonauthorizationaclpyramidformalchemy

Pyramid and FormAlchemy admin interface


I have a pyramid project using the formalchemy admin interface. I added the basic ACL authentication and the pyramid_formalchemy plugin always denys even though I am authenticated.

Any thoughts on how only allow authenticated users to use the pyramid_formalchemy admin interface?

The authorization policy was add like this:

authn_policy = AuthTktAuthenticationPolicy('MYhiddenSECRET', callback=groupfinder)
authz_policy = ACLAuthorizationPolicy()

config = Configurator(
   settings=settings,
   root_factory='package.auth.RootFactory',
   authentication_policy=authn_policy,
   authorization_policy=authz_policy
)

# pyramid_formalchemy's configuration
config.include('pyramid_formalchemy')
config.include('fa.jquery')
config.formalchemy_admin('admin', package='package', view='fa.jquery.pyramid.ModelView')

Solution

  • pyramid_formalchemy uses the permissions 'view', 'edit', 'delete', 'new' to determine who can do what. The __acl__ is propagated down from your SQLAlchemy model object. Thus, you need to put an __acl__ on each of your model objects allowing your desired groups access to those permissions. For example, from the pyramid_formalchemy pyramidapp example project:

    class Bar(Base):
        __tablename__ = 'bar'
        __acl__ = [
                (Allow, 'admin', ALL_PERMISSIONS),
                (Allow, 'bar_manager', ('view', 'new', 'edit', 'delete')),
            ]
        id = Column(Integer, primary_key=True)
        foo = Column(Unicode(255))
    

    Of course, if you do not supply an __acl__ then it will look in the lineage of the resource tree until it hits the factory. By default, pyramid_formalchemy defines its own factory pyramid_formalchemy.resources.Models, however you can subclass this and provide an __acl__ to it, as a global for all of your models:

    from pyramid_formalchemy.resources import Models
    
    class ModelsWithACL(Models):
        """A factory to override the default security setting"""
        __acl__ = [
                (Allow, 'admin', ALL_PERMISSIONS),
                (Allow, Authenticated, 'view'),
                (Allow, 'editor', 'edit'),
                (Allow, 'manager', ('new', 'edit', 'delete')),
            ]
    
    config.formalchemy_admin('admin', package='package', view=..., factory=ModelsWithACL)