From a109782c8ac05cf76087f853472b8b733c794fc1 Mon Sep 17 00:00:00 2001 From: Kiall Mac Innes Date: Thu, 28 Nov 2013 12:45:08 +0000 Subject: [PATCH] Allow a context to be elevated to admin status The mimics the method included in the oslo.rpc CommonRpcContext, so will work both at the API and Central layers Change-Id: I55a89fb93618c56caa80d5d471aecbbe7a898cc9 --- designate/context.py | 31 +++++++++++++++++++++++++++++-- designate/tests/test_context.py | 13 +++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/designate/context.py b/designate/context.py index c8a29001..4fc1fd96 100644 --- a/designate/context.py +++ b/designate/context.py @@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__) class DesignateContext(context.RequestContext): def __init__(self, auth_token=None, user=None, tenant=None, is_admin=False, read_only=False, show_deleted=False, request_id=None, - roles=[], service_catalog=None): + original_tenant_id=None, roles=[], service_catalog=None): super(DesignateContext, self).__init__( auth_token=auth_token, user=user, @@ -34,7 +34,7 @@ class DesignateContext(context.RequestContext): show_deleted=show_deleted, request_id=request_id) - self._original_tenant_id = None + self._original_tenant_id = original_tenant_id self.roles = roles self.service_catalog = service_catalog @@ -58,6 +58,15 @@ class DesignateContext(context.RequestContext): LOG.warn('Rejected sudo from user_id %s for tenant_id %s' % (self.user_id, tenant_id)) + def deepcopy(self): + d = self.to_dict() + + # Remove the user and tenant id fields, this map to user and tenant + d.pop('user_id') + d.pop('tenant_id') + + return self.from_dict(d) + def to_dict(self): d = super(DesignateContext, self).to_dict() @@ -71,6 +80,23 @@ class DesignateContext(context.RequestContext): return d + @classmethod + def from_dict(cls, values): + return cls(**values) + + def elevated(self, show_deleted=None): + """Return a version of this context with admin flag set.""" + context = self.deepcopy() + context.is_admin = True + + # NOTE(kiall): Ugly - required to match http://tinyurl.com/o3y8qmw + context.roles.append('admin') + + if show_deleted is not None: + context.show_deleted = show_deleted + + return context + @property def user_id(self): return self.user @@ -100,6 +126,7 @@ class DesignateContext(context.RequestContext): @classmethod def get_admin_context(cls, **kwargs): + # TODO(kiall): Remove Me kwargs['is_admin'] = True kwargs['roles'] = ['admin'] diff --git a/designate/tests/test_context.py b/designate/tests/test_context.py index 5ed85680..5f6321f6 100644 --- a/designate/tests/test_context.py +++ b/designate/tests/test_context.py @@ -37,3 +37,16 @@ class TestDesignateContext(TestCase): self.assertEqual('original', ctxt.tenant_id) self.assertEqual('original', ctxt.original_tenant_id) + + def test_deepcopy(self): + orig = context.DesignateContext(user='12345', tenant='54321') + copy = orig.deepcopy() + + self.assertEqual(orig.to_dict(), copy.to_dict()) + + def test_elevated(self): + ctxt = context.DesignateContext(user='12345', tenant='54321') + admin_ctxt = ctxt.elevated() + + self.assertFalse(ctxt.is_admin) + self.assertTrue(admin_ctxt.is_admin)