diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index 988cae37c4..05368fbfb4 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -319,10 +319,17 @@ class Manager(manager.Manager): role_id, user_id=user_id, project_id=tenant_id) COMPUTED_ASSIGNMENTS_REGION.invalidate() - @notifications.internal(notifications.INVALIDATE_USER_TOKEN_PERSISTENCE) def _emit_invalidate_user_token_persistence(self, user_id): self.identity_api.emit_invalidate_user_token_persistence(user_id) + # NOTE(lbragstad): The previous notification decorator behavior didn't + # send the notification unless the operation was successful. We + # maintain that behavior here by calling to the notification module + # after the call to emit invalid user tokens. + notifications.Audit.internal( + notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, user_id + ) + def _emit_invalidate_grant_token_persistence(self, user_id, project_id): self.identity_api.emit_invalidate_grant_token_persistence( {'user_id': user_id, 'project_id': project_id} @@ -1078,17 +1085,11 @@ class Manager(manager.Manager): user_and_project_ids_to_action.append(user_and_project_id) for user_id, project_id in user_and_project_ids_to_action: - self._emit_invalidate_user_project_tokens_notification( - {'user_id': user_id, - 'project_id': project_id}) - - @notifications.internal( - notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE) - def _emit_invalidate_user_project_tokens_notification(self, payload): - # This notification's payload is a dict of user_id and - # project_id so the token provider can invalidate the tokens - # from persistence if persistence is enabled. - pass + payload = {'user_id': user_id, 'project_id': project_id} + notifications.Audit.internal( + notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE, + payload + ) # The AssignmentDriverBase class is the set of driver methods from earlier diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 5827c44f68..8a38198cd4 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -1118,7 +1118,6 @@ class Manager(manager.Manager): notifications.Audit.removed_from(self._GROUP, group_id, self._USER, user_id, initiator) - @notifications.internal(notifications.INVALIDATE_USER_TOKEN_PERSISTENCE) def emit_invalidate_user_token_persistence(self, user_id): """Emit a notification to the callback system to revoke user tokens. @@ -1128,10 +1127,10 @@ class Manager(manager.Manager): :param user_id: user identifier :type user_id: string """ - pass + notifications.Audit.internal( + notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, user_id + ) - @notifications.internal( - notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE) def emit_invalidate_grant_token_persistence(self, user_project): """Emit a notification to the callback system to revoke grant tokens. @@ -1141,7 +1140,10 @@ class Manager(manager.Manager): :param user_project: {'user_id': user_id, 'project_id': project_id} :type user_project: dict """ - pass + notifications.Audit.internal( + notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE, + user_project + ) @domains_configured @exception_translated('user') diff --git a/keystone/notifications.py b/keystone/notifications.py index aa27fc7a2d..eab62fcfbc 100644 --- a/keystone/notifications.py +++ b/keystone/notifications.py @@ -183,6 +183,18 @@ class Audit(object): cls._emit(ACTIONS.updated, target_type, target_id, initiator, public, actor_dict=actor_dict) + @classmethod + def internal(cls, resource_type, resource_id): + # NOTE(lbragstad): Internal notifications are never public and have + # never used the initiator variable, but the _emit() method expects + # them. Let's set them here but not expose them through the method + # signature - that way someone can not do something like send an + # internal notification publicly. + initiator = None + public = False + cls._emit(ACTIONS.internal, resource_type, resource_id, initiator, + public) + class ManagerNotificationWrapper(object): """Send event notifications for ``Manager`` methods. diff --git a/keystone/oauth1/controllers.py b/keystone/oauth1/controllers.py index 205d4bff4f..489bb4c7c1 100644 --- a/keystone/oauth1/controllers.py +++ b/keystone/oauth1/controllers.py @@ -34,14 +34,15 @@ from keystone.oauth1 import validator CONF = cfg.CONF -@notifications.internal(notifications.INVALIDATE_USER_OAUTH_CONSUMER_TOKENS, - resource_id_arg_index=0) def _emit_user_oauth_consumer_token_invalidate(payload): # This is a special case notification that expect the payload to be a dict # containing the user_id and the consumer_id. This is so that the token # provider can invalidate any tokens in the token persistence if # token persistence is enabled - pass + notifications.Audit.internal( + notifications.INVALIDATE_USER_OAUTH_CONSUMER_TOKENS, + payload, + ) @dependency.requires('oauth_api', 'token_provider_api') diff --git a/keystone/resource/core.py b/keystone/resource/core.py index ce90111d6e..542fff1873 100644 --- a/keystone/resource/core.py +++ b/keystone/resource/core.py @@ -472,7 +472,10 @@ class Manager(manager.Manager): self.assignment_api.list_user_ids_for_project(project_id)) for user_id in project_user_ids: payload = {'user_id': user_id, 'project_id': project_id} - self._emit_invalidate_user_project_tokens_notification(payload) + notifications.Audit.internal( + notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE, + payload + ) def _post_delete_cleanup_project(self, project_id, project, initiator=None): @@ -873,14 +876,6 @@ class Manager(manager.Manager): def get_project_by_name(self, project_name, domain_id): return self.driver.get_project_by_name(project_name, domain_id) - @notifications.internal( - notifications.INVALIDATE_USER_PROJECT_TOKEN_PERSISTENCE) - def _emit_invalidate_user_project_tokens_notification(self, payload): - # This notification's payload is a dict of user_id and - # project_id so the token provider can invalidate the tokens - # from persistence if persistence is enabled. - pass - def ensure_default_domain_exists(self): """Creates the default domain if it doesn't exist.