Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different login views in Pyramid

Tags:

python

pyramid

There are some URLs which are handled by my Pyramid application. When an unauthenticated user tries to open any URL then the user is redirected to login form:

def forbidden(request):
    if request.user.keyname == 'guest':
        return HTTPFound(location=request.route_url('auth.login',))

    request.response.status = 403
    return dict(subtitle=u"Access denied")

config.add_view(forbidden, context=HTTPForbidden, renderer='auth/forbidden.mako')

But for some urls (routes) I have to return not the login form, but a 401 Unauthorized status code with WWW-Authenticate header. How I can setup my routes to accomplish this? I am guessing that I have to use route_predicate.

like image 880
drnextgis Avatar asked Jun 30 '15 07:06

drnextgis


2 Answers

You can wrap those two errors into your custom one, and raise that in place of both. Then you can handle your exception and run the desired scenario for each error. Here is an example:

class YourError(HTTPException):
    def __init__(self, error):
        super(YourError, self).__init__()

        self.error = error

    def handle(self, request):
        if error is HTTPForbidden or is instance(error, HTTPForbidden):
            return self._handle403(request)
        elif error is HTTPUnauthorized or is instance(error, HTTPUnauthorized):
            return self._handle401(request)

    def _handle403(self, request):
        # do your stuff for 403

    def _handle401(self, request):
        # do your stuff for 401

# ...modify your view
def forbidden(context, request):
    return context.handle(request)

Then edit your view configuration:

config.add_view(forbidden, context=YourError, renderer='auth/forbidden.mako')

And then in other views where you need to return 403 or 401, go this way:

def another_view(request)
    ...
    raise YourError(HTTPForbidden)
    # or
    raise YourError(HTTPUnauthorized)
    ...

Then you will only need to implement your handling logic inside the YourError class.

like image 83
bagrat Avatar answered Sep 28 '22 23:09

bagrat


I came across some discussion on the Pyramid issues list that looks like it might address this problem.

That said, I think what you might be able to do is override the Forbidden view using hooks and create a custom exception handler. Then in there I think you could differentiate between 403 and 401 errors and redirect / display an appropriate response message and customize the response however you need.

like image 27
Peter Tirrell Avatar answered Sep 29 '22 00:09

Peter Tirrell