Exemple #1
0
def create_analysis(
        analysis: AnalysisCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new analysis Node using the data from the request
    new_analysis: Analysis = create_node(node_create=analysis,
                                         db_node_type=Analysis,
                                         db=db,
                                         exclude={"parent_observable_uuid"})

    # If an analysis module type was given, get it from the database to use with the new analysis
    if analysis.analysis_module_type:
        new_analysis.analysis_module_type = crud.read(
            uuid=analysis.analysis_module_type,
            db_table=AnalysisModuleType,
            db=db)

    # Set the parent observable if one was given
    if analysis.parent_observable_uuid:
        new_analysis.parent_observable = crud.read(
            uuid=analysis.parent_observable_uuid,
            db_table=ObservableInstance,
            db=db)

        # This counts as editing the observable instance, so it should receive an updated version
        new_analysis.parent_observable.version = uuid4()

    # Save the new analysis to the database
    db.add(new_analysis)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_analysis", uuid=new_analysis.uuid)
Exemple #2
0
def create_user(
        user: UserCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new user using the data from the request
    new_user = User(**user.dict())

    # Get the alert queue from the database to associate with the new user
    new_user.default_alert_queue = crud.read_by_value(user.default_alert_queue,
                                                      db_table=AlertQueue,
                                                      db=db)

    # Get the user roles from the database to associate with the new user
    new_user.roles = crud.read_by_values(user.roles, db_table=UserRole, db=db)

    # Securely hash and salt the password. Bcrypt_256 is used to get around the Bcrypt limitations
    # of silently truncating passwords longer than 72 characters as well as not handling NULL bytes.
    new_user.password = hash_password(new_user.password)

    # Save the new user to the database
    db.add(new_user)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_user",
                                                           uuid=new_user.uuid)
Exemple #3
0
def update_node_comment(
        uuid: UUID,
        node_comment: NodeCommentUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Read the current node comment from the database
    db_node_comment: NodeComment = crud.read(uuid=uuid,
                                             db_table=NodeComment,
                                             db=db)

    # Read the node from the database
    db_node = crud.read(uuid=db_node_comment.node_uuid, db_table=Node, db=db)

    # Set the new comment value
    db_node_comment.value = node_comment.value

    # Modifying the comment counts as modifying the node, so it should receive a new version
    db_node.version = uuid4()

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_node_comment",
                                                           uuid=uuid)
Exemple #4
0
def create_event(
        event: EventCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new event Node using the data from the request
    new_event: Event = create_node(node_create=event,
                                   db_node_type=Event,
                                   db=db,
                                   exclude={"alert_uuids"})

    # Set the required event properties
    new_event.status = crud.read_by_value(value=event.status,
                                          db_table=EventStatus,
                                          db=db)

    # Set the various optional event properties if they were given in the request.
    if event.owner:
        new_event.owner = crud.read_user_by_username(username=event.owner,
                                                     db=db)

    if event.prevention_tools:
        new_event.prevention_tools = crud.read_by_values(
            values=event.prevention_tools,
            db_table=EventPreventionTool,
            db=db,
        )

    if event.remediations:
        new_event.remediations = crud.read_by_values(values=event.remediations,
                                                     db_table=EventRemediation,
                                                     db=db)

    if event.risk_level:
        new_event.risk_level = crud.read_by_value(value=event.risk_level,
                                                  db_table=EventRiskLevel,
                                                  db=db)

    if event.source:
        new_event.source = crud.read_by_value(value=event.source,
                                              db_table=EventSource,
                                              db=db)

    if event.type:
        new_event.type = crud.read_by_value(value=event.type,
                                            db_table=EventType,
                                            db=db)

    if event.vectors:
        new_event.vectors = crud.read_by_values(values=event.vectors,
                                                db_table=EventVector,
                                                db=db)

    # Save the new event to the database
    db.add(new_event)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_event",
                                                           uuid=new_event.uuid)
Exemple #5
0
def update_observable(
        uuid: UUID,
        observable: ObservableUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Read the current observable from the database
    db_observable: Observable = crud.read(uuid=uuid,
                                          db_table=Observable,
                                          db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = observable.dict(exclude_unset=True)

    if "expires_on" in update_data:
        db_observable.expires_on = update_data["expires_on"]

    if "for_detection" in update_data:
        db_observable.for_detection = update_data["for_detection"]

    if "type" in update_data:
        db_observable.type = crud.read_by_value(value=update_data["type"],
                                                db_table=ObservableType,
                                                db=db)

    if "value" in update_data:
        db_observable.value = update_data["value"]

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_observable",
                                                           uuid=uuid)
Exemple #6
0
def create_node_comment(
        node_comment: NodeCommentCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new node comment
    new_comment = NodeComment(**node_comment.dict())

    # Make sure the node actually exists
    db_node = crud.read(uuid=node_comment.node_uuid, db_table=Node, db=db)

    # This counts a modifying the node, so it should receive a new version.
    db_node.version = uuid4()

    # Set the user on the comment
    new_comment.user = crud.read_user_by_username(username=node_comment.user,
                                                  db=db)

    # Save the new comment to the database
    db.add(new_comment)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_node_comment", uuid=new_comment.uuid)
Exemple #7
0
def update_node_threat(
        uuid: UUID,
        node_threat: NodeThreatUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Read the current node threat from the database
    db_node_threat: NodeThreat = crud.read(uuid=uuid,
                                           db_table=NodeThreat,
                                           db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = node_threat.dict(exclude_unset=True)

    if "description" in update_data:
        db_node_threat.description = update_data["description"]

    if "value" in update_data:
        db_node_threat.value = update_data["value"]

    if "types" in update_data:
        db_node_threat.types = crud.read_by_values(values=update_data["types"],
                                                   db_table=NodeThreatType,
                                                   db=db)

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_node_threat",
                                                           uuid=uuid)
Exemple #8
0
def update_analysis_module_type(
        uuid: UUID,
        analysis_module_type: AnalysisModuleTypeUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Read the current analysis module type from the database
    db_analysis_module_type: AnalysisModuleType = crud.read(
        uuid=uuid, db_table=AnalysisModuleType, db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = analysis_module_type.dict(exclude_unset=True)

    if "description" in update_data:
        db_analysis_module_type.description = update_data["description"]

    if "extended_version" in update_data:
        db_analysis_module_type.extended_version = update_data[
            "extended_version"]

    if "manual" in update_data:
        db_analysis_module_type.manual = update_data["manual"]

    if "value" in update_data:
        db_analysis_module_type.value = update_data["value"]

    if "observable_types" in update_data:
        db_analysis_module_type.observable_types = crud.read_by_values(
            values=update_data["observable_types"],
            db_table=ObservableType,
            db=db)

    if "required_directives" in update_data:
        db_analysis_module_type.required_directives = crud.read_by_values(
            values=update_data["required_directives"],
            db_table=NodeDirective,
            db=db)

    if "required_tags" in update_data:
        db_analysis_module_type.required_tags = crud.read_by_values(
            values=update_data["required_tags"], db_table=NodeTag, db=db)

    if "version" in update_data:
        db_analysis_module_type.version = update_data["version"]

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_analysis_module_type", uuid=uuid)
def update_observable_instance(
        uuid: UUID,
        observable_instance: ObservableInstanceUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Update the Node attributes
    db_observable_instance: ObservableInstance = update_node(
        node_update=observable_instance,
        uuid=uuid,
        db_table=ObservableInstance,
        db=db,
    )

    # Get the data that was given in the request and use it to update the database object
    update_data = observable_instance.dict(exclude_unset=True)

    if "context" in update_data:
        db_observable_instance.context = update_data["context"]

    # Any UUIDs given in this list add to the existing ones and do not replace them
    if "performed_analysis_uuids" in update_data:
        for performed_analysis_uuid in update_data["performed_analysis_uuids"]:
            db_analysis = crud.read(uuid=performed_analysis_uuid,
                                    db_table=Analysis,
                                    db=db)
            db_observable_instance.performed_analyses.append(db_analysis)

            # This counts as editing the analysis, so it should receive an updated version
            db_analysis.version = uuid4()

    if "redirection_uuid" in update_data:
        db_observable_instance.redirection = crud.read(
            uuid=update_data["redirection_uuid"],
            db_table=ObservableInstance,
            db=db)

        # TODO: Figure out why setting the redirection field above does not set the redirection_uuid
        # the same way it does in the create endpoint.
        db_observable_instance.redirection_uuid = update_data[
            "redirection_uuid"]

    if "time" in update_data:
        db_observable_instance.time = update_data["time"]

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_observable_instance", uuid=uuid)
Exemple #10
0
def update_user(
        uuid: UUID,
        user: UserUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Read the current user from the database
    db_user: User = crud.read(uuid=uuid, db_table=User, db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = user.dict(exclude_unset=True)

    if "default_alert_queue" in update_data:
        db_user.default_alert_queue = crud.read_by_value(
            value=update_data["default_alert_queue"],
            db_table=AlertQueue,
            db=db)

    if "display_name" in update_data:
        db_user.display_name = update_data["display_name"]

    if "email" in update_data:
        db_user.email = update_data["email"]

    if "enabled" in update_data:
        db_user.enabled = update_data["enabled"]

    if "password" in update_data:
        db_user.password = hash_password(update_data["password"])

    if "roles" in update_data:
        db_user.roles = crud.read_by_values(values=update_data["roles"],
                                            db_table=UserRole,
                                            db=db)

    if "timezone" in update_data:
        db_user.timezone = update_data["timezone"]

    if "username" in update_data:
        db_user.username = update_data["username"]

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_user",
                                                           uuid=uuid)
Exemple #11
0
def create_alert(
        alert: AlertCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new alert Node using the data from the request
    new_alert: Alert = create_node(node_create=alert,
                                   db_node_type=Alert,
                                   db=db)

    # Set the required alert properties
    new_alert.queue = crud.read_by_value(value=alert.queue,
                                         db_table=AlertQueue,
                                         db=db)
    new_alert.type = crud.read_by_value(value=alert.type,
                                        db_table=AlertType,
                                        db=db)

    # Set the various optional alert properties if they were given in the request.
    if alert.owner:
        new_alert.owner = crud.read_user_by_username(username=alert.owner,
                                                     db=db)

    if alert.tool:
        new_alert.tool = crud.read_by_value(value=alert.tool,
                                            db_table=AlertTool,
                                            db=db)

    if alert.tool_instance:
        new_alert.tool_instance = crud.read_by_value(
            value=alert.tool_instance, db_table=AlertToolInstance, db=db)

    # Alerts must point to an Analysis, so if we get this far without any errors, a new Analysis needs to be created.
    new_alert.analysis = create_node(node_create=AnalysisCreate(),
                                     db_node_type=Analysis,
                                     db=db)

    # Save the new alert (including the new analysis) to the database
    db.add(new_alert)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_alert",
                                                           uuid=new_alert.uuid)
Exemple #12
0
def create_observable(
        observable: ObservableCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new observable using the data from the request
    new_observable = Observable(**observable.dict())

    # Get the observable type from the database to associate with the new observable
    new_observable.type = crud.read_by_value(observable.type,
                                             db_table=ObservableType,
                                             db=db)

    # Save the new observable to the database
    db.add(new_observable)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_observable", uuid=new_observable.uuid)
Exemple #13
0
def create_analysis_module_type(
        analysis_module_type: AnalysisModuleTypeCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new analysis module type using the data from the request
    new_analysis_module_type = AnalysisModuleType(
        **analysis_module_type.dict())

    # If observable types were given, get them from the database and use them in the new analysis module type
    db_observable_types = []
    if analysis_module_type.observable_types:
        db_observable_types = crud.read_by_values(
            values=analysis_module_type.observable_types,
            db_table=ObservableType,
            db=db)
    new_analysis_module_type.observable_types = db_observable_types

    # If required directives were given, get them from the database and use them in the new analysis module type
    db_required_directives = []
    if analysis_module_type.required_directives:
        db_required_directives = crud.read_by_values(
            values=analysis_module_type.required_directives,
            db_table=NodeDirective,
            db=db)
    new_analysis_module_type.required_directives = db_required_directives

    # If required tags were given, get them from the database and use them in the new analysis module type
    db_required_tags = []
    if analysis_module_type.required_tags:
        db_required_tags = crud.read_by_values(
            values=analysis_module_type.required_tags, db_table=NodeTag, db=db)
    new_analysis_module_type.required_tags = db_required_tags

    # Save the new analysis module type to the database
    db.add(new_analysis_module_type)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_analysis_module_type", uuid=new_analysis_module_type.uuid)
Exemple #14
0
def update_analysis(
        uuid: UUID,
        analysis: AnalysisUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Update the Node attributes
    db_analysis: Analysis = update_node(node_update=analysis,
                                        uuid=uuid,
                                        db_table=Analysis,
                                        db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = analysis.dict(exclude_unset=True)

    if "analysis_module_type" in update_data:
        db_analysis_module_type = crud.read(
            uuid=update_data["analysis_module_type"],
            db_table=AnalysisModuleType,
            db=db)
        db_analysis.analysis_module_type = db_analysis_module_type

    if "details" in update_data:
        db_analysis.details = update_data["details"]

    if "error_message" in update_data:
        db_analysis.error_message = update_data["error_message"]

    if "stack_trace" in update_data:
        db_analysis.stack_trace = update_data["stack_trace"]

    if "summary" in update_data:
        db_analysis.summary = update_data["summary"]

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_analysis",
                                                           uuid=uuid)
Exemple #15
0
def create_node_threat(
        node_threat: NodeThreatCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Make sure that all the threat types that were given actually exist
    db_threat_types = crud.read_by_values(values=node_threat.types,
                                          db_table=NodeThreatType,
                                          db=db)

    # Create the new node threat
    new_threat = NodeThreat(**node_threat.dict())

    # Set the threat types on the new node threat
    new_threat.types = db_threat_types

    # Save the new node threat to the database
    db.add(new_threat)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_node_threat", uuid=new_threat.uuid)
Exemple #16
0
def update_event(
        uuid: UUID,
        event: EventUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Update the Node attributes
    db_event: Event = update_node(node_update=event,
                                  uuid=uuid,
                                  db_table=Event,
                                  db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = event.dict(exclude_unset=True)

    if "alert_time" in update_data:
        db_event.alert_time = update_data["alert_time"]

    if "contain_time" in update_data:
        db_event.contain_time = update_data["contain_time"]

    if "disposition_time" in update_data:
        db_event.disposition_time = update_data["disposition_time"]

    if "event_time" in update_data:
        db_event.event_time = update_data["event_time"]

    if "name" in update_data:
        db_event.name = update_data["name"]

    if "owner" in update_data:
        db_event.owner = crud.read_user_by_username(
            username=update_data["owner"], db=db)

    if "ownership_time" in update_data:
        db_event.ownership_time = update_data["ownership_time"]

    if "prevention_tools" in update_data:
        db_event.prevention_tools = crud.read_by_values(
            values=update_data["prevention_tools"],
            db_table=EventPreventionTool,
            db=db,
        )

    if "remediation_time" in update_data:
        db_event.remediation_time = update_data["remediation_time"]

    if "remediations" in update_data:
        db_event.remediations = crud.read_by_values(
            values=update_data["remediations"],
            db_table=EventRemediation,
            db=db,
        )

    if "risk_level" in update_data:
        db_event.risk_level = crud.read_by_value(
            value=update_data["risk_level"], db_table=EventRiskLevel, db=db)

    if "source" in update_data:
        db_event.source = crud.read_by_value(value=update_data["source"],
                                             db_table=EventSource,
                                             db=db)

    if "status" in update_data:
        db_event.status = crud.read_by_value(value=update_data["status"],
                                             db_table=EventStatus,
                                             db=db)

    if "type" in update_data:
        db_event.type = crud.read_by_value(value=update_data["type"],
                                           db_table=EventType,
                                           db=db)

    if "vectors" in update_data:
        db_event.vectors = crud.read_by_values(values=update_data["vectors"],
                                               db_table=EventVector,
                                               db=db)

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_event",
                                                           uuid=uuid)
Exemple #17
0
        # Make sure there is always an "admin" role
        if "admin" not in data["user_role"]:
            data["user_role"].append("admin")

        for value in data["user_role"]:
            db.add(UserRole(value=value))
            print(f"Adding user role: {value}")
    else:
        # Make sure there is always an "admin" role
        db.add(UserRole(value="admin"))
        print("Adding user role: admin")

# Add an "analyst" user if there are no existing users
if not crud.read_all(db_table=User, db=db):
    # Commit the database changes so that they can be used to create the analyst user
    crud.commit(db)

    db.add(
        User(
            default_alert_queue=crud.read_by_value(value="default",
                                                   db_table=AlertQueue,
                                                   db=db),
            display_name="Analyst",
            email="analyst@localhost",
            password="******",
            roles=crud.read_by_values(values=["admin"],
                                      db_table=UserRole,
                                      db=db),
            username="******",
        ))
    print("Adding user: analyst")
def create_observable_instance(
        observable_instance: ObservableInstanceCreate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Create the new observable instance Node using the data from the request
    new_observable_instance: ObservableInstance = create_node(
        node_create=observable_instance,
        db_node_type=ObservableInstance,
        db=db,
        exclude={
            "parent_analysis_uuid", "performed_analysis_uuids", "type", "value"
        },
    )

    # Read the required fields from the database to use with the new observable instance
    new_observable_instance.alert = crud.read(
        uuid=observable_instance.alert_uuid, db_table=Alert, db=db)
    new_observable_instance.parent_analysis = crud.read(
        uuid=observable_instance.parent_analysis_uuid,
        db_table=Analysis,
        db=db)

    # Adding an observable instance counts as modifying the alert and the analysis, so they should both get new versions
    new_observable_instance.alert.version = uuid4()
    new_observable_instance.parent_analysis.version = uuid4()

    # Set any performed analyses that were given
    for performed_analysis_uuid in observable_instance.performed_analysis_uuids:
        db_analysis = crud.read(uuid=performed_analysis_uuid,
                                db_table=Analysis,
                                db=db)
        new_observable_instance.performed_analyses.append(db_analysis)

        # This counts as editing the analysis, so it should receive an updated version
        db_analysis.version = uuid4()

    # Set the redirection observable instance if one was given
    if observable_instance.redirection_uuid:
        new_observable_instance.redirection = crud.read(
            uuid=observable_instance.redirection_uuid,
            db_table=ObservableInstance,
            db=db,
        )

    # Lastly, check if the Observable represented by this instance already exists. Create it if it does not.
    db_observable = crud.read_observable(type=observable_instance.type,
                                         value=observable_instance.value,
                                         db=db)
    if not db_observable:
        db_observable_type = crud.read_by_value(value=observable_instance.type,
                                                db_table=ObservableType,
                                                db=db)
        db_observable = Observable(type=db_observable_type,
                                   value=observable_instance.value)

    # Associate the observable instance with its observable
    new_observable_instance.observable = db_observable

    # Save the new analysis to the database
    db.add(new_observable_instance)
    crud.commit(db)

    response.headers["Content-Location"] = request.url_for(
        "get_observable_instance", uuid=new_observable_instance.uuid)
Exemple #19
0
def update_alert(
        uuid: UUID,
        alert: AlertUpdate,
        request: Request,
        response: Response,
        db: Session = Depends(get_db),
):
    # Update the Node attributes
    db_alert: Alert = update_node(node_update=alert,
                                  uuid=uuid,
                                  db_table=Alert,
                                  db=db)

    # Get the data that was given in the request and use it to update the database object
    update_data = alert.dict(exclude_unset=True)

    if "description" in update_data:
        db_alert.description = update_data["description"]

    if "disposition" in update_data:
        db_alert.disposition = crud.read_by_value(
            value=update_data["disposition"], db_table=AlertDisposition, db=db)

    if "event_uuid" in update_data:
        db_alert.event = crud.read(uuid=update_data["event_uuid"],
                                   db_table=Event,
                                   db=db)

        # This counts as editing the event, so it should receive a new version.
        db_alert.event.version = uuid4()

    if "event_time" in update_data:
        db_alert.event_time = update_data["event_time"]

    if "instructions" in update_data:
        db_alert.instructions = update_data["instructions"]

    if "name" in update_data:
        db_alert.name = update_data["name"]

    if "owner" in update_data:
        db_alert.owner = crud.read_user_by_username(
            username=update_data["owner"], db=db)

    if "queue" in update_data:
        db_alert.queue = crud.read_by_value(value=update_data["queue"],
                                            db_table=AlertQueue,
                                            db=db)

    if "tool" in update_data:
        db_alert.tool = crud.read_by_value(value=update_data["tool"],
                                           db_table=AlertTool,
                                           db=db)

    if "tool_instance" in update_data:
        db_alert.tool_instance = crud.read_by_value(
            value=update_data["tool_instance"],
            db_table=AlertToolInstance,
            db=db,
        )

    if "type" in update_data:
        db_alert.type = crud.read_by_value(value=update_data["type"],
                                           db_table=AlertType,
                                           db=db)

    crud.commit(db)

    response.headers["Content-Location"] = request.url_for("get_alert",
                                                           uuid=uuid)