def process_bulk_add_usernames(request, formdict): """ Performs the bulk add of usernames by parsing the request data. Batches some data into a cache object for performance by reducing large amounts of single database queries. :param request: Django request. :type request: :class:`django.http.HttpRequest` :param formdict: The form representing the bulk uploaded data. :type formdict: dict :returns: :class:`django.http.HttpResponse` """ username_names = [] cached_results = {} cleanedRowsData = convert_handsontable_to_rows(request) for rowData in cleanedRowsData: if rowData != None and rowData.get(form_consts.UserName.NAME) != None: username_names.append(rowData.get(form_consts.UserName.NAME).lower()) username_results = UserName.objects(username__in=username_names) for username_result in username_results: cached_results[username_result.username] = username_result cache = {form_consts.UserName.CACHED_RESULTS: cached_results, 'cleaned_rows_data': cleanedRowsData} response = parse_bulk_upload(request, parse_row_to_bound_username_form, add_new_username_via_bulk, formdict, cache) return response
def process_bulk_add_usernames(request, formdict): """ Performs the bulk add of usernames by parsing the request data. Batches some data into a cache object for performance by reducing large amounts of single database queries. :param request: Django request. :type request: :class:`django.http.HttpRequest` :param formdict: The form representing the bulk uploaded data. :type formdict: dict :returns: :class:`django.http.HttpResponse` """ username_names = [] cached_results = {} cleanedRowsData = convert_handsontable_to_rows(request) for rowData in cleanedRowsData: if rowData != None and rowData.get(form_consts.UserName.NAME) != None: username_names.append( rowData.get(form_consts.UserName.NAME).lower()) username_results = UserName.objects(username__in=username_names) for username_result in username_results: cached_results[username_result.username] = username_result cache = { form_consts.UserName.CACHED_RESULTS: cached_results, 'cleaned_rows_data': cleanedRowsData } response = parse_bulk_upload(request, parse_row_to_bound_username_form, add_new_username_via_bulk, formdict, cache) return response
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
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
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
def get_username_details(username_id, analyst): """ Generate the data to render the UserName details template. :param username_id: The id of the username to get details for. :type username_id: str :param analyst: The user requesting this information. :type analyst: str :returns: template (str), arguments (dict) """ template = None allowed_sources = user_sources(analyst) username_object = UserName.objects(username_id=username_id, source__name__in=allowed_sources).first() if not username_object: error = ("Either no data exists for this username" " or you do not have permission to view it.") template = "error.html" args = {'error': error} return template, args username_object.sanitize_sources(username="******" % analyst, sources=allowed_sources) # remove pending notifications for user remove_user_from_notification("%s" % analyst, username_object.id, 'UserName') # subscription subscription = { 'type': 'UserName', 'id': username_object.id, 'subscribed': is_user_subscribed("%s" % analyst, 'UserName', username_object.id), } #objects objects = username_object.sort_objects() #relationships relationships = username_object.sort_relationships("%s" % analyst, meta=True) # relationship relationship = { 'type': 'UserName', 'value': username_object.id } #comments comments = {'comments':username_object.get_comments(), 'url_key':username_object.username_id} # favorites favorite = is_user_favorite("%s" % analyst, 'UserName', username_object.id) # services service_list = get_supported_services('UserName') # analysis results service_results = username_object.get_analysis_results() args = {'username': username_object, 'objects': objects, 'relationships': relationships, 'comments': comments, 'favorite': favorite, 'relationship': relationship, 'subscription': subscription, 'name': username_object.name, 'service_list': service_list, 'service_results': service_results} return template, args
def username_add_update(name, description, 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."} is_item_new = False username_object = None cached_results = cache.get(form_consts.UserName.CACHED_RESULTS) if cached_results != None: username_object = cached_results.get(username) else: username_object = UserName.objects(name=name).first() if not username_object: username_object = UserName() username_object.name = name username_object.description = description is_item_new = True if cached_results != None: cached_results[username] = username_object if not username_object.description: username_object.description = description or '' elif username_object.description != description: username_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: username_object.add_source(s) else: return {"success" : False, "message" : "Missing source information."} if bucket_list: username_object.add_bucket_list(bucket_list, analyst) if ticket: username_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.usernames.views.username_detail', args=[username_object.username_id]) if is_validate_only == False: username_object.save(username=analyst) #set the URL for viewing the new data if is_item_new == True: # Update the username 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 'UserNames' not in count_stats['counts']: count_stats['counts']['UserNames'] = 0 else: count_stats['counts']['UserNames'] = count_stats['counts']['UserNames'] + 1 counts.update({'name': "counts"}, {'$set': {'counts': count_stats['counts']}}, upsert=True) retVal['message'] = ('Success! Click here to view the new UserName: '******'<a href="%s">%s</a>' % (resp_url, username_object.name)) else: message = ('Updated existing UserName: '******'<a href="%s">%s</a>' % (resp_url, username_object.name)) retVal['message'] = message retVal['status'] = form_consts.Status.DUPLICATE retVal['warning'] = message elif is_validate_only == True: if username_object.id != None and is_item_new == False: message = ('Warning: UserName already exists: ' '<a href="%s">%s</a>' % (resp_url, username_object.name)) retVal['message'] = message retVal['status'] = form_consts.Status.DUPLICATE retVal['warning'] = message if related_obj and username_object and relationship_type: relationship_type=RelationshipTypes.inverse(relationship=relationship_type) username_object.add_relationship(related_obj, relationship_type, analyst=analyst, get_rels=False) username_object.save(username=analyst) # run username triage if is_item_new and is_validate_only == False: username_object.reload() run_triage(username_object, analyst) retVal['success'] = True retVal['object'] = username_object return retVal
def get_username_details(username_id, analyst): """ Generate the data to render the UserName details template. :param username_id: The id of the username to get details for. :type username_id: str :param analyst: The user requesting this information. :type analyst: str :returns: template (str), arguments (dict) """ template = None allowed_sources = user_sources(analyst) username_object = UserName.objects( username_id=username_id, source__name__in=allowed_sources).first() if not username_object: error = ("Either no data exists for this username" " or you do not have permission to view it.") template = "error.html" args = {'error': error} return template, args username_object.sanitize_sources(username="******" % analyst, sources=allowed_sources) # remove pending notifications for user remove_user_from_notification("%s" % analyst, username_object.id, 'UserName') # subscription subscription = { 'type': 'UserName', 'id': username_object.id, 'subscribed': is_user_subscribed("%s" % analyst, 'UserName', username_object.id), } #objects objects = username_object.sort_objects() #relationships relationships = username_object.sort_relationships("%s" % analyst, meta=True) # relationship relationship = {'type': 'UserName', 'value': username_object.id} #comments comments = { 'comments': username_object.get_comments(), 'url_key': username_object.username_id } # favorites favorite = is_user_favorite("%s" % analyst, 'UserName', username_object.id) # services service_list = get_supported_services('UserName') # analysis results service_results = username_object.get_analysis_results() args = { 'username': username_object, 'objects': objects, 'relationships': relationships, 'comments': comments, 'favorite': favorite, 'relationship': relationship, 'subscription': subscription, 'name': username_object.name, 'service_list': service_list, 'service_results': service_results } return template, args
def username_add_update(name, description, 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."} is_item_new = False username_object = None cached_results = cache.get(form_consts.UserName.CACHED_RESULTS) if cached_results != None: username_object = cached_results.get(username) else: username_object = UserName.objects(name=name).first() if not username_object: username_object = UserName() username_object.name = name username_object.description = description is_item_new = True if cached_results != None: cached_results[username] = username_object if not username_object.description: username_object.description = description or '' elif username_object.description != description: username_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: username_object.add_source(s) else: return {"success": False, "message": "Missing source information."} if bucket_list: username_object.add_bucket_list(bucket_list, analyst) if ticket: username_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.usernames.views.username_detail', args=[username_object.username_id]) if is_validate_only == False: username_object.save(username=analyst) #set the URL for viewing the new data if is_item_new == True: # Update the username 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 'UserNames' not in count_stats['counts']: count_stats['counts']['UserNames'] = 0 else: count_stats['counts'][ 'UserNames'] = count_stats['counts']['UserNames'] + 1 counts.update({'name': "counts"}, {'$set': { 'counts': count_stats['counts'] }}, upsert=True) retVal['message'] = ( 'Success! Click here to view the new UserName: '******'<a href="%s">%s</a>' % (resp_url, username_object.name)) else: message = ('Updated existing UserName: '******'<a href="%s">%s</a>' % (resp_url, username_object.name)) retVal['message'] = message retVal['status'] = form_consts.Status.DUPLICATE retVal['warning'] = message elif is_validate_only == True: if username_object.id != None and is_item_new == False: message = ('Warning: UserName already exists: ' '<a href="%s">%s</a>' % (resp_url, username_object.name)) retVal['message'] = message retVal['status'] = form_consts.Status.DUPLICATE retVal['warning'] = message if related_obj and username_object and relationship_type: relationship_type = RelationshipTypes.inverse( relationship=relationship_type) username_object.add_relationship(related_obj, relationship_type, analyst=analyst, get_rels=False) username_object.save(username=analyst) # run username triage if is_item_new and is_validate_only == False: username_object.reload() run_triage(username_object, analyst) retVal['success'] = True retVal['object'] = username_object return retVal