Merge "Fix invalid account acl generating 500 response."
This commit is contained in:
commit
3532d314e5
@ -207,17 +207,21 @@ def parse_acl_v2(data):
|
|||||||
Parses a version-2 Swift ACL string and returns a dict of ACL info.
|
Parses a version-2 Swift ACL string and returns a dict of ACL info.
|
||||||
|
|
||||||
:param data: string containing the ACL data in JSON format
|
:param data: string containing the ACL data in JSON format
|
||||||
:returns: A dict containing ACL info, e.g.:
|
:returns: A dict (possibly empty) containing ACL info, e.g.:
|
||||||
{"groups": [...], "referrers": [...]}
|
{"groups": [...], "referrers": [...]}
|
||||||
:returns: None if data is None
|
:returns: None if data is None, is not valid JSON or does not parse
|
||||||
:returns: empty dictionary if data does not parse as valid JSON
|
as a dict
|
||||||
|
:returns: empty dictionary if data is an empty string
|
||||||
"""
|
"""
|
||||||
if data is None:
|
if data is None:
|
||||||
return None
|
return None
|
||||||
try:
|
if data is '':
|
||||||
return json.loads(data)
|
|
||||||
except ValueError:
|
|
||||||
return {}
|
return {}
|
||||||
|
try:
|
||||||
|
result = json.loads(data)
|
||||||
|
return (result if type(result) is dict else None)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_acl(*args, **kwargs):
|
def parse_acl(*args, **kwargs):
|
||||||
|
@ -324,7 +324,7 @@ class TempAuth(object):
|
|||||||
acl_header = 'x-account-access-control'
|
acl_header = 'x-account-access-control'
|
||||||
acl_data = req.headers.get(acl_header)
|
acl_data = req.headers.get(acl_header)
|
||||||
result = parse_acl(version=2, data=acl_data)
|
result = parse_acl(version=2, data=acl_data)
|
||||||
if (not result and acl_data not in ('', '{}')):
|
if result is None:
|
||||||
return 'Syntax error in input (%r)' % acl_data
|
return 'Syntax error in input (%r)' % acl_data
|
||||||
|
|
||||||
tempauth_acl_keys = 'admin read-write read-only'.split()
|
tempauth_acl_keys = 'admin read-write read-only'.split()
|
||||||
|
@ -90,6 +90,17 @@ class TestACL(unittest.TestCase):
|
|||||||
# No header "hdr" exists -- should return None
|
# No header "hdr" exists -- should return None
|
||||||
({}, None),
|
({}, None),
|
||||||
({'junk': 'junk'}, None),
|
({'junk': 'junk'}, None),
|
||||||
|
|
||||||
|
# Empty ACLs should return empty dict
|
||||||
|
({'hdr': ''}, {}),
|
||||||
|
({'hdr': '{}'}, {}),
|
||||||
|
({'hdr': '{ }'}, {}),
|
||||||
|
|
||||||
|
# Bad input -- should return None
|
||||||
|
({'hdr': '["array"]'}, None),
|
||||||
|
({'hdr': 'null'}, None),
|
||||||
|
({'hdr': '"some_string"'}, None),
|
||||||
|
({'hdr': '123'}, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
for hdrs_in, expected in tests:
|
for hdrs_in, expected in tests:
|
||||||
|
@ -1016,13 +1016,16 @@ class TestAccountAcls(unittest.TestCase):
|
|||||||
|
|
||||||
def test_acl_syntax_verification(self):
|
def test_acl_syntax_verification(self):
|
||||||
test_auth = auth.filter_factory({'user_admin_user': 'testing'})(
|
test_auth = auth.filter_factory({'user_admin_user': 'testing'})(
|
||||||
FakeApp(iter(NO_CONTENT_RESP * 3)))
|
FakeApp(iter(NO_CONTENT_RESP * 5)))
|
||||||
|
|
||||||
good_headers = {'X-Auth-Token': 'AUTH_t'}
|
good_headers = {'X-Auth-Token': 'AUTH_t'}
|
||||||
good_acl = '{"read-only":["a","b"]}'
|
good_acl = '{"read-only":["a","b"]}'
|
||||||
bad_acl = 'syntactically invalid acl -- this does not parse as JSON'
|
bad_acl = 'syntactically invalid acl -- this does not parse as JSON'
|
||||||
wrong_acl = '{"other-auth-system":["valid","json","but","wrong"]}'
|
wrong_acl = '{"other-auth-system":["valid","json","but","wrong"]}'
|
||||||
bad_value_acl = '{"read-write":["fine"],"admin":"should be a list"}'
|
bad_value_acl = '{"read-write":["fine"],"admin":"should be a list"}'
|
||||||
|
not_dict_acl = '["read-only"]'
|
||||||
|
not_dict_acl2 = 1
|
||||||
|
empty_acls = ['{}', '', '{ }']
|
||||||
target = '/v1/AUTH_firstacct'
|
target = '/v1/AUTH_firstacct'
|
||||||
|
|
||||||
# no acls -- no problem!
|
# no acls -- no problem!
|
||||||
@ -1036,6 +1039,14 @@ class TestAccountAcls(unittest.TestCase):
|
|||||||
resp = req.get_response(test_auth)
|
resp = req.get_response(test_auth)
|
||||||
self.assertEquals(resp.status_int, 204)
|
self.assertEquals(resp.status_int, 204)
|
||||||
|
|
||||||
|
# syntactically valid empty acls should go through
|
||||||
|
for acl in empty_acls:
|
||||||
|
update = {'x-account-access-control': acl}
|
||||||
|
req = self._make_request(target,
|
||||||
|
headers=dict(good_headers, **update))
|
||||||
|
resp = req.get_response(test_auth)
|
||||||
|
self.assertEquals(resp.status_int, 204)
|
||||||
|
|
||||||
errmsg = 'X-Account-Access-Control invalid: %s'
|
errmsg = 'X-Account-Access-Control invalid: %s'
|
||||||
# syntactically invalid acls get a 400
|
# syntactically invalid acls get a 400
|
||||||
update = {'x-account-access-control': bad_acl}
|
update = {'x-account-access-control': bad_acl}
|
||||||
@ -1058,6 +1069,20 @@ class TestAccountAcls(unittest.TestCase):
|
|||||||
self.assertEquals(resp.status_int, 400)
|
self.assertEquals(resp.status_int, 400)
|
||||||
self.assertEquals(errmsg % "Value", resp.body[:39])
|
self.assertEquals(errmsg % "Value", resp.body[:39])
|
||||||
|
|
||||||
|
# acls with wrong json structure also get a 400
|
||||||
|
update = {'x-account-access-control': not_dict_acl}
|
||||||
|
req = self._make_request(target, headers=dict(good_headers, **update))
|
||||||
|
resp = req.get_response(test_auth)
|
||||||
|
self.assertEquals(resp.status_int, 400)
|
||||||
|
self.assertEquals(errmsg % "Syntax error", resp.body[:46])
|
||||||
|
|
||||||
|
# acls with wrong json structure also get a 400
|
||||||
|
update = {'x-account-access-control': not_dict_acl2}
|
||||||
|
req = self._make_request(target, headers=dict(good_headers, **update))
|
||||||
|
resp = req.get_response(test_auth)
|
||||||
|
self.assertEquals(resp.status_int, 400)
|
||||||
|
self.assertEquals(errmsg % "Syntax error", resp.body[:46])
|
||||||
|
|
||||||
def test_acls_propagate_to_sysmeta(self):
|
def test_acls_propagate_to_sysmeta(self):
|
||||||
test_auth = auth.filter_factory({'user_admin_user': 'testing'})(
|
test_auth = auth.filter_factory({'user_admin_user': 'testing'})(
|
||||||
FakeApp(iter(NO_CONTENT_RESP * 3)))
|
FakeApp(iter(NO_CONTENT_RESP * 3)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user