[Twisted-web] integration of HTTP Basic Auth and cred
Manlio Perillo
manlio_perillo at libero.it
Sun Jun 4 06:21:20 CDT 2006
Hi.
I have written a small module for integrating HTTP Basic Auth and cred.
This is like guard.SessionWrapper.
I'm posting this module here because I'm not sure I'm doing the right thing.
Thanks and regards Manlio Perillo
-------------- next part --------------
"""cred integration with HTTP Basic Authentication.
"""
from zope.interface import Interface, Attribute, implements
from twisted.web import http
from twisted.cred import portal
from twisted.cred.credentials import UsernamePassword, Anonymous
from twisted.cred.error import UnauthorizedLogin
from nevow import inevow, url, stan
class INamedRealm(portal.IRealm):
# this is used in the HTTP WWW-Authenticate header
name = Attribute("The name of the realm")
class Forbidden(object):
implements(inevow.IResource)
def locateChild(self, ctx, segments):
return self
def renderHTTP(self, ctx):
request = inevow.IRequest(ctx)
request.setResponseCode(http.FORBIDDEN)
return ("<html><head><title>Forbidden</title></head>"
"<body><h1>Forbidden</h1>Request was forbidden.</body></html>")
def nomind(*args): return None
class HTTPAuthWrapper(object):
"""Wrapper for HTTP Basic Authentication
"""
implements(inevow.IResource)
# The interface to cred for when logging into the portal
credInterface = inevow.IResource
resource = None
def __init__(self, portal, mindFactory=None, credInterface=None):
self.portal = portal
if mindFactory is None:
mindFactory = nomind
self.mindFactory = mindFactory
if credInterface is not None:
self.credInterface = credInterface
def renderHTTP(self, ctx):
def _cb((iface, res, logout)):
self.resource = inevow.IResource(res)
req = inevow.IRequest(ctx)
# XXX remove the Authorization header
# (compatibility with guard)
del req.getAllHeaders()["authorization"]
return self.resource.renderHTTP(ctx)
request = inevow.IRequest(ctx)
realm = self.portal.realm
username, password = request.getUser(), request.getPassword()
# XXX TODO handle anonymous access?
if (username, password) == ('', ''):
request.setHeader('WWW-Authenticate',
'Basic realm="%s"' % realm.name)
request.setResponseCode(http.UNAUTHORIZED)
# XXX
return "Authentication required."
else:
credentials = UsernamePassword(username, password)
mind = self.mindFactory(request, credentials)
d = self.portal.login(credentials, mind,
self.credInterface)
d.addCallback(_cb)
d.addErrback(self.incorrectLoginError, ctx)
return d
def locateChild(self, ctx, segments):
# XXX not sure
if not self.resource:
if not segments:
return self, ()
elif not segments[0]:
return self, ()
else:
return None, ()
else:
if not segments:
return self.resource, ()
elif not segments[0]:
return self.resource, ()
else:
return self.resource.locateChild(ctx, segments)
def incorrectLoginError(self, error, ctx):
"""Called on login failure.
You can override this, as an example placing a limit on the
number of failed logins.
"""
request = inevow.IRequest(ctx)
realm = self.portal.realm
error.trap(UnauthorizedLogin)
request.setHeader('WWW-Authenticate',
'Basic realm="%s"' % realm.name)
request.setResponseCode(http.UNAUTHORIZED)
# XXX
return "Authentication failed."
More information about the Twisted-web
mailing list