예제 #1
0
def session_events(session, user=None):
    """
    :type session: Session
    :type user: User
    """
    if request.method == 'GET':
        session = Session.objects.with_id(session)
        if isinstance(session.range, RelativeRange):
            DataModelEvent.objects(sessions=session, time__lt=session.range.start_time).update(pull__sessions=session)

        return DataModelEvent.objects(sessions=session).order_by('time'), HTTPStatus.OK
예제 #2
0
def query_session(session, user=None):
    """
    :type session: Session
    :type user: User
    """
    session_id = session
    session = Session.objects.with_id(session)

    if request.method == 'GET':
        if session:
            return session, HTTPStatus.OK
        return None, HTTPStatus.NOT_FOUND

    elif request.method == 'PUT':
        # Create a new session if it doesn't exist
        if not session:
            session = Session(id=session_id)
            http_status = HTTPStatus.CREATED
        else:
            http_status = HTTPStatus.OK

        try:
            session.update(**request.json)
            session.validate()
        except mongoengine.ValidationError:
            return {'error': 'schema validation error'}, HTTPStatus.BAD_REQUEST

        session.save()
        return None, http_status

    elif request.method == 'POST':
        if 'reset' in request.args:
            DataModelEvent.objects(sessions=session).update(pull__sessions=session)
            AnalyticResult.objects(session=session).delete()
            Job.objects(session=session).delete()
            # Remove the session state
            session.update(state=SessionState())
            # Is this the right http error code?
            return None, HTTPStatus.RESET_CONTENT

        elif 'refresh' in request.args:
            for analytic_state in session.state.analytics:
                job = AnalyticJob.update_existing(analytic=analytic_state.analytic, mode=analytic_state.mode, user=user, session=session)
                job.submit()
            return None, HTTPStatus.RESET_CONTENT

    # TODO: Implement
    elif request.method == 'DELETE':
        DataModelEvent.objects(sessions=session).update(pull__sessions=session)
        AnalyticResult.objects(session=session).delete()
        Job.objects(session=session).delete()
        session.delete()
        return None, HTTPStatus.NO_CONTENT
예제 #3
0
    def get_clusters(self):
        events = list(DataModelEvent.objects(sessions=self).no_dereference())
        results = list(AnalyticResult.objects(session=self).no_dereference())
        event_keys = set(_.id for _ in events)

        def get_neighbors(node):
            neighbors = []
            if isinstance(node, AnalyticResult):
                neighbors.extend(event for event in node.events
                                 if event.id in event_keys)
            elif isinstance(node, DataModelEvent):
                # TODO: Error check to handle for events outside of current session
                neighbors.extend(event for event in node.links
                                 if event.id in event_keys)
                neighbors.extend(event for event in node.reverse_links
                                 if event.id in event_keys)
            return neighbors

        uptree = DisjointSet(events + results, get_neighbors)
        clusters = []
        for cluster in uptree.clusters():
            new_cluster = {'events': [], 'results': []}
            for item in cluster:
                if isinstance(item, AnalyticResult):
                    new_cluster['results'].append(item)
                elif isinstance(item, DataModelEvent):
                    new_cluster['events'].append(item)
            clusters.append(new_cluster)
        return clusters
예제 #4
0
def query_events(user=None):
    """
    :type user: User
    """
    filter = {}
    if request.args.get('session'):
        session = Session.objects.with_id(request.args.get('session'))
        if not session:
            return None, HTTPStatus.NOT_FOUND
        filter['sessions'] = session

    return DataModelEvent.objects(**filter), HTTPStatus.OK
예제 #5
0
def all_sessions(user=None):
    """ :type user: User """
    if request.method == 'GET':
        query = {}
        if 'name' in request.args:
            query['name'] = request.args['name']

        sessions = Session.objects(**query).order_by('name')
        return sessions, HTTPStatus.OK

    elif request.method == 'POST':
        if 'clone' in request.args:
            original = Session.objects.with_id(request.args.get('clone'))
            original_id = original.id

            if original is None:
                return {'error': 'source session could not be found'}, HTTPStatus.BAD_REQUEST

            session = original
            session.id = None
            session.name = request.json['name']
            session.save(validate=True)
            # Clone over all of the data model events
            DataModelEvent.objects(sessions=original_id).update(add_to_set__sessions=session.id)
            for result in AnalyticResult.objects(session=original_id):
                result.id = None
                result.session = session
                result.uuid = result.get_uuid()
                result.save()
        else:
            info = request.json

            if info.get('range') is not None and info.get('name') is not None:
                time_range = DateRange.get_range(info['range'])
                session = Session(range=time_range, name=info['name'])
            session.save(validate=True)

        return session.id, HTTPStatus.OK
예제 #6
0
def export_session(session, user=None):
    session = Session.objects.with_id(session)
    if not isinstance(session, Session):
        return None, HTTPStatus.NOT_FOUND

    events = DataModelEvent.objects(sessions=session)
    results = AnalyticResult.objects(session=session)

    dump = [
        {'collection': 'data_model_event', 'content': events},
        {'collection': 'analytic_result', 'content': results},
        {'collection': 'session', 'content': [session]}
    ]

    return dump, HTTPStatus.OK
예제 #7
0
def query_session_hosts(session, user=None):
    """
    :type session: Session
    :type user: User
    """
    session = Session.objects.with_id(session)
    if not session:
        return None, HTTPStatus.NOT_FOUND

    host_ids = set()
    for event in DataModelEvent.objects(sessions=session):
        event.update_host()
        if event.host:
            host_ids.add(event.host.id)

    host_list = [Host.objects.with_id(_) for _ in host_ids]
    return host_list, HTTPStatus.OK
예제 #8
0
def alert_graph(session, user=None):
    """
    :type session: Session
    :type user: User
    """
    if request.method == 'GET':
        session = Session.objects.with_id(session)
        if not session:
            return None, HTTPStatus.NOT_FOUND

        # Avoid too many database lookups
        events = {e.id: e for e in DataModelEvent.objects(sessions=session)}

        results = list(AnalyticResult.objects(session=session))
        edges = set()
        result_lookup = defaultdict(list)

        for result in results:
            for event in result.events:
                result_lookup[event.id].append(result.id)

        def descendant_analytics(_event):
            children = []
            for child_event in _event.links:
                # Stop once I hit an analytic
                if child_event.id in result_lookup:
                    children.extend(result_lookup[child_event.id])
                elif child_event.id in events:
                    children.extend(descendant_analytics(events[child_event.id]))
            return children

        for i, result in enumerate(results):
            for event in result.events:
                for similar_result in result_lookup[event.id]:
                    if similar_result is not result:
                        pass
                if event.id in events:
                    for edge in descendant_analytics(events[event.id]):
                        if edge != result.id:
                            edges.add((result.id, edge))

        return {'nodes': results, 'edges': list(edges)}, HTTPStatus.OK