diff --git a/oslo_context/context.py b/oslo_context/context.py index 038948d..d4902ad 100644 --- a/oslo_context/context.py +++ b/oslo_context/context.py @@ -34,6 +34,18 @@ import uuid _request_store = threading.local() +# These arguments will be passed to a new context from the first available +# header to support backwards compatibility. +_ENVIRON_HEADERS = {'auth_token': ['HTTP_X_AUTH_TOKEN', + 'HTTP_X_STORAGE_TOKEN'], + 'user': ['HTTP_X_USER_ID', + 'HTTP_X_USER'], + 'tenant': ['HTTP_X_PROJECT_ID', + 'HTTP_X_TENANT_ID', + 'HTTP_X_TENANT'], + 'user_domain': ['HTTP_X_USER_DOMAIN_ID'], + 'project_domain': ['HTTP_X_PROJECT_DOMAIN_ID']} + def generate_request_id(): """Generate a unique request id.""" @@ -148,15 +160,21 @@ class RequestContext(object): # Load a new context object from the environment variables set by # auth_token middleware. See: # http://docs.openstack.org/developer/keystonemiddleware/api/keystonemiddleware.auth_token.html#what-auth-token-adds-to-the-request-for-use-by-the-openstack-service - kwargs.setdefault('auth_token', environ.get('HTTP_X_AUTH_TOKEN')) - kwargs.setdefault('user', environ.get('HTTP_X_USER_ID')) - kwargs.setdefault('tenant', environ.get('HTTP_X_PROJECT_ID')) - kwargs.setdefault('user_domain', environ.get('HTTP_X_USER_DOMAIN_ID')) - kwargs.setdefault('project_domain', - environ.get('HTTP_X_PROJECT_DOMAIN_ID')) - roles = environ.get('HTTP_X_ROLES') - kwargs.setdefault('roles', roles.split(',') if roles else []) + # add kwarg if not specified by user from a list of possible headers + for k, v_list in _ENVIRON_HEADERS.items(): + if k in kwargs: + continue + + for v in v_list: + if v in environ: + kwargs[k] = environ[v] + break + + if 'roles' not in kwargs: + roles = environ.get('HTTP_X_ROLES', environ.get('HTTP_X_ROLE')) + roles = [r.strip() for r in roles.split(',')] if roles else [] + kwargs['roles'] = roles return cls(**kwargs) diff --git a/oslo_context/tests/test_context.py b/oslo_context/tests/test_context.py index 7d13c06..2165608 100644 --- a/oslo_context/tests/test_context.py +++ b/oslo_context/tests/test_context.py @@ -161,6 +161,59 @@ class ContextTest(test_base.BaseTestCase): ctx = context.RequestContext.from_environ(environ={'HTTP_X_ROLES': ''}) self.assertEqual([], ctx.roles) + def test_from_environ_deprecated_variables(self): + value = uuid.uuid4().hex + + environ = {'HTTP_X_USER': value} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(value, ctx.user) + + environ = {'HTTP_X_TENANT_ID': value} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(value, ctx.tenant) + + environ = {'HTTP_X_STORAGE_TOKEN': value} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(value, ctx.auth_token) + + environ = {'HTTP_X_TENANT': value} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(value, ctx.tenant) + + environ = {'HTTP_X_ROLE': value} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual([value], ctx.roles) + + def test_from_environ_deprecated_precendence(self): + old = uuid.uuid4().hex + new = uuid.uuid4().hex + override = uuid.uuid4().hex + + environ = {'HTTP_X_USER': old, + 'HTTP_X_USER_ID': new} + + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(ctx.user, new) + + ctx = context.RequestContext.from_environ(environ=environ, + user=override) + self.assertEqual(ctx.user, override) + + environ = {'HTTP_X_TENANT': old, + 'HTTP_X_PROJECT_ID': new} + + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(ctx.tenant, new) + + ctx = context.RequestContext.from_environ(environ=environ, + tenant=override) + self.assertEqual(ctx.tenant, override) + + def test_from_environ_strip_roles(self): + environ = {'HTTP_X_ROLES': ' abc\t,\ndef\n,ghi\n\n'} + ctx = context.RequestContext.from_environ(environ=environ) + self.assertEqual(['abc', 'def', 'ghi'], ctx.roles) + def test_from_function_and_args(self): ctx = context.RequestContext(user="user1") arg = [] diff --git a/tox.ini b/tox.ini index d43baa6..c44a34c 100644 --- a/tox.ini +++ b/tox.ini @@ -24,7 +24,7 @@ commands = python setup.py test --coverage --coverage-package-name=oslo_context show-source = True ignore = E123,E125,H803 -exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build +exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build [hacking] import_exceptions =