Example #1
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 #2
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 #3
0
def dataset_add_update(name, description=None, source=None, method='', reference='',
                  analyst=None, bucket_list=None, ticket=None,
                  is_validate_only=False, cache={}, related_id=None,
                  related_type=None, relationship_type=None):

    retVal = {}
    
    if not source:
        return {"success" : False, "message" : "Missing source information."}              
        
    is_item_new = False

    dataset_object = None
    cached_results = cache.get(form_consts.Dataset.CACHED_RESULTS)

    if cached_results != None:
        dataset_object = cached_results.get(name)
    else:
        dataset_object = Dataset.objects(name=name).first()
    
    if not dataset_object:
        dataset_object = Dataset()
        dataset_object.name = name
        dataset_object.description = description

        is_item_new = True

        if cached_results != None:
            cached_results[name] = dataset_object

    if not dataset_object.description:
        dataset_object.description = description or ''
    elif dataset_object.description != description:
        if description:
            dataset_object.description += "\n" + (description or '')

    if isinstance(source, basestring):
        source = [create_embedded_source(source,
                                         reference=reference,
                                         method=method,
                                         analyst=analyst)]

    if source:
        for s in source:
            dataset_object.add_source(s)
    else:
        return {"success" : False, "message" : "Missing source information."}

    if bucket_list:
        dataset_object.add_bucket_list(bucket_list, analyst)

    if ticket:
        dataset_object.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    resp_url = reverse('cripts.datasets.views.email_address_detail', args=[dataset_object.name])

    if is_validate_only == False:
        dataset_object.save(username=analyst)

        #set the URL for viewing the new data
        if is_item_new == True:
            
            # Update the email stats
            counts = mongo_connector(settings.COL_COUNTS)
            count_stats = counts.find_one({'name': 'counts'})
            if not count_stats or ('counts' not in count_stats):
                count_stats = {'counts':{}}
            if 'Datasets' not in count_stats['counts']:
                count_stats['counts']['Datasets'] = 0
            else:
                count_stats['counts']['Datasets'] = count_stats['counts']['Datasets'] + 1
            
            counts.update({'name': "counts"}, {'$set': {'counts': count_stats['counts']}}, upsert=True)
            
            retVal['message'] = ('Success! Click here to view the new Dataset: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
        else:
            message = ('Updated existing Dataset: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    elif is_validate_only == True:
        if dataset_object.id != None and is_item_new == False:
            message = ('Warning: Dataset already exists: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    if related_obj and email_object and relationship_type:
        relationship_type=RelationshipTypes.inverse(relationship=relationship_type)
        dataset_object.add_relationship(related_obj,
                              relationship_type,
                              analyst=analyst,
                              get_rels=False)
        dataset_object.save(username=analyst)

    # run dataset triage
    if is_item_new and is_validate_only == False:
        dataset_object.reload()
        run_triage(dataset_object, analyst)

    retVal['success'] = True
    retVal['object'] = dataset_object

    return retVal
Example #4
0
def email_address_add_update(address, description=None, source=None, method='', reference='',
                  analyst=None, datasets=None, bucket_list=None, ticket=None,
                  is_validate_only=False, cache={}, related_id=None,
                  related_type=None, relationship_type=None):

    retVal = {}
    
    if not source:
        return {"success" : False, "message" : "Missing source information."}              
                  
    # Parse out the e-mail address. Return an error if it looks invalid, (aka missing the @, has whitespace, etc)
    try:
        if ' ' in address:
            raise ValueError
        local_name, domain_part = address.strip().split('@', 1)
        if len(local_name) == 0 or len(domain_part) == 0:
            raise ValueError
        # lowercase the domain name and recreate the e-mail address
        address = '@'.join([local_name, domain_part.lower()])
    except ValueError:
        return {'success': False, 'message': "Invalid Email Address Format"}
        
    is_item_new = False

    email_object = None
    cached_results = cache.get(form_consts.EmailAddress.CACHED_RESULTS)

    if cached_results != None:
        email_object = cached_results.get(address)
    else:
        email_object = EmailAddress.objects(address=address).first()
    
    if not email_object:
        email_object = EmailAddress()
        email_object.address = address
        email_object.description = description
        email_object.local_name = local_name
        email_object.domain = domain_part.lower()
        is_item_new = True

        if cached_results != None:
            cached_results[address] = email_object

    if not email_object.description:
        email_object.description = description or ''
    elif email_object.description != description:
        if description:
            email_object.description += "\n" + (description or '')

    if isinstance(source, basestring):
        source = [create_embedded_source(source,
                                         reference=reference,
                                         method=method,
                                         analyst=analyst)]

    if source:
        for s in source:
            email_object.add_source(s)
    else:
        return {"success" : False, "message" : "Missing source information."}

    if bucket_list:
        email_object.add_bucket_list(bucket_list, analyst)

    if ticket:
        email_object.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    resp_url = reverse('cripts.email_addresses.views.email_address_detail', args=[email_object.address])

    if is_validate_only == False:
        email_object.save(username=analyst)

        #set the URL for viewing the new data
        if is_item_new == True:
            
            # Update the email stats
            counts = mongo_connector(settings.COL_COUNTS)
            count_stats = counts.find_one({'name': 'counts'})
            if not count_stats or ('counts' not in count_stats):
                count_stats = {'counts':{}}
            if 'Email Addresses' not in count_stats['counts']:
                count_stats['counts']['Email Addresses'] = 0
            else:
                count_stats['counts']['Email Addresses'] = count_stats['counts']['Email Addresses'] + 1
            
            counts.update({'name': "counts"}, {'$set': {'counts': count_stats['counts']}}, upsert=True)
            
            retVal['message'] = ('Success! Click here to view the new Email: '
                                 '<a href="%s">%s</a>' % (resp_url, email_object.address))
        else:
            message = ('Updated existing Email: '
                                 '<a href="%s">%s</a>' % (resp_url, email_object.address))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    elif is_validate_only == True:
        if email_object.id != None and is_item_new == False:
            message = ('Warning: Email already exists: '
                                 '<a href="%s">%s</a>' % (resp_url, email_object.address))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    if related_obj and email_object and relationship_type:
        relationship_type=RelationshipTypes.inverse(relationship=relationship_type)
        email_object.add_relationship(related_obj,
                              relationship_type,
                              analyst=analyst,
                              get_rels=False)
        email_object.save(username=analyst)

    # run email triage
    if is_item_new and is_validate_only == False:
        email_object.reload()
        run_triage(email_object, analyst)

    retVal['success'] = True
    retVal['object'] = email_object

    return retVal
Example #5
0
def add_new_event(title,
                  description,
                  event_type,
                  source,
                  method,
                  reference,
                  date,
                  analyst,
                  bucket_list=None,
                  ticket=None,
                  related_id=None,
                  related_type=None,
                  relationship_type=None):
    """
    Add a new Event to CRIPTs.

    :param title: Event title.
    :type title: str
    :param description: Event description.
    :type description: str
    :param event_type: Event type.
    :type event_type: str
    :param source: The source which provided this information.
    :type source: str
    :param method: THe method of acquiring this information.
    :type method: str
    :param reference: Reference to this data.
    :type reference: str
    :param date: Date of acquiring this data.
    :type date: datetime.datetime
    :param analyst: The user adding this Event.
    :type analyst: str
    :param bucket_list: The bucket(s) to associate with this Event.
    :type: str
    :param ticket: Ticket to associate with this event.
    :type ticket: str
    :param related_id: ID of object to create relationship with
    :type related_id: str
    :param related_type: Type of object to create relationship with
    :type related_type: str
    :param relationship_type: Type of relationship to create.
    :type relationship_type: str
    :returns: dict with keys "success" (boolean) and "message" (str)
    """
    result = dict()
    if not source:
        return {'success': False, 'message': "Missing source information."}

    event = Event()
    event.title = title
    event.description = description
    event.set_event_type(event_type)

    s = create_embedded_source(name=source,
                               reference=reference,
                               method=method,
                               analyst=analyst,
                               date=date)
    event.add_source(s)

    if bucket_list:
        event.add_bucket_list(bucket_list, analyst)

    if ticket:
        event.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    try:
        event.save(username=analyst)

        if related_obj and event and relationship_type:
            relationship_type = RelationshipTypes.inverse(
                relationship=relationship_type)
            event.add_relationship(related_obj,
                                   relationship_type,
                                   analyst=analyst,
                                   get_rels=False)
            event.save(username=analyst)

        # run event triage
        event.reload()
        run_triage(event, analyst)

        message = ('<div>Success! Click here to view the new event: <a href='
                   '"%s">%s</a></div>' %
                   (reverse('cripts.events.views.view_event', args=[event.id
                                                                    ]), title))
        result = {
            'success': True,
            'message': message,
            'id': str(event.id),
            'object': event
        }

    except ValidationError, e:
        result = {'success': False, 'message': e}
Example #6
0
def dataset_add_update(name, description=None, source=None, method='', reference='',
                  analyst=None, bucket_list=None, ticket=None,
                  is_validate_only=False, cache={}, related_id=None,
                  related_type=None, relationship_type=None):

    retVal = {}
    
    if not source:
        return {"success" : False, "message" : "Missing source information."}              
        
    is_item_new = False

    dataset_object = None
    cached_results = cache.get(form_consts.Dataset.CACHED_RESULTS)

    if cached_results != None:
        dataset_object = cached_results.get(name)
    else:
        dataset_object = Dataset.objects(name=name).first()
    
    if not dataset_object:
        dataset_object = Dataset()
        dataset_object.name = name
        dataset_object.description = description

        is_item_new = True

        if cached_results != None:
            cached_results[name] = dataset_object

    if not dataset_object.description:
        dataset_object.description = description or ''
    elif dataset_object.description != description:
        if description:
            dataset_object.description += "\n" + (description or '')

    if isinstance(source, basestring):
        source = [create_embedded_source(source,
                                         reference=reference,
                                         method=method,
                                         analyst=analyst)]

    if source:
        for s in source:
            dataset_object.add_source(s)
    else:
        return {"success" : False, "message" : "Missing source information."}

    if bucket_list:
        dataset_object.add_bucket_list(bucket_list, analyst)

    if ticket:
        dataset_object.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    resp_url = reverse('cripts.datasets.views.dataset_detail', args=[dataset_object.name])

    if is_validate_only == False:
        dataset_object.save(username=analyst)

        #set the URL for viewing the new data
        if is_item_new == True:
            
            # Update the dataset stats
            counts = mongo_connector(settings.COL_COUNTS)
            count_stats = counts.find_one({'name': 'counts'})
            if not count_stats or ('counts' not in count_stats):
                count_stats = {'counts':{}}
            if 'Datasets' not in count_stats['counts']:
                count_stats['counts']['Datasets'] = 0
            else:
                count_stats['counts']['Datasets'] = count_stats['counts']['Datasets'] + 1
            
            counts.update({'name': "counts"}, {'$set': {'counts': count_stats['counts']}}, upsert=True)
            
            retVal['message'] = ('Success! Click here to view the new Dataset: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
        else:
            message = ('Updated existing Dataset: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    elif is_validate_only == True:
        if dataset_object.id != None and is_item_new == False:
            message = ('Warning: Dataset already exists: '
                                 '<a href="%s">%s</a>' % (resp_url, dataset_object.name))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    if related_obj and email_object and relationship_type:
        relationship_type=RelationshipTypes.inverse(relationship=relationship_type)
        dataset_object.add_relationship(related_obj,
                              relationship_type,
                              analyst=analyst,
                              get_rels=False)
        dataset_object.save(username=analyst)

    # run dataset triage
    if is_item_new and is_validate_only == False:
        dataset_object.reload()
        run_triage(dataset_object, analyst)

    retVal['success'] = True
    retVal['object'] = dataset_object

    return retVal
Example #7
0
def email_address_add_update(address,
                             description=None,
                             source=None,
                             method='',
                             reference='',
                             analyst=None,
                             datasets=None,
                             bucket_list=None,
                             ticket=None,
                             is_validate_only=False,
                             cache={},
                             related_id=None,
                             related_type=None,
                             relationship_type=None):

    retVal = {}

    if not source:
        return {"success": False, "message": "Missing source information."}

    # Parse out the e-mail address. Return an error if it looks invalid, (aka missing the @, has whitespace, etc)
    try:
        if ' ' in address:
            raise ValueError
        local_name, domain_part = address.strip().split('@', 1)
        if len(local_name) == 0 or len(domain_part) == 0:
            raise ValueError
        # lowercase the domain name and recreate the e-mail address
        address = '@'.join([local_name, domain_part.lower()])
    except ValueError:
        return {'success': False, 'message': "Invalid Email Address Format"}

    is_item_new = False

    email_object = None
    cached_results = cache.get(form_consts.EmailAddress.CACHED_RESULTS)

    if cached_results != None:
        email_object = cached_results.get(address)
    else:
        email_object = EmailAddress.objects(address=address).first()

    if not email_object:
        email_object = EmailAddress()
        email_object.address = address
        email_object.description = description
        email_object.local_name = local_name
        email_object.domain = domain_part.lower()
        is_item_new = True

        if cached_results != None:
            cached_results[address] = email_object

    if not email_object.description:
        email_object.description = description or ''
    elif email_object.description != description:
        if description:
            email_object.description += "\n" + (description or '')

    if isinstance(source, basestring):
        source = [
            create_embedded_source(source,
                                   reference=reference,
                                   method=method,
                                   analyst=analyst)
        ]

    if source:
        for s in source:
            email_object.add_source(s)
    else:
        return {"success": False, "message": "Missing source information."}

    if bucket_list:
        email_object.add_bucket_list(bucket_list, analyst)

    if ticket:
        email_object.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    resp_url = reverse('cripts.email_addresses.views.email_address_detail',
                       args=[email_object.address])

    if is_validate_only == False:
        email_object.save(username=analyst)

        #set the URL for viewing the new data
        if is_item_new == True:

            # Update the email stats
            counts = mongo_connector(settings.COL_COUNTS)
            count_stats = counts.find_one({'name': 'counts'})
            if not count_stats or ('counts' not in count_stats):
                count_stats = {'counts': {}}
            if 'Email Addresses' not in count_stats['counts']:
                count_stats['counts']['Email Addresses'] = 0
            else:
                count_stats['counts']['Email Addresses'] = count_stats[
                    'counts']['Email Addresses'] + 1

            counts.update({'name': "counts"},
                          {'$set': {
                              'counts': count_stats['counts']
                          }},
                          upsert=True)

            retVal['message'] = ('Success! Click here to view the new Email: '
                                 '<a href="%s">%s</a>' %
                                 (resp_url, email_object.address))
        else:
            message = ('Updated existing Email: '
                       '<a href="%s">%s</a>' %
                       (resp_url, email_object.address))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    elif is_validate_only == True:
        if email_object.id != None and is_item_new == False:
            message = ('Warning: Email already exists: '
                       '<a href="%s">%s</a>' %
                       (resp_url, email_object.address))
            retVal['message'] = message
            retVal['status'] = form_consts.Status.DUPLICATE
            retVal['warning'] = message

    if related_obj and email_object and relationship_type:
        relationship_type = RelationshipTypes.inverse(
            relationship=relationship_type)
        email_object.add_relationship(related_obj,
                                      relationship_type,
                                      analyst=analyst,
                                      get_rels=False)
        email_object.save(username=analyst)

    # run email triage
    if is_item_new and is_validate_only == False:
        email_object.reload()
        run_triage(email_object, analyst)

    retVal['success'] = True
    retVal['object'] = email_object

    return retVal
Example #8
0
def add_new_event(title, description, event_type, source, method, reference,
                  date, analyst, bucket_list=None, ticket=None,
                  related_id=None,
                  related_type=None, relationship_type=None):
    """
    Add a new Event to CRIPTs.

    :param title: Event title.
    :type title: str
    :param description: Event description.
    :type description: str
    :param event_type: Event type.
    :type event_type: str
    :param source: The source which provided this information.
    :type source: str
    :param method: THe method of acquiring this information.
    :type method: str
    :param reference: Reference to this data.
    :type reference: str
    :param date: Date of acquiring this data.
    :type date: datetime.datetime
    :param analyst: The user adding this Event.
    :type analyst: str
    :param bucket_list: The bucket(s) to associate with this Event.
    :type: str
    :param ticket: Ticket to associate with this event.
    :type ticket: str
    :param related_id: ID of object to create relationship with
    :type related_id: str
    :param related_type: Type of object to create relationship with
    :type related_type: str
    :param relationship_type: Type of relationship to create.
    :type relationship_type: str
    :returns: dict with keys "success" (boolean) and "message" (str)
    """
    result = dict()
    if not source:
        return {'success': False, 'message': "Missing source information."}

    event = Event()
    event.title = title
    event.description = description
    event.set_event_type(event_type)

    s = create_embedded_source(name=source,
                               reference=reference,
                               method=method,
                               analyst=analyst,
                               date=date)
    event.add_source(s)

    if bucket_list:
        event.add_bucket_list(bucket_list, analyst)

    if ticket:
        event.add_ticket(ticket, analyst)

    related_obj = None
    if related_id:
        related_obj = class_from_id(related_type, related_id)
        if not related_obj:
            retVal['success'] = False
            retVal['message'] = 'Related Object not found.'
            return retVal

    try:
        event.save(username=analyst)

        if related_obj and event and relationship_type:
            relationship_type=RelationshipTypes.inverse(relationship=relationship_type)
            event.add_relationship(related_obj,
                                  relationship_type,
                                  analyst=analyst,
                                  get_rels=False)
            event.save(username=analyst)

        # run event triage
        event.reload()
        run_triage(event, analyst)

        message = ('<div>Success! Click here to view the new event: <a href='
                   '"%s">%s</a></div>' % (reverse('cripts.events.views.view_event',
                                                  args=[event.id]),
                                          title))
        result = {'success': True,
                  'message': message,
                  'id': str(event.id),
                  'object': event}

    except ValidationError, e:
        result = {'success': False,
                  'message': e}