summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Elliott <bdelliott@gmail.com>2012-08-24 15:59:40 -0500
committerBrian Elliott <brian.elliott@rackspace.com>2012-08-28 16:16:56 +0000
commitbc0ba55ae6ce7b9b9bf5c9dd359f9d812ac8d18d (patch)
treea37b52374afa51328ce9db7ffe3426b97c9c59c3
parent458ee2eac0dbcfb1596cd6cf43b7a341e78f8f82 (diff)
Accept role list from either X-Roles or X-Role
Accept the list of roles from either the newer X-Roles header or the deprecated X-Role header. This is useful for interoperability with a software proxy in front of Nova API that performs token authentication and might use the older header. Change-Id: I47e33233edf596dd14d07b6be16b030fd6bc352d
-rw-r--r--nova/api/auth.py18
-rw-r--r--nova/tests/api/test_auth.py58
2 files changed, 74 insertions, 2 deletions
diff --git a/nova/api/auth.py b/nova/api/auth.py
index 8bc3c9d94..be99f7041 100644
--- a/nova/api/auth.py
+++ b/nova/api/auth.py
@@ -77,8 +77,9 @@ class NovaKeystoneContext(wsgi.Middleware):
if user_id is None:
LOG.debug("Neither X_USER_ID nor X_USER found in request")
return webob.exc.HTTPUnauthorized()
- # get the roles
- roles = [r.strip() for r in req.headers.get('X_ROLE', '').split(',')]
+
+ roles = self._get_roles(req)
+
if 'X_TENANT_ID' in req.headers:
# This is the new header since Keystone went to ID/Name
project_id = req.headers['X_TENANT_ID']
@@ -117,3 +118,16 @@ class NovaKeystoneContext(wsgi.Middleware):
req.environ['nova.context'] = ctx
return self.application
+
+ def _get_roles(self, req):
+ """Get the list of roles"""
+
+ if 'X_ROLES' in req.headers:
+ roles = req.headers.get('X_ROLES', '')
+ else:
+ # Fallback to deprecated role header:
+ roles = req.headers.get('X_ROLE', '')
+ if roles:
+ LOG.warn(_("Sourcing roles from deprecated X-Role HTTP "
+ "header"))
+ return [r.strip() for r in roles.split(',')]
diff --git a/nova/tests/api/test_auth.py b/nova/tests/api/test_auth.py
index c77bcfa55..38306068a 100644
--- a/nova/tests/api/test_auth.py
+++ b/nova/tests/api/test_auth.py
@@ -64,3 +64,61 @@ class TestNovaKeystoneContextMiddleware(test.TestCase):
self.request.headers['X_SERVICE_CATALOG'] = "bad json"
response = self.request.get_response(self.middleware)
self.assertEqual(response.status, '500 Internal Server Error')
+
+
+class TestKeystoneMiddlewareRoles(test.TestCase):
+
+ def setUp(self):
+ super(TestKeystoneMiddlewareRoles, self).setUp()
+
+ @webob.dec.wsgify()
+ def role_check_app(req):
+ context = req.environ['nova.context']
+
+ if "knight" in context.roles and "bad" not in context.roles:
+ return webob.Response(status=_("200 Role Match"))
+ elif context.roles == ['']:
+ return webob.Response(status=_("200 No Roles"))
+ else:
+ raise Exception(context.roles)
+ raise webob.exc.HTTPBadRequest(_("unexpected role header"))
+
+ self.middleware = nova.api.auth.NovaKeystoneContext(role_check_app)
+ self.request = webob.Request.blank('/')
+ self.request.headers['X_USER'] = 'testuser'
+ self.request.headers['X_TENANT_ID'] = 'testtenantid'
+ self.request.headers['X_AUTH_TOKEN'] = 'testauthtoken'
+ self.request.headers['X_SERVICE_CATALOG'] = json.dumps({})
+
+ self.roles = "pawn, knight, rook"
+
+ def test_roles(self):
+ """Test that the newer style role header takes precedence"""
+ self.request.headers['X_ROLES'] = 'pawn,knight,rook'
+ self.request.headers['X_ROLE'] = 'bad'
+
+ response = self.request.get_response(self.middleware)
+ self.assertEqual(response.status, '200 Role Match')
+
+ def test_roles_empty(self):
+ self.request.headers['X_ROLES'] = ''
+ response = self.request.get_response(self.middleware)
+ self.assertEqual(response.status, '200 No Roles')
+
+ def test_deprecated_role(self):
+ """Test fallback to older role header"""
+ self.request.headers['X_ROLE'] = 'pawn,knight,rook'
+
+ response = self.request.get_response(self.middleware)
+ self.assertEqual(response.status, '200 Role Match')
+
+ def test_role_empty(self):
+ self.request.headers['X_ROLE'] = ''
+ response = self.request.get_response(self.middleware)
+ self.assertEqual(response.status, '200 No Roles')
+
+ def test_no_role_headers(self):
+ """Test with no role headers set"""
+
+ response = self.request.get_response(self.middleware)
+ self.assertEqual(response.status, '200 No Roles')