Skip to content

cortex_job models

cortex_job.models

Analyzer

Bases: Model

name = models.CharField(max_length=50, unique=True, db_index=True) class-attribute instance-attribute

weight = models.FloatField(default=0.2) class-attribute instance-attribute

analyzer_cortex_id = models.CharField(max_length=50, unique=True, db_index=True) class-attribute instance-attribute

is_active = models.BooleanField(default=True) class-attribute instance-attribute

creation_date = models.DateTimeField(auto_now_add=True, db_index=True) class-attribute instance-attribute

last_update = models.DateTimeField(auto_now=True) class-attribute instance-attribute

Meta

ordering = ['-creation_date'] class-attribute instance-attribute

AnalyzerReport

Bases: Model

cortex_job_id = models.CharField(max_length=50, db_index=True) class-attribute instance-attribute

type = models.CharField(max_length=50, db_index=True) class-attribute instance-attribute

status = models.CharField(max_length=50, db_index=True) class-attribute instance-attribute

analyzer = models.ForeignKey(Analyzer, on_delete=(models.CASCADE), related_name='analyzer_reports') class-attribute instance-attribute

url = models.ForeignKey(URL, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

domain = models.ForeignKey(Domain, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

mail = models.ForeignKey(MailAddress, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

hash = models.ForeignKey(Hash, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

file = models.ForeignKey(File, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

ip = models.ForeignKey(IP, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

mail_body = models.ForeignKey(MailBody, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

mail_header = models.ForeignKey(MailHeader, on_delete=(models.CASCADE), related_name='analyzer_reports', null=True, blank=True) class-attribute instance-attribute

level = models.CharField(max_length=50, db_index=True) class-attribute instance-attribute

confidence = models.FloatField() class-attribute instance-attribute

score = models.FloatField() class-attribute instance-attribute

category = models.TextField(null=True, blank=True) class-attribute instance-attribute

report_summary = models.JSONField() class-attribute instance-attribute

report_taxonomy = models.JSONField() class-attribute instance-attribute

report_full = models.JSONField() class-attribute instance-attribute

creation_date = models.DateTimeField(auto_now_add=True, db_index=True) class-attribute instance-attribute

last_update = models.DateTimeField(auto_now=True) class-attribute instance-attribute

Meta

ordering = ['-creation_date'] class-attribute instance-attribute
indexes = [models.Index(fields=['type', 'status', 'domain']), models.Index(fields=['type', 'status', 'url']), models.Index(fields=['type', 'status', 'ip']), models.Index(fields=['type', 'status', 'hash']), models.Index(fields=['type', 'status', 'mail']), models.Index(fields=['type', 'status', 'file']), models.Index(fields=['type', 'status', 'mail_body']), models.Index(fields=['type', 'status', 'mail_header'])] class-attribute instance-attribute

set_category(categories)

Store the report category as a comma-separated string.

get_category()

Return the report categories as a list.

CaseAnalyzerJob

Bases: Model

Per-case ledger of dispatched Cortex jobs.

One row per (case, cortex_job_id). Multiple cases may share the same cortex_job_id when a deduplicated artifact (file, URL, hash, etc.) is referenced by several cases — that's why this is a junction table and not an FK on AnalyzerReport.

Status mirrors AnalyzerReport.status but is per-case so we can answer 'which jobs is this case waiting on' without joining.

STATUS_WAITING = 'Waiting' class-attribute instance-attribute

STATUS_INPROGRESS = 'InProgress' class-attribute instance-attribute

STATUS_SUCCESS = 'Success' class-attribute instance-attribute

STATUS_FAILURE = 'Failure' class-attribute instance-attribute

STATUS_DELETED = 'Deleted' class-attribute instance-attribute

STATUS_CHOICES = [(STATUS_WAITING, 'Waiting'), (STATUS_INPROGRESS, 'InProgress'), (STATUS_SUCCESS, 'Success'), (STATUS_FAILURE, 'Failure'), (STATUS_DELETED, 'Deleted')] class-attribute instance-attribute

PENDING_STATUSES = (STATUS_WAITING, STATUS_INPROGRESS) class-attribute instance-attribute

case = models.ForeignKey('case_handler.Case', on_delete=(models.CASCADE), related_name='analyzer_jobs') class-attribute instance-attribute

cortex_job_id = models.CharField(max_length=50) class-attribute instance-attribute

analyzer = models.ForeignKey(Analyzer, on_delete=(models.PROTECT), related_name='case_jobs') class-attribute instance-attribute

analyzer_report = models.ForeignKey(AnalyzerReport, on_delete=(models.SET_NULL), related_name='case_jobs', null=True, blank=True) class-attribute instance-attribute

status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_INPROGRESS) class-attribute instance-attribute

created_at = models.DateTimeField(auto_now_add=True) class-attribute instance-attribute

completed_at = models.DateTimeField(null=True, blank=True) class-attribute instance-attribute

Meta

constraints = [models.UniqueConstraint(fields=['case', 'cortex_job_id'], name='uniq_case_cortexjob')] class-attribute instance-attribute
indexes = [models.Index(fields=['cortex_job_id']), models.Index(fields=['case', 'status']), models.Index(fields=['status', 'created_at'])] class-attribute instance-attribute