From e71a708d06b5498c6c527a4ec263f3b99e350d32 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 26 Nov 2011 18:38:35 +0100 Subject: broaden AuthDigestMiddleware.authorization_required The interface of this internal function has changed in a backwards incompatible way. The last parameter is no longer the bool stale, but an exception now, which encodes more information than the previous bool. This was made possible by the previous commit. This exception can then be used by the new method www_authenticate to generate a suitable WWW-Authenticate header. The idea behind this change is that at some point it should be possible to override authorization_required (still internal now) to evaluate what condition lead to the failure and to generate custom error pages. --- wsgitools/digest.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'wsgitools') diff --git a/wsgitools/digest.py b/wsgitools/digest.py index cbb902e..53b7dea 100644 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -720,11 +720,8 @@ class AuthDigestMiddleware: if response is None or response != credresponse: raise AuthenticationRequired("wrong response") - except StaleNonce: - return self.authorization_required(environ, start_response, - stale=True) - except AuthenticationRequired: - return self.authorization_required(environ, start_response) + except AuthenticationRequired, exc: + return self.authorization_required(environ, start_response, exc) else: environ["REMOTE_USER"] = credentials["username"] def modified_start_response(status, headers, exc_info=None): @@ -773,18 +770,28 @@ class AuthDigestMiddleware: dig.insert(0, a1h) return self.algorithms[algo](":".join(dig)) - def authorization_required(self, environ, start_response, stale=False): - """internal method implementing wsgi interface, serving 401 page""" + def www_authenticate(self, exception): + """Generates a WWW-Authenticate header. + + @type exception: AuthenticationRequired + @param exception: reason for generating the header + @rtype: (str, str) + @returns: the header as (part_before_colon, part_after_colon) + """ digest = dict(nonce=self.noncestore.newnonce(), realm=self.gentoken.realm, algorithm="md5", qop="auth") - if stale: + if isinstance(exception, StaleNonce): digest["stale"] = "TRUE" challenge = ", ".join(map('%s="%s"'.__mod__, digest.items())) + return ("WWW-Authenticate", "Digest %s" % challenge) + + def authorization_required(self, environ, start_response, exception): + """internal method implementing wsgi interface, serving 401 page""" status = "401 Not authorized" headers = [("Content-type", "text/html"), - ("WWW-Authenticate", "Digest %s" % challenge)] + self.www_authenticate(exception)] data = "401 Not authorized

" data += "401 Not authorized

" headers.append(("Content-length", str(len(data)))) -- cgit v1.2.3