diff --git a/keystone/revoke/core.py b/keystone/revoke/core.py index c00ed6991d..321c7eb4a1 100644 --- a/keystone/revoke/core.py +++ b/keystone/revoke/core.py @@ -87,11 +87,6 @@ class Manager(manager.Manager): self.revoke( revoke_model.RevokeEvent(project_id=payload['resource_info'])) - def _domain_callback(self, service, resource_type, operation, - payload): - self.revoke( - revoke_model.RevokeEvent(domain_id=payload['resource_info'])) - def _trust_callback(self, service, resource_type, operation, payload): self.revoke( @@ -111,9 +106,7 @@ class Manager(manager.Manager): ['project', self._project_callback], ], notifications.ACTIONS.disabled: [ - ['user', self._user_callback], - ['project', self._project_callback], - ['domain', self._domain_callback], + ['user', self._user_callback] ], notifications.ACTIONS.internal: [ [notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index 24655ae827..8eab410f84 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -3256,23 +3256,6 @@ class TestTokenRevokeApi(TestTokenRevokeById): expected_response = {'events': [{'project_id': project_id}]} self.assertEqual(expected_response, events_response) - def assertDomainAndProjectInList(self, events_response, domain_id): - events = events_response['events'] - self.assertEqual(2, len(events)) - self.assertEqual(domain_id, events[0]['project_id']) - self.assertEqual(domain_id, events[1]['domain_id']) - self.assertIsNotNone(events[0]['issued_before']) - self.assertIsNotNone(events[1]['issued_before']) - self.assertIsNotNone(events_response['links']) - del (events_response['events'][0]['issued_before']) - del (events_response['events'][1]['issued_before']) - del (events_response['events'][0]['revoked_at']) - del (events_response['events'][1]['revoked_at']) - del (events_response['links']) - expected_response = {'events': [{'project_id': domain_id}, - {'domain_id': domain_id}]} - self.assertEqual(expected_response, events_response) - def assertValidRevokedTokenResponse(self, events_response, **kwargs): events = events_response['events'] self.assertEqual(1, len(events)) @@ -3318,18 +3301,6 @@ class TestTokenRevokeApi(TestTokenRevokeById): self.assertValidDeletedProjectResponse(events_response, self.projectA['id']) - def test_disable_domain_shows_in_event_list(self): - events = self.get('/OS-REVOKE/events').json_body['events'] - self.assertEqual([], events) - disable_body = {'domain': {'enabled': False}} - self.patch( - '/domains/%(project_id)s' % {'project_id': self.domainA['id']}, - body=disable_body) - - events = self.get('/OS-REVOKE/events').json_body - - self.assertDomainAndProjectInList(events, self.domainA['id']) - def assertEventDataInList(self, events, **kwargs): found = False for e in events: diff --git a/keystone/token/providers/common.py b/keystone/token/providers/common.py index 6b630ff9de..d0e6512d52 100644 --- a/keystone/token/providers/common.py +++ b/keystone/token/providers/common.py @@ -93,11 +93,33 @@ class V3TokenDataHelper(object): super(V3TokenDataHelper, self).__init__() def _get_filtered_domain(self, domain_id): + """Ensure the domain is enabled and return domain id and name. + + :param domain_id: The ID of the domain to validate + :returns: A dictionary containing two keys, the `id` of the domain and + the `name` of the domain. + """ domain_ref = self.resource_api.get_domain(domain_id) + if not domain_ref.get('enabled'): + msg = _('Unable to validate token because domain %(id)s is ' + 'disabled') % {'id': domain_ref['id']} + LOG.warning(msg) + raise exception.DomainNotFound(msg) return {'id': domain_ref['id'], 'name': domain_ref['name']} def _get_filtered_project(self, project_id): + """Ensure the project and parent domain is enabled. + + :param project_id: The ID of the project to validate + :return: A dictionary containing up to three keys, the `id` of the + project, the `name` of the project, and the parent `domain`. + """ project_ref = self.resource_api.get_project(project_id) + if not project_ref.get('enabled'): + msg = _('Unable to validate token because project %(id)s is ' + 'disabled') % {'id': project_ref['id']} + LOG.warning(msg) + raise exception.ProjectNotFound(msg) filtered_project = { 'id': project_ref['id'], 'name': project_ref['name']} diff --git a/releasenotes/notes/bug-1524030-0814724d5c2b7c8d.yaml b/releasenotes/notes/bug-1524030-0814724d5c2b7c8d.yaml new file mode 100644 index 0000000000..619c369ac4 --- /dev/null +++ b/releasenotes/notes/bug-1524030-0814724d5c2b7c8d.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + [`bug 1524030 `_] + Revocation records are no longer written to the ``revocation_event`` table + when a domain or project is disabled. These records were only ever used + during the token validation process. In favor of revocation events, the + project or domain will be validated online when the token is validated. This + results in less database bloat while maintaining security during token + validation.