Implement system admin for policy association

This change modifies the policies for policy
association API to be more self-service by properly
checking for system scopes. It also includes the test cases.

Subsequent patches will -

 - add domains user test coverage for policy association
 - add project user test coverage for policy association
 - Removing obsolete policies in policy.v3cloudsample.json file
Partial-Bug: #1805409

Change-Id: I7ed54a378dc20680cd987142c71afc36cb1dbd25
This commit is contained in:
Vishakha Agarwal 2019-08-22 17:51:31 +05:30
parent b831856af3
commit 2d185a5a91
3 changed files with 258 additions and 12 deletions

View File

@ -44,6 +44,36 @@ deprecated_list_endpoints_for_policy = policy.DeprecatedRule(
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_create_policy_association_for_endpoint = policy.DeprecatedRule(
name=base.IDENTITY % 'create_policy_association_for_endpoint',
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_delete_policy_association_for_endpoint = policy.DeprecatedRule(
name=base.IDENTITY % 'delete_policy_association_for_endpoint',
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_create_policy_association_for_service = policy.DeprecatedRule(
name=base.IDENTITY % 'create_policy_association_for_service',
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_delete_policy_association_for_service = policy.DeprecatedRule(
name=base.IDENTITY % 'delete_policy_association_for_service',
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_create_policy_association_for_region_and_service = policy.DeprecatedRule(
name=base.IDENTITY % 'create_policy_association_for_region_and_service',
check_str=base.RULE_ADMIN_REQUIRED,
)
deprecated_delete_policy_association_for_region_and_service = policy.DeprecatedRule(
name=base.IDENTITY % 'delete_policy_association_for_region_and_service',
check_str=base.RULE_ADMIN_REQUIRED,
)
DEPRECATED_REASON = """
As of the Train release, the policy association API now understands default
roles and system-scoped tokens, making the API more granular by default without
@ -55,12 +85,15 @@ relying on overrides in your deployment for the policy association API.
policy_association_policies = [
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'create_policy_association_for_endpoint',
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description='Associate a policy to a specific endpoint.',
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'endpoints/{endpoint_id}'),
'method': 'PUT'}]),
'method': 'PUT'}],
deprecated_rule=deprecated_create_policy_association_for_endpoint,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'check_policy_association_for_endpoint',
check_str=base.SYSTEM_READER,
@ -77,20 +110,26 @@ policy_association_policies = [
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'delete_policy_association_for_endpoint',
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description='Delete policy association for endpoint.',
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'endpoints/{endpoint_id}'),
'method': 'DELETE'}]),
'method': 'DELETE'}],
deprecated_rule=deprecated_delete_policy_association_for_endpoint,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'create_policy_association_for_service',
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description='Associate a policy to a specific service.',
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'services/{service_id}'),
'method': 'PUT'}]),
'method': 'PUT'}],
deprecated_rule=deprecated_create_policy_association_for_service,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'check_policy_association_for_service',
check_str=base.SYSTEM_READER,
@ -107,22 +146,28 @@ policy_association_policies = [
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'delete_policy_association_for_service',
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description='Delete policy association for service.',
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'services/{service_id}'),
'method': 'DELETE'}]),
'method': 'DELETE'}],
deprecated_rule=deprecated_delete_policy_association_for_service,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % (
'create_policy_association_for_region_and_service'),
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description=('Associate a policy to a specific region and service '
'combination.'),
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'services/{service_id}/regions/{region_id}'),
'method': 'PUT'}]),
'method': 'PUT'}],
deprecated_rule=deprecated_create_policy_association_for_region_and_service,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'check_policy_association_for_region_and_service',
check_str=base.SYSTEM_READER,
@ -140,12 +185,15 @@ policy_association_policies = [
policy.DocumentedRuleDefault(
name=base.IDENTITY % (
'delete_policy_association_for_region_and_service'),
check_str=base.RULE_ADMIN_REQUIRED,
check_str=base.SYSTEM_ADMIN,
scope_types=['system'],
description='Delete policy association for region and service.',
operations=[{'path': ('/v3/policies/{policy_id}/OS-ENDPOINT-POLICY/'
'services/{service_id}/regions/{region_id}'),
'method': 'DELETE'}]),
'method': 'DELETE'}],
deprecated_rule=deprecated_delete_policy_association_for_region_and_service,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.TRAIN),
policy.DocumentedRuleDefault(
name=base.IDENTITY % 'get_policy_for_endpoint',
check_str=base.SYSTEM_READER,

View File

@ -292,3 +292,129 @@ class SystemMemberTests(base_classes.TestCaseWithBootstrap,
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
class SystemAdminTests(base_classes.TestCaseWithBootstrap,
common_auth.AuthTestMixin,
_SystemUserPoliciesAssociationTests):
def setUp(self):
super(SystemAdminTests, self).setUp()
self.loadapp()
self.useFixture(ksfixtures.Policy(self.config_fixture))
self.config_fixture.config(group='oslo_policy', enforce_scope=True)
# Reuse the system administrator account created during
# ``keystone-manage bootstrap``
self.user_id = self.bootstrapper.admin_user_id
auth = self.build_authentication_request(
user_id=self.user_id,
password=self.bootstrapper.admin_password,
system=True
)
# Grab a token using the persona we're testing and prepare headers
# for requests we'll be making in the tests.
with self.test_client() as c:
r = c.post('/v3/auth/tokens', json=auth)
self.token_id = r.headers['X-Subject-Token']
self.headers = {'X-Auth-Token': self.token_id}
def test_user_can_create_policy_association_for_endpoint(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
endpoint = unit.new_endpoint_ref(service['id'], region_id=None)
endpoint = PROVIDERS.catalog_api.create_endpoint(
endpoint['id'], endpoint
)
with self.test_client() as c:
c.put(
'/v3/policies/%s/OS-ENDPOINT-POLICY/endpoints/%s'
% (policy['id'], endpoint['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)
def test_user_can_delete_policy_association_for_endpoint(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
endpoint = unit.new_endpoint_ref(service['id'], region_id=None)
endpoint = PROVIDERS.catalog_api.create_endpoint(
endpoint['id'], endpoint
)
with self.test_client() as c:
c.delete(
'/v3/policies/%s/OS-ENDPOINT-POLICY/endpoints/%s'
% (policy['id'], endpoint['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)
def test_user_can_create_policy_association_for_service(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
with self.test_client() as c:
c.put(
'/v3/policies/%s/OS-ENDPOINT-POLICY/services/%s'
% (policy['id'], service['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)
def test_user_can_delete_policy_association_for_service(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
with self.test_client() as c:
c.delete(
'/v3/policies/%s/OS-ENDPOINT-POLICY/services/%s'
% (policy['id'], service['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)
def test_user_can_create_policy_association_for_region_and_service(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
region = PROVIDERS.catalog_api.create_region(unit.new_region_ref())
with self.test_client() as c:
c.put(
'/v3/policies/%s/OS-ENDPOINT-POLICY/services/%s/regions/%s'
% (policy['id'], service['id'], region['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)
def test_user_can_delete_policy_association_for_region_and_service(self):
policy = unit.new_policy_ref()
policy = PROVIDERS.policy_api.create_policy(policy['id'], policy)
service = PROVIDERS.catalog_api.create_service(
uuid.uuid4().hex, unit.new_service_ref()
)
region = PROVIDERS.catalog_api.create_region(unit.new_region_ref())
with self.test_client() as c:
c.delete(
'/v3/policies/%s/OS-ENDPOINT-POLICY/services/%s/regions/%s'
% (policy['id'], service['id'], region['id']),
headers=self.headers,
expected_status_code=http_client.NO_CONTENT
)

View File

@ -0,0 +1,72 @@
---
features:
- |
[`bug 1805409 <https://bugs.launchpad.net/keystone/+bug/1805409>`_]
The policy and policy associations API now supports the ``admin``,
``member``, and ``reader`` default roles.
upgrade:
- |
[`bug 1805409 <https://bugs.launchpad.net/keystone/+bug/1805409>`_]
The policy and policy associations API uses new default policies to
make it more accessible to end users and administrators in a secure way.
Please consider these new defaults if your deployment overrides policy
and policy associations policies.
deprecations:
- |
[`bug 1805409 <https://bugs.launchpad.net/keystone/+bug/1805409>`_]
The policy and policy associations policies have been deprecated. The
``identity:get_policy`` policy now uses
``role:reader and system_scope:all`` instead of
``rule:admin_required``. The ``identity:list_policies`` policy
now uses ``role:reader and system_scope:all`` instead of
``rule:admin_required``. The ``identity:update_policy`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.The ``identity:create_policy`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``. The ``identity:delete_policy`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:check_policy_association_for_endpoint`` policy
now uses ``role:reader and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:check_policy_association_for_service`` policy
now uses ``role:reader and system_scope:all`` instead of
``role:reader and system_scope:all``.
The ``identity:check_policy_association_for_region_and_service`` policy
now uses ``role:reader and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:get_policy_for_endpoint`` policy
now uses ``role:reader and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:list_endpoints_for_policy`` policy
now use ``role:reader and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:create_policy_association_for_endpoint`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:delete_policy_association_for_endpoint`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:create_policy_association_for_service`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:delete_policy_association_for_service`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:create_policy_association_for_region_and_service`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
The ``identity:delete_policy_association_for_region_and_service`` policy
now use ``role:admin and system_scope:all`` instead of
``rule:admin_required``.
These new defaults automatically account for system-scope and support
a read-only role, making it easier for system administrators to delegate
subsets of responsibility without compromising security. Please consider
these new defaults if your deployment overrides the policy and policy
associations policies.
security:
- |
[`bug 1805409 <https://bugs.launchpad.net/keystone/+bug/1805409>`_]
The policy and policy associations API now uses system-scope and default
roles to provide better accessibility to users in a secure manner.