From 9be1caff97355099d25170fe390dd15d6f592d56 Mon Sep 17 00:00:00 2001 From: Colleen Murphy Date: Fri, 16 Aug 2019 11:14:16 -0700 Subject: [PATCH] Implement system admin for trusts API This change enables a system admin to delete trusts. Previously, only the trustor or the is_admin admin could delete a trust. This changes makes the trusts API more useful to system administrators who need to clean up trusts and makes the API consistent with others. This does not enable system admins to create trusts. A trust can only be scoped to a project, so creating one is inherently a project-scoped action. If trusts later gain the ability to be scoped to the system or domains, we can add those scopes to the create_trust scope_types. Change-Id: Idf13b862f345388bb2372609787947eb43d7ba75 Closes-bug: #1818846 Closes-bug: #1818850 Related-Bug: #968696 --- keystone/common/policies/trust.py | 14 +++++-- .../tests/unit/protection/v3/test_trusts.py | 10 ++--- .../notes/bug-1818846-d1a8c77d20659ad6.yaml | 41 +++++++++++++++++++ 3 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 releasenotes/notes/bug-1818846-d1a8c77d20659ad6.yaml diff --git a/keystone/common/policies/trust.py b/keystone/common/policies/trust.py index bcd681f9c2..96fb698e58 100644 --- a/keystone/common/policies/trust.py +++ b/keystone/common/policies/trust.py @@ -22,6 +22,7 @@ SYSTEM_READER_OR_TRUSTOR_OR_TRUSTEE = ( ) SYSTEM_READER_OR_TRUSTOR = base.SYSTEM_READER + ' or ' + RULE_TRUSTOR SYSTEM_READER_OR_TRUSTEE = base.SYSTEM_READER + ' or ' + RULE_TRUSTEE +SYSTEM_ADMIN_OR_TRUSTOR = base.SYSTEM_ADMIN + ' or ' + RULE_TRUSTOR deprecated_list_trusts = policy.DeprecatedRule( name=base.IDENTITY % 'list_trusts', @@ -35,6 +36,10 @@ deprecated_get_role_for_trust = policy.DeprecatedRule( name=base.IDENTITY % 'get_role_for_trust', check_str=RULE_TRUSTOR + ' or ' + RULE_TRUSTEE ) +deprecated_delete_trust = policy.DeprecatedRule( + name=base.IDENTITY % 'delete_trust', + check_str=RULE_TRUSTOR +) deprecated_get_trust = policy.DeprecatedRule( name=base.IDENTITY % 'get_trust', check_str=RULE_TRUSTOR + ' or ' + RULE_TRUSTEE @@ -115,11 +120,14 @@ trust_policies = [ deprecated_since=versionutils.deprecated.TRAIN), policy.DocumentedRuleDefault( name=base.IDENTITY % 'delete_trust', - check_str=RULE_TRUSTOR, - scope_types=['project'], + check_str=SYSTEM_ADMIN_OR_TRUSTOR, + scope_types=['system', 'project'], description='Revoke trust.', operations=[{'path': '/v3/OS-TRUST/trusts/{trust_id}', - 'method': 'DELETE'}]), + 'method': 'DELETE'}], + deprecated_rule=deprecated_delete_trust, + deprecated_reason=DEPRECATED_REASON, + deprecated_since=versionutils.deprecated.TRAIN), policy.DocumentedRuleDefault( name=base.IDENTITY % 'get_trust', check_str=SYSTEM_READER_OR_TRUSTOR_OR_TRUSTEE, diff --git a/keystone/tests/unit/protection/v3/test_trusts.py b/keystone/tests/unit/protection/v3/test_trusts.py index 2a3a8da266..0cb3b06c54 100644 --- a/keystone/tests/unit/protection/v3/test_trusts.py +++ b/keystone/tests/unit/protection/v3/test_trusts.py @@ -378,9 +378,7 @@ class SystemAdminTests(TrustTests, _AdminTestsMixin, _SystemUserTests): def setUp(self): super(SystemAdminTests, self).setUp() - # TODO(cmurphy) enable enforce_scope when trust policies become - # system-scope aware - # self.config_fixture.config(group='oslo_policy', enforce_scope=True) + self.config_fixture.config(group='oslo_policy', enforce_scope=True) self.user_id = self.bootstrapper.admin_user_id auth = self.build_authentication_request( @@ -396,16 +394,14 @@ class SystemAdminTests(TrustTests, _AdminTestsMixin, _SystemUserTests): self.token_id = r.headers['X-Subject-Token'] self.headers = {'X-Auth-Token': self.token_id} - def test_admin_cannot_delete_trust_for_other_user(self): - # only the is_admin admin can do this + def test_admin_can_delete_trust_for_other_user(self): ref = PROVIDERS.trust_api.create_trust( self.trust_id, **self.trust_data) with self.test_client() as c: c.delete( '/v3/OS-TRUST/trusts/%s' % ref['id'], - headers=self.headers, - expected_status_code=http_client.FORBIDDEN + headers=self.headers ) def test_admin_cannot_delete_trust_for_user_overridden_defaults(self): diff --git a/releasenotes/notes/bug-1818846-d1a8c77d20659ad6.yaml b/releasenotes/notes/bug-1818846-d1a8c77d20659ad6.yaml new file mode 100644 index 0000000000..f397dd44a6 --- /dev/null +++ b/releasenotes/notes/bug-1818846-d1a8c77d20659ad6.yaml @@ -0,0 +1,41 @@ +--- +features: + - | + [`bug 1818846 `_] + The trusts API now supports the ``admin``, ``member``, and ``reader`` + default roles. System users can now audit and clean up trusts using the + default policies. +upgrade: + - | + [`bug 1818846 `_] + [`bug 1818850 `_] + The trusts API uses new default policies that make it more + accessible to end users and administrators in a secure way. Please + consider these new defaults if your deployment overrides + trust policies. +deprecations: + - | + [`bug 1818846 `_] + [`bug 1818850 `_] + The trust policies have been deprecated. The ``identity:list_trusts`` + policy now uses ``(role:reader and system_scope:all)`` instead of + ``rule_admin_required``. The ``identity:list_roles_for_trust``, + ``identity:get_role_for_trust``, and ``identity:get_trust`` policies now + use ``(role:reader and system_scope:all) or + user_id:%(target.trust.trustor_user_id)s or + user_id:%(target.trust.trustee_user_id)s`` instead + of``user_id:%(target.trust.trustor_user_id)s or + user_id:%(target.trust.trustee_user_id)s``. The ``identity:delete_trust`` + policy now uses ``(role:admin and system_scope:all) or + user_id:%(target.trust.trustor_user_id)s`` instead of + ``user_id:%(target.trust.trustor_user_id)s``. 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 trust policies. +security: + - | + [`bug 1818846 `_] + [`bug 1818850 `_] + The trusts API now uses system-scope and default roles to + provide better accessibility to users in a secure way.