Пример #1
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)
Пример #2
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)
Пример #3
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)
Пример #4
0
def create_node(
    node_create: NodeCreate,
    db_node_type: DeclarativeMeta,
    db: Session,
    exclude: dict = None,
) -> DeclarativeMeta:
    """
    Helper function when creating a new Node that sets the attributes inherited from Node.
    """

    db_node: Node = db_node_type(**node_create.dict(exclude=exclude))

    if node_create.directives:
        db_node.directives = crud.read_by_values(values=node_create.directives,
                                                 db_table=NodeDirective,
                                                 db=db)

    if node_create.tags:
        db_node.tags = crud.read_by_values(values=node_create.tags,
                                           db_table=NodeTag,
                                           db=db)

    if node_create.threat_actor:
        db_node.threat_actor = crud.read_by_value(
            value=node_create.threat_actor, db_table=NodeThreatActor, db=db)

    if node_create.threats:
        db_node.threats = crud.read_by_values(values=node_create.threats,
                                              db_table=NodeThreat,
                                              db=db)

    return db_node
Пример #5
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)
Пример #6
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)
Пример #7
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)
Пример #8
0
def update_node(node_update: NodeUpdate, uuid: UUID, db_table: DeclarativeMeta,
                db: Session) -> DeclarativeMeta:
    """
    Helper function when updating a Node that enforces version matching and updates the attributes inherited from Node.
    """

    # Fetch the Node from the database
    db_node: Node = crud.read(uuid=uuid, db_table=db_table, db=db)

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

    # Return an exception if the passed in version does not match the Node's current version
    if update_data["version"] != db_node.version:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="Unable to update Node due to version mismatch")

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

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

    if "threat_actor" in update_data:
        db_node.threat_actor = crud.read_by_value(
            value=update_data["threat_actor"], db_table=NodeThreatActor, db=db)

    if "threats" in update_data:
        db_node.threats = crud.read_by_values(values=update_data["threats"],
                                              db_table=NodeThreat,
                                              db=db)

    # Update the node version
    db_node.version = uuid4()

    return db_node
Пример #9
0
        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")

# Commit all of the changes
crud.commit(db)
Пример #10
0
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)
Пример #11
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)
Пример #12
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)