summaryrefslogtreecommitdiff
path: root/wsgitools/authentication.py
diff options
context:
space:
mode:
Diffstat (limited to 'wsgitools/authentication.py')
-rw-r--r--wsgitools/authentication.py38
1 files changed, 33 insertions, 5 deletions
diff --git a/wsgitools/authentication.py b/wsgitools/authentication.py
index a36b794..0c69f95 100644
--- a/wsgitools/authentication.py
+++ b/wsgitools/authentication.py
@@ -12,10 +12,10 @@ class ProtocolViolation(AuthenticationRequired):
class AuthenticationMiddleware:
"""Base class for HTTP authorization schemes.
- @cvar authorization_required: the implemented Authorization method. It will
+ @cvar authorization_method: the implemented Authorization method. It will
be verified against Authorization headers. Subclasses must define this
attribute.
- @type authorization_required: str
+ @type authorization_method: str
"""
authorization_method = None
def __init__(self, app):
@@ -25,14 +25,31 @@ class AuthenticationMiddleware:
assert self.authorization_method is not None
self.app = app
- def authenticate(self, auth, environ, start_response):
- """
+ def authenticate(self, auth, environ):
+ """Try to authenticate a request. The Authorization header is examined
+ and checked agains the L{authorization_method} before being passed to
+ this method. This method must either raise an AuthenticationRequired
+ instance or return a dictionary explaining what was successfully
+ authenticated.
+
@type auth: str
@param auth: is the part of the Authorization header after the method
+ @type environ: {str: object}
+ @param environ: is the environment passed with a WSGI request
+ @rtype: {str: object}
+ @returns: a dictionary that provides a key "user" listing the
+ authenticated username as a string. It may also provide the key
+ "outheaders" with a [(str, str)] value to extend the response
+ headers.
+ @raises AuthenticationRequired: if the authentication was unsuccessful
"""
raise NotImplementedError
def __call__(self, environ, start_response):
+ """wsgi interface
+
+ @type environ: {str: object}
+ """
assert isinstance(environ, dict)
try:
try:
@@ -46,9 +63,20 @@ class AuthenticationMiddleware:
if method.lower() != self.authorization_method:
raise AuthenticationRequired(
"authorization method not implemented: %r" % method)
- return self.authenticate(rest, environ, start_response)
+ result = self.authenticate(rest, environ)
except AuthenticationRequired, exc:
return self.authorization_required(environ, start_response, exc)
+ assert isinstance(result, dict)
+ assert "user" in result
+ environ["REMOTE_USER"] = result["user"]
+ if "outheaders" in result:
+ def modified_start_response(status, headers, exc_info=None):
+ assert isinstance(headers, list)
+ headers.extend(result["outheaders"])
+ return start_response(status, headers, exc_info)
+ else:
+ modified_start_response = start_response
+ return self.app(environ, modified_start_response)
def www_authenticate(self, exception):
"""Generates a WWW-Authenticate header. Subclasses must implement this