Nav apraksta

models.py 31KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. # IRIS Source Code
  2. # Copyright (C) 2021 - Airbus CyberSecurity (SAS)
  3. # ir@cyberactionlab.net
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 3 of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. import datetime
  19. # IMPORTS ------------------------------------------------
  20. import enum
  21. import uuid
  22. from sqlalchemy import BigInteger, UniqueConstraint, Table
  23. from sqlalchemy import Boolean
  24. from sqlalchemy import Column
  25. from sqlalchemy import DateTime
  26. from sqlalchemy import ForeignKey
  27. from sqlalchemy import Integer
  28. from sqlalchemy import LargeBinary
  29. from sqlalchemy import Sequence
  30. from sqlalchemy import String
  31. from sqlalchemy import TIMESTAMP
  32. from sqlalchemy import Text
  33. from sqlalchemy import create_engine
  34. from sqlalchemy import text
  35. from sqlalchemy.dialects.postgresql import JSON, JSONB
  36. from sqlalchemy.dialects.postgresql import UUID
  37. from sqlalchemy.ext.declarative import declarative_base
  38. from sqlalchemy.orm import relationship
  39. from sqlalchemy.orm import sessionmaker
  40. from sqlalchemy.sql import func
  41. from app import app
  42. from app import db
  43. Base = declarative_base()
  44. metadata = Base.metadata
  45. class CaseStatus(enum.Enum):
  46. unknown = 0x0
  47. false_positive = 0x1
  48. true_positive_with_impact = 0x2
  49. not_applicable = 0x3
  50. true_positive_without_impact = 0x4
  51. legitimate = 0x5
  52. class ReviewStatusList:
  53. no_review_required = "No review required"
  54. not_reviewed = "Not reviewed"
  55. pending_review = "Pending review"
  56. review_in_progress = "Review in progress"
  57. reviewed = "Reviewed"
  58. class CompromiseStatus(enum.Enum):
  59. to_be_determined = 0x0
  60. compromised = 0x1
  61. not_compromised = 0x2
  62. unknown = 0x3
  63. @classmethod
  64. def has_value(cls, value):
  65. return value in cls._value2member_map_
  66. def create_safe(session, model, **kwargs):
  67. instance = session.query(model).filter_by(**kwargs).first()
  68. if instance:
  69. return False
  70. else:
  71. instance = model(**kwargs)
  72. session.add(instance)
  73. session.commit()
  74. return True
  75. def create_safe_limited(session, model, keywords_list, **kwargs):
  76. kwdup = kwargs.keys()
  77. for kw in list(kwdup):
  78. if kw not in keywords_list:
  79. kwargs.pop(kw)
  80. instance = session.query(model).filter_by(**kwargs).first()
  81. if instance:
  82. return False
  83. else:
  84. instance = model(**kwargs)
  85. session.add(instance)
  86. session.commit()
  87. return True
  88. def get_by_value_or_create(session, model, fieldname, **kwargs):
  89. select_value = {fieldname: kwargs.get(fieldname)}
  90. instance = session.query(model).filter_by(**select_value).first()
  91. if instance:
  92. return instance
  93. else:
  94. instance = model(**kwargs)
  95. session.add(instance)
  96. session.commit()
  97. return instance
  98. def get_or_create(session, model, **kwargs):
  99. instance = session.query(model).filter_by(**kwargs).first()
  100. if instance:
  101. return instance
  102. else:
  103. instance = model(**kwargs)
  104. session.add(instance)
  105. session.commit()
  106. return instance
  107. class Client(db.Model):
  108. __tablename__ = 'client'
  109. client_id = Column(BigInteger, primary_key=True)
  110. client_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
  111. name = Column(Text, unique=True)
  112. description = Column(Text)
  113. sla = Column(Text)
  114. creation_date = Column(DateTime, server_default=func.now(), nullable=True)
  115. created_by = Column(ForeignKey('user.id'), nullable=True)
  116. last_update_date = Column(DateTime, server_default=func.now(), nullable=True)
  117. custom_attributes = Column(JSON)
  118. class AssetsType(db.Model):
  119. __tablename__ = 'assets_type'
  120. asset_id = Column(Integer, primary_key=True)
  121. asset_name = Column(String(155))
  122. asset_description = Column(String(255))
  123. asset_icon_not_compromised = Column(String(255))
  124. asset_icon_compromised = Column(String(255))
  125. alert_assets_association = Table(
  126. 'alert_assets_association',
  127. db.Model.metadata,
  128. Column('alert_id', ForeignKey('alerts.alert_id'), primary_key=True),
  129. Column('asset_id', ForeignKey('case_assets.asset_id'), primary_key=True)
  130. )
  131. alert_iocs_association = Table(
  132. 'alert_iocs_association',
  133. db.Model.metadata,
  134. Column('alert_id', ForeignKey('alerts.alert_id'), primary_key=True),
  135. Column('ioc_id', ForeignKey('ioc.ioc_id'), primary_key=True)
  136. )
  137. class CaseAssets(db.Model):
  138. __tablename__ = 'case_assets'
  139. asset_id = Column(BigInteger, primary_key=True)
  140. asset_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
  141. asset_name = Column(Text)
  142. asset_description = Column(Text)
  143. asset_domain = Column(Text)
  144. asset_ip = Column(Text)
  145. asset_info = Column(Text)
  146. asset_compromise_status_id = Column(Integer, nullable=True)
  147. asset_type_id = Column(ForeignKey('assets_type.asset_id'))
  148. asset_tags = Column(Text)
  149. case_id = Column(ForeignKey('cases.case_id'))
  150. date_added = Column(DateTime)
  151. date_update = Column(DateTime)
  152. user_id = Column(ForeignKey('user.id'))
  153. analysis_status_id = Column(ForeignKey('analysis_status.id'))
  154. custom_attributes = Column(JSON)
  155. asset_enrichment = Column(JSONB)
  156. modification_history = Column(JSON)
  157. case = relationship('Cases')
  158. user = relationship('User')
  159. asset_type = relationship('AssetsType')
  160. analysis_status = relationship('AnalysisStatus')
  161. alerts = relationship('Alert', secondary=alert_assets_association, back_populates='assets')
  162. iocs = relationship('IocAssetLink', back_populates='asset')
  163. class AnalysisStatus(db.Model):
  164. __tablename__ = 'analysis_status'
  165. id = Column(Integer, primary_key=True)
  166. name = Column(Text)
  167. class CaseClassification(db.Model):
  168. __tablename__ = 'case_classification'
  169. id = Column(Integer, primary_key=True)
  170. name = Column(Text)
  171. name_expanded = Column(Text)
  172. description = Column(Text)
  173. creation_date = Column(DateTime, server_default=func.now(), nullable=True)
  174. created_by_id = Column(ForeignKey('user.id'), nullable=True)
  175. created_by = relationship('User')
  176. class EvidenceTypes(db.Model):
  177. __tablename__ = 'evidence_type'
  178. id = Column(Integer, primary_key=True)
  179. name = Column(Text)
  180. description = Column(Text)
  181. creation_date = Column(DateTime, server_default=func.now(), nullable=True)
  182. created_by_id = Column(ForeignKey('user.id'), nullable=True)
  183. created_by = relationship('User')
  184. class CaseTemplate(db.Model):
  185. __tablename__ = 'case_template'
  186. # Metadata
  187. id = Column(Integer, primary_key=True)
  188. created_by_user_id = Column(Integer, db.ForeignKey('user.id'))
  189. created_at = Column(DateTime, server_default=func.now())
  190. updated_at = Column(DateTime, onupdate=func.now())
  191. # Data
  192. name = Column(String, nullable=False)
  193. display_name = Column(String, nullable=True)
  194. description = Column(Text, nullable=True)
  195. author = Column(String, nullable=True)
  196. title_prefix = Column(String, nullable=True)
  197. summary = Column(String, nullable=True)
  198. tags = Column(JSON, nullable=True)
  199. tasks = Column(JSON, nullable=True)
  200. note_directories = Column(JSON, nullable=True)
  201. classification = Column(String, nullable=True)
  202. created_by_user = relationship('User')
  203. def __init__(self, **kwargs):
  204. super().__init__(**kwargs)
  205. def update_from_dict(self, data: dict):
  206. for field, value in data.items():
  207. setattr(self, field, value)
  208. class Contact(db.Model):
  209. __tablename__ = 'contact'
  210. id = Column(BigInteger, primary_key=True)
  211. contact_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
  212. contact_name = Column(Text)
  213. contact_email = Column(Text)
  214. contact_role = Column(Text)
  215. contact_note = Column(Text)
  216. contact_work_phone = Column(Text)
  217. contact_mobile_phone = Column(Text)
  218. custom_attributes = Column(JSON)
  219. client_id = Column(ForeignKey('client.client_id'))
  220. client = relationship('Client')
  221. class CaseEventsAssets(db.Model):
  222. __tablename__ = 'case_events_assets'
  223. id = Column(BigInteger, primary_key=True)
  224. event_id = Column(ForeignKey('cases_events.event_id'))
  225. asset_id = Column(ForeignKey('case_assets.asset_id'))
  226. case_id = Column(ForeignKey('cases.case_id'))
  227. event = relationship('CasesEvent')
  228. asset = relationship('CaseAssets')
  229. case = relationship('Cases')
  230. class CaseEventsIoc(db.Model):
  231. __tablename__ = 'case_events_ioc'
  232. id = Column(BigInteger, primary_key=True)
  233. event_id = Column(ForeignKey('cases_events.event_id'))
  234. ioc_id = Column(ForeignKey('ioc.ioc_id'))
  235. case_id = Column(ForeignKey('cases.case_id'))
  236. event = relationship('CasesEvent')
  237. ioc = relationship('Ioc')
  238. case = relationship('Cases')
  239. class ObjectState(db.Model):
  240. __tablename__ = 'object_state'
  241. object_id = Column(BigInteger, primary_key=True)
  242. object_case_id = Column(ForeignKey('cases.case_id'))
  243. object_updated_by_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
  244. object_name = Column(Text)
  245. object_state = Column(BigInteger)
  246. object_last_update = Column(TIMESTAMP)
  247. case = relationship('Cases')
  248. updated_by = relationship('User')
  249. class EventCategory(db.Model):
  250. __tablename__ = 'event_category'
  251. id = Column(Integer, primary_key=True)
  252. name = Column(Text)
  253. class CaseEventCategory(db.Model):
  254. __tablename__ = 'case_events_category'
  255. id = Column(Integer, primary_key=True)
  256. event_id = Column(ForeignKey('cases_events.event_id'), unique=True)
  257. category_id = Column(ForeignKey('event_category.id'))
  258. event = relationship('CasesEvent', cascade="delete")
  259. category = relationship('EventCategory')
  260. class CaseGraphAssets(db.Model):
  261. __tablename__ = 'case_graph_assets'
  262. id = Column(Integer, primary_key=True)
  263. case_id = Column(ForeignKey('cases.case_id'))
  264. asset_id = Column(Integer)
  265. asset_type_id = Column(ForeignKey('assets_type.asset_id'))
  266. case = relationship('Cases')
  267. asset_type = relationship('AssetsType')
  268. class CaseGraphLinks(db.Model):
  269. __tablename__ = 'case_graph_links'
  270. id = Column(Integer, primary_key=True)
  271. case_id = Column(ForeignKey('cases.case_id'))
  272. source_id = Column(ForeignKey('case_graph_assets.id'))
  273. dest_id = Column(ForeignKey('case_graph_assets.id'))
  274. case = relationship('Cases')
  275. class Languages(db.Model):
  276. __tablename__ = 'languages'
  277. id = db.Column(db.Integer(), primary_key=True)
  278. name = db.Column(db.String(), unique=True)
  279. code = db.Column(db.String(), unique=True)
  280. class ReportType(db.Model):
  281. __tablename__ = 'report_type'
  282. id = db.Column(db.Integer(), primary_key=True)
  283. name = db.Column(db.Text(), unique=True)
  284. class CaseTemplateReport(db.Model):
  285. __tablename__ = 'case_template_report'
  286. id = db.Column(db.Integer(), primary_key=True)
  287. name = db.Column(db.String())
  288. description = db.Column(db.String())
  289. internal_reference = db.Column(db.String(), unique=True)
  290. naming_format = db.Column(db.String())
  291. created_by_user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
  292. date_created = db.Column(DateTime)
  293. language_id = db.Column(db.Integer(), db.ForeignKey('languages.id'))
  294. report_type_id = db.Column(db.Integer(), db.ForeignKey('report_type.id'))
  295. report_type = relationship('ReportType')
  296. language = relationship('Languages')
  297. created_by_user = relationship('User')
  298. class Tlp(db.Model):
  299. __tablename__ = 'tlp'
  300. tlp_id = Column(Integer, primary_key=True)
  301. tlp_name = Column(Text)
  302. tlp_bscolor = Column(Text)
  303. class Ioc(db.Model):
  304. __tablename__ = 'ioc'
  305. ioc_id = Column(BigInteger, primary_key=True)
  306. ioc_uuid = Column(UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False)
  307. ioc_value = Column(Text)
  308. ioc_type_id = Column(ForeignKey('ioc_type.type_id'))
  309. ioc_description = Column(Text)
  310. ioc_tags = Column(String(512))
  311. user_id = Column(ForeignKey('user.id'))
  312. ioc_misp = Column(Text)
  313. ioc_tlp_id = Column(ForeignKey('tlp.tlp_id'))
  314. custom_attributes = Column(JSON)
  315. ioc_enrichment = Column(JSONB)
  316. modification_history = Column(JSON)
  317. case_id = Column(ForeignKey('cases.case_id'), nullable=True)
  318. user = relationship('User')
  319. tlp = relationship('Tlp')
  320. ioc_type = relationship('IocType')
  321. case = relationship('Cases')
  322. assets = relationship('IocAssetLink', back_populates='ioc', cascade="delete")
  323. events = relationship('CaseEventsIoc', back_populates='ioc', cascade="delete")
  324. comments = relationship('IocComments', back_populates='ioc', cascade="all, delete")
  325. alerts = relationship('Alert', secondary=alert_iocs_association, back_populates='iocs')
  326. class CustomAttribute(db.Model):
  327. __tablename__ = 'custom_attribute'
  328. attribute_id = Column(Integer, primary_key=True)
  329. attribute_display_name = Column(Text)
  330. attribute_description = Column(Text)
  331. attribute_for = Column(Text)
  332. attribute_content = Column(JSON)
  333. class DataStorePath(db.Model):
  334. __tablename__ = 'data_store_path'
  335. path_id = Column(BigInteger, primary_key=True)
  336. path_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4)
  337. path_name = Column(Text, nullable=False)
  338. path_parent_id = Column(BigInteger)
  339. path_is_root = Column(Boolean)
  340. path_case_id = Column(ForeignKey('cases.case_id'), nullable=False)
  341. case = relationship('Cases')
  342. class DataStoreFile(db.Model):
  343. __tablename__ = 'data_store_file'
  344. file_id = Column(BigInteger, primary_key=True)
  345. file_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
  346. file_original_name = Column(Text, nullable=False)
  347. file_local_name = Column(Text, nullable=False)
  348. file_description = Column(Text)
  349. file_date_added = Column(DateTime)
  350. file_tags = Column(Text)
  351. file_size = Column(BigInteger)
  352. file_is_ioc = Column(Boolean)
  353. file_is_evidence = Column(Boolean)
  354. file_password = Column(Text)
  355. file_parent_id = Column(ForeignKey('data_store_path.path_id'), nullable=False)
  356. file_sha256 = Column(Text)
  357. added_by_user_id = Column(ForeignKey('user.id'), nullable=False)
  358. modification_history = Column(JSON)
  359. file_case_id = Column(ForeignKey('cases.case_id'), nullable=False)
  360. case = relationship('Cases')
  361. user = relationship('User')
  362. data_parent = relationship('DataStorePath')
  363. class IocType(db.Model):
  364. __tablename__ = 'ioc_type'
  365. type_id = Column(Integer, primary_key=True)
  366. type_name = Column(Text)
  367. type_description = Column(Text)
  368. type_taxonomy = Column(Text)
  369. type_validation_regex = Column(Text)
  370. type_validation_expect = Column(Text)
  371. class IocAssetLink(db.Model):
  372. __tablename__ = 'ioc_asset_link'
  373. ioc_asset_link_id = Column(Integer, primary_key=True)
  374. ioc_id = Column(ForeignKey('ioc.ioc_id'), nullable=False)
  375. asset_id = Column(ForeignKey('case_assets.asset_id'), nullable=False)
  376. ioc = relationship('Ioc', back_populates='assets')
  377. asset = relationship('CaseAssets', back_populates='iocs')
  378. class OsType(db.Model):
  379. __tablename__ = 'os_type'
  380. type_id = Column(Integer, primary_key=True)
  381. type_name = Column(String(155))
  382. class CasesAssetsExt(db.Model):
  383. __tablename__ = 'cases_assets_ext'
  384. asset_id = Column(Integer, primary_key=True)
  385. type_id = Column(ForeignKey('assets_type.asset_id'))
  386. case_id = Column(ForeignKey('cases.case_id'))
  387. asset_content = Column(Text)
  388. type = relationship('AssetsType')
  389. case = relationship('Cases')
  390. class Notes(db.Model):
  391. __tablename__ = 'notes'
  392. note_id = Column(BigInteger, primary_key=True)
  393. note_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
  394. note_title = Column(String(155))
  395. note_content = Column(Text)
  396. note_user = Column(ForeignKey('user.id'))
  397. note_creationdate = Column(DateTime)
  398. note_lastupdate = Column(DateTime)
  399. note_case_id = Column(ForeignKey('cases.case_id'))
  400. custom_attributes = Column(JSON)
  401. directory_id = Column(ForeignKey('note_directory.id'), nullable=True)
  402. modification_history = Column(JSON)
  403. user = relationship('User')
  404. case = relationship('Cases')
  405. directory = relationship('NoteDirectory', backref='notes')
  406. versions = relationship('NoteRevisions', back_populates='note', cascade="all, delete-orphan")
  407. class NoteRevisions(db.Model):
  408. __tablename__ = 'note_revisions'
  409. revision_id = Column(BigInteger, primary_key=True)
  410. note_id = Column(BigInteger, ForeignKey('notes.note_id'), nullable=False)
  411. revision_number = Column(Integer, nullable=False)
  412. note_title = Column(String(155))
  413. note_content = Column(Text)
  414. note_user = Column(ForeignKey('user.id'))
  415. revision_timestamp = Column(DateTime, default=datetime.datetime.utcnow)
  416. user = relationship('User')
  417. note = relationship('Notes', back_populates='versions')
  418. class NoteDirectory(db.Model):
  419. __tablename__ = 'note_directory'
  420. id = Column(BigInteger, primary_key=True)
  421. name = Column(Text, nullable=False)
  422. parent_id = Column(ForeignKey('note_directory.id'), nullable=True)
  423. case_id = Column(ForeignKey('cases.case_id'), nullable=False)
  424. parent = relationship('NoteDirectory', remote_side=[id], backref='subdirectories')
  425. case = relationship('Cases', backref='note_directories')
  426. class NotesGroup(db.Model):
  427. __tablename__ = 'notes_group'
  428. group_id = Column(BigInteger, primary_key=True)
  429. group_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
  430. nullable=False)
  431. group_title = Column(String(155))
  432. group_user = Column(ForeignKey('user.id'))
  433. group_creationdate = Column(DateTime)
  434. group_lastupdate = Column(DateTime)
  435. group_case_id = Column(ForeignKey('cases.case_id'))
  436. user = relationship('User')
  437. case = relationship('Cases')
  438. class NotesGroupLink(db.Model):
  439. __tablename__ = 'notes_group_link'
  440. link_id = Column(BigInteger, primary_key=True)
  441. group_id = Column(ForeignKey('notes_group.group_id'))
  442. note_id = Column(ForeignKey('notes.note_id'))
  443. case_id = Column(ForeignKey('cases.case_id'))
  444. note = relationship('Notes')
  445. note_group = relationship('NotesGroup')
  446. case = relationship('Cases')
  447. class CaseKanban(db.Model):
  448. __tablename__ = 'case_kanban'
  449. case_id = Column(ForeignKey('cases.case_id'), primary_key=True)
  450. kanban_data = Column(Text)
  451. case = relationship('Cases')
  452. class CaseReceivedFile(db.Model):
  453. __tablename__ = 'case_received_file'
  454. id = Column(BigInteger, primary_key=True)
  455. file_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
  456. filename = Column(Text)
  457. date_added = Column(DateTime)
  458. acquisition_date = Column(DateTime)
  459. file_hash = Column(Text)
  460. file_description = Column(Text)
  461. file_size = Column(BigInteger)
  462. start_date = Column(DateTime)
  463. end_date = Column(DateTime)
  464. case_id = Column(ForeignKey('cases.case_id'))
  465. user_id = Column(ForeignKey('user.id'))
  466. type_id = Column(ForeignKey('evidence_type.id'))
  467. custom_attributes = Column(JSON)
  468. chain_of_custody = Column(JSON)
  469. modification_history = Column(JSON)
  470. case = relationship('Cases')
  471. user = relationship('User')
  472. type = relationship('EvidenceTypes')
  473. class TaskStatus(db.Model):
  474. __tablename__ = 'task_status'
  475. id = Column(Integer, primary_key=True)
  476. status_name = Column(Text)
  477. status_description = Column(Text)
  478. status_bscolor = Column(Text)
  479. class CaseTasks(db.Model):
  480. __tablename__ = 'case_tasks'
  481. id = Column(BigInteger, primary_key=True)
  482. task_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
  483. task_title = Column(Text)
  484. task_description = Column(Text)
  485. task_tags = Column(Text)
  486. task_open_date = Column(DateTime)
  487. task_close_date = Column(DateTime)
  488. task_last_update = Column(DateTime)
  489. task_userid_open = Column(ForeignKey('user.id'))
  490. task_userid_close = Column(ForeignKey('user.id'))
  491. task_userid_update = Column(ForeignKey('user.id'))
  492. task_status_id = Column(ForeignKey('task_status.id'))
  493. task_case_id = Column(ForeignKey('cases.case_id'))
  494. custom_attributes = Column(JSON)
  495. modification_history = Column(JSON)
  496. case = relationship('Cases')
  497. user_open = relationship('User', foreign_keys=[task_userid_open])
  498. user_close = relationship('User', foreign_keys=[task_userid_close])
  499. user_update = relationship('User', foreign_keys=[task_userid_update])
  500. status = relationship('TaskStatus', foreign_keys=[task_status_id])
  501. class Tags(db.Model):
  502. __tablename__ = 'tags'
  503. id = Column(BigInteger, primary_key=True, nullable=False)
  504. tag_title = Column(Text, unique=True)
  505. tag_creation_date = Column(DateTime)
  506. tag_namespace = Column(Text)
  507. cases = relationship('Cases', secondary="case_tags", back_populates='tags', viewonly=True)
  508. def __init__(self, tag_title, namespace=None):
  509. self.id = None
  510. self.tag_title = tag_title
  511. self.tag_creation_date = datetime.datetime.now()
  512. self.tag_namespace = namespace
  513. def save(self):
  514. existing_tag = self.get_by_title(self.tag_title)
  515. if existing_tag is not None:
  516. return existing_tag
  517. else:
  518. db.session.add(self)
  519. db.session.commit()
  520. return self
  521. @classmethod
  522. def get_by_title(cls, tag_title):
  523. return cls.query.filter_by(tag_title=tag_title).first()
  524. class TaskAssignee(db.Model):
  525. __tablename__ = "task_assignee"
  526. id = Column(BigInteger, primary_key=True, nullable=False)
  527. user_id = Column(BigInteger, ForeignKey('user.id'), nullable=False)
  528. task_id = Column(BigInteger, ForeignKey('case_tasks.id'), nullable=False)
  529. user = relationship('User')
  530. task = relationship('CaseTasks')
  531. UniqueConstraint('user_id', 'task_id')
  532. class GlobalTasks(db.Model):
  533. __tablename__ = 'global_tasks'
  534. id = Column(BigInteger, primary_key=True)
  535. task_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"), nullable=False)
  536. task_title = Column(Text)
  537. task_description = Column(Text)
  538. task_tags = Column(Text)
  539. task_open_date = Column(DateTime)
  540. task_close_date = Column(DateTime)
  541. task_last_update = Column(DateTime)
  542. task_userid_open = Column(ForeignKey('user.id'))
  543. task_userid_close = Column(ForeignKey('user.id'))
  544. task_userid_update = Column(ForeignKey('user.id'))
  545. task_assignee_id = Column(ForeignKey('user.id'), nullable=True)
  546. task_status_id = Column(ForeignKey('task_status.id'))
  547. user_open = relationship('User', foreign_keys=[task_userid_open])
  548. user_close = relationship('User', foreign_keys=[task_userid_close])
  549. user_update = relationship('User', foreign_keys=[task_userid_update])
  550. user_assigned = relationship('User', foreign_keys=[task_assignee_id])
  551. status = relationship('TaskStatus', foreign_keys=[task_status_id])
  552. class UserActivity(db.Model):
  553. __tablename__ = "user_activity"
  554. id = Column(BigInteger, primary_key=True)
  555. user_id = Column(ForeignKey('user.id'), nullable=True)
  556. case_id = Column(ForeignKey('cases.case_id'), nullable=True)
  557. activity_date = Column(DateTime)
  558. activity_desc = Column(Text)
  559. user_input = Column(Boolean, default=False)
  560. is_from_api = Column(Boolean, default=False)
  561. display_in_ui = Column(Boolean, default=True)
  562. user = relationship('User')
  563. case = relationship('Cases')
  564. class ServerSettings(db.Model):
  565. __table_name__ = "server_settings"
  566. id = Column(Integer, primary_key=True)
  567. https_proxy = Column(Text)
  568. http_proxy = Column(Text)
  569. prevent_post_mod_repush = Column(Boolean)
  570. prevent_post_objects_repush = Column(Boolean, default=False)
  571. has_updates_available = Column(Boolean)
  572. enable_updates_check = Column(Boolean)
  573. password_policy_min_length = Column(Integer)
  574. password_policy_upper_case = Column(Boolean)
  575. password_policy_lower_case = Column(Boolean)
  576. password_policy_digit = Column(Boolean)
  577. password_policy_special_chars = Column(Text)
  578. enforce_mfa = Column(Boolean)
  579. class Comments(db.Model):
  580. __tablename__ = "comments"
  581. comment_id = Column(BigInteger, primary_key=True)
  582. comment_uuid = Column(UUID(as_uuid=True), default=uuid.uuid4, server_default=text("gen_random_uuid()"),
  583. nullable=False)
  584. comment_text = Column(Text)
  585. comment_date = Column(DateTime)
  586. comment_update_date = Column(DateTime)
  587. comment_user_id = Column(ForeignKey('user.id'))
  588. comment_case_id = Column(ForeignKey('cases.case_id'))
  589. comment_alert_id = Column(ForeignKey('alerts.alert_id'))
  590. user = relationship('User')
  591. case = relationship('Cases')
  592. alert = relationship('Alert')
  593. class EventComments(db.Model):
  594. __tablename__ = "event_comments"
  595. id = Column(BigInteger, primary_key=True)
  596. comment_id = Column(ForeignKey('comments.comment_id'))
  597. comment_event_id = Column(ForeignKey('cases_events.event_id'))
  598. event = relationship('CasesEvent')
  599. comment = relationship('Comments')
  600. class TaskComments(db.Model):
  601. __tablename__ = "task_comments"
  602. id = Column(BigInteger, primary_key=True)
  603. comment_id = Column(ForeignKey('comments.comment_id'))
  604. comment_task_id = Column(ForeignKey('case_tasks.id'))
  605. task = relationship('CaseTasks')
  606. comment = relationship('Comments')
  607. class IocComments(db.Model):
  608. __tablename__ = "ioc_comments"
  609. id = Column(BigInteger, primary_key=True)
  610. comment_id = Column(ForeignKey('comments.comment_id'))
  611. comment_ioc_id = Column(ForeignKey('ioc.ioc_id'))
  612. ioc = relationship('Ioc')
  613. comment = relationship('Comments')
  614. class AssetComments(db.Model):
  615. __tablename__ = "asset_comments"
  616. id = Column(BigInteger, primary_key=True)
  617. comment_id = Column(ForeignKey('comments.comment_id'))
  618. comment_asset_id = Column(ForeignKey('case_assets.asset_id'))
  619. asset = relationship('CaseAssets')
  620. comment = relationship('Comments')
  621. class EvidencesComments(db.Model):
  622. __tablename__ = "evidence_comments"
  623. id = Column(BigInteger, primary_key=True)
  624. comment_id = Column(ForeignKey('comments.comment_id'))
  625. comment_evidence_id = Column(ForeignKey('case_received_file.id'))
  626. evidence = relationship('CaseReceivedFile')
  627. comment = relationship('Comments')
  628. class NotesComments(db.Model):
  629. __tablename__ = "note_comments"
  630. id = Column(BigInteger, primary_key=True)
  631. comment_id = Column(ForeignKey('comments.comment_id'))
  632. comment_note_id = Column(ForeignKey('notes.note_id'))
  633. note = relationship('Notes')
  634. comment = relationship('Comments')
  635. class IrisModule(db.Model):
  636. __tablename__ = "iris_module"
  637. id = Column(Integer, primary_key=True)
  638. added_by_id = Column(ForeignKey('user.id'), nullable=False)
  639. module_human_name = Column(Text)
  640. module_name = Column(Text)
  641. module_description = Column(Text)
  642. module_version = Column(Text)
  643. interface_version = Column(Text)
  644. date_added = Column(DateTime)
  645. is_active = Column(Boolean)
  646. has_pipeline = Column(Boolean)
  647. pipeline_args = Column(JSON)
  648. module_config = Column(JSON)
  649. module_type = Column(Text)
  650. user = relationship('User')
  651. class IrisHook(db.Model):
  652. __tablename__ = "iris_hooks"
  653. id = Column(Integer, primary_key=True)
  654. hook_name = Column(Text)
  655. hook_description = Column(Text)
  656. class IrisModuleHook(db.Model):
  657. __tablename__ = "iris_module_hooks"
  658. id = Column(BigInteger, primary_key=True)
  659. module_id = Column(ForeignKey('iris_module.id'), nullable=False)
  660. hook_id = Column(ForeignKey('iris_hooks.id'), nullable=False)
  661. is_manual_hook = Column(Boolean)
  662. manual_hook_ui_name = Column(Text)
  663. retry_on_fail = Column(Boolean)
  664. max_retry = Column(Integer)
  665. run_asynchronously = Column(Boolean)
  666. wait_till_return = Column(Boolean)
  667. module = relationship('IrisModule')
  668. hook = relationship('IrisHook')
  669. class IrisReport(db.Model):
  670. __tablename__ = 'iris_reports'
  671. report_id = Column(db.Integer, Sequence("iris_reports_id_seq"), primary_key=True)
  672. case_id = Column(ForeignKey('cases.case_id'), nullable=False)
  673. report_title = Column(String(155))
  674. report_date = Column(DateTime)
  675. report_content = Column('report_content', JSON)
  676. user_id = Column(ForeignKey('user.id'))
  677. user = relationship('User')
  678. case = relationship('Cases')
  679. def __init__(self, case_id, report_title, report_date, report_content, user_id):
  680. self.case_id = case_id
  681. self.report_title = report_title
  682. self.report_date = report_date
  683. self.report_content = report_content
  684. self.user_id = user_id
  685. def save(self):
  686. # Create an engine and a session because this method
  687. # will be called from Celery thread and might cause
  688. # error if it uses the session context of the app
  689. engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
  690. Session = sessionmaker(bind=engine)
  691. session = Session()
  692. # inject self into db session
  693. session.add(self)
  694. # commit change and save the object
  695. session.commit()
  696. # Close session
  697. session.close()
  698. # Dispose engine
  699. engine.dispose()
  700. return self
  701. class SavedFilter(db.Model):
  702. __tablename__ = 'saved_filters'
  703. filter_id = Column(BigInteger, primary_key=True)
  704. created_by = Column(ForeignKey('user.id'), nullable=False)
  705. filter_name = Column(Text, nullable=False)
  706. filter_description = Column(Text)
  707. filter_data = Column(JSON, nullable=False)
  708. filter_is_private = Column(Boolean, nullable=False)
  709. filter_type = Column(Text, nullable=False)
  710. user = relationship('User', foreign_keys=[created_by])
  711. class ReviewStatus(db.Model):
  712. __tablename__ = 'review_status'
  713. id = Column(Integer, primary_key=True)
  714. status_name = Column(Text, nullable=False)
  715. class CeleryTaskMeta(db.Model):
  716. __bind_key__ = 'iris_tasks'
  717. __tablename__ = 'celery_taskmeta'
  718. id = Column(BigInteger, Sequence('task_id_sequence'), primary_key=True)
  719. task_id = Column(String(155))
  720. status = Column(String(50))
  721. result = Column(LargeBinary)
  722. date_done = Column(DateTime)
  723. traceback = Column(Text)
  724. name = Column(String(155))
  725. args = Column(LargeBinary)
  726. kwargs = Column(LargeBinary)
  727. worker = Column(String(155))
  728. retries = Column(Integer)
  729. queue = Column(String(155))
  730. def __repr__(self):
  731. return str(self.id) + ' - ' + str(self.user)
  732. def create_safe_attr(session, attribute_display_name, attribute_description, attribute_for, attribute_content):
  733. cat = CustomAttribute.query.filter(
  734. CustomAttribute.attribute_display_name == attribute_display_name,
  735. CustomAttribute.attribute_description == attribute_description,
  736. CustomAttribute.attribute_for == attribute_for
  737. ).first()
  738. if cat:
  739. return False
  740. else:
  741. instance = CustomAttribute()
  742. instance.attribute_display_name = attribute_display_name
  743. instance.attribute_description = attribute_description
  744. instance.attribute_for = attribute_for
  745. instance.attribute_content = attribute_content
  746. session.add(instance)
  747. session.commit()
  748. return True