From 02cc5c6760a294d49f70751bbaed574bf74f7068 Mon Sep 17 00:00:00 2001 From: Goutham Pacha Ravi Date: Wed, 24 Mar 2021 23:28:08 -0700 Subject: [PATCH] Set "context_is_admin" to system scope admin roles This policy governs manila APIs that are meant to be cross tenant - so it should default to system scope in the new secure rbac system. Also reformat the policy.py file so that we are consistent with using "rules" as we were doing in the older releases. Rules abstract keystone concepts such as roles and scopes. Change-Id: I31b8eb5232a5cd286db18c2b14833c0682574958 Signed-off-by: Goutham Pacha Ravi --- manila/policies/base.py | 77 +++++++++++++++++++++++++++++++++++++---- manila/policy.py | 8 +++-- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/manila/policies/base.py b/manila/policies/base.py index 31465b12b0..3fe7ad7557 100644 --- a/manila/policies/base.py +++ b/manila/policies/base.py @@ -13,47 +13,58 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_log import versionutils from oslo_policy import policy RULE_ADMIN_OR_OWNER = 'rule:admin_or_owner' RULE_ADMIN_API = 'rule:admin_api' RULE_DEFAULT = 'rule:default' +deprecation_msg = ("The `context_is_admin` check is superseded by more " + "specific check strings that consume system and project " + "scope attributes from keystone tokens.") +DEPRECATED_CONTEXT_IS_ADMIN = policy.DeprecatedRule( + name='context_is_admin', + check_str='role:admin', + deprecated_reason=deprecation_msg, + deprecated_since=versionutils.deprecated.WALLABY +) + # Generic policy check string for system administrators. These are the people # who need the highest level of authorization to operate the deployment. # They're allowed to create, read, update, or delete any system-specific # resource. They can also operate on project-specific resources where # applicable (e.g., cleaning up shares or snapshots). -SYSTEM_ADMIN = 'role:admin and system_scope:all' +SYSTEM_ADMIN = 'rule:system-admin' # Generic policy check string for system users who don't require all the # authorization that system administrators typically have. This persona, or # check string, typically isn't used by default, but it's existence it useful # in the event a deployment wants to offload some administrative action from # system administrator to system members. -SYSTEM_MEMBER = 'role:member and system_scope:all' +SYSTEM_MEMBER = 'rule:system-member' # Generic policy check string for read-only access to system-level resources. # This persona is useful for someone who needs access for auditing or even # support. These uses are also able to view project-specific resources where # applicable (e.g., listing all shares in the deployment, regardless of the # project they belong to). -SYSTEM_READER = 'role:reader and system_scope:all' +SYSTEM_READER = 'rule:system-reader' # This check string is reserved for actions that require the highest level of # authorization on a project or resources within the project (e.g., resyncing a # share replica). -PROJECT_ADMIN = 'role:admin and project_id:%(project_id)s' +PROJECT_ADMIN = 'rule:project-admin' # This check string is the primary use case for typical end-users, who are # working with resources that belong to a project (e.g., managing shares or # share replicas). -PROJECT_MEMBER = 'role:member and project_id:%(project_id)s' +PROJECT_MEMBER = 'rule:project-member' # This check string should only be used to protect read-only project-specific # resources. It should not be used to protect APIs that make writable changes # (e.g., updating a share or snapshot). -PROJECT_READER = 'role:reader and project_id:%(project_id)s' +PROJECT_READER = 'rule:project-reader' # The following are common composite check strings that are useful for # protecting APIs designed to operate with multiple scopes (e.g., a system @@ -70,7 +81,59 @@ SYSTEM_OR_PROJECT_READER = ( ) rules = [ - policy.RuleDefault(name='context_is_admin', check_str='role:admin'), + # ***Default OpenStack scoped personas*** # + # System scoped Administrator + policy.RuleDefault( + name='system-admin', + check_str='role:admin and ' + 'system_scope:all', + scope_types=['system']), + + # System scoped Member + policy.RuleDefault( + name='system-member', + check_str='role:member and ' + 'system_scope:all', + scope_types=['system']), + + # System scoped Reader + policy.RuleDefault( + name='system-reader', + check_str='role:reader and ' + 'system_scope:all', + scope_types=['system']), + + # Project scoped Administrator + policy.RuleDefault( + name='project-admin', + check_str='role:admin and ' + 'project_id:%(project_id)s', + scope_types=['project']), + + # Project scoped Member + policy.RuleDefault( + name='project-member', + check_str='role:member and ' + 'project_id:%(project_id)s', + scope_types=['project']), + + # Project scoped Reader + policy.RuleDefault( + name='project-reader', + check_str='role:reader and ' + 'project_id:%(project_id)s', + scope_types=['project']), + + # ***Special personas for Manila*** # + # Privileged users checked via "context.is_admin" + policy.RuleDefault( + name='context_is_admin', + check_str='rule:system-admin', + deprecated_rule=DEPRECATED_CONTEXT_IS_ADMIN, + scope_types=['system']), + + # ***Legacy/deprecated unscoped rules*** # + # can be removed after "enforce_scope" defaults to True in oslo.policy policy.RuleDefault( name='admin_or_owner', check_str='is_admin:True or project_id:%(project_id)s'), diff --git a/manila/policy.py b/manila/policy.py index f0501999a0..860ea3660c 100644 --- a/manila/policy.py +++ b/manila/policy.py @@ -183,7 +183,10 @@ def authorize(context, action, target, do_raise=True, exc=None): with excutils.save_and_reraise_exception(): LOG.exception('Policy not registered') except policy.InvalidScope: - raise exception.PolicyNotAuthorized(action=action) + if do_raise: + raise exception.PolicyNotAuthorized(action=action) + else: + return False except Exception: with excutils.save_and_reraise_exception(): msg_args = { @@ -203,10 +206,9 @@ def check_is_admin(context): """Whether or not user is admin according to policy setting. """ - init() # the target is user-self target = default_target(context) - return _ENFORCER.authorize('context_is_admin', target, context) + return authorize(context, 'context_is_admin', target, do_raise=False) def wrap_check_policy(resource):