diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-04-22 02:33:32 +0200 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-04-22 02:33:32 +0200 |
commit | 916a56715c777e39461627ea564bc0625712c733 (patch) | |
tree | a58fb49cd65f9b7ff24029aeb4dfaccd657128dd /paste/auth | |
parent | d705a0524606c7b9b11f935de5a69d173c61ec0d (diff) | |
parent | 6c4ef4b3876812e6bbbb3e4748793997067aa85c (diff) | |
download | paste-git-916a56715c777e39461627ea564bc0625712c733.tar.gz |
Merged in mfrobben/paste (pull request #21)
Fix bad reference to iterator variable
Diffstat (limited to 'paste/auth')
-rw-r--r-- | paste/auth/basic.py | 4 | ||||
-rw-r--r-- | paste/auth/cookie.py | 19 | ||||
-rw-r--r-- | paste/auth/digest.py | 29 | ||||
-rw-r--r-- | paste/auth/form.py | 2 | ||||
-rw-r--r-- | paste/auth/grantip.py | 14 | ||||
-rw-r--r-- | paste/auth/open_id.py | 10 |
6 files changed, 51 insertions, 27 deletions
diff --git a/paste/auth/basic.py b/paste/auth/basic.py index 69db128..24d1731 100644 --- a/paste/auth/basic.py +++ b/paste/auth/basic.py @@ -108,14 +108,14 @@ def make_basic(app, global_conf, realm, authfunc, **kw): use = egg:Paste#auth_basic realm=myrealm authfunc=somepackage.somemodule:somefunction - + """ from paste.util.import_string import eval_import import types authfunc = eval_import(authfunc) assert isinstance(authfunc, types.FunctionType), "authfunc must resolve to a function" return AuthBasicHandler(app, realm, authfunc) - + if "__main__" == __name__: import doctest diff --git a/paste/auth/cookie.py b/paste/auth/cookie.py index c636824..8f11d1b 100644 --- a/paste/auth/cookie.py +++ b/paste/auth/cookie.py @@ -74,7 +74,10 @@ class CookieTooLarge(RuntimeError): _all_chars = ''.join([chr(x) for x in range(0, 255)]) def new_secret(): """ returns a 64 byte secret """ - return ''.join(random.sample(_all_chars, 64)) + secret = ''.join(random.sample(_all_chars, 64)) + if six.PY3: + secret = secret.encode('utf8') + return secret class AuthCookieSigner(object): """ @@ -137,12 +140,16 @@ class AuthCookieSigner(object): need to be escaped and quoted). The expiration of this cookie is handled server-side in the auth() function. """ + timestamp = make_time(time.time() + 60*self.timeout) + if six.PY3: + content = content.encode('utf8') + timestamp = timestamp.encode('utf8') cookie = base64.encodestring( hmac.new(self.secret, content, sha1).digest() + - make_time(time.time() + 60*self.timeout) + + timestamp + content) - cookie = cookie.replace("/", "_").replace("=", "~") - cookie = cookie.replace('\n', '').replace('\r', '') + cookie = cookie.replace(b"/", b"_").replace(b"=", b"~") + cookie = cookie.replace(b'\n', b'').replace(b'\r', b'') if len(cookie) > self.maxlen: raise CookieTooLarge(content, cookie) return cookie @@ -298,6 +305,8 @@ class AuthCookieHandler(object): if content: content = ";".join(content) content = self.signer.sign(content) + if six.PY3: + content = content.decode('utf8') cookie = '%s=%s; Path=/;' % (self.cookie_name, content) if 'https' == environ['wsgi.url_scheme']: cookie += ' secure;' @@ -368,7 +377,7 @@ def make_auth_cookie( The maximum length of the cookie that is sent (default 4k, which is a typical browser maximum) - + """ if isinstance(scanlist, six.string_types): scanlist = scanlist.split() diff --git a/paste/auth/digest.py b/paste/auth/digest.py index 798f447..85e0362 100644 --- a/paste/auth/digest.py +++ b/paste/auth/digest.py @@ -37,6 +37,7 @@ except ImportError: from md5 import md5 import time, random from six.moves.urllib.parse import quote as url_quote +import six def _split_auth_string(auth_string): """ split a digest auth string into individual key=value strings """ @@ -68,7 +69,10 @@ def _auth_to_kv_pairs(auth_string): def digest_password(realm, username, password): """ construct the appropriate hashcode needed for HTTP digest """ - return md5("%s:%s:%s" % (username, realm, password)).hexdigest() + content = "%s:%s:%s" % (username, realm, password) + if six.PY3: + content = content.encode('utf8') + return md5(content).hexdigest() class AuthDigestAuthenticator(object): """ implementation of RFC 2617 - HTTP Digest Authentication """ @@ -79,10 +83,16 @@ class AuthDigestAuthenticator(object): def build_authentication(self, stale = ''): """ builds the authentication error """ - nonce = md5( - "%s:%s" % (time.time(), random.random())).hexdigest() - opaque = md5( - "%s:%s" % (time.time(), random.random())).hexdigest() + content = "%s:%s" % (time.time(), random.random()) + if six.PY3: + content = content.encode('utf-8') + nonce = md5(content).hexdigest() + + content = "%s:%s" % (time.time(), random.random()) + if six.PY3: + content = content.encode('utf-8') + opaque = md5(content).hexdigest() + self.nonce[nonce] = None parts = {'realm': self.realm, 'qop': 'auth', 'nonce': nonce, 'opaque': opaque } @@ -97,17 +107,22 @@ class AuthDigestAuthenticator(object): """ computes the authentication, raises error if unsuccessful """ if not ha1: return self.build_authentication() - ha2 = md5('%s:%s' % (method, path)).hexdigest() + content = '%s:%s' % (method, path) + if six.PY3: + content = content.encode('utf8') + ha2 = md5(content).hexdigest() if qop: chk = "%s:%s:%s:%s:%s:%s" % (ha1, nonce, nc, cnonce, qop, ha2) else: chk = "%s:%s:%s" % (ha1, nonce, ha2) + if six.PY3: + chk = chk.encode('utf8') if response != md5(chk).hexdigest(): if nonce in self.nonce: del self.nonce[nonce] return self.build_authentication() pnc = self.nonce.get(nonce,'00000000') - if nc <= pnc: + if pnc is not None and nc <= pnc: if nonce in self.nonce: del self.nonce[nonce] return self.build_authentication(stale = True) diff --git a/paste/auth/form.py b/paste/auth/form.py index 4e6aa49..9be82a2 100644 --- a/paste/auth/form.py +++ b/paste/auth/form.py @@ -131,7 +131,7 @@ def make_form(app, global_conf, realm, authfunc, **kw): use = egg:Paste#auth_form realm=myrealm authfunc=somepackage.somemodule:somefunction - + """ from paste.util.import_string import eval_import import types diff --git a/paste/auth/grantip.py b/paste/auth/grantip.py index 4ea6df5..3fe6e1c 100644 --- a/paste/auth/grantip.py +++ b/paste/auth/grantip.py @@ -38,7 +38,7 @@ class GrantIPMiddleware(object): if roles and isinstance(roles, six.string_types): roles = roles.split(',') return (username, roles) - + def __call__(self, environ, start_response): addr = ip4.ip2int(environ['REMOTE_ADDR'], False) remove_user = False @@ -62,7 +62,7 @@ class GrantIPMiddleware(object): def _set_roles(self, environ, roles): cur_roles = environ.get('REMOTE_USER_TOKENS', '').split(',') # Get rid of empty roles: - cur_roles = filter(None, cur_roles) + cur_roles = list(filter(None, cur_roles)) remove_roles = [] for role in roles: if role.startswith('-'): @@ -74,8 +74,8 @@ class GrantIPMiddleware(object): if role in cur_roles: cur_roles.remove(role) environ['REMOTE_USER_TOKENS'] = ','.join(cur_roles) - - + + def make_grantip(app, global_conf, clobber_username=False, **kw): """ Grant roles or usernames based on IP addresses. @@ -93,7 +93,7 @@ def make_grantip(app, global_conf, clobber_username=False, **kw): 192.168.0.7 = joe # And one IP is should not be logged in: 192.168.0.10 = __remove__:-editor - + """ from paste.deploy.converters import asbool clobber_username = asbool(clobber_username) @@ -110,5 +110,5 @@ def make_grantip(app, global_conf, clobber_username=False, **kw): role = '' ip_map[key] = value return GrantIPMiddleware(app, ip_map, clobber_username) - - + + diff --git a/paste/auth/open_id.py b/paste/auth/open_id.py index 967e699..f79f7f8 100644 --- a/paste/auth/open_id.py +++ b/paste/auth/open_id.py @@ -91,20 +91,20 @@ class AuthOpenIDHandler(object): ``app`` Your WSGI app to call - + ``data_store_path`` Directory to store crypto data in for use with OpenID servers. - + ``auth_prefix`` Location for authentication process/verification - + ``login_redirect`` Location to load after successful process of login - + ``catch_401`` If true, then any 401 responses will turn into open ID login requirements. - + ``url_to_username`` A function called like ``url_to_username(environ, url)``, which should return a string username. If not given, the URL will be the username. |