Implements configurable swift_owner_headers
These are headers that will be stripped unless the WSGI environment contains a true value for 'swift_owner'. The exact definition of a swift_owner is up to the auth system in use, but usually indicates administrative responsibilities. DocImpact Change-Id: I972772fbbd235414e00130ca663428e8750cabca
This commit is contained in:
parent
716ad3e07b
commit
52eca4d8a7
@ -836,6 +836,13 @@ request_node_count 2 * replicas Set to the number of nodes to
|
|||||||
given times the number of
|
given times the number of
|
||||||
replicas for the ring being used
|
replicas for the ring being used
|
||||||
for the request.
|
for the request.
|
||||||
|
swift_owner_headers <see the sample These are the headers whose
|
||||||
|
conf file for values will only be shown to
|
||||||
|
the list of swift_owners. The exact
|
||||||
|
default definition of a swift_owner is
|
||||||
|
headers> up to the auth system in use,
|
||||||
|
but usually indicates
|
||||||
|
administrative responsibilities.
|
||||||
============================ =============== =============================
|
============================ =============== =============================
|
||||||
|
|
||||||
[tempauth]
|
[tempauth]
|
||||||
|
@ -176,6 +176,11 @@ use = egg:swift#proxy
|
|||||||
# times the number of replicas for the ring being used for the
|
# times the number of replicas for the ring being used for the
|
||||||
# request.
|
# request.
|
||||||
# write_affinity_node_count = 2 * replicas
|
# write_affinity_node_count = 2 * replicas
|
||||||
|
#
|
||||||
|
# These are the headers whose values will only be shown to swift_owners. The
|
||||||
|
# exact definition of a swift_owner is up to the auth system in use, but
|
||||||
|
# usually indicates administrative responsibilities.
|
||||||
|
# swift_owner_headers = x-container-read, x-container-write, x-container-sync-key, x-container-sync-to, x-account-meta-temp-url-key, x-account-meta-temp-url-key-2
|
||||||
|
|
||||||
|
|
||||||
[filter:tempauth]
|
[filter:tempauth]
|
||||||
|
@ -63,8 +63,12 @@ class AccountController(Controller):
|
|||||||
content_type, error = account_listing_content_type(req)
|
content_type, error = account_listing_content_type(req)
|
||||||
if error:
|
if error:
|
||||||
return error
|
return error
|
||||||
return account_listing_response(self.account_name, req,
|
resp = account_listing_response(self.account_name, req,
|
||||||
content_type)
|
content_type)
|
||||||
|
if not req.environ.get('swift_owner', False):
|
||||||
|
for key in self.app.swift_owner_headers:
|
||||||
|
if key in resp.headers:
|
||||||
|
del resp.headers[key]
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@public
|
@public
|
||||||
|
@ -82,8 +82,7 @@ class ContainerController(Controller):
|
|||||||
if aresp:
|
if aresp:
|
||||||
return aresp
|
return aresp
|
||||||
if not req.environ.get('swift_owner', False):
|
if not req.environ.get('swift_owner', False):
|
||||||
for key in ('x-container-read', 'x-container-write',
|
for key in self.app.swift_owner_headers:
|
||||||
'x-container-sync-key', 'x-container-sync-to'):
|
|
||||||
if key in resp.headers:
|
if key in resp.headers:
|
||||||
del resp.headers[key]
|
del resp.headers[key]
|
||||||
return resp
|
return resp
|
||||||
|
@ -155,6 +155,14 @@ class Application(object):
|
|||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Invalid write_affinity_node_count value: %r' % ''.join(value))
|
'Invalid write_affinity_node_count value: %r' % ''.join(value))
|
||||||
|
swift_owner_headers = conf.get(
|
||||||
|
'swift_owner_headers',
|
||||||
|
'x-container-read, x-container-write, '
|
||||||
|
'x-container-sync-key, x-container-sync-to, '
|
||||||
|
'x-account-meta-temp-url-key, x-account-meta-temp-url-key-2')
|
||||||
|
self.swift_owner_headers = [
|
||||||
|
name.strip()
|
||||||
|
for name in swift_owner_headers.split(',') if name.strip()]
|
||||||
|
|
||||||
def get_controller(self, path):
|
def get_controller(self, path):
|
||||||
"""
|
"""
|
||||||
|
@ -40,6 +40,28 @@ class TestAccountController(unittest.TestCase):
|
|||||||
self.assertEqual(headers_to_account_info(resp.headers),
|
self.assertEqual(headers_to_account_info(resp.headers),
|
||||||
resp.environ['swift.account/AUTH_bob'])
|
resp.environ['swift.account/AUTH_bob'])
|
||||||
|
|
||||||
|
def test_swift_owner(self):
|
||||||
|
owner_headers = {
|
||||||
|
'x-account-meta-temp-url-key': 'value',
|
||||||
|
'x-account-meta-temp-url-key-2': 'value'}
|
||||||
|
controller = proxy_server.AccountController(self.app, 'a')
|
||||||
|
|
||||||
|
req = Request.blank('/a')
|
||||||
|
with mock.patch('swift.proxy.controllers.base.http_connect',
|
||||||
|
fake_http_connect(200, 200, headers=owner_headers)):
|
||||||
|
resp = controller.HEAD(req)
|
||||||
|
self.assertEquals(2, resp.status_int // 100)
|
||||||
|
for key in owner_headers:
|
||||||
|
self.assertTrue(key not in resp.headers)
|
||||||
|
|
||||||
|
req = Request.blank('/a', environ={'swift_owner': True})
|
||||||
|
with mock.patch('swift.proxy.controllers.base.http_connect',
|
||||||
|
fake_http_connect(200, 200, headers=owner_headers)):
|
||||||
|
resp = controller.HEAD(req)
|
||||||
|
self.assertEquals(2, resp.status_int // 100)
|
||||||
|
for key in owner_headers:
|
||||||
|
self.assertTrue(key in resp.headers)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -40,6 +40,28 @@ class TestContainerController(unittest.TestCase):
|
|||||||
self.assertEqual(headers_to_container_info(resp.headers),
|
self.assertEqual(headers_to_container_info(resp.headers),
|
||||||
resp.environ['swift.container/a/c'])
|
resp.environ['swift.container/a/c'])
|
||||||
|
|
||||||
|
def test_swift_owner(self):
|
||||||
|
owner_headers = {
|
||||||
|
'x-container-read': 'value', 'x-container-write': 'value',
|
||||||
|
'x-container-sync-key': 'value', 'x-container-sync-to': 'value'}
|
||||||
|
controller = proxy_server.ContainerController(self.app, 'a', 'c')
|
||||||
|
|
||||||
|
req = Request.blank('/a/c')
|
||||||
|
with mock.patch('swift.proxy.controllers.base.http_connect',
|
||||||
|
fake_http_connect(200, 200, headers=owner_headers)):
|
||||||
|
resp = controller.HEAD(req)
|
||||||
|
self.assertEquals(2, resp.status_int // 100)
|
||||||
|
for key in owner_headers:
|
||||||
|
self.assertTrue(key not in resp.headers)
|
||||||
|
|
||||||
|
req = Request.blank('/a/c', environ={'swift_owner': True})
|
||||||
|
with mock.patch('swift.proxy.controllers.base.http_connect',
|
||||||
|
fake_http_connect(200, 200, headers=owner_headers)):
|
||||||
|
resp = controller.HEAD(req)
|
||||||
|
self.assertEquals(2, resp.status_int // 100)
|
||||||
|
for key in owner_headers:
|
||||||
|
self.assertTrue(key in resp.headers)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user