Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s
951 lines
29 KiB
Python
951 lines
29 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# IRIS Source Code
|
|
# Copyright (C) 2021 - Airbus CyberSecurity (SAS)
|
|
# ir@cyberactionlab.net
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 3 of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
import datetime
|
|
|
|
# IMPORTS ------------------------------------------------
|
|
import enum
|
|
import uuid
|
|
|
|
from sqlalchemy import BigInteger, UniqueConstraint, Table
|
|
from sqlalchemy import Boolean
|
|
from sqlalchemy import Column
|
|
from sqlalchemy import DateTime
|
|
from sqlalchemy import ForeignKey
|
|
from sqlalchemy import Integer
|
|
from sqlalchemy import LargeBinary
|
|
from sqlalchemy import Sequence
|
|
from sqlalchemy import String
|
|
from sqlalchemy import TIMESTAMP
|
|
from sqlalchemy import Text
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy import text
|
|
from sqlalchemy.dialects.postgresql import JSON, JSONB
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.orm import sessionmaker
|
|
from sqlalchemy.sql import func
|
|
|
|
from app import app
|
|
from app import db
|
|
|
|
Base = declarative_base()
|
|
metadata = Base.metadata
|
|
|
|
|
|
class CaseStatus(enum.Enum):
|
|
unknown = 0x0
|
|
false_positive = 0x1
|
|
true_positive_with_impact = 0x2
|
|
not_applicable = 0x3
|
|
true_positive_without_impact = 0x4
|
|
|
|
|
|
class ReviewStatusList:
|
|
no_review_required = "No review required"
|
|
not_reviewed = "Not reviewed"
|
|
pending_review = "Pending review"
|
|
review_in_progress = "Review in progress"
|
|
reviewed = "Reviewed"
|
|
|
|
|
|
class CompromiseStatus(enum.Enum):
|
|
to_be_determined = 0x0
|
|
compromised = 0x1
|
|
not_compromised = 0x2
|
|
unknown = 0x3
|
|
|
|
@classmethod
|
|
def has_value(cls, value):
|
|
return value in cls._value2member_map_
|
|
|
|
|
|
def create_safe(session, model, **kwargs):
|
|
instance = session.query(model).filter_by(**kwargs).first()
|
|
if instance:
|
|
return False
|
|
else:
|
|
instance = model(**kwargs)
|
|
session.add(instance)
|
|
session.commit()
|
|
return True
|
|
|
|
|
|
def create_safe_limited(session, model, keywords_list, **kwargs):
|
|
kwdup = kwargs.keys()
|
|
for kw in list(kwdup):
|
|
if kw not in keywords_list:
|
|
kwargs.pop(kw)
|
|
|
|
instance = session.query(model).filter_by(**kwargs).first()
|
|
if instance:
|
|
return False
|
|
else:
|
|
instance = model(**kwargs)
|
|
session.add(instance)
|
|
session.commit()
|
|
return True
|
|
|
|
|
|
def get_by_value_or_create(session, model, fieldname, **kwargs):
|
|
select_value = {fieldname: kwargs.get(fieldname)}
|
|
instance = session.query(model).filter_by(**select_value).first()
|
|
if instance:
|
|
return instance
|
|
else:
|
|
instance = model(**kwargs)
|
|
session.add(instance)
|
|
session.commit()
|
|
return instance
|
|
|
|
|
|
def get_or_create(session, model, **kwargs):
|
|
instance = session.query(model).filter_by(**kwargs).first()
|
|
if instance:
|
|
return instance
|
|
else:
|
|
instance = model(**kwargs)
|
|
session.add(instance)
|
|
session.commit()
|
|
return instance
|
|
|
|
|
|
# CONTENT ------------------------------------------------
|
|
class Client(db.Model):
|
|
__tablename__ = 'client'
|
|
|
|
client_id = Column(BigInteger, primary_key=True)
|
|
client_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
|
|
name = Column(Text, unique=True)
|
|
description = Column(Text)
|
|
sla = Column(Text)
|
|
creation_date = Column(DateTime, server_default=func.now(), nullable=True)
|
|
created_by = Column(ForeignKey('user.id'), nullable=True)
|
|
last_update_date = Column(DateTime, server_default=func.now(), nullable=True)
|
|
|
|
custom_attributes = Column(JSON)
|
|
|
|
|
|
class AssetsType(db.Model):
|
|
__tablename__ = 'assets_type'
|
|
|
|
asset_id = Column(Integer, primary_key=True)
|
|
asset_name = Column(String(155))
|
|
asset_description = Column(String(255))
|
|
asset_icon_not_compromised = Column(String(255))
|
|
asset_icon_compromised = Column(String(255))
|
|
|
|
|
|
alert_assets_association = Table(
|
|
'alert_assets_association',
|
|
db.Model.metadata,
|
|
Column('alert_id', ForeignKey('alerts.alert_id'), primary_key=True),
|
|
Column('asset_id', ForeignKey('case_assets.asset_id'), primary_key=True)
|
|
)
|
|
|
|
|
|
alert_iocs_association = Table(
|
|
'alert_iocs_association',
|
|
db.Model.metadata,
|
|
Column('alert_id', ForeignKey('alerts.alert_id'), primary_key=True),
|
|
Column('ioc_id', ForeignKey('ioc.ioc_id'), primary_key=True)
|
|
)
|
|
|
|
|
|
class CaseAssets(db.Model):
|
|
__tablename__ = 'case_assets'
|
|
|
|
asset_id = Column(BigInteger, primary_key=True)
|
|
asset_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
|
|
asset_name = Column(Text)
|
|
asset_description = Column(Text)
|
|
asset_domain = Column(Text)
|
|
asset_ip = Column(Text)
|
|
asset_info = Column(Text)
|
|
asset_compromise_status_id = Column(Integer, nullable=True)
|
|
asset_type_id = Column(ForeignKey('assets_type.asset_id'))
|
|
asset_tags = Column(Text)
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
date_added = Column(DateTime)
|
|
date_update = Column(DateTime)
|
|
user_id = Column(ForeignKey('user.id'))
|
|
analysis_status_id = Column(ForeignKey('analysis_status.id'))
|
|
custom_attributes = Column(JSON)
|
|
asset_enrichment = Column(JSONB)
|
|
|
|
case = relationship('Cases')
|
|
user = relationship('User')
|
|
asset_type = relationship('AssetsType')
|
|
analysis_status = relationship('AnalysisStatus')
|
|
|
|
alerts = relationship('Alert', secondary=alert_assets_association, back_populates='assets')
|
|
|
|
|
|
class AnalysisStatus(db.Model):
|
|
__tablename__ = 'analysis_status'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(Text)
|
|
|
|
|
|
class CaseClassification(db.Model):
|
|
__tablename__ = 'case_classification'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(Text)
|
|
name_expanded = Column(Text)
|
|
description = Column(Text)
|
|
creation_date = Column(DateTime, server_default=func.now(), nullable=True)
|
|
created_by_id = Column(ForeignKey('user.id'), nullable=True)
|
|
|
|
created_by = relationship('User')
|
|
|
|
|
|
class CaseTemplate(db.Model):
|
|
__tablename__ = 'case_template'
|
|
|
|
# Metadata
|
|
id = Column(Integer, primary_key=True)
|
|
created_by_user_id = Column(Integer, db.ForeignKey('user.id'))
|
|
created_at = Column(DateTime, server_default=func.now())
|
|
updated_at = Column(DateTime, onupdate=func.now())
|
|
# Data
|
|
name = Column(String, nullable=False)
|
|
display_name = Column(String, nullable=True)
|
|
description = Column(Text, nullable=True)
|
|
author = Column(String, nullable=True)
|
|
title_prefix = Column(String, nullable=True)
|
|
summary = Column(String, nullable=True)
|
|
tags = Column(JSON, nullable=True)
|
|
tasks = Column(JSON, nullable=True)
|
|
note_groups = Column(JSON, nullable=True)
|
|
classification = Column(String, nullable=True)
|
|
|
|
created_by_user = relationship('User')
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(**kwargs)
|
|
|
|
def update_from_dict(self, data: dict):
|
|
for field, value in data.items():
|
|
setattr(self, field, value)
|
|
|
|
|
|
class Contact(db.Model):
|
|
__tablename__ = 'contact'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
contact_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
|
|
contact_name = Column(Text)
|
|
contact_email = Column(Text)
|
|
contact_role = Column(Text)
|
|
contact_note = Column(Text)
|
|
contact_work_phone = Column(Text)
|
|
contact_mobile_phone = Column(Text)
|
|
custom_attributes = Column(JSON)
|
|
client_id = Column(ForeignKey('client.client_id'))
|
|
|
|
client = relationship('Client')
|
|
|
|
|
|
class CaseEventsAssets(db.Model):
|
|
__tablename__ = 'case_events_assets'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
event_id = Column(ForeignKey('cases_events.event_id'))
|
|
asset_id = Column(ForeignKey('case_assets.asset_id'))
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
|
|
event = relationship('CasesEvent')
|
|
asset = relationship('CaseAssets')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class CaseEventsIoc(db.Model):
|
|
__tablename__ = 'case_events_ioc'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
event_id = Column(ForeignKey('cases_events.event_id'))
|
|
ioc_id = Column(ForeignKey('ioc.ioc_id'))
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
|
|
event = relationship('CasesEvent')
|
|
ioc = relationship('Ioc')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class ObjectState(db.Model):
|
|
__tablename__ = 'object_state'
|
|
|
|
object_id = Column(BigInteger, primary_key=True)
|
|
object_case_id = Column(ForeignKey('cases.case_id'))
|
|
object_updated_by_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
|
|
object_name = Column(Text)
|
|
object_state = Column(BigInteger)
|
|
object_last_update = Column(TIMESTAMP)
|
|
|
|
case = relationship('Cases')
|
|
updated_by = relationship('User')
|
|
|
|
|
|
class EventCategory(db.Model):
|
|
__tablename__ = 'event_category'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
name = Column(Text)
|
|
|
|
|
|
class CaseEventCategory(db.Model):
|
|
__tablename__ = 'case_events_category'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
event_id = Column(ForeignKey('cases_events.event_id'), unique=True)
|
|
category_id = Column(ForeignKey('event_category.id'))
|
|
|
|
event = relationship('CasesEvent', cascade="delete")
|
|
category = relationship('EventCategory')
|
|
|
|
|
|
class CaseGraphAssets(db.Model):
|
|
__tablename__ = 'case_graph_assets'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
asset_id = Column(Integer)
|
|
asset_type_id = Column(ForeignKey('assets_type.asset_id'))
|
|
|
|
case = relationship('Cases')
|
|
asset_type = relationship('AssetsType')
|
|
|
|
|
|
class CaseGraphLinks(db.Model):
|
|
__tablename__ = 'case_graph_links'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
source_id = Column(ForeignKey('case_graph_assets.id'))
|
|
dest_id = Column(ForeignKey('case_graph_assets.id'))
|
|
|
|
case = relationship('Cases')
|
|
|
|
|
|
class Languages(db.Model):
|
|
__tablename__ = 'languages'
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
name = db.Column(db.String(), unique=True)
|
|
code = db.Column(db.String(), unique=True)
|
|
|
|
|
|
class ReportType(db.Model):
|
|
__tablename__ = 'report_type'
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
name = db.Column(db.Text(), unique=True)
|
|
|
|
|
|
class CaseTemplateReport(db.Model):
|
|
__tablename__ = 'case_template_report'
|
|
|
|
id = db.Column(db.Integer(), primary_key=True)
|
|
name = db.Column(db.String())
|
|
description = db.Column(db.String())
|
|
internal_reference = db.Column(db.String(), unique=True)
|
|
naming_format = db.Column(db.String())
|
|
created_by_user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
|
|
date_created = db.Column(DateTime)
|
|
language_id = db.Column(db.Integer(), db.ForeignKey('languages.id'))
|
|
report_type_id = db.Column(db.Integer(), db.ForeignKey('report_type.id'))
|
|
|
|
report_type = relationship('ReportType')
|
|
language = relationship('Languages')
|
|
created_by_user = relationship('User')
|
|
|
|
|
|
class Tlp(db.Model):
|
|
__tablename__ = 'tlp'
|
|
|
|
tlp_id = Column(Integer, primary_key=True)
|
|
tlp_name = Column(Text)
|
|
tlp_bscolor = Column(Text)
|
|
|
|
|
|
class Ioc(db.Model):
|
|
__tablename__ = 'ioc'
|
|
|
|
ioc_id = Column(BigInteger, primary_key=True)
|
|
ioc_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
|
|
ioc_value = Column(Text)
|
|
ioc_type_id = Column(ForeignKey('ioc_type.type_id'))
|
|
ioc_description = Column(Text)
|
|
ioc_tags = Column(String(512))
|
|
user_id = Column(ForeignKey('user.id'))
|
|
ioc_misp = Column(Text)
|
|
ioc_tlp_id = Column(ForeignKey('tlp.tlp_id'))
|
|
custom_attributes = Column(JSON)
|
|
ioc_enrichment = Column(JSONB)
|
|
|
|
user = relationship('User')
|
|
tlp = relationship('Tlp')
|
|
ioc_type = relationship('IocType')
|
|
|
|
alerts = relationship('Alert', secondary=alert_iocs_association, back_populates='iocs')
|
|
|
|
|
|
class CustomAttribute(db.Model):
|
|
__tablename__ = 'custom_attribute'
|
|
|
|
attribute_id = Column(Integer, primary_key=True)
|
|
attribute_display_name = Column(Text)
|
|
attribute_description = Column(Text)
|
|
attribute_for = Column(Text)
|
|
attribute_content = Column(JSON)
|
|
|
|
|
|
class DataStorePath(db.Model):
|
|
__tablename__ = 'data_store_path'
|
|
|
|
path_id = Column(BigInteger, primary_key=True)
|
|
path_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4)
|
|
path_name = Column(Text, nullable=False)
|
|
path_parent_id = Column(BigInteger)
|
|
path_is_root = Column(Boolean)
|
|
path_case_id = Column(ForeignKey('cases.case_id'), nullable=False)
|
|
|
|
case = relationship('Cases')
|
|
|
|
|
|
class DataStoreFile(db.Model):
|
|
__tablename__ = 'data_store_file'
|
|
|
|
file_id = Column(BigInteger, primary_key=True)
|
|
file_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
|
|
file_original_name = Column(Text, nullable=False)
|
|
file_local_name = Column(Text, nullable=False)
|
|
file_description = Column(Text)
|
|
file_date_added = Column(DateTime)
|
|
file_tags = Column(Text)
|
|
file_size = Column(BigInteger)
|
|
file_is_ioc = Column(Boolean)
|
|
file_is_evidence = Column(Boolean)
|
|
file_password = Column(Text)
|
|
file_parent_id = Column(ForeignKey('data_store_path.path_id'), nullable=False)
|
|
file_sha256 = Column(Text)
|
|
added_by_user_id = Column(ForeignKey('user.id'), nullable=False)
|
|
modification_history = Column(JSON)
|
|
file_case_id = Column(ForeignKey('cases.case_id'), nullable=False)
|
|
|
|
case = relationship('Cases')
|
|
user = relationship('User')
|
|
data_parent = relationship('DataStorePath')
|
|
|
|
|
|
class IocType(db.Model):
|
|
__tablename__ = 'ioc_type'
|
|
|
|
type_id = Column(Integer, primary_key=True)
|
|
type_name = Column(Text)
|
|
type_description = Column(Text)
|
|
type_taxonomy = Column(Text)
|
|
type_validation_regex = Column(Text)
|
|
type_validation_expect = Column(Text)
|
|
|
|
|
|
class IocLink(db.Model):
|
|
__tablename__ = 'ioc_link'
|
|
|
|
ioc_link_id = Column(Integer, primary_key=True)
|
|
ioc_id = Column(ForeignKey('ioc.ioc_id'))
|
|
case_id = Column(ForeignKey('cases.case_id'), nullable=False)
|
|
|
|
ioc = relationship('Ioc')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class IocAssetLink(db.Model):
|
|
__tablename__ = 'ioc_asset_link'
|
|
|
|
ioc_asset_link_id = Column(Integer, primary_key=True)
|
|
ioc_id = Column(ForeignKey('ioc.ioc_id'), nullable=False)
|
|
asset_id = Column(ForeignKey('case_assets.asset_id'), nullable=False)
|
|
|
|
ioc = relationship('Ioc')
|
|
asset = relationship('CaseAssets')
|
|
|
|
|
|
class OsType(db.Model):
|
|
__tablename__ = 'os_type'
|
|
|
|
type_id = Column(Integer, primary_key=True)
|
|
type_name = Column(String(155))
|
|
|
|
|
|
class CasesAssetsExt(db.Model):
|
|
__tablename__ = 'cases_assets_ext'
|
|
|
|
asset_id = Column(Integer, primary_key=True)
|
|
type_id = Column(ForeignKey('assets_type.asset_id'))
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
asset_content = Column(Text)
|
|
|
|
type = relationship('AssetsType')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class Notes(db.Model):
|
|
__tablename__ = 'notes'
|
|
|
|
note_id = Column(BigInteger, primary_key=True)
|
|
note_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
|
|
note_title = Column(String(155))
|
|
note_content = Column(Text)
|
|
note_user = Column(ForeignKey('user.id'))
|
|
note_creationdate = Column(DateTime)
|
|
note_lastupdate = Column(DateTime)
|
|
note_case_id = Column(ForeignKey('cases.case_id'))
|
|
custom_attributes = Column(JSON)
|
|
|
|
user = relationship('User')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class NotesGroup(db.Model):
|
|
__tablename__ = 'notes_group'
|
|
|
|
group_id = Column(BigInteger, primary_key=True)
|
|
group_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
|
|
nullable=False)
|
|
group_title = Column(String(155))
|
|
group_user = Column(ForeignKey('user.id'))
|
|
group_creationdate = Column(DateTime)
|
|
group_lastupdate = Column(DateTime)
|
|
group_case_id = Column(ForeignKey('cases.case_id'))
|
|
|
|
user = relationship('User')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class NotesGroupLink(db.Model):
|
|
__tablename__ = 'notes_group_link'
|
|
|
|
link_id = Column(BigInteger, primary_key=True)
|
|
group_id = Column(ForeignKey('notes_group.group_id'))
|
|
note_id = Column(ForeignKey('notes.note_id'))
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
|
|
note = relationship('Notes')
|
|
note_group = relationship('NotesGroup')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class CaseKanban(db.Model):
|
|
__tablename__ = 'case_kanban'
|
|
|
|
case_id = Column(ForeignKey('cases.case_id'), primary_key=True)
|
|
kanban_data = Column(Text)
|
|
|
|
case = relationship('Cases')
|
|
|
|
|
|
class CaseReceivedFile(db.Model):
|
|
__tablename__ = 'case_received_file'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
file_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
|
|
filename = Column(Text)
|
|
date_added = Column(DateTime)
|
|
file_hash = Column(String(65))
|
|
file_description = Column(Text)
|
|
file_size = Column(BigInteger)
|
|
case_id = Column(ForeignKey('cases.case_id'))
|
|
user_id = Column(ForeignKey('user.id'))
|
|
custom_attributes = Column(JSON)
|
|
|
|
case = relationship('Cases')
|
|
user = relationship('User')
|
|
|
|
|
|
class TaskStatus(db.Model):
|
|
__tablename__ = 'task_status'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
status_name = Column(Text)
|
|
status_description = Column(Text)
|
|
status_bscolor = Column(Text)
|
|
|
|
|
|
class CaseTasks(db.Model):
|
|
__tablename__ = 'case_tasks'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
task_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
|
|
task_title = Column(Text)
|
|
task_description = Column(Text)
|
|
task_tags = Column(Text)
|
|
task_open_date = Column(DateTime)
|
|
task_close_date = Column(DateTime)
|
|
task_last_update = Column(DateTime)
|
|
task_userid_open = Column(ForeignKey('user.id'))
|
|
task_userid_close = Column(ForeignKey('user.id'))
|
|
task_userid_update = Column(ForeignKey('user.id'))
|
|
task_status_id = Column(ForeignKey('task_status.id'))
|
|
task_case_id = Column(ForeignKey('cases.case_id'))
|
|
custom_attributes = Column(JSON)
|
|
|
|
case = relationship('Cases')
|
|
user_open = relationship('User', foreign_keys=[task_userid_open])
|
|
user_close = relationship('User', foreign_keys=[task_userid_close])
|
|
user_update = relationship('User', foreign_keys=[task_userid_update])
|
|
status = relationship('TaskStatus', foreign_keys=[task_status_id])
|
|
|
|
|
|
class Tags(db.Model):
|
|
__tablename__ = 'tags'
|
|
|
|
id = Column(BigInteger, primary_key=True, nullable=False)
|
|
tag_title = Column(Text, unique=True)
|
|
tag_creation_date = Column(DateTime)
|
|
|
|
cases = relationship('Cases', secondary="case_tags", back_populates='tags', viewonly=True)
|
|
|
|
def __init__(self, tag_title):
|
|
self.id = None
|
|
self.tag_title = tag_title
|
|
self.tag_creation_date = datetime.datetime.now()
|
|
|
|
def save(self):
|
|
existing_tag = self.get_by_title(self.tag_title)
|
|
if existing_tag is not None:
|
|
return existing_tag
|
|
else:
|
|
db.session.add(self)
|
|
db.session.commit()
|
|
return self
|
|
|
|
@classmethod
|
|
def get_by_title(cls, tag_title):
|
|
return cls.query.filter_by(tag_title=tag_title).first()
|
|
|
|
|
|
class TaskAssignee(db.Model):
|
|
__tablename__ = "task_assignee"
|
|
|
|
id = Column(BigInteger, primary_key=True, nullable=False)
|
|
user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
|
|
task_id = Column(BigInteger, ForeignKey('case_tasks.id'), nullable=False)
|
|
|
|
user = relationship('User')
|
|
task = relationship('CaseTasks')
|
|
|
|
UniqueConstraint('user_id', 'task_id')
|
|
|
|
|
|
class GlobalTasks(db.Model):
|
|
__tablename__ = 'global_tasks'
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
task_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
|
|
task_title = Column(Text)
|
|
task_description = Column(Text)
|
|
task_tags = Column(Text)
|
|
task_open_date = Column(DateTime)
|
|
task_close_date = Column(DateTime)
|
|
task_last_update = Column(DateTime)
|
|
task_userid_open = Column(ForeignKey('user.id'))
|
|
task_userid_close = Column(ForeignKey('user.id'))
|
|
task_userid_update = Column(ForeignKey('user.id'))
|
|
task_assignee_id = Column(ForeignKey('user.id'), nullable=True)
|
|
task_status_id = Column(ForeignKey('task_status.id'))
|
|
|
|
user_open = relationship('User', foreign_keys=[task_userid_open])
|
|
user_close = relationship('User', foreign_keys=[task_userid_close])
|
|
user_update = relationship('User', foreign_keys=[task_userid_update])
|
|
user_assigned = relationship('User', foreign_keys=[task_assignee_id])
|
|
status = relationship('TaskStatus', foreign_keys=[task_status_id])
|
|
|
|
|
|
class UserActivity(db.Model):
|
|
__tablename__ = "user_activity"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
user_id = Column(ForeignKey('user.id'), nullable=True)
|
|
case_id = Column(ForeignKey('cases.case_id'), nullable=True)
|
|
activity_date = Column(DateTime)
|
|
activity_desc = Column(Text)
|
|
user_input = Column(Boolean, default=False)
|
|
is_from_api = Column(Boolean, default=False)
|
|
display_in_ui = Column(Boolean, default=True)
|
|
|
|
user = relationship('User')
|
|
case = relationship('Cases')
|
|
|
|
|
|
class ServerSettings(db.Model):
|
|
__table_name__ = "server_settings"
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
https_proxy = Column(Text)
|
|
http_proxy = Column(Text)
|
|
prevent_post_mod_repush = Column(Boolean)
|
|
prevent_post_objects_repush = Column(Boolean, default=False)
|
|
has_updates_available = Column(Boolean)
|
|
enable_updates_check = Column(Boolean)
|
|
password_policy_min_length = Column(Integer)
|
|
password_policy_upper_case = Column(Boolean)
|
|
password_policy_lower_case = Column(Boolean)
|
|
password_policy_digit = Column(Boolean)
|
|
password_policy_special_chars = Column(Text)
|
|
|
|
|
|
class Comments(db.Model):
|
|
__tablename__ = "comments"
|
|
|
|
comment_id = Column(BigInteger, primary_key=True)
|
|
comment_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
|
|
nullable=False)
|
|
comment_text = Column(Text)
|
|
comment_date = Column(DateTime)
|
|
comment_update_date = Column(DateTime)
|
|
comment_user_id = Column(ForeignKey('user.id'))
|
|
comment_case_id = Column(ForeignKey('cases.case_id'))
|
|
comment_alert_id = Column(ForeignKey('alerts.alert_id'))
|
|
|
|
user = relationship('User')
|
|
case = relationship('Cases')
|
|
alert = relationship('Alert')
|
|
|
|
|
|
class EventComments(db.Model):
|
|
__tablename__ = "event_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_event_id = Column(ForeignKey('cases_events.event_id'))
|
|
|
|
event = relationship('CasesEvent')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class TaskComments(db.Model):
|
|
__tablename__ = "task_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_task_id = Column(ForeignKey('case_tasks.id'))
|
|
|
|
task = relationship('CaseTasks')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class IocComments(db.Model):
|
|
__tablename__ = "ioc_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_ioc_id = Column(ForeignKey('ioc.ioc_id'))
|
|
|
|
ioc = relationship('Ioc')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class AssetComments(db.Model):
|
|
__tablename__ = "asset_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_asset_id = Column(ForeignKey('case_assets.asset_id'))
|
|
|
|
asset = relationship('CaseAssets')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class EvidencesComments(db.Model):
|
|
__tablename__ = "evidence_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_evidence_id = Column(ForeignKey('case_received_file.id'))
|
|
|
|
evidence = relationship('CaseReceivedFile')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class NotesComments(db.Model):
|
|
__tablename__ = "note_comments"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
comment_id = Column(ForeignKey('comments.comment_id'))
|
|
comment_note_id = Column(ForeignKey('notes.note_id'))
|
|
|
|
note = relationship('Notes')
|
|
comment = relationship('Comments')
|
|
|
|
|
|
class IrisModule(db.Model):
|
|
__tablename__ = "iris_module"
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
added_by_id = Column(ForeignKey('user.id'), nullable=False)
|
|
module_human_name = Column(Text)
|
|
module_name = Column(Text)
|
|
module_description = Column(Text)
|
|
module_version = Column(Text)
|
|
interface_version = Column(Text)
|
|
date_added = Column(DateTime)
|
|
is_active = Column(Boolean)
|
|
has_pipeline = Column(Boolean)
|
|
pipeline_args = Column(JSON)
|
|
module_config = Column(JSON)
|
|
module_type = Column(Text)
|
|
|
|
user = relationship('User')
|
|
|
|
|
|
class IrisHook(db.Model):
|
|
__tablename__ = "iris_hooks"
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
hook_name = Column(Text)
|
|
hook_description = Column(Text)
|
|
|
|
|
|
class IrisModuleHook(db.Model):
|
|
__tablename__ = "iris_module_hooks"
|
|
|
|
id = Column(BigInteger, primary_key=True)
|
|
module_id = Column(ForeignKey('iris_module.id'), nullable=False)
|
|
hook_id = Column(ForeignKey('iris_hooks.id'), nullable=False)
|
|
is_manual_hook = Column(Boolean)
|
|
manual_hook_ui_name = Column(Text)
|
|
retry_on_fail = Column(Boolean)
|
|
max_retry = Column(Integer)
|
|
run_asynchronously = Column(Boolean)
|
|
wait_till_return = Column(Boolean)
|
|
|
|
module = relationship('IrisModule')
|
|
hook = relationship('IrisHook')
|
|
|
|
|
|
class IrisReport(db.Model):
|
|
__tablename__ = 'iris_reports'
|
|
|
|
report_id = Column(db.Integer, Sequence("iris_reports_id_seq"), primary_key=True)
|
|
case_id = Column(ForeignKey('cases.case_id'), nullable=False)
|
|
report_title = Column(String(155))
|
|
report_date = Column(DateTime)
|
|
report_content = Column('report_content', JSON)
|
|
user_id = Column(ForeignKey('user.id'))
|
|
|
|
user = relationship('User')
|
|
case = relationship('Cases')
|
|
|
|
def __init__(self, case_id, report_title, report_date, report_content, user_id):
|
|
self.case_id = case_id
|
|
self.report_title = report_title
|
|
self.report_date = report_date
|
|
self.report_content = report_content
|
|
self.user_id = user_id
|
|
|
|
def save(self):
|
|
# Create an engine and a session because this method
|
|
# will be called from Celery thread and might cause
|
|
# error if it uses the session context of the app
|
|
engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
|
|
Session = sessionmaker(bind=engine)
|
|
session = Session()
|
|
|
|
# inject self into db session
|
|
session.add(self)
|
|
|
|
# commit change and save the object
|
|
session.commit()
|
|
|
|
# Close session
|
|
session.close()
|
|
|
|
# Dispose engine
|
|
engine.dispose()
|
|
|
|
return self
|
|
|
|
|
|
class SavedFilter(db.Model):
|
|
__tablename__ = 'saved_filters'
|
|
|
|
filter_id = Column(BigInteger, primary_key=True)
|
|
created_by = Column(ForeignKey('user.id'), nullable=False)
|
|
filter_name = Column(Text, nullable=False)
|
|
filter_description = Column(Text)
|
|
filter_data = Column(JSON, nullable=False)
|
|
filter_is_private = Column(Boolean, nullable=False)
|
|
filter_type = Column(Text, nullable=False)
|
|
|
|
user = relationship('User', foreign_keys=[created_by])
|
|
|
|
|
|
class ReviewStatus(db.Model):
|
|
__tablename__ = 'review_status'
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
status_name = Column(Text, nullable=False)
|
|
|
|
|
|
class CeleryTaskMeta(db.Model):
|
|
__bind_key__ = 'iris_tasks'
|
|
__tablename__ = 'celery_taskmeta'
|
|
|
|
id = Column(BigInteger, Sequence('task_id_sequence'), primary_key=True)
|
|
task_id = Column(String(155))
|
|
status = Column(String(50))
|
|
result = Column(LargeBinary)
|
|
date_done = Column(DateTime)
|
|
traceback = Column(Text)
|
|
name = Column(String(155))
|
|
args = Column(LargeBinary)
|
|
kwargs = Column(LargeBinary)
|
|
worker = Column(String(155))
|
|
retries = Column(Integer)
|
|
queue = Column(String(155))
|
|
|
|
def __repr__(self):
|
|
return str(self.id) + ' - ' + str(self.user)
|
|
|
|
|
|
def create_safe_attr(session, attribute_display_name, attribute_description, attribute_for, attribute_content):
|
|
cat = CustomAttribute.query.filter(
|
|
CustomAttribute.attribute_display_name == attribute_display_name,
|
|
CustomAttribute.attribute_description == attribute_description,
|
|
CustomAttribute.attribute_for == attribute_for
|
|
).first()
|
|
|
|
if cat:
|
|
return False
|
|
else:
|
|
instance = CustomAttribute()
|
|
instance.attribute_display_name = attribute_display_name
|
|
instance.attribute_description = attribute_description
|
|
instance.attribute_for = attribute_for
|
|
instance.attribute_content = attribute_content
|
|
session.add(instance)
|
|
session.commit()
|
|
return True
|
|
|
|
|