# HG changeset patch # User paulb # Date 1078013102 0 # Node ID 75c2149dbcd33efccb7cfb6bd0367470c9a24b6c # Parent 3cbc736c09a2fd9dfc8be0fd281a50d4fb30e164 [project @ 2004-02-29 00:05:02 by paulb] Added authenticator support. diff -r 3cbc736c09a2 -r 75c2149dbcd3 WebStack/Adapters/BaseHTTPRequestHandler.py --- a/WebStack/Adapters/BaseHTTPRequestHandler.py Sun Feb 29 00:04:53 2004 +0000 +++ b/WebStack/Adapters/BaseHTTPRequestHandler.py Sun Feb 29 00:05:02 2004 +0000 @@ -11,28 +11,36 @@ "A factory class creating WebStack dispatcher objects." - def __init__(self, resource): + def __init__(self, resource, authenticator=None): - "Initialise the root application-specific 'resource'." + """ + Initialise the root application-specific 'resource' and optional + 'authenticator'. + """ self.webstack_resource = resource + self.webstack_authenticator = authenticator def __call__(self, request, client_address, server): "Act as a factory for the server objects." - handler = Handler(request, client_address, server, self.webstack_resource) + handler = Handler(request, client_address, server, self.webstack_resource, + self.webstack_authenticator) return handler class Handler(BaseHTTPServer.BaseHTTPRequestHandler): "A class dispatching requests to WebStack resources." - def __init__(self, request, client_address, server, resource): + def __init__(self, request, client_address, server, resource, authenticator): - "Initialise the root application-specific 'resource'." + """ + Initialise the root application-specific 'resource' and 'authenticator'. + """ self.webstack_resource = resource + self.webstack_authenticator = authenticator BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, server) def handle(self): @@ -46,7 +54,13 @@ return trans = WebStack.BaseHTTPRequestHandler.Transaction(self) - self.webstack_resource.respond(trans) + if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): + self.webstack_resource.respond(trans) + else: + trans.set_response_code(401) # Unauthorized + trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( + self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) + trans.commit() # vim: tabstop=4 expandtab shiftwidth=4 diff -r 3cbc736c09a2 -r 75c2149dbcd3 WebStack/Adapters/ModPython.py --- a/WebStack/Adapters/ModPython.py Sun Feb 29 00:04:53 2004 +0000 +++ b/WebStack/Adapters/ModPython.py Sun Feb 29 00:05:02 2004 +0000 @@ -7,7 +7,7 @@ import WebStack.ModPython from mod_python import apache -def dispatch(request, resource, debug=0): +def respond(request, resource, debug=0): """ Dispatch the given 'request' to the root application-specific 'resource'. @@ -33,4 +33,32 @@ else: raise +def authenticate(request, authenticator, debug=0): + + """ + Dispatch the given 'request' to the application-specific 'authenticator'. + The optional 'debug' flag, if set to 1, causes tracebacks to be displayed in + the browser. + """ + + trans = WebStack.ModPython.Transaction(request) + + # NOTE: Resource pooling may be appropriate. + # NOTE: Forbidden access is not yet considered here. + + try: + if authenticator.authenticate(trans): + return apache.OK + else: + return apache.HTTP_UNAUTHORIZED + except: + + # NOTE: Error conditions should be investigated further, along with + # NOTE: other response states. + + if not debug: + return apache.HTTP_INTERNAL_SERVER_ERROR + else: + raise + # vim: tabstop=4 expandtab shiftwidth=4 diff -r 3cbc736c09a2 -r 75c2149dbcd3 WebStack/Adapters/Twisted.py --- a/WebStack/Adapters/Twisted.py Sun Feb 29 00:04:53 2004 +0000 +++ b/WebStack/Adapters/Twisted.py Sun Feb 29 00:05:02 2004 +0000 @@ -13,12 +13,16 @@ isLeaf = 1 - def __init__(self, resource): + def __init__(self, resource, authenticator=None): - "Initialise the root application-specific 'resource'." + """ + Initialise the root application-specific 'resource' and optional + 'authenticator'. + """ twisted.web.resource.Resource.__init__(self) self.webstack_resource = resource + self.webstack_authenticator = authenticator def getChild(self, path, request): raise NotImplementedError, "getChild" @@ -28,7 +32,13 @@ "Dispatch the given 'request' to the root application-specific resource." trans = WebStack.Twisted.Transaction(request) - self.webstack_resource.respond(trans) + if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(trans): + self.webstack_resource.respond(trans) + else: + trans.set_response_code(401) # Unauthorized + trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( + self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) + trans.commit() request.finish() return twisted.web.server.NOT_DONE_YET diff -r 3cbc736c09a2 -r 75c2149dbcd3 WebStack/Adapters/Webware.py --- a/WebStack/Adapters/Webware.py Sun Feb 29 00:04:53 2004 +0000 +++ b/WebStack/Adapters/Webware.py Sun Feb 29 00:05:02 2004 +0000 @@ -28,14 +28,15 @@ instantiation. """ - def __init__(self, resource): + def __init__(self, resource, authenticator=None): """ Initialise the parser object with the given root application-specific - 'resource'. + 'resource' and optional 'authenticator'. """ self.webstack_resource = resource + self.webstack_authenticator = authenticator def parse(self, trans, requestPath): @@ -50,7 +51,7 @@ should be available elsewhere. """ - return WebStackServlet(self.webstack_resource) + return WebStackServlet(self.webstack_resource, self.webstack_authenticator) # For Webware 0.8.1 and earlier, employ servlet factories and servlets. @@ -64,17 +65,19 @@ application-specific resources. """ - def __init__(self, application, resource, file_extensions): + def __init__(self, application, resource, file_extensions, authenticator=None): """ Initialise the servlet factory with the Webware 'application' and the WebStack root application-specific 'resource'. The 'file_extensions' - specified indicate for which files this factory is invoked. + specified indicate for which files this factory is invoked. An optional + 'authenticator' is used to control access to the resource. """ ServletFactory.__init__(self, application) self.webstack_resource = resource self.file_extensions = file_extensions + self.webstack_authenticator = authenticator def uniqueness(self): @@ -101,7 +104,7 @@ method is invoked on the servlet. """ - return WebStackServlet(self.webstack_resource) + return WebStackServlet(self.webstack_resource, self.webstack_authenticator) # Servlets are common to both solutions. @@ -109,12 +112,16 @@ "A servlet which dispatches transactions to application-specific resources." - def __init__(self, resource): + def __init__(self, resource, authenticator): - "Initialise the servlet with an application-specific 'resource'." + """ + Initialise the servlet with an application-specific 'resource' and + 'authenticator'. + """ Servlet.__init__(self) self.webstack_resource = resource + self.webstack_authenticator = authenticator def respond(self, trans): @@ -124,7 +131,13 @@ """ new_trans = WebStack.Webware.Transaction(trans) - self.webstack_resource.respond(new_trans) + if self.webstack_authenticator is None or self.webstack_authenticator.authenticate(new_trans): + self.webstack_resource.respond(new_trans) + else: + new_trans.set_response_code(401) # Unauthorized + new_trans.set_header_value("WWW-Authenticate", '%s realm="%s"' % ( + self.webstack_authenticator.get_auth_type(), self.webstack_authenticator.get_realm())) + new_trans.commit() # vim: tabstop=4 expandtab shiftwidth=4