Esempio n. 1
0
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:`crits.core.crits_mongoengine.CritsBaseAttributes`
    :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['crits_type']

    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)
    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]

        if obj_type == 'Comment':
            # for comments, use the sources from the object that it is linked to
            # instead of the comments's sources
            referenced_obj = class_from_id(n.obj_type, n.obj_id)
            sources = [s.name for s in referenced_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:
                        n.users.append(subscribed_user)
                        break
    else:
        n.users = get_subscribed_users(n.obj_type, n.obj_id, [])

    if obj_type == 'Comment':
        for u in obj.users:
            if u not in n.users:
                n.users.append(u)

    # 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()
Esempio n. 2
0
def generate_audit_notification(username, operation_type, obj, changed_fields,
                                what_changed, is_new_doc=False):
    """
    Generate an audit notification on the specific change, if applicable.
    This is called during an audit of the object, before the actual save
    to the database occurs.

    :param username: The user creating the notification.
    :type username: str
    :param operation_type: The type of operation (i.e. save or delete).
    :type operation_type: str
    :param obj: The object.
    :type obj: class which inherits from
               :class:`crits.core.crits_mongoengine.CritsBaseAttributes`
    :param changed_fields: A list of field names that were changed.
    :type changed_fields: list of str
    :param message: A message summarizing what changed.
    :type message: str
    :param is_new_doc: Indicates if the input obj is newly created.
    :type is_new_doc: bool
    """

    obj_type = obj._meta['crits_type']

    supported_notification = __supported_notification_types__.get(obj_type)

    # Check if the obj is supported for notifications
    if supported_notification is None:
        return

    if operation_type == "save":
        message = "%s updated the following attributes: %s" % (username,
                                                               what_changed)
    elif operation_type == "delete":
        header_description = generate_notification_header(obj)
        message = "%s deleted the following: %s" % (username,
                                                    header_description)

    if is_new_doc:
        sources = []

        if hasattr(obj, 'source'):
            sources = [s.name for s in obj.source]

        message = None
        target_users = get_subscribed_users(obj_type, obj.id, sources)
        header = generate_notification_header(obj)
        link_url = None

        if hasattr(obj, 'get_details_url'):
            link_url = obj.get_details_url()

        if header is not None:
            header = "New " + header

        create_general_notification(username,
                                    target_users,
                                    header,
                                    link_url,
                                    message)

    process_result = process_changed_fields(message, changed_fields, obj)

    message = process_result.get('message')
    source_filter = process_result.get('source_filter')

    if message is not None:
        message = html_escape(message)
        create_notification(obj, username, message, source_filter, NotificationType.ALERT)