first sync
Some checks failed
Deployment Verification / deploy-and-test (push) Failing after 29s

This commit is contained in:
2025-03-04 07:59:21 +01:00
parent 9cdcf486b6
commit 506716e703
1450 changed files with 577316 additions and 62 deletions

View File

@ -0,0 +1,6 @@
from app.models.models import ObjectState
from app.models.cases import Cases
from app.models.cases import CasesEvent
from app.models.cases import Client
from app.models.models import *

View File

@ -0,0 +1,116 @@
from datetime import datetime
import uuid
from sqlalchemy.dialects.postgresql import JSON
from sqlalchemy import BigInteger, Table, Boolean
from sqlalchemy import Column
from sqlalchemy import DateTime
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import Text
from sqlalchemy import text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship, backref
from app import db
from app.models import Base, alert_assets_association, alert_iocs_association
from app.models.cases import Cases
class AlertCaseAssociation(db.Model):
__tablename__ = 'alert_case_association'
alert_id = Column(ForeignKey('alerts.alert_id'), primary_key=True, nullable=False)
case_id = Column(ForeignKey('cases.case_id'), primary_key=True, nullable=False, index=True)
class Alert(db.Model):
__tablename__ = 'alerts'
alert_id = Column(BigInteger, primary_key=True)
alert_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, nullable=False,
server_default=text('gen_random_uuid()'), unique=True)
alert_title = Column(Text, nullable=False)
alert_description = Column(Text)
alert_source = Column(Text)
alert_source_ref = Column(Text)
alert_source_link = Column(Text)
alert_source_content = Column(JSON)
alert_severity_id = Column(ForeignKey('severities.severity_id'), nullable=False)
alert_status_id = Column(ForeignKey('alert_status.status_id'), nullable=False)
alert_context = Column(JSON)
alert_source_event_time = Column(DateTime, nullable=False, server_default=text("now()"))
alert_creation_time = Column(DateTime, nullable=False, server_default=text("now()"))
alert_note = Column(Text)
alert_tags = Column(Text)
alert_owner_id = Column(ForeignKey('user.id'))
modification_history = Column(JSON)
alert_customer_id = Column(ForeignKey('client.client_id'), nullable=False)
alert_classification_id = Column(ForeignKey('case_classification.id'))
alert_resolution_status_id = Column(ForeignKey('alert_resolution_status.resolution_status_id'), nullable=True)
owner = relationship('User', foreign_keys=[alert_owner_id])
severity = relationship('Severity')
status = relationship('AlertStatus')
customer = relationship('Client')
classification = relationship('CaseClassification')
resolution_status = relationship('AlertResolutionStatus')
cases = relationship('Cases', secondary="alert_case_association", back_populates='alerts')
comments = relationship('Comments', back_populates='alert', cascade='all, delete-orphan')
assets = relationship('CaseAssets', secondary=alert_assets_association, back_populates='alerts')
iocs = relationship('Ioc', secondary=alert_iocs_association, back_populates='alerts')
class Severity(db.Model):
__tablename__ = 'severities'
severity_id = Column(Integer, primary_key=True)
severity_name = Column(Text, nullable=False, unique=True)
severity_description = Column(Text)
class AlertStatus(db.Model):
__tablename__ = 'alert_status'
status_id = Column(Integer, primary_key=True)
status_name = Column(Text, nullable=False, unique=True)
status_description = Column(Text)
class AlertResolutionStatus(db.Model):
__tablename__ = 'alert_resolution_status'
resolution_status_id = Column(Integer, primary_key=True)
resolution_status_name = Column(Text, nullable=False, unique=True)
resolution_status_description = Column(Text)
class SimilarAlertsCache(db.Model):
__tablename__ = 'similar_alerts_cache'
id = Column(BigInteger, primary_key=True)
customer_id = Column(BigInteger, ForeignKey('client.client_id'), nullable=False)
asset_name = Column(Text, nullable=True)
ioc_value = Column(Text, nullable=True)
alert_id = Column(BigInteger, ForeignKey('alerts.alert_id'), nullable=False)
created_at = Column(DateTime, nullable=False, server_default=text("now()"))
asset_type_id = Column(Integer, ForeignKey('assets_type.asset_id'), nullable=True)
ioc_type_id = Column(Integer, ForeignKey('ioc_type.type_id'), nullable=True)
alert = relationship('Alert')
customer = relationship('Client')
asset_type = relationship('AssetsType')
ioc_type = relationship('IocType')
def __init__(self, customer_id, alert_id, asset_name=None, ioc_value=None, asset_type_id=None, ioc_type_id=None,
created_at=None):
self.customer_id = customer_id
self.asset_name = asset_name
self.ioc_value = ioc_value
self.alert_id = alert_id
self.asset_type_id = asset_type_id
self.ioc_type_id = ioc_type_id
self.created_at = created_at if created_at else datetime.utcnow()

View File

@ -0,0 +1,207 @@
import enum
import secrets
import uuid
from flask_login import UserMixin
from sqlalchemy import BigInteger
from sqlalchemy import Boolean
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import Text
from sqlalchemy import UniqueConstraint
from sqlalchemy import text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from app import db
class CaseAccessLevel(enum.Enum):
deny_all = 0x1
read_only = 0x2
full_access = 0x4
@classmethod
def has_value(cls, value):
return value in cls._value2member_map_
class Permissions(enum.Enum):
standard_user = 0x1
server_administrator = 0x2
alerts_read = 0x4
alerts_write = 0x8
alerts_delete = 0x10
search_across_cases = 0x20
customers_read = 0x40
customers_write = 0x80
case_templates_read = 0x100
case_templates_write = 0x200
activities_read = 0x400
all_activities_read = 0x800
class Organisation(db.Model):
__tablename__ = 'organisations'
org_id = Column(BigInteger, primary_key=True)
org_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, nullable=False,
server_default=text('gen_random_uuid()'), unique=True)
org_name = Column(Text, nullable=False, unique=True)
org_description = Column(Text)
org_url = Column(Text)
org_logo = Column(Text)
org_email = Column(Text)
org_nationality = Column(Text)
org_sector = Column(Text)
org_type = Column(Text)
UniqueConstraint('org_name')
class OrganisationCaseAccess(db.Model):
__tablename__ = "organisation_case_access"
id = Column(BigInteger, primary_key=True)
org_id = Column(BigInteger, ForeignKey('organisations.org_id'), nullable=False)
case_id = Column(BigInteger, ForeignKey('cases.case_id'), nullable=False)
access_level = Column(BigInteger, nullable=False)
org = relationship('Organisation')
case = relationship('Cases')
UniqueConstraint('case_id', 'org_id')
class Group(db.Model):
__tablename__ = 'groups'
group_id = Column(BigInteger, primary_key=True)
group_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, nullable=False,
server_default=text('gen_random_uuid()'), unique=True)
group_name = Column(Text, nullable=False, unique=True)
group_description = Column(Text)
group_permissions = Column(BigInteger, nullable=False)
group_auto_follow = Column(Boolean, nullable=False, default=False)
group_auto_follow_access_level = Column(BigInteger, nullable=False, default=0)
UniqueConstraint('group_name')
class GroupCaseAccess(db.Model):
__tablename__ = "group_case_access"
id = Column(BigInteger, primary_key=True)
group_id = Column(BigInteger, ForeignKey('groups.group_id'), nullable=False)
case_id = Column(BigInteger, ForeignKey('cases.case_id'), nullable=False)
access_level = Column(BigInteger, nullable=False)
group = relationship('Group')
case = relationship('Cases')
UniqueConstraint('case_id', 'group_id')
class UserCaseAccess(db.Model):
__tablename__ = "user_case_access"
id = Column(BigInteger, primary_key=True, nullable=False)
user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
case_id = Column(BigInteger, ForeignKey('cases.case_id'), nullable=False)
access_level = Column(BigInteger, nullable=False)
user = relationship('User')
case = relationship('Cases')
UniqueConstraint('case_id', 'user_id')
class UserCaseEffectiveAccess(db.Model):
__tablename__ = "user_case_effective_access"
id = Column(BigInteger, primary_key=True, nullable=False)
user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
case_id = Column(BigInteger, ForeignKey('cases.case_id'), nullable=False)
access_level = Column(BigInteger, nullable=False)
user = relationship('User')
case = relationship('Cases')
UniqueConstraint('case_id', 'user_id')
class UserOrganisation(db.Model):
__tablename__ = "user_organisation"
id = Column(BigInteger, primary_key=True, nullable=False)
user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
org_id = Column(BigInteger, ForeignKey('organisations.org_id'), nullable=False)
is_primary_org = Column(Boolean, nullable=False)
user = relationship('User')
org = relationship('Organisation')
UniqueConstraint('user_id', 'org_id')
class UserGroup(db.Model):
__tablename__ = "user_group"
id = Column(BigInteger, primary_key=True, nullable=False)
user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
group_id = Column(BigInteger, ForeignKey('groups.group_id'), nullable=False)
user = relationship('User')
group = relationship('Group')
UniqueConstraint('user_id', 'group_id')
class User(UserMixin, db.Model):
__tablename__ = 'user'
id = Column(BigInteger, primary_key=True)
user = Column(String(64), unique=True)
name = Column(String(64), unique=False)
email = Column(String(120), unique=True)
uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, nullable=False,
server_default=text('gen_random_uuid()'), unique=True)
password = Column(String(500))
ctx_case = Column(Integer)
ctx_human_case = Column(String(256))
active = Column(Boolean())
api_key = Column(Text(), unique=True)
external_id = Column(Text, unique=True)
in_dark_mode = Column(Boolean())
has_mini_sidebar = Column(Boolean(), default=False)
has_deletion_confirmation = Column(Boolean(), default=False)
is_service_account = Column(Boolean(), default=False)
def __init__(self, user: str, name: str, email: str, password: str, active: bool,
external_id: str = None, is_service_account: bool = False):
self.user = user
self.name = name
self.password = password
self.email = email
self.active = active
self.external_id = external_id
self.is_service_account = is_service_account
def __repr__(self):
return str(self.id) + ' - ' + str(self.user)
def save(self):
self.api_key = secrets.token_urlsafe(nbytes=64)
# inject self into db session
db.session.add(self)
db.session.commit()
return self

View File

@ -0,0 +1,223 @@
#!/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 uuid
from datetime import datetime
from flask_login import current_user
# IMPORTS ------------------------------------------------
from sqlalchemy import BigInteger, Table
from sqlalchemy import Boolean
from sqlalchemy import Column
from sqlalchemy import Date
from sqlalchemy import DateTime
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import Text
from sqlalchemy import UniqueConstraint
from sqlalchemy import text
from sqlalchemy.dialects.postgresql import JSON
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from app import db
from app.datamgmt.states import update_assets_state
from app.datamgmt.states import update_evidences_state
from app.datamgmt.states import update_ioc_state
from app.datamgmt.states import update_notes_state
from app.datamgmt.states import update_tasks_state
from app.datamgmt.states import update_timeline_state
from app.models.models import Client, Base
class Cases(db.Model):
__tablename__ = 'cases'
case_id = Column(BigInteger, primary_key=True)
soc_id = Column(String(256))
client_id = Column(ForeignKey('client.client_id'), nullable=False)
name = Column(String(256))
description = Column(Text)
open_date = Column(Date)
close_date = Column(Date)
initial_date = Column(DateTime, nullable=False, server_default=text("now()"))
closing_note = Column(Text)
user_id = Column(ForeignKey('user.id'))
owner_id = Column(ForeignKey('user.id'))
status_id = Column(Integer, nullable=False, server_default=text("0"))
state_id = Column(ForeignKey('case_state.state_id'), nullable=True)
custom_attributes = Column(JSON)
case_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
nullable=False)
classification_id = Column(ForeignKey('case_classification.id'))
reviewer_id = Column(ForeignKey('user.id'), nullable=True)
review_status_id = Column(ForeignKey('review_status.id'), nullable=True)
modification_history = Column(JSON)
client = relationship('Client')
user = relationship('User', foreign_keys=[user_id])
owner = relationship('User', foreign_keys=[owner_id])
classification = relationship('CaseClassification')
reviewer = relationship('User', foreign_keys=[reviewer_id])
alerts = relationship('Alert', secondary="alert_case_association", back_populates='cases', viewonly=True)
tags = relationship('Tags', secondary="case_tags", back_populates='cases')
state = relationship('CaseState', back_populates='cases')
review_status = relationship('ReviewStatus')
def __init__(self,
name=None,
soc_id=None,
client_id=None,
description=None,
user=None,
custom_attributes=None,
classification_id=None,
state_id=None
):
self.name = name[:200] if name else None,
self.soc_id = soc_id,
self.client_id = client_id,
self.description = description,
self.user_id = current_user.id if current_user else user.id
self.owner_id = self.user_id
self.author = current_user.user if current_user else user.user
self.description = description
self.open_date = datetime.utcnow()
self.close_date = None
self.initial_date = datetime.utcnow()
self.custom_attributes = custom_attributes
self.case_uuid = uuid.uuid4()
self.status_id = 0
self.classification_id = classification_id
self.state_id = state_id
def save(self):
"""
Save the current case in database
:return:
"""
# Inject self into db
db.session.add(self)
# Commit the changes
db.session.commit()
# Rename case with the ID
self.name = "#{id} - {name}".format(id=self.case_id, name=self.name)
# Create the states
update_timeline_state(caseid=self.case_id, userid=self.user_id)
update_tasks_state(caseid=self.case_id, userid=self.user_id)
update_evidences_state(caseid=self.case_id, userid=self.user_id)
update_ioc_state(caseid=self.case_id, userid=self.user_id)
update_assets_state(caseid=self.case_id, userid=self.user_id)
update_notes_state(caseid=self.case_id, userid=self.user_id)
db.session.commit()
return self
def validate_on_build(self):
"""
Execute an autocheck of the case metadata and validate it
:return: True if valid else false; Tuple with errors
"""
# TODO : Check if case name already exists
res = Client.query\
.with_entities(Client.client_id)\
.filter(Client.client_id == self.client_id)\
.first()
self.client_id = res[0]
return True, []
class CaseTags(db.Model):
__tablename__ = 'case_tags'
__table_args__ = (
UniqueConstraint('case_id', 'tag_id', name='case_tags_case_id_tag_id_key'),
)
case_id = Column(ForeignKey('cases.case_id'), primary_key=True, nullable=False)
tag_id = Column(ForeignKey('tags.id'), primary_key=True, nullable=False, index=True)
class CasesEvent(db.Model):
__tablename__ = "cases_events"
event_id = Column(BigInteger, primary_key=True)
event_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
nullable=False)
case_id = Column(ForeignKey('cases.case_id'))
event_title = Column(Text)
event_source = Column(Text)
event_content = Column(Text)
event_raw = Column(Text)
event_date = Column(DateTime)
event_added = Column(DateTime)
event_in_graph = Column(Boolean)
event_in_summary = Column(Boolean)
user_id = Column(ForeignKey('user.id'))
modification_history = Column(JSONB)
event_color = Column(Text)
event_tags = Column(Text)
event_tz = Column(Text)
event_date_wtz = Column(DateTime)
event_is_flagged = Column(Boolean, default=False)
custom_attributes = Column(JSONB)
case = relationship('Cases')
user = relationship('User')
category = relationship('EventCategory', secondary="case_events_category",
primaryjoin="CasesEvent.event_id==CaseEventCategory.event_id",
secondaryjoin="CaseEventCategory.category_id==EventCategory.id",
viewonly=True)
class CaseState(db.Model):
__tablename__ = 'case_state'
state_id = Column(Integer, primary_key=True)
state_name = Column(Text, nullable=False)
state_description = Column(Text)
protected = Column(Boolean, default=False)
cases = relationship('Cases', back_populates='state')
class CaseProtagonist(db.Model):
__tablename__ = "case_protagonist"
id = Column(Integer, primary_key=True)
case_id = Column(ForeignKey('cases.case_id'))
user_id = Column(ForeignKey('user.id'))
name = Column(Text)
contact = Column(Text)
role = Column(Text)
case = relationship('Cases')
user = relationship('User')

View File

@ -0,0 +1,950 @@
#!/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