summaryrefslogtreecommitdiff
path: root/cherrypy/lib
diff options
context:
space:
mode:
authorSylvain Hellegouarch <sh@defuze.org>2006-09-11 19:53:21 +0000
committerSylvain Hellegouarch <sh@defuze.org>2006-09-11 19:53:21 +0000
commit4cd65390c6f0b88694b6e01ed333bf702ad7cee8 (patch)
tree12dbf61d540a5d897d4c13b5b5d76e130f0858cc /cherrypy/lib
parent06d8ffcd7c9e19c220bb22c0957df6df9bf56c1d (diff)
downloadcherrypy-git-4cd65390c6f0b88694b6e01ed333bf702ad7cee8.tar.gz
Digest and basic auth can now take a callable which must return a dict with user credentials so that it can fetch those from a database for instance.
Basic takes also an encrypt parameter which must be a callable that will encrypt the password sent back the user-agent. So that passwords can be stored encrypted on the server.
Diffstat (limited to 'cherrypy/lib')
-rw-r--r--cherrypy/lib/auth.py24
-rw-r--r--cherrypy/lib/httpauth.py10
2 files changed, 22 insertions, 12 deletions
diff --git a/cherrypy/lib/auth.py b/cherrypy/lib/auth.py
index fed8820f..4f2eb053 100644
--- a/cherrypy/lib/auth.py
+++ b/cherrypy/lib/auth.py
@@ -3,31 +3,41 @@ import cherrypy
from httpauth import parseAuthorization, checkResponse, basicAuth, digestAuth
-def check_auth(users):
+def check_auth(users, encrypt=None):
"""If an authorization header contains credentials, return True, else False."""
if 'authorization' in cherrypy.request.headers:
# make sure the provided credentials are correctly set
ah = parseAuthorization(cherrypy.request.headers['authorization'])
if ah is None:
raise cherrypy.HTTPError(400, 'Bad Request')
-
+
+ if not encrypt:
+ encrypt = lambda x: x
+
+ if callable(users):
+ users = users() # expect it to return a dictionary
+
+ if not isinstance(users, dict):
+ raise ValueError, "Authentication users must be passed contained in a dictionary"
+
# fetch the user password
password = users.get(ah["username"], None)
# validate the authorization by re-computing it here
# and compare it with what the user-agent provided
- if checkResponse(ah, password, method=cherrypy.request.method):
+ if checkResponse(ah, password, method=cherrypy.request.method, encrypt=encrypt):
return True
return False
-def basic_auth(realm, users):
+def basic_auth(realm, users, encrypt=None):
"""If auth fails, raise 401 with a basic authentication header.
realm: a string containing the authentication realm.
- users: a dict of the form: {username: password}.
+ users: a dict of the form: {username: password} or a callable returning a dict.
+ encrypt: callable used to encrypt the password returned from the user-agent.
"""
- if check_auth(users):
+ if check_auth(users, encrypt):
return
# inform the user-agent this path is protected
@@ -39,7 +49,7 @@ def digest_auth(realm, users):
"""If auth fails, raise 401 with a digest authentication header.
realm: a string containing the authentication realm.
- users: a dict of the form: {username: password}.
+ users: a dict of the form: {username: password} or a callable returning a dict.
"""
if check_auth(users):
return
diff --git a/cherrypy/lib/httpauth.py b/cherrypy/lib/httpauth.py
index dac20813..8aab3cc2 100644
--- a/cherrypy/lib/httpauth.py
+++ b/cherrypy/lib/httpauth.py
@@ -295,7 +295,7 @@ def _computeDigestResponse(auth_map, password, method = "GET", A1 = None,**kwarg
return KD(H_A1, request)
-def _checkDigestResponse(auth_map, password, method = "GET", A1 = None,**kwargs):
+def _checkDigestResponse(auth_map, password, method = "GET", A1 = None, **kwargs):
"""This function is used to verify the response given by the client when
he tries to authenticate.
Optional arguments:
@@ -308,15 +308,15 @@ def _checkDigestResponse(auth_map, password, method = "GET", A1 = None,**kwargs)
return response == auth_map["response"]
-def _checkBasicResponse (auth_map, password, method='GET', **kwargs):
- return auth_map["password"] == password
+def _checkBasicResponse (auth_map, password, method='GET', encrypt=None, **kwargs):
+ return encrypt(auth_map["password"]) == password
AUTH_RESPONSES = {
"basic": _checkBasicResponse,
"digest": _checkDigestResponse,
}
-def checkResponse (auth_map, password, method = "GET", **kwargs):
+def checkResponse (auth_map, password, method = "GET", encrypt=None, **kwargs):
"""'checkResponse' compares the auth_map with the password and optionally
other arguments that each implementation might need.
@@ -335,7 +335,7 @@ def checkResponse (auth_map, password, method = "GET", **kwargs):
"""
global AUTH_RESPONSES
checker = AUTH_RESPONSES[auth_map["auth_scheme"]]
- return checker (auth_map, password, method, **kwargs)
+ return checker (auth_map, password, method=method, encrypt=encrypt, **kwargs)