Question

In my forbidden view, I want to redirect all members to their dashboard if they visit a page for guests, and I want to redirect all guests to the login page if they visit a page for members. This is easy enough.

However, there are some cases where I need to throw an HTTPForbidden error which is not the cause of a failed permission and simply display the reason to the user. How can I determine whether an HTTPForbidden is a result of a failed permission or some other reason? I suppose I could do some weird stuff with pyramid.security.has_permission (haven't tried it yet), but there has to be an easier way.

An old question from 2011 where it was stated that this was on the to do list How to check what permission failed in authorization in pyramid (pylons 2)?

Was it helpful?

Solution

I haven't tested it, but what I'd try to do is to raise something else than HTTPForbidden in the places where you do this manually. You can even subclass HTTPForbidden:

class WeDontLikeYourFace(HTTPForbidden):
    pass

def my_view(context, request):
    if request['face'] != 'beautyful':
        raise WeDontLikeYourFace("go away")

Then you can register a custom view for your custom exception, or do some if/else stuff in the common view method registered for HTTPForbidden.

You can also add custom fields to your subclass to pass any information you need.

OTHER TIPS

This is not exactly what you asked for but it may still help you. The right answer to your question was already given: you'd better raise a specific exception that is more appropriate than HTTPForbidden.

But if you really want to change the behavior of your forbidden view depending on the missing permission that triggered the HTTPForbidden exception, you need to grab its name. The name of the missing permission can be found inside the HTTPForbidden exception object in HTTPForbidden.result.permission. But first, the HTTPForbidden exception needs to be passed as a context of your forbidden view.

For instance, here is how I use this in my webapps to inform the user why he cannot access a particular feature so that he can ask a manager to re-configure ACL accordingly if appropriate.

@forbidden_view_config(renderer='/forbidden.mako')
def forbidden(context, request):
    return { 'required_permission': context.result.permission }

It works with pyramid 1.4. I couldn't find anything in the documentation so I hacked this by debugging pyramid. This is more a workaround than a clean solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top