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:
parent
52642cc562
commit
f0319c752a
@ -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)
|
||||
|
@ -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'])
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
10
releasenotes/notes/bug-1622310-c501cf77437fdfa6.yaml
Normal file
10
releasenotes/notes/bug-1622310-c501cf77437fdfa6.yaml
Normal 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.
|
Loading…
Reference in New Issue
Block a user