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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With