diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 38ebe2fbdd..18286ff12e 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -1310,6 +1310,12 @@ class Manager(manager.Manager): for user_id in user_ids: self._persist_revocation_event_for_user(user_id) + reason_s = ( + 'Invalidating the token cache because group %(group_id)s ' + 'has been deleted.' % {'group_id': group_id} + ) + notifications.invalidate_token_cache_notification(reason_s) + # Invalidate user role assignments cache region, as it may be caching # role assignments expanded from the specified group to its users assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate() @@ -1362,6 +1368,16 @@ class Manager(manager.Manager): # Invalidate user role assignments cache region, as it may be caching # role assignments expanded from this group to this user assignment.COMPUTED_ASSIGNMENTS_REGION.invalidate() + reason = ( + 'Invalidating the token cache because user %(user_id)s was ' + 'removed from group %(group_id)s. Authorization will be ' + 'calculated and enforced accordingly the next time they ' + 'authenticate or validate a token.' % { + 'user_id': user_id, + 'group_id': group_id, + } + ) + notifications.invalidate_token_cache_notification(reason) notifications.Audit.removed_from(self._GROUP, group_id, self._USER, user_id, initiator) @@ -1474,6 +1490,13 @@ class Manager(manager.Manager): notifications.Audit.updated(self._USER, user_id, initiator) self._persist_revocation_event_for_user(user_id) + reason_s = ( + 'Invalidating the token cache because user %(user_id)s changed ' + 'the password. Authorization will be calculated and enforced ' + 'accordingly the next time they authenticate or validate a ' + 'token.' % {'user_id': user_id} + ) + notifications.invalidate_token_cache_notification(reason_s) @MEMOIZE def _shadow_nonlocal_user(self, user): diff --git a/keystone/token/provider.py b/keystone/token/provider.py index 9d888fdbcd..885d015838 100644 --- a/keystone/token/provider.py +++ b/keystone/token/provider.py @@ -129,12 +129,13 @@ class Manager(manager.Manager): if CONF.token.cache_on_issue or CONF.token.caching: TOKENS_REGION.invalidate() - def check_revocation_v3(self, token): - token_values = self.revoke_api.model.build_token_values(token) + @MEMOIZE_TOKENS + def check_revocation_v3(self, token_values): PROVIDERS.revoke_api.check_token(token_values) def check_revocation(self, token): - return self.check_revocation_v3(token) + token_values = self.revoke_api.model.build_token_values(token) + return self.check_revocation_v3(token_values) def validate_token(self, token_id, window_seconds=0, access_rules_support=None): @@ -298,7 +299,7 @@ class Manager(manager.Manager): return token - def invalidate_individual_token_cache(self, token_id): + def invalidate_individual_token_cache(self, token): # NOTE(morganfainberg): invalidate takes the exact same arguments as # the normal method, this means we need to pass "self" in (which gets # stripped off). @@ -308,7 +309,9 @@ class Manager(manager.Manager): # consulted before accepting a token as valid. For now we will # do the explicit individual token invalidation. - self._validate_token.invalidate(self, token_id) + self._validate_token.invalidate(self, token.id) + token_values = self.revoke_api.model.build_token_values(token) + self.check_revocation_v3.invalidate(self, token_values) def revoke_token(self, token_id, revoke_chain=False): token = self.validate_token(token_id) @@ -328,4 +331,4 @@ class Manager(manager.Manager): # invalidated? We maintain a cached revocation list, which should be # consulted before accepting a token as valid. For now we will # do the explicit individual token invalidation. - self.invalidate_individual_token_cache(token_id) + self.invalidate_individual_token_cache(token)