summaryrefslogtreecommitdiff
path: root/oslo_context
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_context')
-rw-r--r--oslo_context/context.py27
-rw-r--r--oslo_context/tests/test_context.py31
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"