devicehub-django/evidence/models.py

182 lines
5.1 KiB
Python
Raw Normal View History

2024-07-18 15:21:22 +00:00
import json
2024-09-18 16:01:46 +00:00
from dmidecode import DMIParse
2024-06-12 07:32:49 +00:00
from django.db import models
2024-07-18 15:21:22 +00:00
2024-11-12 15:22:09 +00:00
from django.db.models import Q
from utils.constants import STR_EXTEND_SIZE, CHASSIS_DH
2024-07-26 15:59:34 +00:00
from evidence.xapian import search
from evidence.parse_details import ParseSnapshot
from user.models import User, Institution
2024-06-12 07:32:49 +00:00
2024-11-12 15:22:09 +00:00
#TODO: base class is abstract; revise if should be for query efficiency
class Property(models.Model):
2024-07-31 11:28:46 +00:00
class Type(models.IntegerChoices):
2024-11-04 07:21:01 +00:00
SYSTEM = 0, "System"
2024-07-31 11:28:46 +00:00
USER = 1, "User"
DOCUMENT = 2, "Document"
2024-10-28 16:52:34 +00:00
ERASE_SERVER = 3, "EraseServer"
2024-07-31 11:28:46 +00:00
created = models.DateTimeField(auto_now_add=True)
uuid = models.UUIDField()
2024-09-18 16:01:46 +00:00
owner = models.ForeignKey(Institution, on_delete=models.CASCADE)
2024-11-04 07:21:01 +00:00
user = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, blank=True)
type = models.SmallIntegerField(choices=Type)
2024-07-31 11:28:46 +00:00
key = models.CharField(max_length=STR_EXTEND_SIZE)
value = models.CharField(max_length=STR_EXTEND_SIZE)
class Meta:
#Only for shared behaviour, it is not a table
2024-11-12 15:22:09 +00:00
abstract = True
class SystemProperty(Property):
class Meta:
constraints = [
models.CheckConstraint(
check=~Q(type=1), #Enforce that type is not User
name='property_cannot_be_user'
),
]
#Django orm wont inherit constraints to child
#TODO: check if this is needed
constraints = [
models.UniqueConstraint(
fields=["type", "key", "uuid"], name="system_unique_type_key_uuid")
]
2024-11-12 15:22:09 +00:00
class UserProperty(Property):
type = models.SmallIntegerField(default=Property.Type.USER)
class Meta:
constraints = [
models.CheckConstraint(
check=Q(type=1), #Enforce that type is User
name='property_needs_to_be_user'
),
]
constraints = [
models.UniqueConstraint(
fields=["type", "key", "uuid"], name="user_unique_type_key_uuid")
]
2024-11-12 15:22:09 +00:00
2024-07-31 11:28:46 +00:00
2024-07-26 15:59:34 +00:00
class Evidence:
2024-07-18 15:21:22 +00:00
def __init__(self, uuid):
self.uuid = uuid
self.owner = None
self.doc = None
self.created = None
2024-09-18 16:01:46 +00:00
self.dmi = None
self.properties = []
2024-11-04 07:21:01 +00:00
self.components = []
self.default = "n/a"
2024-06-12 07:32:49 +00:00
2024-07-18 15:21:22 +00:00
self.get_owner()
self.get_time()
2024-06-12 07:32:49 +00:00
def get_properties(self):
self.properties = SystemProperty.objects.filter(
2024-07-18 15:21:22 +00:00
uuid=self.uuid
).order_by("created")
2024-07-31 11:28:46 +00:00
2024-07-18 15:21:22 +00:00
def get_owner(self):
if not self.properties:
self.get_properties()
a = self.properties.first()
2024-07-18 15:21:22 +00:00
if a:
self.owner = a.owner
2024-06-12 07:32:49 +00:00
2024-07-18 15:21:22 +00:00
def get_doc(self):
self.doc = {}
if not self.owner:
self.get_owner()
2024-07-18 15:21:22 +00:00
qry = 'uuid:"{}"'.format(self.uuid)
matches = search(self.owner, qry, limit=1)
2024-10-25 15:36:13 +00:00
if matches and matches.size() < 0:
2024-07-18 15:21:22 +00:00
return
for xa in matches:
self.doc = json.loads(xa.document.get_data())
if not self.is_legacy():
2024-09-18 16:01:46 +00:00
dmidecode_raw = self.doc["data"]["dmidecode"]
self.dmi = DMIParse(dmidecode_raw)
2024-07-18 15:21:22 +00:00
def get_time(self):
if not self.doc:
self.get_doc()
self.created = self.doc.get("endTime")
if not self.created:
self.created = self.properties.last().created
2024-07-18 15:21:22 +00:00
def get_components(self):
if self.is_legacy():
return self.doc.get('components', [])
self.set_components()
return self.components
2024-07-01 10:17:23 +00:00
2024-09-18 16:01:46 +00:00
def get_manufacturer(self):
2024-11-06 16:21:48 +00:00
if self.is_web_snapshot():
kv = self.doc.get('kv', {})
if len(kv) < 1:
return ""
return list(self.doc.get('kv').values())[0]
if self.is_legacy():
2024-09-18 16:01:46 +00:00
return self.doc['device']['manufacturer']
2024-09-18 16:01:46 +00:00
return self.dmi.manufacturer().strip()
2024-09-18 16:01:46 +00:00
def get_model(self):
2024-11-06 16:21:48 +00:00
if self.is_web_snapshot():
kv = self.doc.get('kv', {})
if len(kv) < 2:
return ""
return list(self.doc.get('kv').values())[1]
if self.is_legacy():
2024-09-18 16:01:46 +00:00
return self.doc['device']['model']
2024-09-18 16:01:46 +00:00
return self.dmi.model().strip()
def get_chassis(self):
if self.is_legacy():
2024-09-18 16:01:46 +00:00
return self.doc['device']['model']
chassis = self.dmi.get("Chassis")[0].get("Type", '_virtual')
2024-09-18 16:01:46 +00:00
lower_type = chassis.lower()
2024-09-18 16:01:46 +00:00
for k, v in CHASSIS_DH.items():
if lower_type in v:
return k
return ""
2024-11-04 07:21:01 +00:00
def get_serial_number(self):
if self.is_legacy():
return self.doc['device']['serialNumber']
return self.dmi.serial_number().strip()
2024-07-31 11:28:46 +00:00
@classmethod
def get_all(cls, user):
return SystemProperty.objects.filter(
2024-09-18 16:01:46 +00:00
owner=user.institution,
2024-11-13 22:16:33 +00:00
type=Property.Type.SYSTEM,
2024-10-16 12:17:35 +00:00
key="hidalgo1",
2024-10-21 11:28:20 +00:00
).order_by("-created").values_list("uuid", "created").distinct()
def set_components(self):
snapshot = ParseSnapshot(self.doc).snapshot_json
self.components = snapshot['components']
def is_legacy(self):
return self.doc.get("software") != "workbench-script"
2024-11-04 07:21:01 +00:00
2024-11-06 16:21:48 +00:00
def is_web_snapshot(self):
2024-11-04 07:21:01 +00:00
return self.doc.get("type") == "WebSnapshot"