Merge "tempurl: Deprecate sha1 signatures"

This commit is contained in:
Zuul 2022-06-01 15:54:25 +00:00 committed by Gerrit Code Review
commit 5398204f22
9 changed files with 188 additions and 130 deletions

View File

@ -38,7 +38,7 @@ parameters:
.. code:: .. code::
https://swift-cluster.example.com/v1/my_account/container/object https://swift-cluster.example.com/v1/my_account/container/object
?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709 ?temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b
&temp_url_expires=1323479485 &temp_url_expires=1323479485
&filename=My+Test+File.pdf &filename=My+Test+File.pdf
@ -47,9 +47,11 @@ The example shows these elements:
**Object URL**: Required. The full path URL to the object. **Object URL**: Required. The full path URL to the object.
**temp\_url\_sig**: Required. An HMAC-SHA1 cryptographic signature that defines **temp\_url\_sig**: Required. An HMAC cryptographic signature that defines
the allowed HTTP method, expiration date, full path to the object, and the the allowed HTTP method, expiration date, full path to the object, and the
secret key for the temporary URL. secret key for the temporary URL. The digest used (for example, SHA-256 or
SHA-512) must be supported by the cluster; supported digests will be listed
in the ``tempurl.allowed_digests`` key in the cluster's capabilities.
**temp\_url\_expires**: Required. An expiration date as a UNIX Epoch timestamp **temp\_url\_expires**: Required. An expiration date as a UNIX Epoch timestamp
or ISO 8601 UTC timestamp. For example, ``1390852007`` or or ISO 8601 UTC timestamp. For example, ``1390852007`` or
@ -72,7 +74,7 @@ by all object names for which the URL is valid.
.. code:: .. code::
https://swift-cluster.example.com/v1/my_account/container/my_prefix/object https://swift-cluster.example.com/v1/my_account/container/my_prefix/object
?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709 ?temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b
&temp_url_expires=2011-12-10T01:11:25Z &temp_url_expires=2011-12-10T01:11:25Z
&temp_url_prefix=my_prefix &temp_url_prefix=my_prefix
@ -117,15 +119,15 @@ Note
Changing these headers invalidates any previously generated temporary Changing these headers invalidates any previously generated temporary
URLs within 60 seconds, which is the memcache time for the key. URLs within 60 seconds, which is the memcache time for the key.
HMAC-SHA1 signature for temporary URLs HMAC signature for temporary URLs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Temporary URL middleware uses an HMAC-SHA1 cryptographic signature. This Temporary URL middleware uses an HMAC cryptographic signature. This
signature includes these elements: signature includes these elements:
- The allowed method. Typically, **GET** or **PUT**. - The allowed method. Typically, **GET** or **PUT**.
- Expiry time. In the example for the HMAC-SHA1 signature for temporary - Expiry time. In the example for the HMAC-SHA256 signature for temporary
URLs below, the expiry time is set to ``86400`` seconds (or 1 day) URLs below, the expiry time is set to ``86400`` seconds (or 1 day)
into the future. Please be aware that you have to use a UNIX timestamp into the future. Please be aware that you have to use a UNIX timestamp
for generating the signature (in the API request it is also allowed to for generating the signature (in the API request it is also allowed to
@ -141,12 +143,12 @@ signature includes these elements:
These sample Python codes show how to compute a signature for use with These sample Python codes show how to compute a signature for use with
temporary URLs: temporary URLs:
**Example HMAC-SHA1 signature for object-based temporary URLs** **Example HMAC-SHA256 signature for object-based temporary URLs**
.. code:: .. code::
import hmac import hmac
from hashlib import sha1 from hashlib import sha256
from time import time from time import time
method = 'GET' method = 'GET'
duration_in_seconds = 60*60*24 duration_in_seconds = 60*60*24
@ -154,14 +156,14 @@ temporary URLs:
path = '/v1/my_account/container/object' path = '/v1/my_account/container/object'
key = 'MYKEY' key = 'MYKEY'
hmac_body = '%s\n%s\n%s' % (method, expires, path) hmac_body = '%s\n%s\n%s' % (method, expires, path)
signature = hmac.new(key, hmac_body, sha1).hexdigest() signature = hmac.new(key, hmac_body, sha256).hexdigest()
**Example HMAC-SHA1 signature for prefix-based temporary URLs** **Example HMAC-SHA512 signature for prefix-based temporary URLs**
.. code:: .. code::
import hmac import hmac
from hashlib import sha1 from hashlib import sha512
from time import time from time import time
method = 'GET' method = 'GET'
duration_in_seconds = 60*60*24 duration_in_seconds = 60*60*24
@ -169,9 +171,9 @@ temporary URLs:
path = 'prefix:/v1/my_account/container/my_prefix' path = 'prefix:/v1/my_account/container/my_prefix'
key = 'MYKEY' key = 'MYKEY'
hmac_body = '%s\n%s\n%s' % (method, expires, path) hmac_body = '%s\n%s\n%s' % (method, expires, path)
signature = hmac.new(key, hmac_body, sha1).hexdigest() signature = hmac.new(key, hmac_body, sha512).hexdigest()
Do not URL-encode the path when you generate the HMAC-SHA1 signature. Do not URL-encode the path when you generate the HMAC signature.
However, when you make the actual HTTP request, you should properly However, when you make the actual HTTP request, you should properly
URL-encode the URL. URL-encode the URL.
@ -200,6 +202,11 @@ parameters. For example, you might run this command:
$ swift tempurl GET 3600 /v1/my_account/container/object MYKEY $ swift tempurl GET 3600 /v1/my_account/container/object MYKEY
.. note::
The ``swift`` tool is not yet updated and continues to use the
deprecated cipher SHA1.
This command returns the path: This command returns the path:
.. code:: .. code::

View File

@ -932,7 +932,7 @@ use = egg:swift#tempurl
# #
# The digest algorithm(s) supported for generating signatures; # The digest algorithm(s) supported for generating signatures;
# whitespace-delimited. # whitespace-delimited.
# allowed_digests = sha1 sha256 sha512 # allowed_digests = sha256 sha512
# Note: Put formpost just before your auth filter(s) in the pipeline # Note: Put formpost just before your auth filter(s) in the pipeline
[filter:formpost] [filter:formpost]

View File

@ -64,7 +64,7 @@ signature is generated using the HTTP method to allow (``GET``, ``PUT``,
the full path to the object, and the key set on the account. the full path to the object, and the key set on the account.
The digest algorithm to be used may be configured by the operator. By default, The digest algorithm to be used may be configured by the operator. By default,
HMAC-SHA1, HMAC-SHA256, and HMAC-SHA512 are supported. Check the HMAC-SHA256 and HMAC-SHA512 are supported. Check the
``tempurl.allowed_digests`` entry in the cluster's capabilities response to ``tempurl.allowed_digests`` entry in the cluster's capabilities response to
see which algorithms are supported by your deployment; see see which algorithms are supported by your deployment; see
:doc:`api/discoverability` for more information. On older clusters, :doc:`api/discoverability` for more information. On older clusters,
@ -75,24 +75,25 @@ For example, here is code generating the signature for a ``GET`` for 60
seconds on ``/v1/AUTH_account/container/object``:: seconds on ``/v1/AUTH_account/container/object``::
import hmac import hmac
from hashlib import sha1 from hashlib import sha256
from time import time from time import time
method = 'GET' method = 'GET'
expires = int(time() + 60) expires = int(time() + 60)
path = '/v1/AUTH_account/container/object' path = '/v1/AUTH_account/container/object'
key = 'mykey' key = 'mykey'
hmac_body = '%s\n%s\n%s' % (method, expires, path) hmac_body = '%s\n%s\n%s' % (method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest() sig = hmac.new(key, hmac_body, sha256).hexdigest()
Be certain to use the full path, from the ``/v1/`` onward. Be certain to use the full path, from the ``/v1/`` onward.
Let's say ``sig`` ends up equaling Let's say ``sig`` ends up equaling
``da39a3ee5e6b4b0d3255bfef95601890afd80709`` and ``expires`` ends up ``732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b`` and
``1323479485``. Then, for example, the website could provide a link to:: ``expires`` ends up ``1512508563``. Then, for example, the website could
provide a link to::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485 temp_url_expires=1512508563
For longer hashes, a hex encoding becomes unwieldy. Base64 encoding is also For longer hashes, a hex encoding becomes unwieldy. Base64 encoding is also
supported, and indicated by prefixing the signature with ``"<digest name>:"``. supported, and indicated by prefixing the signature with ``"<digest name>:"``.
@ -124,11 +125,11 @@ Supposing that ``sig`` ends up equaling
You may also use ISO 8601 UTC timestamps with the format You may also use ISO 8601 UTC timestamps with the format
``"%Y-%m-%dT%H:%M:%SZ"`` instead of UNIX timestamps in the URL ``"%Y-%m-%dT%H:%M:%SZ"`` instead of UNIX timestamps in the URL
(but NOT in the code above for generating the signature!). (but NOT in the code above for generating the signature!).
So, the above HMAC-SHA1 URL could also be formulated as:: So, the above HMAC-SHA246 URL could also be formulated as::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=2011-12-10T01:11:25Z temp_url_expires=2017-12-05T21:16:03Z
If a prefix-based signature with the prefix ``pre`` is desired, set path to:: If a prefix-based signature with the prefix ``pre`` is desired, set path to::
@ -140,31 +141,31 @@ a query parameter called ``temp_url_prefix``. So, if ``sig`` and ``expires``
would end up like above, following URL would be valid:: would end up like above, following URL would be valid::
https://swift-cluster.example.com/v1/AUTH_account/container/pre/object? https://swift-cluster.example.com/v1/AUTH_account/container/pre/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485& temp_url_expires=1512508563&
temp_url_prefix=pre temp_url_prefix=pre
Another valid URL:: Another valid URL::
https://swift-cluster.example.com/v1/AUTH_account/container/pre/ https://swift-cluster.example.com/v1/AUTH_account/container/pre/
subfolder/another_object? subfolder/another_object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485& temp_url_expires=1512508563&
temp_url_prefix=pre temp_url_prefix=pre
If you wish to lock down the ip ranges from where the resource can be accessed If you wish to lock down the ip ranges from where the resource can be accessed
to the ip ``1.2.3.4``:: to the ip ``1.2.3.4``::
import hmac import hmac
from hashlib import sha1 from hashlib import sha256
from time import time from time import time
method = 'GET' method = 'GET'
expires = int(time() + 60) expires = int(time() + 60)
path = '/v1/AUTH_account/container/object' path = '/v1/AUTH_account/container/object'
ip_range = '1.2.3.4' ip_range = '1.2.3.4'
key = 'mykey' key = b'mykey'
hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path) hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest() sig = hmac.new(key, hmac_body.encode('ascii'), sha256).hexdigest()
The generated signature would only be valid from the ip ``1.2.3.4``. The The generated signature would only be valid from the ip ``1.2.3.4``. The
middleware detects an ip-based temporary URL by a query parameter called middleware detects an ip-based temporary URL by a query parameter called
@ -172,29 +173,29 @@ middleware detects an ip-based temporary URL by a query parameter called
above, following URL would be valid:: above, following URL would be valid::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=3f48476acaf5ec272acd8e99f7b5bad96c52ddba53ed27c60613711774a06f0c&
temp_url_expires=1323479485& temp_url_expires=1648082711&
temp_url_ip_range=1.2.3.4 temp_url_ip_range=1.2.3.4
Similarly to lock down the ip to a range of ``1.2.3.X`` so starting Similarly to lock down the ip to a range of ``1.2.3.X`` so starting
from the ip ``1.2.3.0`` to ``1.2.3.255``:: from the ip ``1.2.3.0`` to ``1.2.3.255``::
import hmac import hmac
from hashlib import sha1 from hashlib import sha256
from time import time from time import time
method = 'GET' method = 'GET'
expires = int(time() + 60) expires = int(time() + 60)
path = '/v1/AUTH_account/container/object' path = '/v1/AUTH_account/container/object'
ip_range = '1.2.3.0/24' ip_range = '1.2.3.0/24'
key = 'mykey' key = b'mykey'
hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path) hmac_body = 'ip=%s\n%s\n%s\n%s' % (ip_range, method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest() sig = hmac.new(key, hmac_body.encode('ascii'), sha256).hexdigest()
Then the following url would be valid:: Then the following url would be valid::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=6ff81256b8a3ba11d239da51a703b9c06a56ffddeb8caab74ca83af8f73c9c83&
temp_url_expires=1323479485& temp_url_expires=1648082711&
temp_url_ip_range=1.2.3.0/24 temp_url_ip_range=1.2.3.0/24
@ -222,16 +223,16 @@ can override this with a filename query parameter. Modifying the
above example:: above example::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485&filename=My+Test+File.pdf temp_url_expires=1512508563&filename=My+Test+File.pdf
If you do not want the object to be downloaded, you can cause If you do not want the object to be downloaded, you can cause
``Content-Disposition: inline`` to be set on the response by adding the ``Content-Disposition: inline`` to be set on the response by adding the
``inline`` parameter to the query string, like so:: ``inline`` parameter to the query string, like so::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485&inline temp_url_expires=1512508563&inline
In some cases, the client might not able to present the content of the object, In some cases, the client might not able to present the content of the object,
but you still want the content able to save to local with the specific but you still want the content able to save to local with the specific
@ -240,8 +241,8 @@ set on the response by adding the ``inline&filename=...`` parameter to the
query string, like so:: query string, like so::
https://swift-cluster.example.com/v1/AUTH_account/container/object? https://swift-cluster.example.com/v1/AUTH_account/container/object?
temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709& temp_url_sig=732fcac368abb10c78a4cbe95c3fab7f311584532bf779abd5074e13cbe8b88b&
temp_url_expires=1323479485&inline&filename=My+Test+File.pdf temp_url_expires=1512508563&inline&filename=My+Test+File.pdf
--------------------- ---------------------
Cluster Configuration Cluster Configuration
@ -288,7 +289,7 @@ This middleware understands the following configuration settings:
A whitespace delimited list of digest algorithms that are allowed A whitespace delimited list of digest algorithms that are allowed
to be used when calculating the signature for a temporary URL. to be used when calculating the signature for a temporary URL.
Default: ``sha1 sha256 sha512`` Default: ``sha256 sha512``
""" """
__all__ = ['TempURL', 'filter_factory', __all__ = ['TempURL', 'filter_factory',
@ -299,7 +300,6 @@ __all__ = ['TempURL', 'filter_factory',
import binascii import binascii
from calendar import timegm from calendar import timegm
import hashlib
import six import six
from os.path import basename from os.path import basename
from time import time, strftime, strptime, gmtime from time import time, strftime, strptime, gmtime
@ -341,8 +341,9 @@ DEFAULT_OUTGOING_REMOVE_HEADERS = 'x-object-meta-*'
#: '*' to indicate a prefix match. #: '*' to indicate a prefix match.
DEFAULT_OUTGOING_ALLOW_HEADERS = 'x-object-meta-public-*' DEFAULT_OUTGOING_ALLOW_HEADERS = 'x-object-meta-public-*'
DEFAULT_ALLOWED_DIGESTS = 'sha1 sha256 sha512' DEFAULT_ALLOWED_DIGESTS = 'sha256 sha512'
SUPPORTED_DIGESTS = set(DEFAULT_ALLOWED_DIGESTS.split()) DEPRECATED_DIGESTS = {'sha1'}
SUPPORTED_DIGESTS = set(DEFAULT_ALLOWED_DIGESTS.split()) | DEPRECATED_DIGESTS
CONTAINER_SCOPE = 'container' CONTAINER_SCOPE = 'container'
ACCOUNT_SCOPE = 'account' ACCOUNT_SCOPE = 'account'
@ -749,12 +750,10 @@ class TempURL(object):
if not request_method: if not request_method:
request_method = env['REQUEST_METHOD'] request_method = env['REQUEST_METHOD']
digest = getattr(hashlib, hash_algorithm)
return [ return [
(get_hmac( (get_hmac(
request_method, path, expires, key, request_method, path, expires, key,
digest=digest, ip_range=ip_range digest=hash_algorithm, ip_range=ip_range
), scope) ), scope)
for (key, scope) in scoped_keys] for (key, scope) in scoped_keys]
@ -846,6 +845,8 @@ def filter_factory(global_conf, **local_conf):
conf = global_conf.copy() conf = global_conf.copy()
conf.update(local_conf) conf.update(local_conf)
logger = get_logger(conf, log_route='tempurl')
defaults = { defaults = {
'methods': 'GET HEAD PUT POST DELETE', 'methods': 'GET HEAD PUT POST DELETE',
'incoming_remove_headers': DEFAULT_INCOMING_REMOVE_HEADERS, 'incoming_remove_headers': DEFAULT_INCOMING_REMOVE_HEADERS,
@ -860,10 +861,16 @@ def filter_factory(global_conf, **local_conf):
for digest in info_conf['allowed_digests']) for digest in info_conf['allowed_digests'])
not_supported = allowed_digests - SUPPORTED_DIGESTS not_supported = allowed_digests - SUPPORTED_DIGESTS
if not_supported: if not_supported:
logger = get_logger(conf, log_route='tempurl')
logger.warning('The following digest algorithms are configured but ' logger.warning('The following digest algorithms are configured but '
'not supported: %s', ', '.join(not_supported)) 'not supported: %s', ', '.join(not_supported))
allowed_digests -= not_supported allowed_digests -= not_supported
deprecated = allowed_digests & DEPRECATED_DIGESTS
if deprecated:
logger.warning('The following digest algorithms are configured but '
'deprecated: %s. Support will be removed in a future '
'release.', ', '.join(deprecated))
if not allowed_digests: if not allowed_digests:
raise ValueError('No valid digest algorithms are configured ' raise ValueError('No valid digest algorithms are configured '
'for tempurls') 'for tempurls')

View File

@ -40,7 +40,6 @@ import uuid
import functools import functools
import platform import platform
import email.parser import email.parser
from hashlib import sha1
from random import random, shuffle from random import random, shuffle
from contextlib import contextmanager, closing from contextlib import contextmanager, closing
import ctypes import ctypes
@ -283,7 +282,7 @@ except (InvalidHashPathConfigError, IOError):
pass pass
def get_hmac(request_method, path, expires, key, digest=sha1, def get_hmac(request_method, path, expires, key, digest="sha1",
ip_range=None): ip_range=None):
""" """
Returns the hexdigest string of the HMAC (see RFC 2104) for Returns the hexdigest string of the HMAC (see RFC 2104) for
@ -294,7 +293,8 @@ def get_hmac(request_method, path, expires, key, digest=sha1,
:param expires: Unix timestamp as an int for when the URL :param expires: Unix timestamp as an int for when the URL
expires. expires.
:param key: HMAC shared secret. :param key: HMAC shared secret.
:param digest: constructor for the digest to use in calculating the HMAC :param digest: constructor or the string name for the digest to use in
calculating the HMAC
Defaults to SHA1 Defaults to SHA1
:param ip_range: The ip range from which the resource is allowed :param ip_range: The ip range from which the resource is allowed
to be accessed. We need to put the ip_range as the to be accessed. We need to put the ip_range as the
@ -320,6 +320,9 @@ def get_hmac(request_method, path, expires, key, digest=sha1,
else part.encode("utf-8")) else part.encode("utf-8"))
for fmt, part in zip(formats, parts)) for fmt, part in zip(formats, parts))
if six.PY2 and isinstance(digest, six.string_types):
digest = getattr(hashlib, digest)
return hmac.new(key, message, digest).hexdigest() return hmac.new(key, message, digest).hexdigest()

View File

@ -2578,7 +2578,7 @@ class TestHistoryLocationWithVersioning(TestVersionsLocationWithVersioning):
class TestVersioningAccountTempurl(TestObjectVersioningBase): class TestVersioningAccountTempurl(TestObjectVersioningBase):
env = TestTempurlEnv env = TestTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
self.env.versions_header_key = 'X-Versions-Enabled' self.env.versions_header_key = 'X-Versions-Enabled'
@ -2689,7 +2689,7 @@ class TestVersioningAccountTempurl(TestObjectVersioningBase):
class TestVersioningContainerTempurl(TestObjectVersioningBase): class TestVersioningContainerTempurl(TestObjectVersioningBase):
env = TestContainerTempurlEnv env = TestContainerTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
self.env.versions_header_key = 'X-Versions-Enabled' self.env.versions_header_key = 'X-Versions-Enabled'

View File

@ -2268,7 +2268,7 @@ class TestSymlinkComparison(TestSymlinkTargetObjectComparison):
class TestSymlinkAccountTempurl(Base): class TestSymlinkAccountTempurl(Base):
env = TestTempurlEnv env = TestTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
super(TestSymlinkAccountTempurl, self).setUp() super(TestSymlinkAccountTempurl, self).setUp()
@ -2364,7 +2364,7 @@ class TestSymlinkAccountTempurl(Base):
class TestSymlinkContainerTempurl(Base): class TestSymlinkContainerTempurl(Base):
env = TestContainerTempurlEnv env = TestContainerTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
super(TestSymlinkContainerTempurl, self).setUp() super(TestSymlinkContainerTempurl, self).setUp()

View File

@ -90,7 +90,7 @@ class TestTempurlEnv(TestTempurlBaseEnv):
class TestTempurl(Base): class TestTempurl(Base):
env = TestTempurlEnv env = TestTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
super(TestTempurl, self).setUp() super(TestTempurl, self).setUp()
@ -102,6 +102,8 @@ class TestTempurl(Base):
"Expected tempurl_enabled to be True/False, got %r" % "Expected tempurl_enabled to be True/False, got %r" %
(self.env.tempurl_enabled,)) (self.env.tempurl_enabled,))
# N.B. The default to 'sha1' in case the info has nothing is for
# extremely old clusters, which presumably use SHA1.
if self.digest_name not in cluster_info['tempurl'].get( if self.digest_name not in cluster_info['tempurl'].get(
'allowed_digests', ['sha1']): 'allowed_digests', ['sha1']):
raise SkipTest("tempurl does not support %s signatures" % raise SkipTest("tempurl does not support %s signatures" %
@ -461,7 +463,7 @@ class TestContainerTempurlEnv(BaseEnv):
class TestContainerTempurl(Base): class TestContainerTempurl(Base):
env = TestContainerTempurlEnv env = TestContainerTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
super(TestContainerTempurl, self).setUp() super(TestContainerTempurl, self).setUp()
@ -736,7 +738,7 @@ class TestSloTempurlEnv(TestTempurlBaseEnv):
class TestSloTempurl(Base): class TestSloTempurl(Base):
env = TestSloTempurlEnv env = TestSloTempurlEnv
digest_name = 'sha1' digest_name = 'sha256'
def setUp(self): def setUp(self):
super(TestSloTempurl, self).setUp() super(TestSloTempurl, self).setUp()

View File

@ -130,9 +130,11 @@ class TestTempURL(unittest.TestCase):
self.assertEqual(resp.status_int, 200) self.assertEqual(resp.status_int, 200)
def assert_valid_sig(self, expires, path, keys, sig, environ=None, def assert_valid_sig(self, expires, path, keys, sig, environ=None,
prefix=None): prefix=None, tempurl=None):
if not environ: if not environ:
environ = {} environ = {}
if tempurl is None:
tempurl = self.tempurl
if six.PY3 and isinstance(sig, six.binary_type): if six.PY3 and isinstance(sig, six.binary_type):
sig = sig.decode('utf-8') sig = sig.decode('utf-8')
environ['QUERY_STRING'] = 'temp_url_sig=%s&temp_url_expires=%s' % ( environ['QUERY_STRING'] = 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -140,8 +142,8 @@ class TestTempURL(unittest.TestCase):
if prefix is not None: if prefix is not None:
environ['QUERY_STRING'] += '&temp_url_prefix=%s' % prefix environ['QUERY_STRING'] += '&temp_url_prefix=%s' % prefix
req = self._make_request(path, keys=keys, environ=environ) req = self._make_request(path, keys=keys, environ=environ)
self.tempurl.app = FakeApp(iter([('200 Ok', (), '123')])) tempurl.app = FakeApp(iter([('200 Ok', (), '123')]))
resp = req.get_response(self.tempurl) resp = req.get_response(tempurl)
self.assertEqual(resp.status_int, 200) self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.headers['content-disposition'], self.assertEqual(resp.headers['content-disposition'],
'attachment; filename="o"; ' + "filename*=UTF-8''o") 'attachment; filename="o"; ' + "filename*=UTF-8''o")
@ -157,8 +159,11 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
tempurl1 = tempurl.filter_factory({
'allowed_digests': 'sha1'})(self.auth)
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
self.assert_valid_sig(expires, path, [key], sig) self.assert_valid_sig(expires, path, [key], sig, tempurl=tempurl1)
sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
self.assert_valid_sig(expires, path, [key], sig) self.assert_valid_sig(expires, path, [key], sig)
@ -178,8 +183,8 @@ class TestTempURL(unittest.TestCase):
key1 = b'abc123' key1 = b'abc123'
key2 = b'def456' key2 = b'def456'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig1 = hmac.new(key1, hmac_body, hashlib.sha1).hexdigest() sig1 = hmac.new(key1, hmac_body, hashlib.sha256).hexdigest()
sig2 = hmac.new(key2, hmac_body, hashlib.sha1).hexdigest() sig2 = hmac.new(key2, hmac_body, hashlib.sha256).hexdigest()
for sig in (sig1, sig2): for sig in (sig1, sig2):
self.assert_valid_sig(expires, path, [key1, key2], sig) self.assert_valid_sig(expires, path, [key1, key2], sig)
@ -201,8 +206,8 @@ class TestTempURL(unittest.TestCase):
key1 = b'me' key1 = b'me'
key2 = b'other' key2 = b'other'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig1 = hmac.new(key1, hmac_body, hashlib.sha1).hexdigest() sig1 = hmac.new(key1, hmac_body, hashlib.sha256).hexdigest()
sig2 = hmac.new(key2, hmac_body, hashlib.sha1).hexdigest() sig2 = hmac.new(key2, hmac_body, hashlib.sha256).hexdigest()
account_keys = [] account_keys = []
for sig in (sig1, sig2): for sig in (sig1, sig2):
self.assert_valid_sig(expires, path, account_keys, sig, environ) self.assert_valid_sig(expires, path, account_keys, sig, environ)
@ -210,9 +215,10 @@ class TestTempURL(unittest.TestCase):
def test_signature_trim(self): def test_signature_trim(self):
# Insert proxy logging into the pipeline # Insert proxy logging into the pipeline
p_logging = proxy_logging.filter_factory({})(self.app) p_logging = proxy_logging.filter_factory({})(self.app)
self.auth = tempauth.filter_factory({'reseller_prefix': ''})( self.auth = tempauth.filter_factory({
p_logging) 'reseller_prefix': ''})(p_logging)
self.tempurl = tempurl.filter_factory({})(self.auth) self.tempurl = tempurl.filter_factory({
'allowed_digests': 'sha1'})(self.auth)
sig = 'valid_sigs_will_be_exactly_40_characters' sig = 'valid_sigs_will_be_exactly_40_characters'
expires = int(time() + 1000) expires = int(time() + 1000)
@ -239,7 +245,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'filename=bob%%20%%22killer%%22.txt' % (sig, expires)}) 'filename=bob%%20%%22killer%%22.txt' % (sig, expires)})
@ -261,7 +267,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'REQUEST_METHOD': 'HEAD', 'REQUEST_METHOD': 'HEAD',
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
@ -279,7 +285,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'REQUEST_METHOD': 'HEAD', 'REQUEST_METHOD': 'HEAD',
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s'
@ -290,7 +296,7 @@ class TestTempURL(unittest.TestCase):
get_method = 'GET' get_method = 'GET'
get_hmac_body = ('%s\n%i\n%s' % get_hmac_body = ('%s\n%i\n%s' %
(get_method, expires, path)).encode('utf-8') (get_method, expires, path)).encode('utf-8')
get_sig = hmac.new(key, get_hmac_body, hashlib.sha1).hexdigest() get_sig = hmac.new(key, get_hmac_body, hashlib.sha256).hexdigest()
get_req = self._make_request(path, keys=[key], environ={ get_req = self._make_request(path, keys=[key], environ={
'REQUEST_METHOD': 'GET', 'REQUEST_METHOD': 'GET',
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s'
@ -306,7 +312,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'filename=bob%%20%%22killer%%22.txt&inline=' % (sig, expires)}) 'filename=bob%%20%%22killer%%22.txt&inline=' % (sig, expires)})
@ -328,7 +334,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'inline=' % (sig, expires)}) 'inline=' % (sig, expires)})
@ -349,14 +355,14 @@ class TestTempURL(unittest.TestCase):
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, sig_path)).encode('utf-8') (method, expires, sig_path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix) self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix)
query_path = query_path[:-1] + 'p3/o' query_path = query_path[:-1] + 'p3/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, sig_path)).encode('utf-8') (method, expires, sig_path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix) self.assert_valid_sig(expires, query_path, [key], sig, prefix=prefix)
def test_get_valid_with_prefix_empty(self): def test_get_valid_with_prefix_empty(self):
@ -367,7 +373,7 @@ class TestTempURL(unittest.TestCase):
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, sig_path)).encode('utf-8') (method, expires, sig_path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
self.assert_valid_sig(expires, query_path, [key], sig, prefix='') self.assert_valid_sig(expires, query_path, [key], sig, prefix='')
def test_obj_odd_chars(self): def test_obj_odd_chars(self):
@ -376,7 +382,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/a\r\nb' path = '/v1/a/c/a\r\nb'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(quote(path), keys=[key], environ={ req = self._make_request(quote(path), keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
sig, expires)}) sig, expires)})
@ -396,7 +402,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
sig, expires)}) sig, expires)})
@ -416,7 +422,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o/' path = '/v1/a/c/o/'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
sig, expires)}) sig, expires)})
@ -436,7 +442,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'filename=/i/want/this/just/as/it/is/' % (sig, expires)}) 'filename=/i/want/this/just/as/it/is/' % (sig, expires)})
@ -457,7 +463,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -475,7 +481,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'PUT', environ={'REQUEST_METHOD': 'PUT',
@ -492,7 +498,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'PUT', environ={'REQUEST_METHOD': 'PUT',
@ -526,7 +532,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'PUT', environ={'REQUEST_METHOD': 'PUT',
@ -545,7 +551,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -561,7 +567,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
hmac.new(key, hmac_body, hashlib.sha1).hexdigest() hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_expires=%s' % expires}) environ={'QUERY_STRING': 'temp_url_expires=%s' % expires})
@ -576,7 +582,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s' % sig}) environ={'QUERY_STRING': 'temp_url_sig=%s' % sig})
@ -591,7 +597,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/' path = '/v1/a/c/'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -607,7 +613,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[], path, keys=[],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -623,7 +629,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'HEAD', environ={'REQUEST_METHOD': 'HEAD',
@ -640,7 +646,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'HEAD', environ={'REQUEST_METHOD': 'HEAD',
@ -657,7 +663,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'HEAD', environ={'REQUEST_METHOD': 'HEAD',
@ -674,7 +680,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
# Deliberately fudge expires to show HEADs aren't just automatically # Deliberately fudge expires to show HEADs aren't just automatically
# allowed. # allowed.
expires += 1 expires += 1
@ -694,7 +700,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'POST', environ={'REQUEST_METHOD': 'POST',
@ -712,7 +718,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'DELETE', environ={'REQUEST_METHOD': 'DELETE',
@ -729,7 +735,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'DELETE', environ={'REQUEST_METHOD': 'DELETE',
@ -744,7 +750,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'REQUEST_METHOD': 'UNKNOWN', environ={'REQUEST_METHOD': 'UNKNOWN',
@ -772,7 +778,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(b'account-key', hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(b'account-key', hmac_body, hashlib.sha256).hexdigest()
qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires)
# make request will setup the environ cache for us # make request will setup the environ cache for us
@ -794,7 +800,7 @@ class TestTempURL(unittest.TestCase):
# the container level; a different container in the same account is # the container level; a different container in the same account is
# out of scope and thus forbidden. # out of scope and thus forbidden.
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(b'container-key', hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(b'container-key', hmac_body, hashlib.sha256).hexdigest()
qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires)
req = self._make_request(path + qs, **key_kwargs) req = self._make_request(path + qs, **key_kwargs)
@ -815,7 +821,7 @@ class TestTempURL(unittest.TestCase):
# account-level tempurls by reusing one of the account's keys on a # account-level tempurls by reusing one of the account's keys on a
# container. # container.
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(b'shared-key', hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(b'shared-key', hmac_body, hashlib.sha256).hexdigest()
qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires) qs = '?temp_url_sig=%s&temp_url_expires=%s' % (sig, expires)
req = self._make_request(path + qs, **key_kwargs) req = self._make_request(path + qs, **key_kwargs)
@ -836,7 +842,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path + '2', keys=[key], path + '2', keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -852,7 +858,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
if sig[-1] != '0': if sig[-1] != '0':
sig = sig[:-1] + '0' sig = sig[:-1] + '0'
else: else:
@ -872,7 +878,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -936,7 +942,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key + b'2'], path, keys=[key + b'2'],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -954,7 +960,7 @@ class TestTempURL(unittest.TestCase):
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, sig_path)).encode('utf-8') (method, expires, sig_path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
query_path, keys=[key], query_path, keys=[key],
environ={'QUERY_STRING': environ={'QUERY_STRING':
@ -972,7 +978,7 @@ class TestTempURL(unittest.TestCase):
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, path)).encode('utf-8') (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': environ={'QUERY_STRING':
@ -993,7 +999,7 @@ class TestTempURL(unittest.TestCase):
('X-Symlink-Target', 'cont/symlink')]: ('X-Symlink-Target', 'cont/symlink')]:
hmac_body = ('%s\n%i\n%s' % hmac_body = ('%s\n%i\n%s' %
(method, expires, path)).encode('utf-8') (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, method=method, keys=[key], path, method=method, keys=[key],
headers={hdr: value}, headers={hdr: value},
@ -1014,7 +1020,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={'x-remove-this': 'value'}, headers={'x-remove-this': 'value'},
@ -1033,7 +1039,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={'x-remove-this-one': 'value1', headers={'x-remove-this-one': 'value1',
@ -1055,7 +1061,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={'x-conflict-header': 'value'}, headers={'x-conflict-header': 'value'},
@ -1074,7 +1080,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={'x-conflict-header-test': 'value'}, headers={'x-conflict-header-test': 'value'},
@ -1092,7 +1098,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -1111,7 +1117,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( environ={'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % (
@ -1131,7 +1137,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={}, headers={},
@ -1153,7 +1159,7 @@ class TestTempURL(unittest.TestCase):
path = '/v1/a/c/o' path = '/v1/a/c/o'
key = b'abc' key = b'abc'
hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8') hmac_body = ('%s\n%i\n%s' % (method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request( req = self._make_request(
path, keys=[key], path, keys=[key],
headers={}, headers={},
@ -1467,7 +1473,7 @@ class TestTempURL(unittest.TestCase):
ip_range = '127.0.0.0/29' ip_range = '127.0.0.0/29'
hmac_body = ('ip=%s\n%s\n%i\n%s' % hmac_body = ('ip=%s\n%s\n%i\n%s' %
(ip_range, method, expires, path)).encode('utf-8') (ip_range, method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'temp_url_ip_range=%s' % (sig, expires, ip_range), 'temp_url_ip_range=%s' % (sig, expires, ip_range),
@ -1491,7 +1497,7 @@ class TestTempURL(unittest.TestCase):
ip = '127.0.0.1' ip = '127.0.0.1'
hmac_body = ('ip=%s\n%s\n%i\n%s' % hmac_body = ('ip=%s\n%s\n%i\n%s' %
(ip, method, expires, path)).encode('utf-8') (ip, method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'temp_url_ip_range=%s' % (sig, expires, ip), 'temp_url_ip_range=%s' % (sig, expires, ip),
@ -1536,7 +1542,7 @@ class TestTempURL(unittest.TestCase):
ip = '2001:db8::' ip = '2001:db8::'
hmac_body = ('ip=%s\n%s\n%i\n%s' % hmac_body = ('ip=%s\n%s\n%i\n%s' %
(ip, method, expires, path)).encode('utf-8') (ip, method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'temp_url_ip_range=%s' % (sig, expires, ip), 'temp_url_ip_range=%s' % (sig, expires, ip),
@ -1560,7 +1566,7 @@ class TestTempURL(unittest.TestCase):
ip_range = '2001:db8::/127' ip_range = '2001:db8::/127'
hmac_body = ('ip=%s\n%s\n%i\n%s' % hmac_body = ('ip=%s\n%s\n%i\n%s' %
(ip_range, method, expires, path)).encode('utf-8') (ip_range, method, expires, path)).encode('utf-8')
sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest() sig = hmac.new(key, hmac_body, hashlib.sha256).hexdigest()
req = self._make_request(path, keys=[key], environ={ req = self._make_request(path, keys=[key], environ={
'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&' 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s&'
'temp_url_ip_range=%s' % (sig, expires, ip_range), 'temp_url_ip_range=%s' % (sig, expires, ip_range),
@ -1614,7 +1620,7 @@ class TestSwiftInfo(unittest.TestCase):
set(('x-object-meta-*',))) set(('x-object-meta-*',)))
self.assertEqual(set(info['outgoing_allow_headers']), self.assertEqual(set(info['outgoing_allow_headers']),
set(('x-object-meta-public-*',))) set(('x-object-meta-public-*',)))
self.assertEqual(info['allowed_digests'], ['sha1', 'sha256', 'sha512']) self.assertEqual(info['allowed_digests'], ['sha256', 'sha512'])
def test_non_default_methods(self): def test_non_default_methods(self):
tempurl.filter_factory({ tempurl.filter_factory({
@ -1623,7 +1629,7 @@ class TestSwiftInfo(unittest.TestCase):
'incoming_allow_headers': 'x-timestamp x-versions-location', 'incoming_allow_headers': 'x-timestamp x-versions-location',
'outgoing_remove_headers': 'x-*', 'outgoing_remove_headers': 'x-*',
'outgoing_allow_headers': 'x-object-meta-* content-type', 'outgoing_allow_headers': 'x-object-meta-* content-type',
'allowed_digests': 'sha512 md5 not-a-valid-digest', 'allowed_digests': 'sha1 sha512 md5 not-a-valid-digest',
}) })
swift_info = registry.get_swift_info() swift_info = registry.get_swift_info()
self.assertIn('tempurl', swift_info) self.assertIn('tempurl', swift_info)
@ -1636,7 +1642,7 @@ class TestSwiftInfo(unittest.TestCase):
self.assertEqual(set(info['outgoing_remove_headers']), set(('x-*', ))) self.assertEqual(set(info['outgoing_remove_headers']), set(('x-*', )))
self.assertEqual(set(info['outgoing_allow_headers']), self.assertEqual(set(info['outgoing_allow_headers']),
set(('x-object-meta-*', 'content-type'))) set(('x-object-meta-*', 'content-type')))
self.assertEqual(info['allowed_digests'], ['sha512']) self.assertEqual(info['allowed_digests'], ['sha1', 'sha512'])
def test_bad_config(self): def test_bad_config(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
@ -1645,5 +1651,19 @@ class TestSwiftInfo(unittest.TestCase):
}) })
class TestTempurlWarning(unittest.TestCase):
def test_deprecation_warning(self):
logger = debug_logger()
with mock.patch('swift.common.middleware.tempurl.get_logger',
lambda *a, **kw: logger):
tempurl.filter_factory({'allowed_digests': 'sha1'})
log_lines = logger.get_lines_for_level('warning')
self.assertIn(
'The following digest algorithms are configured but deprecated:'
' sha1. Support will be removed in a future release.',
log_lines)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -3851,6 +3851,25 @@ cluster_dfw1 = http://dfw1.host/v1/
utils.get_hmac(u'GET', u'/path', 1, u'abc', ip_range=u'127.0.0.1'), utils.get_hmac(u'GET', u'/path', 1, u'abc', ip_range=u'127.0.0.1'),
'b30dde4d2b8562b8496466c3b46b2b9ac5054461') 'b30dde4d2b8562b8496466c3b46b2b9ac5054461')
def test_get_hmac_digest(self):
self.assertEqual(
utils.get_hmac(u'GET', u'/path', 1, u'abc', digest='sha256'),
'64c5558394f86b042ce1e929b34907abd9d0a57f3e20cd3f93cffd83de0206a7')
self.assertEqual(
utils.get_hmac(u'GET', u'/path', 1, u'abc', digest=hashlib.sha256),
'64c5558394f86b042ce1e929b34907abd9d0a57f3e20cd3f93cffd83de0206a7')
self.assertEqual(
utils.get_hmac(u'GET', u'/path', 1, u'abc', digest='sha512'),
'7e95af818aec1b69b53fc2cb6d69456ec64ebda6c17b8fc8b7303b78acc8ca'
'14fc4aed96c1614a8e9d6ff45a6237711d8be294cda679624825d79aa6959b'
'5229')
self.assertEqual(
utils.get_hmac(u'GET', u'/path', 1, u'abc', digest=hashlib.sha512),
'7e95af818aec1b69b53fc2cb6d69456ec64ebda6c17b8fc8b7303b78acc8ca'
'14fc4aed96c1614a8e9d6ff45a6237711d8be294cda679624825d79aa6959b'
'5229')
def test_parse_override_options(self): def test_parse_override_options(self):
# When override_<thing> is passed in, it takes precedence. # When override_<thing> is passed in, it takes precedence.
opts = utils.parse_override_options( opts = utils.parse_override_options(