From 5998933acf2358070e9aa14ebb9e712985b5a04c Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 1 Jul 2020 07:29:52 -0700 Subject: [PATCH] Add context.elevated() helper for getting admin privileges This adds an elevated() method to glance.context.RequestContext similar to what Nova and other projects use. When doing something as admin on behalf of a user, this results in a whole context, including information about the user and the request, but with is_admin==True. Change-Id: I5499946425b1c32476c57241b4b14b601daa841f (cherry picked from commit c59ed1bce82c960b205663ba9ac6d038633588dc) --- glance/context.py | 14 ++++++++++++++ glance/tests/unit/test_context.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/glance/context.py b/glance/context.py index 01c26b4cdb..e8c431d5c8 100644 --- a/glance/context.py +++ b/glance/context.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import copy + from oslo_context import context from glance.api import policy @@ -72,6 +74,18 @@ class RequestContext(context.RequestContext): """Admins can see deleted by default""" return self.show_deleted or self.is_admin + def elevated(self): + """Return a copy of this context with admin flag set.""" + + context = copy.copy(self) + context.roles = copy.deepcopy(self.roles) + if 'admin' not in context.roles: + context.roles.append('admin') + + context.is_admin = True + + return context + def get_admin_context(show_deleted=False): """Create an administrator context.""" diff --git a/glance/tests/unit/test_context.py b/glance/tests/unit/test_context.py index a5fa97c687..f3c2b2efbd 100644 --- a/glance/tests/unit/test_context.py +++ b/glance/tests/unit/test_context.py @@ -171,3 +171,32 @@ class TestContext(utils.BaseTestCase): project_domain_id="project-domain") self.assertEqual('user tenant domain user-domain project-domain', ctx.to_dict()["user_identity"]) + + def test_elevated(self): + """Make sure we get a whole admin-capable context from elevated().""" + ctx = context.RequestContext(service_catalog=['foo'], + user_id='dan', + project_id='openstack', + roles=['member']) + admin = ctx.elevated() + self.assertEqual('dan', admin.user_id) + self.assertEqual('openstack', admin.project_id) + self.assertEqual(sorted(['member', 'admin']), + sorted(admin.roles)) + self.assertEqual(['foo'], admin.service_catalog) + self.assertTrue(admin.is_admin) + + def test_elevated_again(self): + """Make sure a second elevation looks the same.""" + ctx = context.RequestContext(service_catalog=['foo'], + user_id='dan', + project_id='openstack', + roles=['member']) + admin = ctx.elevated() + admin = admin.elevated() + self.assertEqual('dan', admin.user_id) + self.assertEqual('openstack', admin.project_id) + self.assertEqual(sorted(['member', 'admin']), + sorted(admin.roles)) + self.assertEqual(['foo'], admin.service_catalog) + self.assertTrue(admin.is_admin)