diff --git a/dashboard/mixins.py b/dashboard/mixins.py index c28dcf8..7e2e236 100644 --- a/dashboard/mixins.py +++ b/dashboard/mixins.py @@ -39,16 +39,16 @@ class DashboardView(LoginRequiredMixin): 'section': self.section, 'path': resolve(self.request.path).url_name, 'user': self.request.user, - 'lot_tags': LotTag.objects.filter(owner=self.request.user) + 'lot_tags': LotTag.objects.filter(owner=self.request.user.institution) }) return context def get_session_devices(self): - # import pdb; pdb.set_trace() dev_ids = self.request.session.pop("devices", []) self._devices = [] - for x in Annotation.objects.filter(value__in=dev_ids).filter(owner=self.request.user).distinct(): + annotation = Annotation.objects.filter(value__in=dev_ids) + for x in annotation.filter(owner=self.request.user.institution).distinct(): self._devices.append(Device(id=x.value)) return self._devices @@ -57,7 +57,7 @@ class DetailsMixin(DashboardView, TemplateView): def get(self, request, *args, **kwargs): self.pk = kwargs['pk'] - self.object = get_object_or_404(self.model, pk=self.pk, owner=self.request.user) + self.object = get_object_or_404(self.model, pk=self.pk, owner=self.request.user.institution) return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): diff --git a/dashboard/views.py b/dashboard/views.py index 79b9346..bcc4eeb 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -12,7 +12,7 @@ class UnassignedDevicesView(InventaryMixin): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - devices = Device.get_unassigned(self.request.user) + devices = Device.get_unassigned(self.request.user.institution) context.update({ 'devices': devices, diff --git a/device/models.py b/device/models.py index f1b1ee7..6e0bc50 100644 --- a/device/models.py +++ b/device/models.py @@ -113,10 +113,10 @@ class Device: self.lots = [x.lot for x in DeviceLot.objects.filter(device_id=self.id)] @classmethod - def get_unassigned(cls, user): - chids = DeviceLot.objects.filter(lot__owner=user).values_list("device_id", flat=True).distinct() + def get_unassigned(cls, institution): + chids = DeviceLot.objects.filter(lot__owner=institution).values_list("device_id", flat=True).distinct() annotations = Annotation.objects.filter( - owner=user, + owner=institution, type=Annotation.Type.SYSTEM, ).exclude(value__in=chids).values_list("value", flat=True).distinct() return [cls(id=x) for x in annotations] @@ -141,22 +141,17 @@ class Device: def manufacturer(self): if not self.last_evidence: self.get_last_evidence() - return self.last_evidence.doc['device']['manufacturer'] + return self.last_evidence.get_manufacturer() @property def type(self): if not self.last_evidence: self.get_last_evidence() - return self.last_evidence.doc['device']['type'] + return self.last_evidence.get_chassis() @property def model(self): if not self.last_evidence: self.get_last_evidence() - return self.last_evidence.doc['device']['model'] + return self.last_evidence.get_model() - @property - def type(self): - if not self.last_evidence: - self.get_last_evidence() - return self.last_evidence.doc['device']['type'] diff --git a/device/views.py b/device/views.py index e89cc3c..0fd9365 100644 --- a/device/views.py +++ b/device/views.py @@ -92,7 +92,7 @@ class DetailsView(DashboardView, TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) self.object.initial() - lot_tags = LotTag.objects.filter(owner=self.request.user) + lot_tags = LotTag.objects.filter(owner=self.request.user.institution) context.update({ 'object': self.object, 'snapshot': self.object.get_last_evidence(), @@ -110,7 +110,7 @@ class AddAnnotationView(DashboardView, CreateView): fields = ("key", "value") def form_valid(self, form): - form.instance.owner = self.request.user + form.instance.owner = self.request.user.institution form.instance.uuid = self.annotation.uuid form.instance.type = Annotation.Type.USER response = super().form_valid(form) @@ -118,11 +118,12 @@ class AddAnnotationView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') + institution = self.request.user.institution self.annotation = Annotation.objects.filter( - owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + owner=institution, value=pk, type=Annotation.Type.SYSTEM ).first() if not self.annotation: - get_object_or_404(Annotation, pk=0, owner=self.request.user) + get_object_or_404(Annotation, pk=0, owner=institution) self.success_url = reverse_lazy('device:details', args=[pk]) kwargs = super().get_form_kwargs() return kwargs @@ -137,7 +138,7 @@ class AddDocumentView(DashboardView, CreateView): fields = ("key", "value") def form_valid(self, form): - form.instance.owner = self.request.user + form.instance.owner = self.request.user.institution form.instance.uuid = self.annotation.uuid form.instance.type = Annotation.Type.DOCUMENT response = super().form_valid(form) @@ -145,11 +146,12 @@ class AddDocumentView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') + institution = self.request.user.institution self.annotation = Annotation.objects.filter( - owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + owner=institution, value=pk, type=Annotation.Type.SYSTEM ).first() if not self.annotation: - get_object_or_404(Annotation, pk=0, owner=self.request.user) + get_object_or_404(Annotation, pk=0, owner=institution) self.success_url = reverse_lazy('device:details', args=[pk]) kwargs = super().get_form_kwargs() return kwargs diff --git a/evidence/forms.py b/evidence/forms.py index ae2630d..be50ca8 100644 --- a/evidence/forms.py +++ b/evidence/forms.py @@ -71,7 +71,7 @@ class UserTagForm(forms.Form): Annotation.objects.create( uuid=self.uuid, - owner=user, + owner=user.institution, type=Annotation.Type.SYSTEM, key='CUSTOM_ID', value=self.tag diff --git a/evidence/migrations/0004_alter_annotation_owner.py b/evidence/migrations/0004_alter_annotation_owner.py new file mode 100644 index 0000000..26c9bda --- /dev/null +++ b/evidence/migrations/0004_alter_annotation_owner.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.6 on 2024-09-18 10:55 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("evidence", "0003_alter_annotation_type"), + ("user", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="annotation", + name="owner", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="user.institution" + ), + ), + ] diff --git a/evidence/models.py b/evidence/models.py index dbb47a0..30625aa 100644 --- a/evidence/models.py +++ b/evidence/models.py @@ -1,10 +1,11 @@ import json +from dmidecode import DMIParse from django.db import models -from utils.constants import STR_SM_SIZE, STR_EXTEND_SIZE +from utils.constants import STR_SM_SIZE, STR_EXTEND_SIZE, CHASSIS_DH from evidence.xapian import search -from user.models import User +from user.models import Institution class Annotation(models.Model): @@ -15,7 +16,7 @@ class Annotation(models.Model): created = models.DateTimeField(auto_now_add=True) uuid = models.UUIDField() - owner = models.ForeignKey(User, on_delete=models.CASCADE) + owner = models.ForeignKey(Institution, on_delete=models.CASCADE) type = models.SmallIntegerField(choices=Type) key = models.CharField(max_length=STR_EXTEND_SIZE) value = models.CharField(max_length=STR_EXTEND_SIZE) @@ -32,6 +33,7 @@ class Evidence: self.owner = None self.doc = None self.created = None + self.dmi = None self.annotations = [] self.get_owner() @@ -58,6 +60,11 @@ class Evidence: for xa in matches: self.doc = json.loads(xa.document.get_data()) + + if self.doc.get("software") == "EreuseWorkbench": + dmidecode_raw = self.doc["data"]["dmidecode"] + self.dmi = DMIParse(dmidecode_raw) + def get_time(self): if not self.doc: @@ -70,9 +77,35 @@ class Evidence: def components(self): return self.doc.get('components', []) + def get_manufacturer(self): + if self.doc.get("software") != "EreuseWorkbench": + return self.doc['device']['manufacturer'] + + return self.dmi.manufacturer().strip() + + def get_model(self): + if self.doc.get("software") != "EreuseWorkbench": + return self.doc['device']['model'] + + return self.dmi.model().strip() + + def get_chassis(self): + if self.doc.get("software") != "EreuseWorkbench": + return self.doc['device']['model'] + + chassis = self.dmi.get("Chassis")[0].get("Type", '_virtual') + lower_type = chassis.lower() + + for k, v in CHASSIS_DH.items(): + if lower_type in v: + return k + return "" + + + @classmethod def get_all(cls, user): return Annotation.objects.filter( - owner=user, + owner=user.institution, type=Annotation.Type.SYSTEM, ).order_by("-created").values_list("uuid", flat=True).distinct() diff --git a/evidence/parse.py b/evidence/parse.py index 614c2ec..d9cfeda 100644 --- a/evidence/parse.py +++ b/evidence/parse.py @@ -4,9 +4,10 @@ import shutil import hashlib from datetime import datetime +from dmidecode import DMIParse from evidence.xapian import search, index from evidence.models import Evidence, Annotation -from utils.constants import ALGOS +from utils.constants import ALGOS, CHASSIS_DH class Build: @@ -33,13 +34,17 @@ class Build: } def get_hid_14(self): - device = self.json['device'] - manufacturer = device.get("manufacturer", '') - model = device.get("model", '') - chassis = device.get("chassis", '') - serial_number = device.get("serialNumber", '') - sku = device.get("sku", '') - hid = f"{manufacturer}{model}{chassis}{serial_number}{sku}" + if self.json.get("software") == "EreuseWorkbench": + hid = self.get_hid(self.json) + else: + device = self.json['device'] + manufacturer = device.get("manufacturer", '') + model = device.get("model", '') + chassis = device.get("chassis", '') + serial_number = device.get("serialNumber", '') + sku = device.get("sku", '') + hid = f"{manufacturer}{model}{chassis}{serial_number}{sku}" + return hashlib.sha3_256(hid.encode()).hexdigest() def create_annotations(self): @@ -47,8 +52,34 @@ class Build: for k, v in self.algorithms.items(): Annotation.objects.create( uuid=self.uuid, - owner=self.user, + owner=self.user.institution, type=Annotation.Type.SYSTEM, key=k, value=v ) + + def get_chassis_dh(self): + chassis = self.get_chassis() + lower_type = chassis.lower() + for k, v in CHASSIS_DH.items(): + if lower_type in v: + return k + return self.default + + def get_sku(self): + return self.dmi.get("System")[0].get("SKU Number", "n/a").strip() + + def get_chassis(self): + return self.dmi.get("Chassis")[0].get("Type", '_virtual') + + def get_hid(self, snapshot): + dmidecode_raw = snapshot["data"]["dmidecode"] + self.dmi = DMIParse(dmidecode_raw) + + manufacturer = self.dmi.manufacturer().strip() + model = self.dmi.model().strip() + chassis = self.get_chassis_dh() + serial_number = self.dmi.serial_number() + sku = self.get_sku() + + return f"{manufacturer}{model}{chassis}{serial_number}{sku}" diff --git a/evidence/views.py b/evidence/views.py index 1e02c7e..d98bddb 100644 --- a/evidence/views.py +++ b/evidence/views.py @@ -89,7 +89,7 @@ class EvidenceView(DashboardView, FormView): def get(self, request, *args, **kwargs): self.pk = kwargs['pk'] self.object = Evidence(self.pk) - if self.object.owner != self.request.user: + if self.object.owner != self.request.user.institution: raise Http403 self.object.get_annotations() @@ -127,7 +127,7 @@ class DownloadEvidenceView(DashboardView, TemplateView): def get(self, request, *args, **kwargs): pk = kwargs['pk'] evidence = Evidence(pk) - if evidence.owner != self.request.user: + if evidence.owner != self.request.user.institution: raise Http403() evidence.get_doc() diff --git a/lot/migrations/0003_alter_lot_owner_alter_lotannotation_owner_and_more.py b/lot/migrations/0003_alter_lot_owner_alter_lotannotation_owner_and_more.py new file mode 100644 index 0000000..806c6f1 --- /dev/null +++ b/lot/migrations/0003_alter_lot_owner_alter_lotannotation_owner_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 5.0.6 on 2024-09-18 10:55 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("lot", "0002_lotannotation"), + ("user", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="lot", + name="owner", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="user.institution" + ), + ), + migrations.AlterField( + model_name="lotannotation", + name="owner", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="user.institution" + ), + ), + migrations.AlterField( + model_name="lottag", + name="owner", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="user.institution" + ), + ), + ] diff --git a/lot/models.py b/lot/models.py index 9078459..3926f29 100644 --- a/lot/models.py +++ b/lot/models.py @@ -6,14 +6,14 @@ from utils.constants import ( STR_EXTEND_SIZE, ) -from user.models import User +from user.models import Institution # from device.models import Device -from evidence.models import Annotation +# from evidence.models import Annotation class LotTag(models.Model): name = models.CharField(max_length=STR_SIZE, blank=False, null=False) - owner = models.ForeignKey(User, on_delete=models.CASCADE) + owner = models.ForeignKey(Institution, on_delete=models.CASCADE) def __str__(self): return self.name @@ -31,7 +31,7 @@ class Lot(models.Model): code = models.CharField(max_length=STR_SIZE, blank=True, null=True) description = models.CharField(max_length=STR_SIZE, blank=True, null=True) closed = models.BooleanField(default=True) - owner = models.ForeignKey(User, on_delete=models.CASCADE) + owner = models.ForeignKey(Institution, on_delete=models.CASCADE) type = models.ForeignKey(LotTag, on_delete=models.CASCADE) def add(self, v): @@ -52,7 +52,7 @@ class LotAnnotation(models.Model): created = models.DateTimeField(auto_now_add=True) lot = models.ForeignKey(Lot, on_delete=models.CASCADE) - owner = models.ForeignKey(User, on_delete=models.CASCADE) + owner = models.ForeignKey(Institution, on_delete=models.CASCADE) type = models.SmallIntegerField(choices=Type) key = models.CharField(max_length=STR_EXTEND_SIZE) value = models.CharField(max_length=STR_EXTEND_SIZE) diff --git a/lot/views.py b/lot/views.py index 280450e..46252c8 100644 --- a/lot/views.py +++ b/lot/views.py @@ -28,7 +28,7 @@ class NewLotView(DashboardView, CreateView): ) def form_valid(self, form): - form.instance.owner = self.request.user + form.instance.owner = self.request.user.institution response = super().form_valid(form) return response @@ -83,8 +83,8 @@ class AddToLotView(DashboardView, FormView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - lots = Lot.objects.filter(owner=self.request.user) - lot_tags = LotTag.objects.filter(owner=self.request.user) + lots = Lot.objects.filter(owner=self.request.user.institution) + lot_tags = LotTag.objects.filter(owner=self.request.user.institution) context.update({ 'lots': lots, 'lot_tags':lot_tags, @@ -93,7 +93,7 @@ class AddToLotView(DashboardView, FormView): def get_form(self): form = super().get_form() - form.fields["lots"].queryset = Lot.objects.filter(owner=self.request.user) + form.fields["lots"].queryset = Lot.objects.filter(owner=self.request.user.institution) return form def form_valid(self, form): @@ -123,10 +123,10 @@ class LotsTagsView(DashboardView, TemplateView): def get_context_data(self, **kwargs): self.pk = kwargs.get('pk') context = super().get_context_data(**kwargs) - tag = get_object_or_404(LotTag, owner=self.request.user, id=self.pk) + tag = get_object_or_404(LotTag, owner=self.request.user.institution, id=self.pk) self.title += " {}".format(tag.name) self.breadcrumb += " {}".format(tag.name) - lots = Lot.objects.filter(owner=self.request.user).filter(type=tag) + lots = Lot.objects.filter(owner=self.request.user.institution).filter(type=tag) context.update({ 'lots': lots, 'title': self.title, @@ -144,7 +144,7 @@ class LotAddDocumentView(DashboardView, CreateView): fields = ("key", "value") def form_valid(self, form): - form.instance.owner = self.request.user + form.instance.owner = self.request.user.institution form.instance.lot = self.lot form.instance.type = LotAnnotation.Type.DOCUMENT response = super().form_valid(form) @@ -152,7 +152,7 @@ class LotAddDocumentView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') - self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user) + self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user.institution) self.success_url = reverse_lazy('lot:documents', args=[pk]) kwargs = super().get_form_kwargs() return kwargs @@ -166,10 +166,10 @@ class LotDocumentsView(DashboardView, TemplateView): def get_context_data(self, **kwargs): self.pk = kwargs.get('pk') context = super().get_context_data(**kwargs) - lot = get_object_or_404(Lot, owner=self.request.user, id=self.pk) + lot = get_object_or_404(Lot, owner=self.request.user.institution, id=self.pk) documents = LotAnnotation.objects.filter( lot=lot, - owner=self.request.user, + owner=self.request.user.institution, type=LotAnnotation.Type.DOCUMENT, ) context.update({ @@ -189,10 +189,10 @@ class LotAnnotationsView(DashboardView, TemplateView): def get_context_data(self, **kwargs): self.pk = kwargs.get('pk') context = super().get_context_data(**kwargs) - lot = get_object_or_404(Lot, owner=self.request.user, id=self.pk) + lot = get_object_or_404(Lot, owner=self.request.user.institution, id=self.pk) annotations = LotAnnotation.objects.filter( lot=lot, - owner=self.request.user, + owner=self.request.user.institution, type=LotAnnotation.Type.USER, ) context.update({ @@ -213,7 +213,7 @@ class LotAddAnnotationView(DashboardView, CreateView): fields = ("key", "value") def form_valid(self, form): - form.instance.owner = self.request.user + form.instance.owner = self.request.user.institution form.instance.lot = self.lot form.instance.type = LotAnnotation.Type.USER response = super().form_valid(form) @@ -221,7 +221,7 @@ class LotAddAnnotationView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') - self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user) + self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user.institution) self.success_url = reverse_lazy('lot:annotations', args=[pk]) kwargs = super().get_form_kwargs() return kwargs diff --git a/user/management/commands/add_institution.py b/user/management/commands/add_institution.py index 622dff8..b7a4a26 100644 --- a/user/management/commands/add_institution.py +++ b/user/management/commands/add_institution.py @@ -1,6 +1,6 @@ from django.core.management.base import BaseCommand from user.models import Institution - +from lot.models import LotTag class Command(BaseCommand): help = "Create a new Institution" @@ -9,4 +9,17 @@ class Command(BaseCommand): parser.add_argument('name', type=str, help='institution') def handle(self, *args, **kwargs): - Institution.objects.create(name=kwargs['name']) + self.institution = Institution.objects.create(name=kwargs['name']) + self.create_lot_tags() + + def create_lot_tags(self): + tags = [ + "Entrada", + "Salida", + "Temporal" + ] + for tag in tags: + LotTag.objects.create( + name=tag, + owner=self.institution + ) diff --git a/user/management/commands/add_user.py b/user/management/commands/add_user.py index 7d31ab7..499adfa 100644 --- a/user/management/commands/add_user.py +++ b/user/management/commands/add_user.py @@ -1,6 +1,5 @@ from django.core.management.base import BaseCommand from django.contrib.auth import get_user_model -from lot.models import LotTag from user.models import Institution @@ -16,29 +15,16 @@ class Command(BaseCommand): parser.add_argument('password', type=str, help='password') def handle(self, *args, **kwargs): - email = kwargs['email'] - password = kwargs['password'] - institution = Institution.objects.get(name=kwargs['institution']) - self.create_user(institution, email, password) - self.create_lot_tags() + self.email = kwargs['email'] + self.password = kwargs['password'] + self.institution = Institution.objects.get(name=kwargs['institution']) + self.create_user() - def create_user(self, institution, email, password): + def create_user(self): self.u = User.objects.create( - institution=institution, - email=email, - password=password + institution=self.institution, + email=self.email, + password=self.password ) - self.u.set_password(password) + self.u.set_password(self.password) self.u.save() - - def create_lot_tags(self): - tags = [ - "Entrada", - "Salida", - "Temporal" - ] - for tag in tags: - LotTag.objects.create( - name=tag, - owner=self.u - ) diff --git a/user/views.py b/user/views.py index 91ea44a..e7f3289 100644 --- a/user/views.py +++ b/user/views.py @@ -1,3 +1,6 @@ from django.shortcuts import render +from django.utils.translation import gettext_lazy as _ +from dashboard.mixins import InventaryMixin, DetailsMixin + + -# Create your views here. diff --git a/utils/constants.py b/utils/constants.py index 2fd9a13..e481d6c 100644 --- a/utils/constants.py +++ b/utils/constants.py @@ -20,3 +20,21 @@ HID_ALGO1 = [ ALGOS = { "hidalgo1": HID_ALGO1, } + + +CHASSIS_DH = { + 'Tower': {'desktop', 'low-profile', 'tower', 'server'}, + 'Docking': {'docking'}, + 'AllInOne': {'all-in-one'}, + 'Microtower': {'mini-tower', 'space-saving', 'mini'}, + 'PizzaBox': {'pizzabox'}, + 'Lunchbox': {'lunchbox'}, + 'Stick': {'stick'}, + 'Netbook': {'notebook', 'sub-notebook'}, + 'Handheld': {'handheld'}, + 'Laptop': {'portable', 'laptop'}, + 'Convertible': {'convertible'}, + 'Detachable': {'detachable'}, + 'Tablet': {'tablet'}, + 'Virtual': {'_virtual'}, +} diff --git a/utils/device.py b/utils/device.py index 2e41597..db9f0ce 100644 --- a/utils/device.py +++ b/utils/device.py @@ -69,7 +69,7 @@ def create_annotation(doc, user, commit=False): data = { 'uuid': doc['uuid'], - 'owner': user, + 'owner': user.institution, 'type': Annotation.Type.SYSTEM, 'key': 'CUSTOMER_ID', 'value': doc['CUSTOMER_ID'],