From 84625bedfb5b4aab053d69192c2dfbb42bdf9dd2 Mon Sep 17 00:00:00 2001 From: Pavlo Shchelokovskyy Date: Wed, 25 Jan 2023 17:06:44 +0200 Subject: Allow easier admin override in policies currently `role:admin` is explicitly used in many policies, which makes it harder to globally override it to e.g. `role:admin and is_admin_project:True`, such change would require many policies to be overrided explicitly as well. This patch swaps `role:admin` for `rule:context_is_admin`, allowing for easier and more centralized override of 'adminness' meaning. Change-Id: I2ba0ce300bcd85c1aca43c166a41fb331ab9dbef --- glance/policies/base.py | 20 ++++++++++---------- glance/policies/discovery.py | 2 +- glance/policies/image.py | 8 ++++---- glance/policies/metadef.py | 3 ++- glance/policies/tasks.py | 2 +- glance/tests/unit/test_policy.py | 6 ++++-- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/glance/policies/base.py b/glance/policies/base.py index 77d023414..3f51eb37a 100644 --- a/glance/policies/base.py +++ b/glance/policies/base.py @@ -57,33 +57,33 @@ PROJECT_READER_OR_PUBLIC_NAMESPACE = ( # typical in OpenStack services. But following check strings offer formal # support for project membership and a read-only variant consistent with # other OpenStack services. -ADMIN_OR_PROJECT_MEMBER = f'role:admin or ({PROJECT_MEMBER})' -ADMIN_OR_PROJECT_READER = f'role:admin or ({PROJECT_READER})' +ADMIN_OR_PROJECT_MEMBER = f'rule:context_is_admin or ({PROJECT_MEMBER})' +ADMIN_OR_PROJECT_READER = f'rule:context_is_admin or ({PROJECT_READER})' ADMIN_OR_PROJECT_READER_GET_IMAGE = ( - f'role:admin or ' + f'rule:context_is_admin or ' f'({PROJECT_READER_OR_IMAGE_MEMBER_OR_COMMUNITY_OR_PUBLIC_OR_SHARED})' ) ADMIN_OR_PROJECT_MEMBER_DOWNLOAD_IMAGE = ( - f'role:admin or ' + f'rule:context_is_admin or ' f'({PROJECT_MEMBER_OR_IMAGE_MEMBER_OR_COMMUNITY_OR_PUBLIC_OR_SHARED})' ) ADMIN_OR_PROJECT_MEMBER_CREATE_IMAGE = ( - f'role:admin or ({PROJECT_MEMBER} and project_id:%(owner)s)' + f'rule:context_is_admin or ({PROJECT_MEMBER} and project_id:%(owner)s)' ) ADMIN_OR_PROJECT_READER_GET_NAMESPACE = ( - f'role:admin or ({PROJECT_READER_OR_PUBLIC_NAMESPACE})' + f'rule:context_is_admin or ({PROJECT_READER_OR_PUBLIC_NAMESPACE})' ) ADMIN_OR_SHARED_MEMBER = ( - f'role:admin or (role:member and {IMAGE_MEMBER_CHECK})' + f'rule:context_is_admin or (role:member and {IMAGE_MEMBER_CHECK})' ) ADMIN_OR_PROJECT_READER_OR_SHARED_MEMBER = ( - f'role:admin or ' + f'rule:context_is_admin or ' f'role:reader and (project_id:%(project_id)s or {IMAGE_MEMBER_CHECK})' ) -ADMIN = f'role:admin' +ADMIN = f'rule:context_is_admin' rules = [ policy.RuleDefault(name='default', check_str='', @@ -92,7 +92,7 @@ rules = [ 'policy in the supplied policy.json file.', deprecated_rule=policy.DeprecatedRule( name='default', - check_str='role:admin', + check_str='rule:context_is_admin', deprecated_reason='In order to allow operators to ' 'accept the default policies from code by not ' 'defining them in the policy file, while still ' diff --git a/glance/policies/discovery.py b/glance/policies/discovery.py index 50a421330..5a0b86e88 100644 --- a/glance/policies/discovery.py +++ b/glance/policies/discovery.py @@ -18,7 +18,7 @@ from oslo_policy import policy discovery_policies = [ policy.DocumentedRuleDefault( name="stores_info_detail", - check_str='role:admin', + check_str='rule:context_is_admin', scope_types=['project'], description='Expose store specific information', operations=[ diff --git a/glance/policies/image.py b/glance/policies/image.py index c4400ec0b..1fdd97acc 100644 --- a/glance/policies/image.py +++ b/glance/policies/image.py @@ -93,7 +93,7 @@ image_policies = [ ), policy.DocumentedRuleDefault( name="publicize_image", - check_str='role:admin', + check_str='rule:context_is_admin', scope_types=['project'], description='Publicize given image', operations=[ @@ -147,7 +147,7 @@ image_policies = [ policy.DocumentedRuleDefault( name="delete_image_location", - check_str="role:admin", + check_str="rule:context_is_admin", scope_types=['project'], description='Deletes the location of given image', operations=[ @@ -261,7 +261,7 @@ image_policies = [ policy.RuleDefault( name="manage_image_cache", - check_str='role:admin', + check_str='rule:context_is_admin', scope_types=['project'], description='Manage image cache' ), @@ -297,7 +297,7 @@ image_policies = [ policy.DocumentedRuleDefault( name="copy_image", - check_str='role:admin', + check_str='rule:context_is_admin', # For now this is restricted to project-admins. # That might change in the future if we decide to push # this functionality down to project-members. diff --git a/glance/policies/metadef.py b/glance/policies/metadef.py index d1feaaed8..84641f42c 100644 --- a/glance/policies/metadef.py +++ b/glance/policies/metadef.py @@ -23,7 +23,8 @@ The metadata API now supports project scope and default roles. metadef_policies = [ policy.RuleDefault(name="metadef_default", check_str=""), - policy.RuleDefault(name="metadef_admin", check_str="role:admin"), + policy.RuleDefault(name="metadef_admin", + check_str="rule:context_is_admin"), policy.DocumentedRuleDefault( name="get_metadef_namespace", check_str=base.ADMIN_OR_PROJECT_READER_GET_NAMESPACE, diff --git a/glance/policies/tasks.py b/glance/policies/tasks.py index 42d25a5f6..64aa9e42a 100644 --- a/glance/policies/tasks.py +++ b/glance/policies/tasks.py @@ -101,7 +101,7 @@ task_policies = [ ), policy.DocumentedRuleDefault( name="tasks_api_access", - check_str="role:admin", + check_str="rule:context_is_admin", scope_types=['project'], description=TASK_ACCESS_DESCRIPTION, operations=[ diff --git a/glance/tests/unit/test_policy.py b/glance/tests/unit/test_policy.py index 70ad783e7..7de253b25 100644 --- a/glance/tests/unit/test_policy.py +++ b/glance/tests/unit/test_policy.py @@ -508,7 +508,8 @@ class TestDefaultPolicyCheckStrings(base.IsolatedUnitTest): self.assertEqual(expected, base_policy.PROJECT_MEMBER) def test_admin_or_project_member_check_string(self): - expected = 'role:admin or (role:member and project_id:%(project_id)s)' + expected = ('rule:context_is_admin or ' + '(role:member and project_id:%(project_id)s)') self.assertEqual(expected, base_policy.ADMIN_OR_PROJECT_MEMBER) def test_project_member_download_image_check_string(self): @@ -528,7 +529,8 @@ class TestDefaultPolicyCheckStrings(base.IsolatedUnitTest): self.assertEqual(expected, base_policy.PROJECT_READER) def test_admin_or_project_reader_check_string(self): - expected = 'role:admin or (role:reader and project_id:%(project_id)s)' + expected = ('rule:context_is_admin or ' + '(role:reader and project_id:%(project_id)s)') self.assertEqual(expected, base_policy.ADMIN_OR_PROJECT_READER) def test_project_reader_get_image_check_string(self): -- cgit v1.2.1