devicehub-django/device/models.py

338 lines
9.9 KiB
Python
Raw Normal View History

import json
from django.db import models, connection
2024-07-18 15:21:22 +00:00
from utils.constants import ALGOS
2024-07-26 15:59:34 +00:00
from evidence.models import Annotation, Evidence
2024-07-19 15:40:01 +00:00
from lot.models import DeviceLot
2024-06-12 07:32:49 +00:00
2024-07-19 15:40:01 +00:00
class Device:
2024-07-05 13:32:07 +00:00
class Types(models.TextChoices):
DESKTOP = "Desktop"
LAPTOP = "Laptop"
SERVER = "Server"
GRAPHICCARD = "GraphicCard"
HARDDRIVE = "HardDrive"
SOLIDSTATEDRIVE = "SolidStateDrive"
MOTHERBOARD = "Motherboard"
NETWORKADAPTER = "NetworkAdapter"
PROCESSOR = "Processor"
RAMMODULE = "RamModule"
SOUNDCARD = "SoundCard"
DISPLAY = "Display"
BATTERY = "Battery"
CAMERA = "Camera"
2024-07-18 15:21:22 +00:00
def __init__(self, *args, **kwargs):
2024-07-19 15:40:01 +00:00
# the id is the chid of the device
self.id = kwargs["id"]
self.pk = self.id
2024-10-14 15:43:32 +00:00
self.shortid = self.pk[:6].upper()
2024-07-19 15:40:01 +00:00
self.algorithm = None
self.owner = None
2024-11-04 07:20:37 +00:00
self.annotations = []
2024-07-18 15:21:22 +00:00
self.hids = []
self.uuids = []
2024-07-26 15:59:34 +00:00
self.evidences = []
2024-07-31 11:21:54 +00:00
self.lots = []
2024-07-26 15:59:34 +00:00
self.last_evidence = None
self.get_last_evidence()
2024-07-18 15:21:22 +00:00
def initial(self):
self.get_annotations()
self.get_uuids()
self.get_hids()
2024-07-26 15:59:34 +00:00
self.get_evidences()
2024-07-31 11:21:54 +00:00
self.get_lots()
2024-08-05 13:06:34 +00:00
2024-07-18 15:21:22 +00:00
def get_annotations(self):
2024-07-19 15:40:01 +00:00
if self.annotations:
return self.annotations
2024-08-05 13:06:34 +00:00
2024-07-18 15:21:22 +00:00
self.annotations = Annotation.objects.filter(
2024-07-19 15:40:01 +00:00
type=Annotation.Type.SYSTEM,
value=self.id
2024-07-18 15:21:22 +00:00
).order_by("-created")
2024-07-19 15:40:01 +00:00
if self.annotations.count():
self.algorithm = self.annotations[0].key
self.owner = self.annotations[0].owner
return self.annotations
2024-07-30 11:37:08 +00:00
def get_user_annotations(self):
if not self.uuids:
self.get_uuids()
annotations = Annotation.objects.filter(
uuid__in=self.uuids,
owner=self.owner,
type=Annotation.Type.USER
)
return annotations
2024-08-05 13:06:34 +00:00
2024-07-30 11:37:08 +00:00
def get_user_documents(self):
if not self.uuids:
self.get_uuids()
annotations = Annotation.objects.filter(
uuid__in=self.uuids,
owner=self.owner,
type=Annotation.Type.DOCUMENT
)
return annotations
2024-08-05 13:06:34 +00:00
2024-07-18 15:21:22 +00:00
def get_uuids(self):
2024-07-19 15:40:01 +00:00
for a in self.get_annotations():
2024-07-30 11:37:08 +00:00
if a.uuid not in self.uuids:
2024-07-18 15:21:22 +00:00
self.uuids.append(a.uuid)
def get_hids(self):
2024-07-19 15:40:01 +00:00
annotations = self.get_annotations()
2024-07-18 15:21:22 +00:00
2024-10-16 15:40:00 +00:00
algos = list(ALGOS.keys())
algos.append('CUSTOM_ID')
2024-09-26 03:10:48 +00:00
self.hids = list(set(annotations.filter(
2024-07-18 15:21:22 +00:00
type=Annotation.Type.SYSTEM,
2024-10-16 15:40:00 +00:00
key__in=algos,
2024-09-26 03:10:48 +00:00
).values_list("value", flat=True)))
2024-07-18 15:21:22 +00:00
2024-07-26 15:59:34 +00:00
def get_evidences(self):
2024-07-18 15:21:22 +00:00
if not self.uuids:
self.get_uuids()
2024-07-26 15:59:34 +00:00
self.evidences = [Evidence(u) for u in self.uuids]
2024-07-18 15:21:22 +00:00
2024-07-26 15:59:34 +00:00
def get_last_evidence(self):
2024-07-19 15:40:01 +00:00
annotations = self.get_annotations()
2024-09-25 17:04:29 +00:00
if not annotations.count():
return
annotation = annotations.first()
2024-07-26 15:59:34 +00:00
self.last_evidence = Evidence(annotation.uuid)
2024-11-04 07:20:37 +00:00
2024-10-28 16:52:34 +00:00
def is_eraseserver(self):
if not self.uuids:
self.get_uuids()
if not self.uuids:
return False
annotation = Annotation.objects.filter(
uuid__in=self.uuids,
owner=self.owner,
type=Annotation.Type.ERASE_SERVER
).first()
2024-11-04 07:20:37 +00:00
2024-10-28 16:52:34 +00:00
if annotation:
return True
return False
2024-07-18 15:21:22 +00:00
2024-07-19 15:40:01 +00:00
def last_uuid(self):
return self.uuids[0]
2024-07-18 15:21:22 +00:00
2024-07-31 11:21:54 +00:00
def get_lots(self):
2024-11-04 07:20:37 +00:00
self.lots = [
x.lot for x in DeviceLot.objects.filter(device_id=self.id)]
2024-07-31 11:21:54 +00:00
2024-07-18 15:21:22 +00:00
@classmethod
2024-10-10 09:44:23 +00:00
def get_unassigned(cls, institution, offset=0, limit=None):
sql = """
2024-10-16 12:17:35 +00:00
WITH RankedAnnotations AS (
SELECT
t1.value,
t1.key,
ROW_NUMBER() OVER (
PARTITION BY t1.uuid
ORDER BY
CASE
WHEN t1.key = 'CUSTOM_ID' THEN 1
WHEN t1.key = 'hidalgo1' THEN 2
ELSE 3
END,
t1.created DESC
) AS row_num
FROM evidence_annotation AS t1
LEFT JOIN lot_devicelot AS t2 ON t1.value = t2.device_id
WHERE t2.device_id IS NULL
AND t1.owner_id = {institution}
AND t1.type = {type}
)
SELECT DISTINCT
value
FROM
RankedAnnotations
WHERE
row_num = 1
""".format(
2024-10-10 09:44:23 +00:00
institution=institution.id,
type=Annotation.Type.SYSTEM,
)
if limit:
sql += " limit {} offset {}".format(int(limit), int(offset))
sql += ";"
annotations = []
with connection.cursor() as cursor:
cursor.execute(sql)
annotations = cursor.fetchall()
devices = [cls(id=x[0]) for x in annotations]
2024-10-10 09:44:23 +00:00
count = cls.get_unassigned_count(institution)
return devices, count
@classmethod
2024-10-10 09:44:23 +00:00
def get_unassigned_count(cls, institution):
sql = """
2024-10-16 12:17:35 +00:00
WITH RankedAnnotations AS (
SELECT
t1.value,
t1.key,
ROW_NUMBER() OVER (
PARTITION BY t1.uuid
ORDER BY
CASE
WHEN t1.key = 'CUSTOM_ID' THEN 1
WHEN t1.key = 'hidalgo1' THEN 2
ELSE 3
END,
t1.created DESC
) AS row_num
FROM evidence_annotation AS t1
LEFT JOIN lot_devicelot AS t2 ON t1.value = t2.device_id
WHERE t2.device_id IS NULL
AND t1.owner_id = {institution}
AND t1.type = {type}
)
SELECT
COUNT(DISTINCT value)
FROM
RankedAnnotations
WHERE
row_num = 1
""".format(
2024-10-10 09:44:23 +00:00
institution=institution.id,
2024-07-19 15:40:01 +00:00
type=Annotation.Type.SYSTEM,
)
with connection.cursor() as cursor:
cursor.execute(sql)
return cursor.fetchall()[0][0]
2024-07-19 15:40:01 +00:00
2024-10-16 12:17:35 +00:00
@classmethod
def get_annotation_from_uuid(cls, uuid, institution):
sql = """
WITH RankedAnnotations AS (
SELECT
t1.value,
t1.key,
ROW_NUMBER() OVER (
PARTITION BY t1.uuid
ORDER BY
CASE
WHEN t1.key = 'CUSTOM_ID' THEN 1
WHEN t1.key = 'hidalgo1' THEN 2
ELSE 3
END,
t1.created DESC
) AS row_num
FROM evidence_annotation AS t1
LEFT JOIN lot_devicelot AS t2 ON t1.value = t2.device_id
WHERE t2.device_id IS NULL
AND t1.owner_id = {institution}
AND t1.type = {type}
AND t1.uuid = '{uuid}'
)
SELECT DISTINCT
value
FROM
RankedAnnotations
WHERE
row_num = 1;
""".format(
uuid=uuid.replace("-", ""),
institution=institution.id,
type=Annotation.Type.SYSTEM,
)
annotations = []
with connection.cursor() as cursor:
cursor.execute(sql)
annotations = cursor.fetchall()
return cls(id=annotations[0][0])
2024-08-05 13:06:34 +00:00
@property
def is_websnapshot(self):
if not self.last_evidence:
self.get_last_evidence()
return self.last_evidence.doc['type'] == "WebSnapshot"
2024-08-05 13:06:34 +00:00
@property
def last_user_evidence(self):
if not self.last_evidence:
self.get_last_evidence()
return self.last_evidence.doc['kv'].items()
2024-07-19 15:40:01 +00:00
@property
def manufacturer(self):
2024-07-26 15:59:34 +00:00
if not self.last_evidence:
self.get_last_evidence()
2024-09-18 16:01:46 +00:00
return self.last_evidence.get_manufacturer()
2024-07-19 15:40:01 +00:00
2024-11-04 07:20:37 +00:00
@property
def serial_number(self):
if not self.last_evidence:
self.get_last_evidence()
return self.last_evidence.get_serial_number()
2024-07-19 15:40:01 +00:00
@property
def type(self):
if self.last_evidence.doc['type'] == "WebSnapshot":
return self.last_evidence.doc.get("device", {}).get("type", "")
2024-07-26 15:59:34 +00:00
if not self.last_evidence:
self.get_last_evidence()
2024-09-18 16:01:46 +00:00
return self.last_evidence.get_chassis()
2024-07-19 15:40:01 +00:00
@property
def model(self):
2024-07-26 15:59:34 +00:00
if not self.last_evidence:
self.get_last_evidence()
2024-09-18 16:01:46 +00:00
return self.last_evidence.get_model()
2024-07-19 15:40:01 +00:00
@property
def components(self):
if not self.last_evidence:
self.get_last_evidence()
return self.last_evidence.get_components()
def get_components_data(self, is_user_authenticated):
if is_user_authenticated:
return self.components
public_components = [component.copy() for component in self.components]
self.remove_sensitive_data_from(public_components)
return public_components
def remove_sensitive_data_from(self, components):
for component in components:
component.pop('SerialNumber', None)
component.pop('serial_number', None)
def get_device_data(self, should_include_sensitive_fields):
data = {
'id': self.id,
'shortid': self.shortid,
'uuids': self.uuids,
'hids': self.hids,
'components': self.get_components_data(should_include_sensitive_fields),
}
if should_include_sensitive_fields:
data.update({
'serial_number': self.serial_number,
})
return data