diff options
| author | Barry Warsaw | 2014-12-11 21:18:12 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2014-12-11 21:18:12 -0500 |
| commit | fe7d286db796630b3bef326bd5106591940c0b5f (patch) | |
| tree | 4a732db60a62d222a8dd998f596789022bbc64bf | |
| parent | 930a1c05b441000fbe5c3c4d8ae36d08bfe3dcdd (diff) | |
| download | mailman-fe7d286db796630b3bef326bd5106591940c0b5f.tar.gz mailman-fe7d286db796630b3bef326bd5106591940c0b5f.tar.zst mailman-fe7d286db796630b3bef326bd5106591940c0b5f.zip | |
| -rw-r--r-- | src/mailman/rest/helpers.py | 8 | ||||
| -rw-r--r-- | src/mailman/rest/root.py | 3 | ||||
| -rw-r--r-- | src/mailman/rest/wsgiapp.py | 2 | ||||
| -rw-r--r-- | src/mailman/testing/helpers.py | 5 |
4 files changed, 12 insertions, 6 deletions
diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 0bc312b1f..2b79a0e8a 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -59,7 +59,7 @@ def path_to(resource): :return: The full path to the resource. :rtype: bytes """ - return b'{0}://{1}:{2}/{3}/{4}'.format( + return '{0}://{1}:{2}/{3}/{4}'.format( ('https' if as_boolean(config.webservice.use_https) else 'http'), config.webservice.hostname, config.webservice.port, @@ -107,8 +107,10 @@ def etag(resource): assert 'http_etag' not in resource, 'Resource already etagged' # Calculate the tag from a predictable (i.e. sorted) representation of the # dictionary. The actual details aren't so important. pformat() is - # guaranteed to sort the keys. - etag = hashlib.sha1(pformat(resource)).hexdigest() + # guaranteed to sort the keys, however it returns a str and the hash + # library requires a bytes. Use the safest possible encoding. + hashfood = pformat(resource).encode('raw-unicode-escape') + etag = hashlib.sha1(hashfood).hexdigest() resource['http_etag'] = '"{0}"'.format(etag) return json.dumps(resource, cls=ExtendedEncoder) diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py index 93a8f0086..a8e975fed 100644 --- a/src/mailman/rest/root.py +++ b/src/mailman/rest/root.py @@ -69,7 +69,8 @@ class Root: b'401 Unauthorized', b'The REST API requires authentication') if request.auth.startswith('Basic '): - credentials = b64decode(request.auth[6:]) + # b64decode() returns bytes, but we require a str. + credentials = b64decode(request.auth[6:]).decode('utf-8') username, password = credentials.split(':', 1) if (username != config.webservice.admin_user or password != config.webservice.admin_pass): diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py index 698c4269d..445adf278 100644 --- a/src/mailman/rest/wsgiapp.py +++ b/src/mailman/rest/wsgiapp.py @@ -85,7 +85,7 @@ class RootedAPI(API): if matcher is _missing: continue result = None - if isinstance(matcher, basestring): + if isinstance(matcher, str): # Is the matcher string a regular expression or plain # string? If it starts with a caret, it's a regexp. if matcher.startswith('^'): diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index 1de0e98cf..882e69cd9 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -333,7 +333,10 @@ def call_api(url, data=None, method=None, username=None, password=None): basic_auth = '{0}:{1}'.format( (config.webservice.admin_user if username is None else username), (config.webservice.admin_pass if password is None else password)) - headers['Authorization'] = 'Basic ' + b64encode(basic_auth) + # b64encode() requires a bytes, but the header value must be str. Do the + # necessary conversion dances. + token = b64encode(basic_auth.encode('utf-8')).decode('ascii') + headers['Authorization'] = 'Basic ' + token response, content = Http().request(url, method, data, headers) # If we did not get a 2xx status code, make this look like a urllib2 # exception, for backward compatibility with existing doctests. |
