Allow a configurable set of TempURL methods

Folks have actually been asking for this. I think they're sending a
DELETE TempURL to someone way ahead of time and the someone issues it
when they're ready. Honestly, I'm not entirely sure of the use case,
but having the set of methods configurable wouldn't hurt.

Change-Id: Ibdb48f8a72077b045eeedddfae4c0a1f56098d7a
This commit is contained in:
gholt 2013-04-04 16:44:22 +00:00
parent 2927dcc967
commit 1cb952a958
4 changed files with 26 additions and 8 deletions

View File

@ -13,8 +13,7 @@ if __name__ == '__main__':
print 'Syntax: %s <method> <seconds> <path> <key>' % prog print 'Syntax: %s <method> <seconds> <path> <key>' % prog
print print
print 'Where:' print 'Where:'
print ' <method> The method to allow, GET or PUT.' print ' <method> The method to allow; GET for example.'
print ' Note: HEAD will also be allowed.'
print ' <seconds> The number of seconds from now to allow requests.' print ' <seconds> The number of seconds from now to allow requests.'
print ' <path> The full path to the resource.' print ' <path> The full path to the resource.'
print ' Example: /v1/AUTH_account/c/o' print ' Example: /v1/AUTH_account/c/o'
@ -35,9 +34,6 @@ if __name__ == '__main__':
'temp_url_expires=1323482948' 'temp_url_expires=1323482948'
exit(1) exit(1)
method, seconds, path, key = argv[1:] method, seconds, path, key = argv[1:]
if method not in ('GET', 'PUT'):
print 'Please use either the GET or PUT method.'
exit(1)
try: try:
expires = int(time() + int(seconds)) expires = int(time() + int(seconds))
except ValueError: except ValueError:

View File

@ -282,6 +282,8 @@ use = egg:swift#staticweb
# Note: Put tempurl just before your auth filter(s) in the pipeline # Note: Put tempurl just before your auth filter(s) in the pipeline
[filter:tempurl] [filter:tempurl]
use = egg:swift#tempurl use = egg:swift#tempurl
# The methods allowed with Temp URLs.
# methods = GET HEAD PUT
# #
# The headers to remove from incoming requests. Simply a whitespace delimited # The headers to remove from incoming requests. Simply a whitespace delimited
# list of header names and names can optionally end with '*' to indicate a # list of header names and names can optionally end with '*' to indicate a

View File

@ -173,6 +173,9 @@ class TempURL(object):
#: The filter configuration dict. #: The filter configuration dict.
self.conf = conf self.conf = conf
#: The methods allowed with Temp URLs.
self.methods = conf.get('methods', 'GET HEAD PUT').split()
headers = DEFAULT_INCOMING_REMOVE_HEADERS headers = DEFAULT_INCOMING_REMOVE_HEADERS
if 'incoming_remove_headers' in conf: if 'incoming_remove_headers' in conf:
headers = conf['incoming_remove_headers'] headers = conf['incoming_remove_headers']
@ -290,14 +293,15 @@ class TempURL(object):
def _get_account(self, env): def _get_account(self, env):
""" """
Returns just the account for the request, if it's an object GET, PUT, Returns just the account for the request, if it's an object
or HEAD request; otherwise, None is returned. request and one of the configured methods; otherwise, None is
returned.
:param env: The WSGI environment for the request. :param env: The WSGI environment for the request.
:returns: Account str or None. :returns: Account str or None.
""" """
account = None account = None
if env['REQUEST_METHOD'] in ('GET', 'PUT', 'HEAD'): if env['REQUEST_METHOD'] in self.methods:
parts = env['PATH_INFO'].split('/', 4) parts = env['PATH_INFO'].split('/', 4)
# Must be five parts, ['', 'v1', 'a', 'c', 'o'], must be a v1 # Must be five parts, ['', 'v1', 'a', 'c', 'o'], must be a v1
# request, have account, container, and object values, and the # request, have account, container, and object values, and the

View File

@ -336,6 +336,22 @@ class TestTempURL(unittest.TestCase):
self.assertEquals(resp.status_int, 401) self.assertEquals(resp.status_int, 401)
self.assertTrue('Temp URL invalid' in resp.body) self.assertTrue('Temp URL invalid' in resp.body)
def test_delete_allowed_with_conf(self):
self.tempurl.methods.append('DELETE')
method = 'DELETE'
expires = int(time() + 86400)
path = '/v1/a/c/o'
key = 'abc'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest()
req = self._make_request(path,
environ={'REQUEST_METHOD': 'DELETE',
'QUERY_STRING':
'temp_url_sig=%s&temp_url_expires=%s' % (sig, expires)})
req.environ['swift.cache'].set('temp-url-key/a', key)
resp = req.get_response(self.tempurl)
self.assertEquals(resp.status_int, 404)
def test_unknown_not_allowed(self): def test_unknown_not_allowed(self):
method = 'UNKNOWN' method = 'UNKNOWN'
expires = int(time() + 86400) expires = int(time() + 86400)