diff options
Diffstat (limited to 'oslo_context')
-rw-r--r-- | oslo_context/context.py | 27 | ||||
-rw-r--r-- | oslo_context/tests/test_context.py | 31 |
2 files changed, 43 insertions, 15 deletions
diff --git a/oslo_context/context.py b/oslo_context/context.py index 19bc1a3..9564abd 100644 --- a/oslo_context/context.py +++ b/oslo_context/context.py @@ -26,6 +26,7 @@ context or provide additional information in their specific WSGI pipeline or logging context. """ +import inspect import itertools import threading import uuid @@ -52,7 +53,7 @@ class RequestContext(object): def __init__(self, auth_token=None, user=None, tenant=None, domain=None, user_domain=None, project_domain=None, is_admin=False, read_only=False, show_deleted=False, request_id=None, - resource_uuid=None, overwrite=True): + resource_uuid=None, overwrite=True, roles=None): """Initialize the RequestContext :param overwrite: Set to False to ensure that the greenthread local @@ -68,6 +69,7 @@ class RequestContext(object): self.read_only = read_only self.show_deleted = show_deleted self.resource_uuid = resource_uuid + self.roles = roles or [] if not request_id: request_id = generate_request_id() self.request_id = request_id @@ -98,6 +100,7 @@ class RequestContext(object): 'auth_token': self.auth_token, 'request_id': self.request_id, 'resource_uuid': self.resource_uuid, + 'roles': self.roles, 'user_identity': user_idt} def get_logging_values(self): @@ -106,20 +109,13 @@ class RequestContext(object): return values @classmethod - def from_dict(cls, ctx): + def from_dict(cls, values): """Construct a context object from a provided dictionary.""" - return cls( - auth_token=ctx.get("auth_token"), - user=ctx.get("user"), - tenant=ctx.get("tenant"), - domain=ctx.get("domain"), - user_domain=ctx.get("user_domain"), - project_domain=ctx.get("project_domain"), - is_admin=ctx.get("is_admin", False), - read_only=ctx.get("read_only", False), - show_deleted=ctx.get("show_deleted", False), - request_id=ctx.get("request_id"), - resource_uuid=ctx.get("resource_uuid")) + allowed = [arg for arg in + inspect.getargspec(RequestContext.__init__).args + if arg != 'self'] + kwargs = {k: v for (k, v) in values.items() if k in allowed} + return cls(**kwargs) @classmethod def from_environ(cls, environ, **kwargs): @@ -141,6 +137,9 @@ class RequestContext(object): 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 []) + return cls(**kwargs) diff --git a/oslo_context/tests/test_context.py b/oslo_context/tests/test_context.py index 1a91023..6b18820 100644 --- a/oslo_context/tests/test_context.py +++ b/oslo_context/tests/test_context.py @@ -104,6 +104,23 @@ class ContextTest(test_base.BaseTestCase): self.assertEqual("request1", ctx.request_id) self.assertEqual("instance1", ctx.resource_uuid) + def test_from_dict_unknown_keys(self): + dct = { + "auth_token": "token1", + "user": "user1", + "read_only": True, + "roles": "role1,role2,role3", # future review provides this + "color": "red", + "unknown": "" + } + ctx = context.RequestContext.from_dict(dct) + self.assertEqual("token1", ctx.auth_token) + self.assertEqual("user1", ctx.user) + self.assertIsNone(ctx.tenant) + self.assertFalse(ctx.is_admin) + self.assertTrue(ctx.read_only) + self.assertRaises(KeyError, lambda: ctx.__dict__['color']) + def test_is_user_context(self): self.assertFalse(context.is_user_context(None)) ctx = context.RequestContext(is_admin=True) @@ -118,12 +135,14 @@ class ContextTest(test_base.BaseTestCase): project_id = uuid.uuid4().hex user_domain_id = uuid.uuid4().hex project_domain_id = uuid.uuid4().hex + roles = [uuid.uuid4().hex, uuid.uuid4().hex, uuid.uuid4().hex] environ = {'HTTP_X_AUTH_TOKEN': auth_token, 'HTTP_X_USER_ID': user_id, 'HTTP_X_PROJECT_ID': project_id, 'HTTP_X_USER_DOMAIN_ID': user_domain_id, - 'HTTP_X_PROJECT_DOMAIN_ID': project_domain_id} + 'HTTP_X_PROJECT_DOMAIN_ID': project_domain_id, + 'HTTP_X_ROLES': ','.join(roles)} ctx = context.RequestContext.from_environ(environ) @@ -132,6 +151,14 @@ class ContextTest(test_base.BaseTestCase): self.assertEqual(project_id, ctx.tenant) self.assertEqual(user_domain_id, ctx.user_domain) self.assertEqual(project_domain_id, ctx.project_domain) + self.assertEqual(roles, ctx.roles) + + def test_from_environ_no_roles(self): + ctx = context.RequestContext.from_environ(environ={}) + self.assertEqual([], ctx.roles) + + ctx = context.RequestContext.from_environ(environ={'HTTP_X_ROLES': ''}) + self.assertEqual([], ctx.roles) def test_from_function_and_args(self): ctx = context.RequestContext(user="user1") @@ -197,6 +224,7 @@ class ContextTest(test_base.BaseTestCase): self.assertIn('request_id', d) self.assertIn('resource_uuid', d) self.assertIn('user_identity', d) + self.assertIn('roles', d) self.assertEqual(auth_token, d['auth_token']) self.assertEqual(tenant, d['tenant']) @@ -211,6 +239,7 @@ class ContextTest(test_base.BaseTestCase): user_identity = "%s %s %s %s %s" % (user, tenant, domain, user_domain, project_domain) self.assertEqual(user_identity, d['user_identity']) + self.assertEqual([], d['roles']) def test_get_logging_values(self): auth_token = "token1" |