Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can do this using the <code>ACLAuthorizationPolicy</code> combined with URL Dispatch by using a custom resource tree designed for this purpose.</p> <p>For example, you have permissions for <code>Foo</code> objects, and permissions for <code>Bar</code> objects. These ACLs can be found by traversing the resource tree using the urls:</p> <pre><code>/foos/{obj} /bars/{obj} </code></pre> <p>Your resource tree then becomes a hierarchy of permissions, where at any point in the tree you can place an <code>__acl__</code> on the resource object:</p> <pre><code>root (Root) |- foos (FooContainer) | `- {obj} (Foo) `- bars (BarContainer) `- {obj} (Bar) </code></pre> <p>You can represent this hierarchy in a resource tree:</p> <pre class="lang-py prettyprint-override"><code>class Root(dict): # this is the root factory, you can set an __acl__ here for all resources __acl__ = [ (Allow, 'admin', ALL_PERMISSIONS), ] def __init__(self, request): self.request = request self['foos'] = FooContainer(self, 'foos') self['bars'] = BarContainer(self, 'bars') class FooContainer(object): # set ACL here for *all* objects of type Foo __acl__ = [ ] def __init__(self, parent, name): self.__parent__ = parent self.__name__ = name def __getitem__(self, key): # get a database connection s = DBSession() obj = s.query(Foo).filter_by(id=key).scalar() if obj is None: raise KeyError obj.__parent__ = self obj.__name__ = key return obj class Foo(object): # this __acl__ is computed dynamically based on the specific object @property def __acl__(self): acls = [(Allow, 'u:%d' % o.id, 'view') for o in self.owners] return acls owners = relation('FooOwner') class Bar(object): # allow any authenticated user to view Bar objects __acl__ = [ (Allow, Authenticated, 'view') ] </code></pre> <p>With a setup like this, you can then map route patterns to your resource tree:</p> <pre class="lang-py prettyprint-override"><code>config = Configurator() config.add_route('item_options', '/item/{item}/some_options', # tell pyramid where in the resource tree to go for this url traverse='/foos/{item}') </code></pre> <p>You will also need to map your route to a specific view:</p> <pre class="lang-py prettyprint-override"><code>config.add_view(route_name='item_options', view='.views.options_view', permission='view', renderer='item_options.mako') </code></pre> <p>Great, now we can define our view and use the loaded context object, knowing that if the view is executed, the user has the appropriate permissions!</p> <pre class="lang-py prettyprint-override"><code>def options_view(request): foo = request.context return { 'foo': foo, } </code></pre> <p>Using this setup, you are using the default <code>ACLAuthorizationPolicy</code>, and you are providing row-level permissions for your objects with URL Dispatch. Note also, that because the objects set the <code>__parent__</code> property on the children, the policy will bubble up the lineage, inheriting permissions from the parents. This can be avoided by simply putting a <code>DENY_ALL</code> ACE in your ACL, or by writing a custom policy that does not use the context's lineage.</p> <p><strong>* Update *</strong> I've turned this post into an actual demo on Github. Hopefully it helps someone. <a href="https://github.com/mmerickel/pyramid_auth_demo" rel="noreferrer">https://github.com/mmerickel/pyramid_auth_demo</a></p> <p><strong>* Update *</strong> I've written a full tutorial around pyramid's authentication and authorization system here: <a href="http://michael.merickel.org/projects/pyramid_auth_demo/" rel="noreferrer">http://michael.merickel.org/projects/pyramid_auth_demo/</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload