Hi Zsolt,

I like this approach, as it makes front end template development
straightforward even if it doesn't represent the pinnacle of clean backend.

On 12 November 2016 at 20:13, Zsolt Ero <zsolt....@gmail.com> wrote:

> OK, here is something I made, by looking at pviews util.
>
> def route_allowed(request, route_name):
>     from zope.interface import providedBy
>     from pyramid.interfaces import IRouteRequest
>     from pyramid.interfaces import IRequest
>     from pyramid.view import _find_views
>
>
>     reg = request.registry
>     request_iface = reg.queryUtility(IRouteRequest, name=route_name,
> default=IRequest)
>     context_iface = providedBy(request.context)
>     views = _find_views(reg, request_iface, context_iface, '')
>
>
>     assert len(views) == 1
>
>
>     view = views[0]
>     permission = view.__permission__
>
>
>     return bool(request.has_permission(permission))
>
> Can you explain why this is wrong or how can I make it better? It is
> limited to the exactly one matching view case (assert len(views) == 1),
> but I believe it's a fair limitation and is not a problem for a typical URL
> Dispatch app, and definitely not a problem for my use case.
>
> Zsolt
>
>
>
>
> On Saturday, 12 November 2016 18:25:45 UTC+1, Zsolt Ero wrote:
>>
>> Here is what I see:
>> - The way Pyramid does everything super flexibly (URL structure, the view
>> callables, the role concepts, and the permissions as you said it) can make
>> it very complicated to do otherwise simple things, such as making a
>> request.route_allowed()...
>> - If request.route_url() exists and works, why can we not make
>> request.route_allowed()? I understand that one route *may* point to
>> multiple views, but that mechanism is implemented already, since Pyramid
>> can decide what to do on every incoming request.
>> - The *only* thing what I can imagine is not obvious from a request and
>> a route_url is the GET/POST, etc. kind, since the user might want to change
>> that between requests. (For example calling a form, etc.).
>>
>> So why can we not make a simple request.route_allowed(**kwargs,
>> method='GET') method, where kwargs would be the same as for route_url()?
>>
>> Zsolt
>>
>>
>> On Saturday, 12 November 2016 00:40:17 UTC+1, Mike Orr wrote:
>>>
>>> On Thu, Nov 10, 2016 at 12:48 PM, Zsolt Ero <zsol...@gmail.com> wrote:
>>> > Hi, I'd like to do the simplest possible thing in Pyramid / URL
>>> Dispatch,
>>> > yet it seems almost impossibly hard to do it.
>>> >
>>> > So it's the super common case of having a menu, and I'd only like to
>>> insert
>>> > menu items which are available for the current user.
>>> >
>>> > I'm looking for a function to fit in this usage:
>>> >
>>> > {% macro nav_item(request, route_name, text) -%}
>>> >   {% if request.view_execution_permitted(route_name) %}
>>> >     <li>
>>> >       <a href="{{ request.route_url(route_name) }}">{{ text }}</a>
>>> >     </li>
>>> >   {% endif %}
>>> > {%- endmacro %}
>>> >
>>> >
>>> > My problems are the following:
>>> >
>>> > 1. view_execution_permitted doesn't work like this, unlike other
>>> security
>>> > functions, for example request.has_permission(). Why?
>>>
>>> There seems to be a logic problem here. Routes aren't
>>> authorization-significant entities; a route is just a URL pattern.
>>> Users belong in roles/groups (Pyramid calls all of these "principals"
>>> -- defined by the "groupfinder" callback in the authentication
>>> policy). Principles have permissions -- defined in the ACLs others
>>> have talked about. A simple URL Dispatch application may have just one
>>> ACL for everything: a root factory defined at startup sets all the
>>> permissions that all the pages need. A more complex URL Dispatch
>>> application may have different roots for different parts of the
>>> application (different view configurations), and each of these can do
>>> their own private traversal to sub-objects. But it's easier to start
>>> with a single root for the entire application. Each request will have
>>> its own instance of that root, which is the "context" available to the
>>> view and the authorization system. Finally, the view configuration
>>> ties all of these together: the view, the route, the root factory with
>>> its ACL, and the permission required to execute the view. The reason
>>> all these are separate is to keep some independence between the URL
>>> structure, the view callables, the role concepts, and the permissions:
>>> so you can design each one autonomously to its best structure, and you
>>> can change one (within limits) without affecting the others.
>>>
>>> So the answer to your question is, what determines which menu items
>>> should be displayed? Not the routes, the *roles* (principles). The
>>> roles imply permissions, and r'equest.has_permission'  tells whether
>>> the user has that permission (i.e., can execute the views that require
>>> that permission). However, there's no formal listing of which routes
>>> go with which permissions; that's all tied up in the complex view
>>> confugrations. But you should know which permission each page
>>> requires. So you should do a (in Mako syntax which I'm more familiar
>>> with) '% if request.has_permission("foo_permission"): <a
>>> href="${request.route_url('foo_route')}">text</a> % endif'. I have one
>>> application with permissions and I use 'pyramid_layout', so I define
>>> several boolean attributes in the layout object ('can_do_this',
>>> 'can_do_that'), and use those to decide which menu items to display in
>>> the site template. For links in individual pages, the view sets
>>> similar booleans. Actually, I don't always use booleans because I like
>>> to generate the URLs outside the templates, so I use None to indicate
>>> no URL (no link), or I give a list of permitted URLs that doesn't
>>> include the unpermitted ones.
>>>
>>> If you need to do something dynamically (e.g., user-defined URLs and
>>> permissions that the developer doesn't know about), then studying
>>> Kotti might be useful, because it allows site admins to define users
>>> and roles and pages and link them together.
>>>
>>> So I don't think you'll need to ask whether a route is permitted to a
>>> user; that concept belongs in the principles and ACLs. But there may
>>> be something I'm missing. As for 'view_execution_permitted', I've
>>> never used that and I'm not sure it's useful for application
>>> developers, especially in a URL Dispatch application. It may be
>>> something Pyramid uses more internally. The fact that it requires a
>>> view name is a red flag. Routes kind of replace view names in URL
>>> Dispatch. Traversal uses view names extensively to choose between
>>> multiple views for a resource. URL Dispatch uses mostly the route name
>>> to choose a view, and specifying a view name could accidentally make
>>> the view configuration not match the request.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to pylons-discuss+unsubscr...@googlegroups.com.
> To post to this group, send email to pylons-discuss@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/pylons-discuss/648eb04e-4036-4161-985a-c7317e8cd653%
> 40googlegroups.com
> <https://groups.google.com/d/msgid/pylons-discuss/648eb04e-4036-4161-985a-c7317e8cd653%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Mikko Ohtamaa
http://opensourcehacker.com
http://twitter.com/moo9000

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to pylons-discuss+unsubscr...@googlegroups.com.
To post to this group, send email to pylons-discuss@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pylons-discuss/CAK8RCUtXpLfn7ejR1yWuEubK9P5yQai8esGchXLK7RfMpBnT1w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to