On Mon, May 28, 2012 at 11:26 AM, Michael Bayer
<[email protected]> wrote:
>
> If I try to put "permission" or "view_permission" on the add_route(), it 
> wants to know the view at that point, implying I wouldn't be able to use 
> view_config() in the first place.   Plus it appears "view_permission" on 
> add_route() is deprecated.
>

The 'permission' or 'view_permission' configuration argument is only
used when a view is specified and I guess the confusion this causes is
part of why it was deprecated.

> Since what I want to do seems natural here, yet it's all explicitly 
> disallowed/discouraged, it suggests my understanding of things is incorrect ? 
>   The goal here is "declare all authorization in one place".   To me, 
> "factory" and "permission" are both dealing with authorization and it isn't 
> clear why add_route() can't have some default notion of "permission", 
> agnostic of individual views which is applied to those views.
>

In Pyramid, routes (URL dispatch) are just one of two different
mechanisms to find a "view". There's also traversal, which many of us
use. Since traversal can use views without ever defining any routes,
it makes sense to have permissions at that level, so that both
approaches use the same kind of view configuration. Also, it's
possible to combine routes and traversal in an application, so that
the first part of a url uses a route to find a matching 'resource'
(think factory) and then traversal is used to get to the appropriate
object and view. In this case, having a permission on the route
doesn't even make sense, because the object that was 'traversed' to in
the end could have a different factory and views with varying
permissions.

Even so, the good news is that there's an easy way to get *more or
less* what you want. You don't even need separate 'useradmin' and
'access' permissions, since the __acl__ is dynamic. Just do the
following:

1. To avoid having to specify a permission in all view declarations,
in your config:

    config.set_default_permission('access')

    This also allows you to have the permission set right below the
route declarations, so you will have all authorization declared  in
one place, like you want.

2. Now all the views will require the 'access' permission. For normal,
non-admin views, make sure the default root factory has an __acl__
like:

    __acl__ = [(Allow, Authenticated, 'access')]

3. For your protected admin views, keep using your AdminUserACL
factory, but you don't need another permission. If the user is an
admin, return:

    [(Allow, Authenticated, 'access')]

    If the user is not an admin:

    [(Deny, Authenticated, 'access')]

4. Finally, the login view must have a special permission declared in
the view configuration: pyramid.security.NO_PERMISSION_REQUIRED:

    @view_config(
    route_name='login',
    permission=NO_PERMISSION_REQUIRED,
    renderer='login.mako',
    )

    This is necessary to allow unauthenticated users to see it,
because if you omit it the login view would also require the 'access'
permission.

That's it. So, no view permission declarations, except one, but you
get one less permission, so it sort of evens out.

I hope this helps,

Carlos de la Guardia

On Mon, May 28, 2012 at 11:26 AM, Michael Bayer
<[email protected]> wrote:
> I've made a 40% effort to figure this one out but at least I've figured many 
> other things out without bugging the list .... (the irc channel is another 
> story ;) )
>
> Here's a route in application.py:
>
> config.add_route('some_admin_thing', '/admin_something', factory=AdminUserACL)
>
> Here's the general idea of AdminUserACL:
>
> class AdminUserACL(object):
>    @property
>    def __acl__(self):
>        # this is programmatic based on who is logged in,
>        # but the end result might be:
>        return [
>           (Allow, Authenticated, "access"),
>           (Allow, Authenticated, "useradmin")
>        ]
>
>   def __init__(self, request):
>        # pull out the admin user from request, do things
>
> So a view that wants to require the "useradmin" permission looks like:
>
> @view_config(route_name='some_admin_thing', renderer='json',
>             request_method='GET', permission='useradmin')
> def some_admin_thing(request):
>     # ...
>
> But the thing is, all views of this route should require "useradmin" 
> permission.    I don't like that I have to split the declaration of 
> authorization in two places (factory on add_route(), permission on 
> view_config()).    If I try to put "permission" or "view_permission" on the 
> add_route(), it wants to know the view at that point, implying I wouldn't be 
> able to use view_config() in the first place.   Plus it appears 
> "view_permission" on add_route() is deprecated.
>
> Since what I want to do seems natural here, yet it's all explicitly 
> disallowed/discouraged, it suggests my understanding of things is incorrect ? 
>   The goal here is "declare all authorization in one place".   To me, 
> "factory" and "permission" are both dealing with authorization and it isn't 
> clear why add_route() can't have some default notion of "permission", 
> agnostic of individual views which is applied to those views.
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "pylons-discuss" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/pylons-discuss?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to