user-panel #9

Merged
cayop merged 25 commits from user-panel into main 2024-10-11 14:26:36 +00:00
17 changed files with 224 additions and 85 deletions
Showing only changes of commit 029e694958 - Show all commits

View file

@ -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):

View file

@ -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,

View file

@ -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']

View file

@ -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

View file

@ -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

View file

@ -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"
),
),
]

View file

@ -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()

View file

@ -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}"

View file

@ -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()

View file

@ -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"
),
),
]

View file

@ -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)

View file

@ -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

View file

@ -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
)

View file

@ -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
)

View file

@ -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.

View file

@ -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'},
}

View file

@ -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'],