Introduce scope_types in Device Profiles Actions
oslo.policy introduced the scope_type feature which can control the access level at system-level and project-level. - https://docs.openstack.org/oslo.policy/latest/user/usage.html#setting-scope - http://specs.openstack.org/openstack/keystone-specs/specs/keystone/queens/system-scope.html Each policy rules will be covered with appropriate oslo.policy’s “scope_types”, ‘system’ and ‘project’ in cyborg cases as that defined in the policies: https://wiki.openstack.org/wiki/Cyborg/Policy This commit introduce scope_type for Device Profiles API policies. Create and delete Device Profiles policies are scopped as 'system' because device_profile operation should not be given access to project scopped token, it has the same security requirement as that of manage a nova flavor. GET operations are scopped as [‘system’, ‘project’] because any reader(either system_reader or project_reader) can retrieve a device profile. Also adds the test case with scope_type enabled and verify we pass and fail the policy check with expected context. Story: 2007024 Task: 40836 Change-Id: Ib58e6ba92513245dac915dfff29b02c556b542ee
This commit is contained in:
@@ -135,6 +135,8 @@ def authorize_wsgi(api_name, act=None, need_target=True):
|
|||||||
context = pecan.request.context
|
context = pecan.request.context
|
||||||
credentials = context.to_policy_values()
|
credentials = context.to_policy_values()
|
||||||
credentials['is_admin'] = context.is_admin
|
credentials['is_admin'] = context.is_admin
|
||||||
|
if context.system_scope == 'all':
|
||||||
|
credentials['system'] = True
|
||||||
target = {}
|
target = {}
|
||||||
# maybe we can pass "_get_resource" to authorize_wsgi
|
# maybe we can pass "_get_resource" to authorize_wsgi
|
||||||
if need_target and hasattr(self, "_get_resource"):
|
if need_target and hasattr(self, "_get_resource"):
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ device_profile_policies = [
|
|||||||
'path': '/v2/device_profiles',
|
'path': '/v2/device_profiles',
|
||||||
'method': 'GET'
|
'method': 'GET'
|
||||||
}],
|
}],
|
||||||
|
scope_types=['system', 'project'],
|
||||||
deprecated_rule=deprecated_get_all,
|
deprecated_rule=deprecated_get_all,
|
||||||
deprecated_reason=('request admin_or_owmer rule is too strict for '
|
deprecated_reason=('request admin_or_owmer rule is too strict for '
|
||||||
'listing device_profile'),
|
'listing device_profile'),
|
||||||
@@ -67,6 +68,7 @@ device_profile_policies = [
|
|||||||
'path': '/v2/device_profiles/{device_profiles_uuid}',
|
'path': '/v2/device_profiles/{device_profiles_uuid}',
|
||||||
'method': 'GET'
|
'method': 'GET'
|
||||||
}],
|
}],
|
||||||
|
scope_types=['system', 'project'],
|
||||||
deprecated_rule=deprecated_get_one,
|
deprecated_rule=deprecated_get_one,
|
||||||
deprecated_reason=('request admin_or_owmer rule is too strict for '
|
deprecated_reason=('request admin_or_owmer rule is too strict for '
|
||||||
'retrieving a device_profile'),
|
'retrieving a device_profile'),
|
||||||
@@ -80,6 +82,7 @@ device_profile_policies = [
|
|||||||
'path': '/v2/device_profiles',
|
'path': '/v2/device_profiles',
|
||||||
'method': 'POST'
|
'method': 'POST'
|
||||||
}],
|
}],
|
||||||
|
scope_types=['system'],
|
||||||
deprecated_rule=deprecated_create,
|
deprecated_rule=deprecated_create,
|
||||||
deprecated_reason=('project_admin_or_owner is too permissive, '
|
deprecated_reason=('project_admin_or_owner is too permissive, '
|
||||||
'introduce system_scoped admin for creation'),
|
'introduce system_scoped admin for creation'),
|
||||||
@@ -96,6 +99,7 @@ device_profile_policies = [
|
|||||||
'path': '/v2/device_profiles?value={device_profile_name1}',
|
'path': '/v2/device_profiles?value={device_profile_name1}',
|
||||||
'method': 'DELETE'},
|
'method': 'DELETE'},
|
||||||
],
|
],
|
||||||
|
scope_types=['system'],
|
||||||
deprecated_rule=deprecated_delete,
|
deprecated_rule=deprecated_delete,
|
||||||
deprecated_reason=('project_admin_or_owner is too permissive, '
|
deprecated_reason=('project_admin_or_owner is too permissive, '
|
||||||
'introduce system_scoped admin for deletion'),
|
'introduce system_scoped admin for deletion'),
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import pecan.testing
|
|||||||
|
|
||||||
from cyborg.tests.unit.db import base
|
from cyborg.tests.unit.db import base
|
||||||
|
|
||||||
|
|
||||||
cfg.CONF.import_group('keystone_authtoken', 'keystonemiddleware.auth_token')
|
cfg.CONF.import_group('keystone_authtoken', 'keystonemiddleware.auth_token')
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +48,12 @@ class BaseApiTest(base.DbTestCase):
|
|||||||
|
|
||||||
self.addCleanup(reset_pecan)
|
self.addCleanup(reset_pecan)
|
||||||
|
|
||||||
|
def flags(self, **kw):
|
||||||
|
"""Override flag variables for a test."""
|
||||||
|
group = kw.pop('group', None)
|
||||||
|
for k, v in kw.items():
|
||||||
|
cfg.CONF.set_override(k, v, group)
|
||||||
|
|
||||||
def _make_app(self):
|
def _make_app(self):
|
||||||
# Determine where we are so we can set up paths in the config
|
# Determine where we are so we can set up paths in the config
|
||||||
root_dir = self.get_path()
|
root_dir = self.get_path()
|
||||||
@@ -132,7 +137,7 @@ class BaseApiTest(base.DbTestCase):
|
|||||||
'X-User-Name': ct.get("user_name") or "user",
|
'X-User-Name': ct.get("user_name") or "user",
|
||||||
'X-User-Id':
|
'X-User-Id':
|
||||||
ct.get("user") or "1d6d686bc2c949ddb685ffb4682e0047",
|
ct.get("user") or "1d6d686bc2c949ddb685ffb4682e0047",
|
||||||
'X-Project-Name': ct.get("project_name") or "project",
|
'X-Project-Name': ct.get("project_name") or "no_project_name",
|
||||||
'X-Project-Id':
|
'X-Project-Id':
|
||||||
ct.get("tenant") or "86f64f561b6d4f479655384572727f70",
|
ct.get("tenant") or "86f64f561b6d4f479655384572727f70",
|
||||||
'X-User-Domain-Id':
|
'X-User-Domain-Id':
|
||||||
@@ -140,8 +145,10 @@ class BaseApiTest(base.DbTestCase):
|
|||||||
'X-User-Domain-Name': ct.get("domain_name") or "no_domain",
|
'X-User-Domain-Name': ct.get("domain_name") or "no_domain",
|
||||||
'X-Auth-Token':
|
'X-Auth-Token':
|
||||||
ct.get("auth_token") or "b9764005b8c145bf972634fb16a826e8",
|
ct.get("auth_token") or "b9764005b8c145bf972634fb16a826e8",
|
||||||
'X-Roles': ct.get("roles") or role
|
'X-Roles': ct.get("roles") or role,
|
||||||
}
|
}
|
||||||
|
if ct.get('system_scope') == 'all':
|
||||||
|
headers.update({'Openstack-System-Scope': 'all'})
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
def get_json(self, path, expect_errors=False, headers=None,
|
def get_json(self, path, expect_errors=False, headers=None,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class DeviceProfilePolicyTest(base.BasePolicyTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(DeviceProfilePolicyTest, self).setUp()
|
super(DeviceProfilePolicyTest, self).setUp()
|
||||||
|
|
||||||
|
self.flags(enforce_scope=False, group="oslo_policy")
|
||||||
self.controller = device_profiles.DeviceProfilesController()
|
self.controller = device_profiles.DeviceProfilesController()
|
||||||
self.fake_dp_objs = fake_device_profile.get_obj_devprofs()
|
self.fake_dp_objs = fake_device_profile.get_obj_devprofs()
|
||||||
self.fake_dps = fake_device_profile.get_api_devprofs()
|
self.fake_dps = fake_device_profile.get_api_devprofs()
|
||||||
@@ -152,3 +153,19 @@ class DeviceProfileScopeTypePolicyTest(DeviceProfilePolicyTest):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(DeviceProfileScopeTypePolicyTest, self).setUp()
|
super(DeviceProfileScopeTypePolicyTest, self).setUp()
|
||||||
|
self.flags(enforce_scope=True, group="oslo_policy")
|
||||||
|
|
||||||
|
# check that system_admin is able to do create and delete operations.
|
||||||
|
self.create_authorized_contexts = [
|
||||||
|
self.system_admin_context]
|
||||||
|
self.delete_authorized_contexts = self.create_authorized_contexts
|
||||||
|
# Check that non-system or non-admin is not able to perform the system
|
||||||
|
# level actions on device_profiles.
|
||||||
|
self.create_unauthorized_contexts = [
|
||||||
|
self.legacy_admin_context, self.system_member_context,
|
||||||
|
self.system_reader_context, self.system_foo_context,
|
||||||
|
self.project_admin_context, self.project_member_context,
|
||||||
|
self.other_project_member_context,
|
||||||
|
self.project_foo_context, self.project_reader_context
|
||||||
|
]
|
||||||
|
self.delete_unauthorized_contexts = self.create_unauthorized_contexts
|
||||||
|
|||||||
Reference in New Issue
Block a user