Invalidate trust when the related project is deleted

The trust without a valid project is useless and will no longer
be active since the id of project is a random number and only
assigned when it created.

The patch invalidate the trust if the related project is deleted.

Change-Id: I51214c46ef5332c159b1e18bbd7046d12aba4a65
Closes-Bug: #1622310
This commit is contained in:
Dave Chen 2016-10-10 19:29:31 +08:00 committed by Steve Martinelli
parent 52642cc562
commit f0319c752a
5 changed files with 55 additions and 1 deletions

View File

@ -37,7 +37,7 @@ MEMOIZE = cache.get_memoization_decorator(group='resource')
@dependency.provider('resource_api')
@dependency.requires('assignment_api', 'credential_api', 'domain_config_api',
'identity_api', 'revoke_api')
'identity_api', 'revoke_api', 'trust_api')
class Manager(manager.Manager):
"""Default pivot point for the Resource backend.
@ -467,6 +467,7 @@ class Manager(manager.Manager):
# the specified project
assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate()
self.credential_api.delete_credentials_for_project(project_id)
self.trust_api.delete_trusts_for_project(project_id)
finally:
# attempt to send audit event even if the cache invalidation raises
notifications.Audit.deleted(self._PROJECT, project_id, initiator)

View File

@ -508,3 +508,30 @@ class TestTrustOperations(test_v3.RestfulTestCase):
self.assertRaises(exception.TrustNotFound,
self.trust_api.get_trust,
trust['id'])
def test_trust_deleted_when_project_deleted(self):
# create trust
ref = unit.new_trust_ref(
trustor_user_id=self.user_id,
trustee_user_id=self.trustee_user_id,
project_id=self.project_id,
impersonation=False,
role_ids=[self.role_id],
allow_redelegation=True)
resp = self.post('/OS-TRUST/trusts', body={'trust': ref})
trust = self.assertValidTrustResponse(resp)
# list all trusts
r = self.get('/OS-TRUST/trusts')
self.assertEqual(1, len(r.result['trusts']))
# delete the project will delete the trust.
self.delete(
'/projects/%(project_id)s' % {'project_id': trust['project_id']})
# call the backend method directly to bypass authentication since the
# user no longer has the assignment on the project.
self.assertRaises(exception.TrustNotFound,
self.trust_api.get_trust,
trust['id'])

View File

@ -70,3 +70,12 @@ class TrustDriverBase(object):
:raises keystone.exception.TrustNotFound: If the trust doesn't exist.
"""
raise exception.NotImplemented() # pragma: no cover
@abc.abstractmethod
def delete_trusts_for_project(self, project_id):
"""Delete all trusts for a project.
:param project_id: ID of a project to filter trusts by.
"""
raise exception.NotImplemented() # pragma: no cover

View File

@ -176,3 +176,10 @@ class Trust(base.TrustDriverBase):
if not trust_ref:
raise exception.TrustNotFound(trust_id=trust_id)
trust_ref.deleted_at = timeutils.utcnow()
def delete_trusts_for_project(self, project_id):
with sql.session_for_write() as session:
query = session.query(TrustModel)
trusts = query.filter_by(project_id=project_id)
for trust_ref in trusts:
trust_ref.deleted_at = timeutils.utcnow()

View File

@ -0,0 +1,10 @@
---
fixes:
- >
[`bug 1622310 <https://bugs.launchpad.net/keystone/+bug/1622310>`_]
Keystone trust will be invalidated if the project to which the trust
is scoped, or the user (trustor or trustee) for which the delegation
is assigned, have been deleted.
other:
- Abstract method ``delete_trusts_for_project`` should be implemented by
custom drivers.