def create_general_notification(username, target_users, header, link_url, message, notification_type=NotificationType.ALERT): """ Generate a general notification -- not based on mongo obj. :param obj: The object. :type obj: class which inherits from :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes` :param username: The user creating the notification. :type username: str :param target_users: The list of users who will get the notification. :type target_users: list(str) :param header: The notification header message. :type header: list(str) :param link_url: A link URL for the header, specify None if there is no link. :type link_url: str :param message: The notification message. :type message: str :param notification_type: The notification type (e.g. alert, error). :type notification_type: str """ if notification_type not in NotificationType.ALL: notification_type = NotificationType.ALERT n = Notification() n.analyst = username n.notification_type = notification_type n.notification = message n.header = header n.link_url = link_url for target_user in target_users: # Check to make sure the user actually exists user = CRIPTsUser.objects(username=target_user).first() if user is not None: n.users.append(target_user) # don't notify the user creating this notification n.users = [u for u in n.users if u != username] if not len(n.users): return try: n.save() except ValidationError: pass # Signal potentially waiting threads that notification information is available for user in n.users: notification_lock = NotificationLockManager.get_notification_lock(user) notification_lock.acquire() try: notification_lock.notifyAll() finally: notification_lock.release()
def remove_user_notifications(username): """ Remove a user from all notifications. :param username: The user to remove. :type username: str :returns: dict with keys "success" (boolean) and "message" (str) if failed. """ Notification.objects(users=username).update(pull__users=username)
def remove_user_from_notification_id(username, id): """ Remove a user from the list of users for a notification. :param username: The user to remove. :type username: str :param obj_id: The ObjectId of the top-level object for this notification. :type obj_id: str :param obj_type: The top-level object type. :type obj_type: str :returns: dict with keys "success" (boolean) and "message" (str) if failed. """ Notification.objects(id=id).update(pull__users=username) return {'success': True}
def handle(self, *args, **options): """ Script Execution. """ # only look for active users who want email notifications users = CRIPTsUser.objects(is_active=True, prefs__notify__email=True) # only get the unprocessed notifications notifications = Notification.objects(status='new') for user in users: # only include notifications where the user is in the users list and # it wasn't created by them. includes = [ x for x in notifications if user.username in x.users and user.username != x.analyst and x.obj_id != None ] # only send an email if there's something to send if len(includes): email = EmailNotification(username=user.username, email=user.email) for include in includes: email.add_to_body(email.create_notification(include)) email.send_email() # clean up after ourselves usernames = [u.username for u in users] self.process_notifications(notifications, usernames)
def handle(self, *args, **options): """ Script Execution. """ # only look for active users who want email notifications users = CRIPTsUser.objects(is_active=True, prefs__notify__email=True) # only get the unprocessed notifications notifications = Notification.objects(status='new') for user in users: # only include notifications where the user is in the users list and # it wasn't created by them. includes = [x for x in notifications if user.username in x.users and user.username != x.analyst and x.obj_id != None] # only send an email if there's something to send if len(includes): email = EmailNotification(username=user.username, email=user.email) for include in includes: email.add_to_body(email.create_notification(include)) email.send_email() # clean up after ourselves usernames = [u.username for u in users] self.process_notifications(notifications, usernames)
def get_user_notifications(username, count=False, newer_than=None): """ Get the notifications for a user. :param username: The user to get notifications for. :type username: str :param count: Only return the count. :type count:bool :returns: int, :class:`cripts.core.cripts_mongoengine.CriptsQuerySet` """ n = None if newer_than is None or newer_than == None: n = Notification.objects(users=username).order_by('-created') else: n = Notification.objects(Q(users=username) & Q(created__gt=newer_than)).order_by('-created') if count: return len(n) else: return n
def get_user_notifications(username, count=False, newer_than=None): """ Get the notifications for a user. :param username: The user to get notifications for. :type username: str :param count: Only return the count. :type count:bool :returns: int, :class:`cripts.core.cripts_mongoengine.CriptsQuerySet` """ n = None if newer_than is None or newer_than == None: n = Notification.objects(users=username).order_by('-created') else: n = Notification.objects( Q(users=username) & Q(created__gt=newer_than)).order_by('-created') if count: return len(n) else: return n
def get_notifications_for_id(username, obj_id, obj_type): """ Get notifications for a specific top-level object and user. :param username: The user to search for. :param obj_id: The ObjectId to search for. :type obj_id: str :param obj_type: The top-level object type. :type obj_type: str :returns: :class:`cripts.core.cripts_mongoengine.CriptsQuerySet` """ return Notification.objects(users=username, obj_id=obj_id, obj_type=obj_type)
def remove_notification(obj_id): """ Remove an existing notification. :param obj_id: The top-level ObjectId to find the notification to remove. :type obj_id: str :returns: dict with keys "success" (boolean) and "message" (str). """ notification = Notification.objects(id=obj_id).first() if not notification: message = "Could not find notification to remove!" result = {'success': False, 'message': message} else: notification.delete() message = "Notification removed successfully!" result = {'success': True, 'message': message} return result
def process_notifications(self, notifications, users): """ Set notifications to processed. Remove users from the list if they received an email. If any notification has 0 users left, remove it. Also remove any processed notifications with 0 users left. :param notifications: The list of notifications to work with. :type notifications: list :param users: The users to work with. :type users: list """ old = Notification.objects(status='processed').only('users') for oldn in old: if not len(oldn.users): oldn.delete() for notice in notifications: notice.users = [u for u in notice.users if u not in users] if not len(notice.users): notice.delete() else: notice.set_status('processed') notice.save()
def create_notification(obj, username, message, source_filter=None, notification_type=NotificationType.ALERT): """ Generate a notification -- based on mongo obj. :param obj: The object. :type obj: class which inherits from :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes` :param username: The user creating the notification. :type username: str :param message: The notification message. :type message: str :param source_filter: Filter on who can see this notification. :type source_filter: list(str) :param notification_type: The notification type (e.g. alert, error). :type notification_type: str """ n = Notification() n.analyst = username obj_type = obj._meta['cripts_type'] users = set() if notification_type not in NotificationType.ALL: notification_type = NotificationType.ALERT n.notification_type = notification_type if obj_type == 'Comment': n.obj_id = obj.obj_id n.obj_type = obj.obj_type n.notification = "%s added a comment: %s" % (username, obj.comment) users.update(obj.users) # notify mentioned users # for comments, use the sources from the object that it is linked to # instead of the comments's sources obj = class_from_id(n.obj_type, n.obj_id) else: n.notification = message n.obj_id = obj.id n.obj_type = obj_type if hasattr(obj, 'source'): sources = [s.name for s in obj.source] subscribed_users = get_subscribed_users(n.obj_type, n.obj_id, sources) # Filter on users that have access to the source of the object for subscribed_user in subscribed_users: allowed_sources = user_sources(subscribed_user) for allowed_source in allowed_sources: if allowed_source in sources: if source_filter is None or allowed_source in source_filter: users.add(subscribed_user) break else: users.update(get_subscribed_users(n.obj_type, n.obj_id, [])) users.discard(username) # don't notify the user creating this notification n.users = list(users) if not len(n.users): return try: n.save() except ValidationError: pass # Signal potentially waiting threads that notification information is available for user in n.users: notification_lock = NotificationLockManager.get_notification_lock(user) notification_lock.acquire() try: notification_lock.notifyAll() finally: notification_lock.release()
def get_new_notifications(): """ Get any new notifications. """ return Notification.objects(status="new")