Remove system scope from all APIs

In line with the recent RBAC working group discussion and operator
feedback, this converts all our APIs back to project-only. It leaves
the actual scope_types in place, with them all set to project. This
allows an operator to turn on scope checking to *ensure* that only
project-scoped tokens are used, in case system scope is in use
elsewhere in the deployment (i.e. for keystone or ironic). Without
this, system scoped tokens will fail some operations in strange
(read: 500 and "database error") ways.

Change-Id: I951a11affa1d1e42863967cdc713618ff0a74814
This commit is contained in:
Dan Smith 2022-06-28 12:45:13 -07:00 committed by Ghanshyam
parent 9a82a90993
commit 066e1e69d1
30 changed files with 189 additions and 155 deletions

View File

@ -33,7 +33,7 @@ aggregates_policies = [
'method': 'POST'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'add_host',
check_str=base.ADMIN,
@ -44,7 +44,7 @@ aggregates_policies = [
'method': 'POST'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str=base.ADMIN,
@ -55,7 +55,7 @@ aggregates_policies = [
'method': 'POST'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'remove_host',
check_str=base.ADMIN,
@ -66,7 +66,7 @@ aggregates_policies = [
'method': 'POST'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.ADMIN,
@ -77,7 +77,7 @@ aggregates_policies = [
'method': 'PUT'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.ADMIN,
@ -88,7 +88,7 @@ aggregates_policies = [
'method': 'GET'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.ADMIN,
@ -99,7 +99,7 @@ aggregates_policies = [
'method': 'DELETE'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.ADMIN,
@ -110,7 +110,7 @@ aggregates_policies = [
'method': 'GET'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=NEW_POLICY_ROOT % 'images',
check_str=base.ADMIN,
@ -121,7 +121,7 @@ aggregates_policies = [
'method': 'POST'
}
],
scope_types=['system']),
scope_types=['project']),
]

View File

@ -33,7 +33,7 @@ availability_zone_policies = [
'path': '/os-availability-zone'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'detail',
check_str=base.ADMIN,
@ -45,7 +45,7 @@ availability_zone_policies = [
'path': '/os-availability-zone/detail'
}
],
scope_types=['system'])
scope_types=['project'])
]

View File

@ -49,7 +49,7 @@ These APIs are proxy calls to the Ironic service and are deprecated.
'path': '/os-baremetal-nodes'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_BAREMETAL_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'show',
@ -61,7 +61,7 @@ These APIs are proxy calls to the Ironic service and are deprecated.
'path': '/os-baremetal-nodes/{node_id}'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_BAREMETAL_POLICY)
]

View File

@ -37,7 +37,7 @@ extensions_policies = [
'path': '/extensions/{alias}'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
]

View File

@ -53,7 +53,7 @@ flavor_access_policies = [
'path': '/flavors/{flavor_id}/action (addTenantAccess)'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'remove_tenant_access',
check_str=base.ADMIN,
@ -64,7 +64,7 @@ flavor_access_policies = [
'path': '/flavors/{flavor_id}/action (removeTenantAccess)'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME,
check_str=base.ADMIN,
@ -79,7 +79,7 @@ to a flavor via an os-flavor-access API.
'path': '/flavors/{flavor_id}/os-flavor-access'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_FLAVOR_ACCESS_POLICY),
]

View File

@ -31,7 +31,7 @@ flavor_extra_specs_policies = [
'method': 'GET'
}
],
scope_types=['system', 'project']
scope_types=['project']
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
@ -43,7 +43,7 @@ flavor_extra_specs_policies = [
'method': 'POST'
}
],
scope_types=['system']
scope_types=['project']
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
@ -56,7 +56,7 @@ flavor_extra_specs_policies = [
'method': 'PUT'
}
],
scope_types=['system']
scope_types=['project']
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
@ -69,7 +69,7 @@ flavor_extra_specs_policies = [
'method': 'DELETE'
}
],
scope_types=['system']
scope_types=['project']
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
@ -100,7 +100,7 @@ flavor_extra_specs_policies = [
'method': 'PUT'
}
],
scope_types=['system', 'project']
scope_types=['project']
),
]

View File

@ -33,7 +33,7 @@ flavor_manage_policies = [
'path': '/flavors'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.ADMIN,
@ -44,7 +44,7 @@ flavor_manage_policies = [
'path': '/flavors/{flavor_id}'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.ADMIN,
@ -55,7 +55,7 @@ flavor_manage_policies = [
'path': '/flavors/{flavor_id}'
}
],
scope_types=['system']),
scope_types=['project']),
]

View File

@ -32,7 +32,7 @@ floating_ip_pools_policies = [
'path': '/os-floating-ip-pools'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
]

View File

@ -48,7 +48,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'show',
@ -62,7 +62,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts/{host_name}'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'update',
@ -76,7 +76,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts/{host_name}'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'reboot',
@ -90,7 +90,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts/{host_name}/reboot'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'shutdown',
@ -104,7 +104,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts/{host_name}/shutdown'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=POLICY_NAME % 'start',
@ -118,7 +118,7 @@ This API is deprecated in favor of os-hypervisors and os-services.""",
'path': '/os-hosts/{host_name}/startup'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
]

View File

@ -45,7 +45,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'list-detail',
@ -57,7 +57,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'statistics',
@ -70,7 +70,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'show',
@ -82,7 +82,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'uptime',
@ -94,7 +94,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'search',
@ -106,7 +106,7 @@ hypervisors_policies = [
'method': 'GET'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'servers',
@ -120,7 +120,7 @@ hypervisors_policies = [
'method': 'GET'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY
),
]

View File

@ -44,7 +44,7 @@ instance_usage_audit_log_policies = [
'path': '/os-instance_usage_audit_log'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'show',
@ -59,7 +59,7 @@ instance_usage_audit_log_policies = [
'path': '/os-instance_usage_audit_log/{before_timestamp}'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_POLICY),
]

View File

@ -31,7 +31,7 @@ keypairs_policies = [
'method': 'GET'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str='(' + base.ADMIN + ') or user_id:%(user_id)s',
@ -42,7 +42,7 @@ keypairs_policies = [
'method': 'POST'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str='(' + base.ADMIN + ') or user_id:%(user_id)s',
@ -53,7 +53,7 @@ keypairs_policies = [
'method': 'DELETE'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str='(' + base.ADMIN + ') or user_id:%(user_id)s',
@ -64,7 +64,7 @@ keypairs_policies = [
'method': 'GET'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
]

View File

@ -32,7 +32,7 @@ quota_class_sets_policies = [
'path': '/os-quota-class-sets/{quota_class}'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.ADMIN,
@ -43,7 +43,7 @@ quota_class_sets_policies = [
'path': '/os-quota-class-sets/{quota_class}'
}
],
scope_types=['system']),
scope_types=['project']),
]

View File

@ -43,7 +43,7 @@ quota_sets_policies = [
'path': '/os-quota-sets/{tenant_id}/defaults'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
# TODO(gmann): Until we have domain admin or so to get other project's

View File

@ -45,7 +45,7 @@ services_policies = [
'path': '/os-services'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_SERVICE_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'update',
@ -58,7 +58,7 @@ services_policies = [
'path': '/os-services/{service_id}'
},
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_SERVICE_POLICY),
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME % 'delete',
@ -70,7 +70,7 @@ services_policies = [
'path': '/os-services/{service_id}'
}
],
scope_types=['system'],
scope_types=['project'],
deprecated_rule=DEPRECATED_SERVICE_POLICY),
]

View File

@ -35,14 +35,14 @@ class AggregatesPolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to perform Aggregate
# Operations.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
@mock.patch('nova.compute.api.AggregateAPI.get_aggregate_list')
def test_list_aggregate_policy(self, mock_list):
rule_name = "os_compute_api:os-aggregates:index"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.index,
self.req)
@ -55,7 +55,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
"hosts": ["host1", "host2"]})
body = {"aggregate": {"name": "test",
"availability_zone": "nova1"}}
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller.create,
self.req, body=body)
@ -63,7 +63,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.AggregateAPI.update_aggregate')
def test_update_aggregate_policy(self, mock_update):
rule_name = "os_compute_api:os-aggregates:update"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.update,
self.req, 1,
body={"aggregate": {"name": "new_name"}})
@ -71,7 +71,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.AggregateAPI.delete_aggregate')
def test_delete_aggregate_policy(self, mock_delete):
rule_name = "os_compute_api:os-aggregates:delete"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller.delete,
self.req, 1)
@ -79,7 +79,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.AggregateAPI.get_aggregate')
def test_show_aggregate_policy(self, mock_show):
rule_name = "os_compute_api:os-aggregates:show"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.show,
self.req, 1)
@ -87,7 +87,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
def test_set_metadata_aggregate_policy(self, mock_metadata):
rule_name = "os_compute_api:os-aggregates:set_metadata"
body = {"set_metadata": {"metadata": {"foo": "bar"}}}
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller._set_metadata,
self.req, 1, body=body)
@ -95,7 +95,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.AggregateAPI.add_host_to_aggregate')
def test_add_host_aggregate_policy(self, mock_add):
rule_name = "os_compute_api:os-aggregates:add_host"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller._add_host,
self.req, 1,
body={"add_host": {"host": "host1"}})
@ -103,7 +103,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.AggregateAPI.remove_host_from_aggregate')
def test_remove_host_aggregate_policy(self, mock_remove):
rule_name = "os_compute_api:os-aggregates:remove_host"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller._remove_host,
self.req, 1,
@ -118,7 +118,7 @@ class AggregatesPolicyTest(base.BasePolicyTest):
body = {'cache': [{'id': uuids.fake_id}]}
req = fakes.HTTPRequest.blank('', version='2.81')
with mock.patch('nova.conductor.api.ComputeTaskAPI.cache_images'):
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.images,
req, 1, body=body)
@ -149,9 +149,10 @@ class AggregatesScopeTypePolicyTest(AggregatesPolicyTest):
super(AggregatesScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope checks enable, only system admin is able to perform
# Aggregate Operations.
self.system_admin_authorized_contexts = [self.system_admin_context]
# With scope checks enabled, only project-scoped admins are
# able to perform Aggregate Operations.
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class AggregatesScopeTypeNoLegacyPolicyTest(AggregatesScopeTypePolicyTest):

View File

@ -34,20 +34,21 @@ class AvailabilityZonePolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to get AZ with host
# information.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
self.project_authorized_contexts = self.all_contexts
@mock.patch('nova.objects.Instance.save')
def test_availability_zone_list_policy(self, mock_save):
rule_name = "os_compute_api:os-availability-zone:list"
self.common_policy_auth(self.all_contexts,
self.common_policy_auth(self.project_authorized_contexts,
rule_name, self.controller.index,
self.req)
def test_availability_zone_detail_policy(self):
rule_name = "os_compute_api:os-availability-zone:detail"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.detail,
self.req)
@ -79,9 +80,11 @@ class AvailabilityZoneScopeTypePolicyTest(AvailabilityZonePolicyTest):
super(AvailabilityZoneScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope checks enable, only system admin is able to get
# AZ with host information.
self.system_admin_authorized_contexts = [self.system_admin_context]
# With scope checks enable, only project-scoped admins are
# able to get AZ with host information.
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
self.project_authorized_contexts = self.all_project_contexts
class AZScopeTypeNoLegacyPolicyTest(AvailabilityZoneScopeTypePolicyTest):

View File

@ -43,13 +43,13 @@ class BaremetalNodesPolicyTest(base.BasePolicyTest):
lambda *_: FAKE_IRONIC_CLIENT)
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to get baremetal nodes.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
def test_index_nodes_policy(self):
rule_name = "os_compute_api:os-baremetal-nodes:list"
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.index,
self.req)
@ -62,7 +62,7 @@ class BaremetalNodesPolicyTest(base.BasePolicyTest):
mock_get.return_value = node
mock_port.return_value = []
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller.show,
self.req, uuids.fake_id)
@ -95,9 +95,10 @@ class BaremetalNodesScopeTypePolicyTest(BaremetalNodesPolicyTest):
super(BaremetalNodesScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope checks enable, only system admin is able to get
# baremetal nodes.
self.system_admin_authorized_contexts = [self.system_admin_context]
# With scope checks enable, only project-scoped admins are
# able to get baremetal nodes.
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class BNScopeTypeNoLegacyPolicyTest(BaremetalNodesScopeTypePolicyTest):

View File

@ -71,6 +71,16 @@ class ExtensionsScopeTypePolicyTest(ExtensionsPolicyTest):
def setUp(self):
super(ExtensionsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
self.everyone_authorized_contexts = [
self.legacy_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_reader_context,
self.other_project_member_context
]
self.everyone_unauthorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context, self.system_foo_context]
class ExtensionsNoLegacyPolicyTest(ExtensionsScopeTypePolicyTest):

View File

@ -122,12 +122,11 @@ class FlavorAccessScopeTypePolicyTest(FlavorAccessPolicyTest):
super(FlavorAccessScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# Scope checks remove project users power.
# Scope checks remove system users' power.
self.admin_authorized_contexts = [
self.system_admin_context]
self.admin_index_authorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context, self.system_foo_context]
self.legacy_admin_context,
self.project_admin_context]
self.admin_index_authorized_contexts = self.all_project_contexts
class FlavorAccessScopeTypeNoLegacyPolicyTest(FlavorAccessScopeTypePolicyTest):
@ -146,5 +145,9 @@ class FlavorAccessScopeTypeNoLegacyPolicyTest(FlavorAccessScopeTypePolicyTest):
def setUp(self):
super(FlavorAccessScopeTypeNoLegacyPolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
self.admin_index_authorized_contexts = [
self.system_admin_context]
# New defaults make this admin-only
self.admin_authorized_contexts = [
self.legacy_admin_context,
self.project_admin_context]
self.admin_index_authorized_contexts = self.admin_authorized_contexts

View File

@ -57,7 +57,7 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
# In the base/legacy case, all project and system contexts are
# authorized in the case of things that distinguish between
# scopes, since scope checking is disabled.
self.all_system_authorized_contexts = (self.all_project_contexts |
self.all_project_authorized_contexts = (self.all_project_contexts |
self.all_system_contexts)
# In the base/legacy case, any admin is an admin.
@ -167,7 +167,7 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
}
}
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_system_authorized_contexts,
self.all_project_authorized_contexts,
rule_name, self.fm_ctrl._create, req, body=body,
fatal=False)
for resp in authorize_res:
@ -187,7 +187,7 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
req = fakes.HTTPRequest.blank('', version='2.61')
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_system_authorized_contexts,
self.all_project_authorized_contexts,
rule_name, self.fm_ctrl._update, req, '1',
body={'flavor': {'description': None}},
fatal=False)
@ -211,11 +211,13 @@ class FlavorExtraSpecsScopeTypePolicyTest(FlavorExtraSpecsPolicyTest):
super(FlavorExtraSpecsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# Only system users are authorized for system APIs
self.all_system_authorized_contexts = self.all_system_contexts
# Only project users are authorized
self.reduce_set('all_project_authorized', self.all_project_contexts)
self.reduce_set('all_authorized', self.all_project_contexts)
# Only system_admin can do system admin things
self.admin_authorized_contexts = [self.system_admin_context]
# Only admins can do admin things
self.admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class FlavorExtraSpecsNoLegacyNoScopeTest(FlavorExtraSpecsPolicyTest):
@ -235,7 +237,7 @@ class FlavorExtraSpecsNoLegacyNoScopeTest(FlavorExtraSpecsPolicyTest):
self.system_foo_context,
self.project_foo_context,
])
self.reduce_set('all_system_authorized', everything_but_foo)
self.reduce_set('all_project_authorized', everything_but_foo)
self.reduce_set('all_authorized', everything_but_foo)
@ -252,11 +254,10 @@ class FlavorExtraSpecsNoLegacyPolicyTest(FlavorExtraSpecsScopeTypePolicyTest):
# contexts. With scope checking enabled, project and system
# contexts stay separate.
self.reduce_set(
'all_system_authorized',
self.all_system_contexts - set([self.system_foo_context]))
everything_but_foo = (
self.all_project_contexts | self.all_system_contexts) - set([
self.system_foo_context,
'all_project_authorized',
self.all_project_contexts - set([self.project_foo_context]))
everything_but_foo_and_system = (
self.all_contexts - set([
self.project_foo_context,
])
self.reduce_set('all_authorized', everything_but_foo)
]) - self.all_system_contexts)
self.reduce_set('all_authorized', everything_but_foo_and_system)

View File

@ -105,10 +105,11 @@ class FlavorManageScopeTypePolicyTest(FlavorManagePolicyTest):
super(FlavorManageScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope enable, only system admin is able to manage
# With scope enabled, only project admin is able to manage
# the flavors.
self.admin_authorized_contexts = [
self.system_admin_context]
self.legacy_admin_context,
self.project_admin_context]
class FlavorManageScopeTypeNoLegacyPolicyTest(

View File

@ -32,15 +32,15 @@ class FloatingIPPoolsPolicyTest(base.BasePolicyTest):
self.req = fakes.HTTPRequest.blank('')
# Check that everyone is able to list FIP pools.
self.everyone_authorized_contexts = [
self.everyone_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_reader_context,
self.other_project_member_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context]
self.everyone_unauthorized_contexts = []
self.system_foo_context])
self.everyone_unauthorized_contexts = set([])
@mock.patch('nova.network.neutron.API.get_floating_ip_pools')
def test_floating_ip_pools_policy(self, mock_get):
@ -66,6 +66,10 @@ class FloatingIPPoolsScopeTypePolicyTest(FloatingIPPoolsPolicyTest):
super(FloatingIPPoolsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
self.reduce_set('everyone_authorized', self.all_project_contexts)
self.everyone_unauthorized_contexts = (
self.all_contexts - self.everyone_authorized_contexts)
class FloatingIPPoolsNoLegacyPolicyTest(FloatingIPPoolsScopeTypePolicyTest):
"""Test Floating IP Pools APIs policies with system scope enabled,

View File

@ -35,14 +35,14 @@ class HostsPolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to perform hosts
# Operations.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
@mock.patch('nova.compute.api.HostAPI.service_get_all')
def test_list_hosts_policy(self, mock_get):
rule_name = policies.POLICY_NAME % 'list'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.index,
self.req)
@ -53,34 +53,34 @@ class HostsPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.HostAPI.instance_get_all_by_host')
def test_show_host_policy(self, mock_get, mock_node, mock_map, mock_set):
rule_name = policies.POLICY_NAME % 'show'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.show,
self.req, 11111)
def test_update_host_policy(self):
rule_name = policies.POLICY_NAME % 'update'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.update,
self.req, 11111, body={})
@mock.patch('nova.compute.api.HostAPI.host_power_action')
def test_reboot_host_policy(self, mock_action):
rule_name = policies.POLICY_NAME % 'reboot'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.reboot,
self.req, 11111)
@mock.patch('nova.compute.api.HostAPI.host_power_action')
def test_shutdown_host_policy(self, mock_action):
rule_name = policies.POLICY_NAME % 'shutdown'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.shutdown,
self.req, 11111)
@mock.patch('nova.compute.api.HostAPI.host_power_action')
def test_startup_host_policy(self, mock_action):
rule_name = policies.POLICY_NAME % 'start'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.startup,
self.req, 11111)
@ -113,7 +113,8 @@ class HostsScopeTypePolicyTest(HostsPolicyTest):
# With scope checks enable, only system admin is able to perform
# hosts Operations.
self.system_admin_authorized_contexts = [self.system_admin_context]
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class HostsScopeTypeNoLegacyPolicyTest(HostsScopeTypePolicyTest):

View File

@ -39,51 +39,51 @@ class HypervisorsPolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to perform hypervisors
# Operations.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
def test_list_hypervisors_policy(self):
rule_name = hv_policies.BASE_POLICY_NAME % 'list'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.index,
self.req)
def test_list_details_hypervisors_policy(self):
rule_name = hv_policies.BASE_POLICY_NAME % 'list-detail'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.detail,
self.req)
def test_show_hypervisors_policy(self):
rule_name = hv_policies.BASE_POLICY_NAME % 'show'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.show,
self.req, 11111)
@mock.patch('nova.compute.api.HostAPI.get_host_uptime')
def test_uptime_hypervisors_policy(self, mock_uptime):
rule_name = hv_policies.BASE_POLICY_NAME % 'uptime'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.uptime,
self.req, 11111)
def test_search_hypervisors_policy(self):
rule_name = hv_policies.BASE_POLICY_NAME % 'search'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.search,
self.req, 11111)
def test_servers_hypervisors_policy(self):
rule_name = hv_policies.BASE_POLICY_NAME % 'servers'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.servers,
self.req, 11111)
@mock.patch('nova.compute.api.HostAPI.compute_node_statistics')
def test_statistics_hypervisors_policy(self, mock_statistics):
rule_name = hv_policies.BASE_POLICY_NAME % 'statistics'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.statistics,
self.req)
@ -115,7 +115,8 @@ class HypervisorsScopeTypePolicyTest(HypervisorsPolicyTest):
# With scope checks enable, only system admin is able to perform
# hypervisors Operations.
self.system_admin_authorized_contexts = [self.system_admin_context]
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class HypervisorsScopeTypeNoLegacyPolicyTest(HypervisorsScopeTypePolicyTest):

View File

@ -85,7 +85,8 @@ class InstanceUsageScopeTypePolicyTest(InstanceUsageAuditLogPolicyTest):
# Scope checks remove project users power.
self.admin_authorized_contexts = [
self.system_admin_context]
self.legacy_admin_context,
self.project_admin_context]
class InstanceUsageScopeTypeNoLegacyPolicyTest(

View File

@ -35,7 +35,7 @@ class KeypairsPolicyTest(base.BasePolicyTest):
# Check that everyone is able to create, delete and get
# their keypairs.
self.everyone_authorized_contexts = [
self.everyone_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context,
self.system_member_context, self.system_reader_context,
@ -43,13 +43,13 @@ class KeypairsPolicyTest(base.BasePolicyTest):
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context,
]
])
# Check that admin is able to create, delete and get
# other users keypairs.
self.admin_authorized_contexts = [
self.admin_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
self.project_admin_context])
@mock.patch('nova.compute.api.KeypairAPI.get_key_pairs')
def test_index_keypairs_policy(self, mock_get):
@ -152,6 +152,12 @@ class KeypairsScopeTypePolicyTest(KeypairsPolicyTest):
super(KeypairsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope checking, only project-scoped users are allowed
self.reduce_set('everyone_authorized', self.all_project_contexts)
self.admin_authorized_contexts = [
self.legacy_admin_context,
self.project_admin_context]
class KeypairsNoLegacyPolicyTest(KeypairsScopeTypePolicyTest):
"""Test Keypairs APIs policies with system scope enabled,

View File

@ -34,7 +34,7 @@ class QuotaClassSetsPolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to get, update quota
# class.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
@ -46,7 +46,7 @@ class QuotaClassSetsPolicyTest(base.BasePolicyTest):
'ram': 51200, 'floating_ips': -1,
'fixed_ips': -1, 'instances': 10,
'injected_files': 5, 'cores': 20}}
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller.update,
self.req, 'test_class',
@ -55,7 +55,7 @@ class QuotaClassSetsPolicyTest(base.BasePolicyTest):
@mock.patch('nova.quota.QUOTAS.get_class_quotas')
def test_show_quota_class_sets_policy(self, mock_get):
rule_name = policies.POLICY_ROOT % 'show'
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name,
self.controller.show,
self.req, 'test_class')
@ -86,9 +86,10 @@ class QuotaClassSetsScopeTypePolicyTest(QuotaClassSetsPolicyTest):
super(QuotaClassSetsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope checks enable, only system admin is able to update
# and get quota class.
self.system_admin_authorized_contexts = [self.system_admin_context]
# With scope checks enable, only project admins are able to
# update and get quota class.
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class QuotaClassScopeTypeNoLegacyPolicyTest(QuotaClassSetsScopeTypePolicyTest):

View File

@ -36,27 +36,27 @@ class QuotaSetsPolicyTest(base.BasePolicyTest):
# With legacy rule all admin is able to update or revert their quota
# to default or get other project quota.
self.project_admin_authorized_contexts = [
self.project_admin_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
self.project_admin_context])
# With legacy rule, everyone is able to get their own quota.
self.project_reader_authorized_contexts = [
self.project_reader_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context]
self.other_project_reader_context])
# Everyone is able to get the default quota
self.everyone_authorized_contexts = [
self.everyone_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context]
self.other_project_reader_context])
@mock.patch('nova.quota.QUOTAS.get_project_quotas')
@mock.patch('nova.quota.QUOTAS.get_settable_quotas')
@ -176,16 +176,13 @@ class QuotaSetsScopeTypePolicyTest(QuotaSetsPolicyTest):
super(QuotaSetsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# With scope enable, system users will be disallowed.
self.project_admin_authorized_contexts = [
# With scope enabled, system users will be disallowed.
self.reduce_set('project_admin_authorized', set([
self.legacy_admin_context,
self.project_admin_context]
self.project_reader_authorized_contexts = [
self.legacy_admin_context, self.project_admin_context,
self.project_member_context, self.project_reader_context,
self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context]
self.project_admin_context]))
self.reduce_set('project_reader_authorized',
self.all_project_contexts)
self.everyone_authorized_contexts = self.all_project_contexts
class QuotaSetsScopeTypeNoLegacyPolicyTest(QuotaSetsScopeTypePolicyTest):
@ -197,6 +194,8 @@ class QuotaSetsScopeTypeNoLegacyPolicyTest(QuotaSetsScopeTypePolicyTest):
def setUp(self):
super(QuotaSetsScopeTypeNoLegacyPolicyTest, self).setUp()
self.project_reader_authorized_contexts = [
self.legacy_admin_context, self.project_admin_context,
self.project_member_context, self.project_reader_context]
# With scope enabled and no legacy, system and
# non-reader/member users are disallowed.
self.reduce_set('project_reader_authorized',
self.all_project_contexts -
set([self.project_foo_context]))

View File

@ -35,21 +35,21 @@ class ServicesPolicyTest(base.BasePolicyTest):
# With legacy rule and scope check disabled by default, system admin,
# legacy admin, and project admin will be able to perform Services
# Operations.
self.system_admin_authorized_contexts = [
self.project_admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
def test_delete_service_policy(self):
rule_name = "os_compute_api:os-services:delete"
with mock.patch('nova.compute.api.HostAPI.service_get_by_id'):
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.delete,
self.req, 1)
def test_index_service_policy(self):
rule_name = "os_compute_api:os-services:list"
with mock.patch('nova.compute.api.HostAPI.service_get_all'):
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.index,
self.req)
@ -58,7 +58,7 @@ class ServicesPolicyTest(base.BasePolicyTest):
body = {'host': 'host1', 'binary': 'nova-compute'}
update = 'nova.compute.api.HostAPI.service_update_by_host_and_binary'
with mock.patch(update):
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.update,
self.req, 'enable', body=body)
@ -69,7 +69,7 @@ class ServicesPolicyTest(base.BasePolicyTest):
service = self.start_service(
'compute', 'fake-compute-host').service_ref
with mock.patch('nova.compute.api.HostAPI.service_update'):
self.common_policy_auth(self.system_admin_authorized_contexts,
self.common_policy_auth(self.project_admin_authorized_contexts,
rule_name, self.controller.update,
req, service.uuid,
body={'status': 'enabled'})
@ -107,7 +107,8 @@ class ServicesScopeTypePolicyTest(ServicesPolicyTest):
# With scope checks enable, only system admin is able to perform
# Service Operations.
self.system_admin_authorized_contexts = [self.system_admin_context]
self.project_admin_authorized_contexts = [self.legacy_admin_context,
self.project_admin_context]
class ServicesScopeTypeNoLegacyPolicyTest(ServicesScopeTypePolicyTest):