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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
# 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)
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)