Merge "absolute expiry option for tempURL generation"

This commit is contained in:
Jenkins 2015-09-05 20:16:38 +00:00 committed by Gerrit Code Review
commit fa7ffdd292
5 changed files with 52 additions and 20 deletions
doc/manpages
swiftclient
tests/unit

@ -104,12 +104,14 @@ is not provided the storage-url retrieved after authentication is used as
proxy-url.
.RE
\fBtempurl\fR method seconds path key
\fBtempurl\fR \fImethod\fR \fIseconds\fR \fIpath\fR \fIkey\fR [\fI--absolute\fR]
.RS 4
Generates a temporary URL allowing unauthenticated access to the Swift object at
the given path, using the given HTTP method, for the given number of seconds,
using the given TempURL key. \fBExample\fR: tempurl GET 86400
/v1/AUTH_foo/bar_container/quux.md my_secret_tempurl_key
Generates a temporary URL allowing unauthenticated access to the Swift object
at the given path, using the given HTTP method, for the given number of
seconds, using the given TempURL key. If optional --absolute argument is
provided, seconds is instead interpreted as a Unix timestamp at which the URL
should expire. \fBExample\fR: tempurl GET $(date -d "Jan 1 2016" +%s)
/v1/AUTH_foo/bar_container/quux.md my_secret_tempurl_key --absolute
.RE
.SH OPTIONS

@ -1013,17 +1013,30 @@ Generates a temporary URL for a Swift object.
Positional arguments:
<method> An HTTP method to allow for this temporary URL.
Usually 'GET' or 'PUT'.
<seconds> The amount of time in seconds the temporary URL will
be valid for.
<seconds> The amount of time in seconds the temporary URL will be
valid for; or, if --absolute is passed, the Unix
timestamp when the temporary URL will expire.
<path> The full path to the Swift object. Example:
/v1/AUTH_account/c/o.
<key> The secret temporary URL key set on the Swift cluster.
To set a key, run \'swift post -m
"Temp-URL-Key:b3968d0207b54ece87cccc06515a89d4"\'
Optional arguments:
--absolute Interpet the <seconds> positional argument as a Unix
timestamp rather than a number of seconds in the
future.
'''.strip('\n')
def st_tempurl(parser, args, thread_manager):
parser.add_option(
'--absolute', action='store_true',
dest='absolute_expiry', default=False,
help=("If present, seconds argument will be interpreted as a Unix "
"timestamp representing when the tempURL should expire, rather "
"than an offset from the current time")
)
(options, args) = parse_args(parser, args)
args = args[1:]
if len(args) < 4:
@ -1040,7 +1053,8 @@ def st_tempurl(parser, args, thread_manager):
thread_manager.print_msg('WARNING: Non default HTTP method %s for '
'tempurl specified, possibly an error' %
method.upper())
url = generate_temp_url(path, seconds, key, method)
url = generate_temp_url(path, seconds, key, method,
absolute=options.absolute_expiry)
thread_manager.print_msg(url)

@ -65,8 +65,8 @@ def prt_bytes(bytes, human_flag):
return bytes
def generate_temp_url(path, seconds, key, method):
""" Generates a temporary URL that gives unauthenticated access to the
def generate_temp_url(path, seconds, key, method, absolute=False):
"""Generates a temporary URL that gives unauthenticated access to the
Swift object.
:param path: The full path to the Swift object. Example:
@ -85,7 +85,10 @@ def generate_temp_url(path, seconds, key, method):
if seconds < 0:
raise ValueError('seconds must be a positive integer')
try:
expiration = int(time.time() + seconds)
if not absolute:
expiration = int(time.time() + seconds)
else:
expiration = int(seconds)
except TypeError:
raise TypeError('seconds must be an integer')

@ -922,15 +922,21 @@ class TestShell(unittest.TestCase):
self.assertTrue(output.err != '')
self.assertTrue(output.err.startswith('Usage'))
@mock.patch('swiftclient.shell.generate_temp_url')
@mock.patch('swiftclient.shell.generate_temp_url', return_value='')
def test_temp_url(self, temp_url):
argv = ["", "tempurl", "GET", "60", "/v1/AUTH_account/c/o",
"secret_key"
]
temp_url.return_value = ""
"secret_key"]
swiftclient.shell.main(argv)
temp_url.assert_called_with(
'/v1/AUTH_account/c/o', 60, 'secret_key', 'GET')
'/v1/AUTH_account/c/o', 60, 'secret_key', 'GET', absolute=False)
@mock.patch('swiftclient.shell.generate_temp_url', return_value='')
def test_absolute_expiry_temp_url(self, temp_url):
argv = ["", "tempurl", "GET", "60", "/v1/AUTH_account/c/o",
"secret_key", "--absolute"]
swiftclient.shell.main(argv)
temp_url.assert_called_with(
'/v1/AUTH_account/c/o', 60, 'secret_key', 'GET', absolute=True)
@mock.patch('swiftclient.service.Connection')
def test_capabilities(self, connection):

@ -132,11 +132,9 @@ class TestTempURL(testtools.TestCase):
self.key = 'correcthorsebatterystaple'
self.method = 'GET'
@mock.patch('hmac.HMAC.hexdigest')
@mock.patch('time.time')
@mock.patch('hmac.HMAC.hexdigest', return_value='temp_url_signature')
@mock.patch('time.time', return_value=1400000000)
def test_generate_temp_url(self, time_mock, hmac_mock):
time_mock.return_value = 1400000000
hmac_mock.return_value = 'temp_url_signature'
expected_url = (
'/v1/AUTH_account/c/o?'
'temp_url_sig=temp_url_signature&'
@ -145,6 +143,15 @@ class TestTempURL(testtools.TestCase):
self.method)
self.assertEqual(url, expected_url)
@mock.patch('hmac.HMAC.hexdigest', return_value="temp_url_signature")
def test_generate_absolute_expiry_temp_url(self, hmac_mock):
expected_url = ('/v1/AUTH_account/c/o?'
'temp_url_sig=temp_url_signature&'
'temp_url_expires=2146636800')
url = u.generate_temp_url(self.url, 2146636800, self.key, self.method,
absolute=True)
self.assertEqual(url, expected_url)
def test_generate_temp_url_bad_seconds(self):
self.assertRaises(TypeError,
u.generate_temp_url,