Example #1
0
def get_aggregate_comments(atype, value, username, date=None):
    """
    Generate a list of comments for the aggregate view.

    :param atype: How to limit the comments ("bytag", "byuser", "bycomment").
    :type atype: str
    :param value: If limiting by atype, the value to limit by.
    :type value: str
    :param username: The user getting the comments.
    :type username: str
    :param date: The specific date to get comments for.
    :type date: datetime.datetime
    :returns: list of :class:`cripts.comments.comment.Comment`
    """

    results = None
    if date:
        end_date = date + datetime.timedelta(days=1)
        query = {'date': {'$gte': date, '$lte': end_date}}
    else:
        query = {}
    if atype == 'bytag':
        query['tags'] = value
    elif atype == 'byuser':
        query['$or'] = [{'users': value}, {'analyst': value}]
    elif atype == 'bycomment':
        query['comment'] = {'$regex': value}

    results = Comment.objects(__raw__=query)
    sources = user_sources(username)
    return get_user_allowed_comments(results, sources)
Example #2
0
def comment_remove(obj_id, analyst, date):
    """
    Remove an existing comment.

    :param obj_id: The top-level ObjectId to find the comment to remove.
    :type obj_id: str
    :param analyst: The user removing the comment.
    :type analyst: str
    :param date: The date of the comment to remove.
    :type date: datetime.datetime
    :returns: dict with keys "success" (boolean) and "message" (str).
    """

    comment = Comment.objects(obj_id=obj_id, created=date).first()
    if not comment:
        message = "Could not find comment to remove!"
        result = {'success': False, 'message': message}
    elif comment.analyst != analyst:
        # Should admin users be able to delete others comments?
        message = "You cannot delete comments from other analysts!"
        result = {'success': False, 'message': message}
    else:
        comment.delete()
        message = "Comment removed successfully!"
        result = {'success': True, 'message': message}
    return result
Example #3
0
def comment_remove(obj_id, analyst, date):
    """
    Remove an existing comment.

    :param obj_id: The top-level ObjectId to find the comment to remove.
    :type obj_id: str
    :param analyst: The user removing the comment.
    :type analyst: str
    :param date: The date of the comment to remove.
    :type date: datetime.datetime
    :returns: dict with keys "success" (boolean) and "message" (str).
    """

    comment = Comment.objects(obj_id=obj_id,
                              created=date).first()
    if not comment:
        message = "Could not find comment to remove!"
        result = {'success': False, 'message': message}
    elif comment.analyst != analyst:
        # Should admin users be able to delete others comments?
        message = "You cannot delete comments from other analysts!"
        result = {'success': False, 'message': message}
    else:
        comment.delete()
        message = "Comment removed successfully!"
        result = {'success': True, 'message': message}
    return result
Example #4
0
def get_aggregate_comments(atype, value, username, date=None):
    """
    Generate a list of comments for the aggregate view.

    :param atype: How to limit the comments ("bytag", "byuser", "bycomment").
    :type atype: str
    :param value: If limiting by atype, the value to limit by.
    :type value: str
    :param username: The user getting the comments.
    :type username: str
    :param date: The specific date to get comments for.
    :type date: datetime.datetime
    :returns: list of :class:`cripts.comments.comment.Comment`
    """

    results = None
    if date:
        end_date = date+datetime.timedelta(days=1)
        query = {'date':{'$gte':date, '$lte':end_date}}
    else:
        query = {}
    if atype == 'bytag':
        query['tags'] = value
    elif atype == 'byuser':
        query['$or'] = [{'users':value}, {'analyst':value}]
    elif atype == 'bycomment':
        query['comment'] = {'$regex':value}

    results = Comment.objects(__raw__=query)
    sources = user_sources(username)
    return get_user_allowed_comments(results, sources)
Example #5
0
def class_from_id(type_, _id):
    """
    Return an instantiated class object.

    :param type_: The CRIPTs top-level object type.
    :type type_: str
    :param _id: The ObjectId to search for.
    :type _id: str
    :returns: class which inherits from
              :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes`
    """

    #Quick fail
    if not _id or not type_:
        return None

    # doing this to avoid circular imports
    from cripts.comments.comment import Comment
    from cripts.core.cripts_mongoengine import Action
    from cripts.core.source_access import SourceAccess
    from cripts.core.user_role import UserRole
    from cripts.events.event import Event
    from cripts.usernames.username import UserName
    from cripts.targets.target import Target
    from cripts.hashes.hash import Hash
    from cripts.datasets.dataset import Dataset
    from cripts.email_addresses.email_address import EmailAddress

    # make sure it's a string
    _id = str(_id)

    # Use bson.ObjectId to make sure this is a valid ObjectId, otherwise
    # the queries below will raise a ValidationError exception.
    if not ObjectId.is_valid(_id.decode('utf8')):
        return None

    if type_ == 'Comment':
        return Comment.objects(id=_id).first()
    elif type_ == 'Event':
        return Event.objects(id=_id).first()
    elif type_ == 'Action':
        return Action.objects(id=_id).first()
    elif type_ == 'SourceAccess':
        return SourceAccess.objects(id=_id).first()
    elif type_ == 'UserRole':
        return UserRole.objects(id=_id).first()
    elif type_ == 'UserName':
        return UserName.objects(id=_id).first()
    elif type_ == 'Target':
        return Target.objects(id=_id).first()
    elif type_ == 'Hash':
        return Hash.objects(id=_id).first()
    elif type_ == 'Dataset':
        return Dataset.objects(id=_id).first()
    elif type_ == 'EmailAddress':
        return EmailAddress.objects(id=_id).first()
    else:
        return None
Example #6
0
def class_from_id(type_, _id):
    """
    Return an instantiated class object.

    :param type_: The CRIPTs top-level object type.
    :type type_: str
    :param _id: The ObjectId to search for.
    :type _id: str
    :returns: class which inherits from
              :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes`
    """

    #Quick fail
    if not _id or not type_:
        return None

    # doing this to avoid circular imports
    from cripts.comments.comment import Comment
    from cripts.core.cripts_mongoengine import Action
    from cripts.core.source_access import SourceAccess
    from cripts.core.user_role import UserRole
    from cripts.events.event import Event
    from cripts.usernames.username import UserName
    from cripts.targets.target import Target
    from cripts.hashes.hash import Hash
    from cripts.datasets.dataset import Dataset
    from cripts.email_addresses.email_address import EmailAddress

    # make sure it's a string
    _id = str(_id)

    # Use bson.ObjectId to make sure this is a valid ObjectId, otherwise
    # the queries below will raise a ValidationError exception.
    if not ObjectId.is_valid(_id.decode('utf8')):
        return None

    if type_ == 'Comment':
        return Comment.objects(id=_id).first()
    elif type_ == 'Event':
        return Event.objects(id=_id).first()
    elif type_ == 'Action':
        return Action.objects(id=_id).first()
    elif type_ == 'SourceAccess':
        return SourceAccess.objects(id=_id).first()
    elif type_ == 'UserRole':
        return UserRole.objects(id=_id).first()
    elif type_ == 'UserName':
        return UserName.objects(id=_id).first()
    elif type_ == 'Target':
        return Target.objects(id=_id).first()
    elif type_ == 'Hash':
        return Hash.objects(id=_id).first()
    elif type_ == 'Dataset':
        return Dataset.objects(id=_id).first()
    elif type_ == 'EmailAddress':
        return EmailAddress.objects(id=_id).first()
    else:
        return None
Example #7
0
def class_from_value(type_, value):
    """
    Return an instantiated class object.

    :param type_: The CRIPTs top-level object type.
    :type type_: str
    :param value: The value to search for.
    :type value: str
    :returns: class which inherits from
              :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes`
    """

    #Quick fail
    if not type_ or not value:
        return None

    # doing this to avoid circular imports
    from cripts.comments.comment import Comment
    from cripts.events.event import Event
    from cripts.usernames.username import UserName
    from cripts.targets.target import Target
    from cripts.hashes.hash import Hash
    from cripts.datasets.dataset import Dataset
    from cripts.email_addresses.email_address import EmailAddress

    # Make sure value is a string...
    value = str(value)

    # Use bson.ObjectId to make sure this is a valid ObjectId, otherwise
    # the queries below will raise a ValidationError exception.
    if (type_ in [
            'Comment', 'Event', 'UserName', 'Target', 'Hash', 'Dataset',
            'EmailAddress'
    ] and not ObjectId.is_valid(value.decode('utf8'))):
        return None

    if type_ == 'Comment':
        return Comment.objects(id=value).first()
    elif type_ == 'Event':
        return Event.objects(id=value).first()
    elif type_ == 'UserName':
        return UserName.objects(id=value).first()
    elif type_ == 'Target':
        return Target.objects(id=value).first()
    elif type_ == 'Hash':
        return Hash.objects(id=value).first()
    elif type_ == 'Dataset':
        return Dataset.objects(id=value).first()
    elif type_ == 'EmailAddress':
        return EmailAddress.objects(id=value).first()
    else:
        return None
Example #8
0
def class_from_value(type_, value):
    """
    Return an instantiated class object.

    :param type_: The CRIPTs top-level object type.
    :type type_: str
    :param value: The value to search for.
    :type value: str
    :returns: class which inherits from
              :class:`cripts.core.cripts_mongoengine.CriptsBaseAttributes`
    """

    #Quick fail
    if not type_ or not value:
        return None

    # doing this to avoid circular imports
    from cripts.comments.comment import Comment
    from cripts.events.event import Event
    from cripts.usernames.username import UserName
    from cripts.targets.target import Target
    from cripts.hashes.hash import Hash
    from cripts.datasets.dataset import Dataset
    from cripts.email_addresses.email_address import EmailAddress

    # Make sure value is a string...
    value = str(value)

    # Use bson.ObjectId to make sure this is a valid ObjectId, otherwise
    # the queries below will raise a ValidationError exception.
    if (type_ in ['Comment','Event','UserName','Target','Hash','Dataset','EmailAddress'] and
       not ObjectId.is_valid(value.decode('utf8'))):
        return None
    
    if type_ == 'Comment':
        return Comment.objects(id=value).first()
    elif type_ == 'Event':
        return Event.objects(id=value).first()
    elif type_ == 'UserName':
        return UserName.objects(id=value).first()
    elif type_ == 'Target':
        return Target.objects(id=value).first()
    elif type_ == 'Hash':
        return Hash.objects(id=value).first()
    elif type_ == 'Dataset':
        return Dataset.objects(id=value).first()
    elif type_ == 'EmailAddress':
        return EmailAddress.objects(id=value).first()
    else:
        return None
Example #9
0
def comment_update(cleaned_data, obj_type, obj_id, subscr, analyst):
    """
    Update an existing comment.

    :param cleaned_data: Cleaned data from the Django form submission.
    :type cleaned_data: dict
    :param obj_type: The top-level object type to find the comment to update.
    :type obj_type: str
    :param obj_id: The top-level ObjectId to find the comment to update.
    :type obj_id: str
    :param subscr: The subscription information for the top-level object.
    :type subscr: dict
    :param analyst: The user updating the comment.
    :type analyst: str
    :returns: :class:`django.http.HttpResponse`
    """

    result = None
    date = cleaned_data['parent_date']
    comment = Comment.objects(obj_id=obj_id, created=date).first()
    if not comment:
        message = "Cannot find comment to update!"
        result = {'success': False, 'message': message}
    elif comment.analyst != analyst:
        # Should admin users be able to edit others comments?
        message = "You cannot edit comments from other analysts!"
        result = {'success': False, 'message': message}
    else:
        comment.edit_comment(cleaned_data['comment'])
        try:
            comment.save()
            comment.comment_to_html()
            html = render_to_string(
                'comments_row_widget.html', {
                    'comment': comment,
                    'user': {
                        'username': analyst
                    },
                    'subscription': subscr
                })
            message = "Comment updated successfully!"
            result = {'success': True, 'html': html, 'message': message}
        except ValidationError, e:
            result = {'success': False, 'message': e}
Example #10
0
def get_comments(obj_id, obj_type):
    """
    Get Comments for a specific top-level object.

    :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: list of :class:`cripts.comments.comment.Comment`
    """

    #TODO: add source filtering for non-UI based applications
    results = Comment.objects(obj_id=obj_id,
                              obj_type=obj_type).order_by('+created')
    final_comments = []
    for result in results:
        result.comment_to_html()
        final_comments.append(result)
    return final_comments
Example #11
0
def get_comments(obj_id, obj_type):
    """
    Get Comments for a specific top-level object.

    :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: list of :class:`cripts.comments.comment.Comment`
    """

    #TODO: add source filtering for non-UI based applications
    results = Comment.objects(obj_id=obj_id,
                              obj_type=obj_type).order_by('+created')
    final_comments = []
    for result in results:
        result.comment_to_html()
        final_comments.append(result)
    return final_comments
Example #12
0
def comment_update(cleaned_data, obj_type, obj_id, subscr, analyst):
    """
    Update an existing comment.

    :param cleaned_data: Cleaned data from the Django form submission.
    :type cleaned_data: dict
    :param obj_type: The top-level object type to find the comment to update.
    :type obj_type: str
    :param obj_id: The top-level ObjectId to find the comment to update.
    :type obj_id: str
    :param subscr: The subscription information for the top-level object.
    :type subscr: dict
    :param analyst: The user updating the comment.
    :type analyst: str
    :returns: :class:`django.http.HttpResponse`
    """

    result = None
    date = cleaned_data['parent_date']
    comment = Comment.objects(obj_id=obj_id,
                              created=date).first()
    if not comment:
        message = "Cannot find comment to update!"
        result = {'success': False, 'message': message}
    elif comment.analyst != analyst:
        # Should admin users be able to edit others comments?
        message = "You cannot edit comments from other analysts!"
        result = {'success': False, 'message': message}
    else:
        comment.edit_comment(cleaned_data['comment'])
        try:
            comment.save()
            comment.comment_to_html()
            html = render_to_string('comments_row_widget.html',
                                    {'comment': comment,
                                     'user': {'username': analyst},
                                     'subscription': subscr})
            message = "Comment updated successfully!"
            result = {'success': True, 'html': html, 'message': message}
        except ValidationError, e:
            result = {'success': False, 'message': e}
Example #13
0
def comment_add(cleaned_data, obj_type, obj_id, method, subscr, analyst):
    """
    Add a new comment.

    :param cleaned_data: Cleaned data from the Django form submission.
    :type cleaned_data: dict
    :param obj_type: The top-level object type to add the comment to.
    :type obj_type: str
    :param obj_id: The top-level ObjectId to add the comment to.
    :type obj_id: str
    :param method: If this is a reply or not (set method to "reply").
    :type method: str
    :param subscr: The subscription information for the top-level object.
    :type subscr: dict
    :param analyst: The user adding the comment.
    :type analyst: str
    :returns: dict with keys:
              'success' (boolean),
              'message': (str),
              'html' (str) if successful.
    """

    comment = Comment()
    comment.comment = cleaned_data['comment']
    comment.parse_comment()
    comment.set_parent_object(obj_type, obj_id)
    if method == "reply":
        comment.set_parent_comment(cleaned_data['parent_date'],
                                   cleaned_data['parent_analyst'])
    comment.analyst = analyst
    comment.set_url_key(cleaned_data['url_key'])
    source = create_embedded_source(name=get_user_organization(analyst),
                                    analyst=analyst)
    comment.source = [source]
    try:
        comment.save(username=analyst)
        # this is silly :( in the comment object the dates are still
        # accurate to .###### seconds, but in the database are only
        # accurate to .### seconds. This messes with the template's ability
        # to compare creation and edit times.
        comment.reload()
        comment.comment_to_html()
        html = render_to_string(
            'comments_row_widget.html', {
                'comment': comment,
                'user': {
                    'username': analyst
                },
                'subscription': subscr
            })
        message = "Comment added successfully!"
        result = {'success': True, 'html': html, 'message': message}
    except ValidationError, e:
        result = {'success': False, 'message': e}
Example #14
0
def comment_add(cleaned_data, obj_type, obj_id, method, subscr, analyst):
    """
    Add a new comment.

    :param cleaned_data: Cleaned data from the Django form submission.
    :type cleaned_data: dict
    :param obj_type: The top-level object type to add the comment to.
    :type obj_type: str
    :param obj_id: The top-level ObjectId to add the comment to.
    :type obj_id: str
    :param method: If this is a reply or not (set method to "reply").
    :type method: str
    :param subscr: The subscription information for the top-level object.
    :type subscr: dict
    :param analyst: The user adding the comment.
    :type analyst: str
    :returns: dict with keys:
              'success' (boolean),
              'message': (str),
              'html' (str) if successful.
    """

    comment = Comment()
    comment.comment = cleaned_data['comment']
    comment.parse_comment()
    comment.set_parent_object(obj_type, obj_id)
    if method == "reply":
        comment.set_parent_comment(cleaned_data['parent_date'],
                                   cleaned_data['parent_analyst'])
    comment.analyst = analyst
    comment.set_url_key(cleaned_data['url_key'])
    source = create_embedded_source(name=get_user_organization(analyst),
                                    analyst=analyst)
    comment.source = [source]
    try:
        comment.save(username=analyst)
        # this is silly :( in the comment object the dates are still
        # accurate to .###### seconds, but in the database are only
        # accurate to .### seconds. This messes with the template's ability
        # to compare creation and edit times.
        comment.reload()
        comment.comment_to_html()
        html = render_to_string('comments_row_widget.html',
                                {'comment': comment,
                                 'user': {'username': analyst},
                                 'subscription': subscr})
        message = "Comment added successfully!"
        result = {'success': True, 'html': html, 'message': message}
    except ValidationError, e:
        result = {'success': False, 'message': e}