From 693dbc639c9d1456ce35604102abc20ec5cf5129 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 4 Oct 2024 17:32:53 +0200 Subject: [PATCH] add institutio as owner of devices and add owner to xapian docs --- dashboard/mixins.py | 4 ++- device/forms.py | 2 +- device/views.py | 29 +++++++++++++------ evidence/forms.py | 14 +++++---- evidence/migrations/0001_initial.py | 14 +++++++-- .../migrations/0002_alter_annotation_type.py | 20 ------------- .../migrations/0003_alter_annotation_type.py | 20 ------------- evidence/models.py | 11 ++++--- evidence/parse.py | 7 +++-- evidence/views.py | 11 +++++-- evidence/xapian.py | 14 ++++++--- utils/device.py | 7 +++-- 12 files changed, 78 insertions(+), 75 deletions(-) delete mode 100644 evidence/migrations/0002_alter_annotation_type.py delete mode 100644 evidence/migrations/0003_alter_annotation_type.py diff --git a/dashboard/mixins.py b/dashboard/mixins.py index 07004ee..8b70934 100644 --- a/dashboard/mixins.py +++ b/dashboard/mixins.py @@ -47,7 +47,9 @@ class DashboardView(LoginRequiredMixin): 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(): + for x in Annotation.objects.filter(value__in=dev_ids).filter( + owner=self.request.user.institution + ).distinct(): self._devices.append(Device(id=x.value)) return self._devices diff --git a/device/forms.py b/device/forms.py index b6c1d21..a770218 100644 --- a/device/forms.py +++ b/device/forms.py @@ -56,7 +56,7 @@ class BaseDeviceFormSet(forms.BaseFormSet): if not commit: return doc - create_index(doc) + create_index(doc, self.user) create_annotation(doc, user, commit=commit) return doc diff --git a/device/views.py b/device/views.py index e89cc3c..05183b0 100644 --- a/device/views.py +++ b/device/views.py @@ -9,9 +9,8 @@ from django.views.generic.edit import ( FormView, ) from django.views.generic.base import TemplateView -from dashboard.mixins import DashboardView +from dashboard.mixins import DashboardView, Http403 from evidence.models import Annotation -from evidence.xapian import search from lot.models import LotTag from device.models import Device from device.forms import DeviceFormSet @@ -72,7 +71,11 @@ class EditDeviceView(DashboardView, UpdateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') - self.object = get_object_or_404(self.model, pk=pk) + self.object = get_object_or_404( + self.model, + pk=pk, + owner=self.request.user.institution + ) self.success_url = reverse_lazy('device:details', args=[pk]) kwargs = super().get_form_kwargs() return kwargs @@ -87,6 +90,9 @@ class DetailsView(DashboardView, TemplateView): def get(self, request, *args, **kwargs): self.pk = kwargs['pk'] self.object = Device(id=self.pk) + if self.object.owner != self.request.user.institution: + raise Http403 + return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): @@ -110,7 +116,9 @@ 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.user = self.request.user + form.instance.uuid = self.annotation.uuid form.instance.uuid = self.annotation.uuid form.instance.type = Annotation.Type.USER response = super().form_valid(form) @@ -119,10 +127,12 @@ class AddAnnotationView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') self.annotation = Annotation.objects.filter( - owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + owner=self.request.user.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=self.request.user.institution) self.success_url = reverse_lazy('device:details', args=[pk]) kwargs = super().get_form_kwargs() return kwargs @@ -137,7 +147,8 @@ 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.user = self.request.user form.instance.uuid = self.annotation.uuid form.instance.type = Annotation.Type.DOCUMENT response = super().form_valid(form) @@ -146,10 +157,10 @@ class AddDocumentView(DashboardView, CreateView): def get_form_kwargs(self): pk = self.kwargs.get('pk') self.annotation = Annotation.objects.filter( - owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + owner=self.request.user.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=self.request.user.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 da5760c..db98f2d 100644 --- a/evidence/forms.py +++ b/evidence/forms.py @@ -57,10 +57,12 @@ class UserTagForm(forms.Form): def __init__(self, *args, **kwargs): self.pk = None self.uuid = kwargs.pop('uuid', None) + self.user = kwargs.pop('user') instance = Annotation.objects.filter( uuid=self.uuid, type=Annotation.Type.SYSTEM, - key='CUSTOM_ID' + key='CUSTOM_ID', + owner=self.user.institution ).first() if instance: @@ -77,7 +79,8 @@ class UserTagForm(forms.Form): self.instance = Annotation.objects.filter( uuid=self.uuid, type=Annotation.Type.SYSTEM, - key='CUSTOM_ID' + key='CUSTOM_ID', + owner=self.user.institution ).first() return True @@ -95,10 +98,11 @@ class UserTagForm(forms.Form): Annotation.objects.create( uuid=self.uuid, - owner=user, type=Annotation.Type.SYSTEM, key='CUSTOM_ID', - value=self.tag + value=self.tag, + owner=self.user.institution, + user=self.user ) @@ -148,7 +152,7 @@ class ImportForm(forms.Form): if commit: for doc, cred in table: cred.save() - create_index(doc) + create_index(doc, self.user) return table return diff --git a/evidence/migrations/0001_initial.py b/evidence/migrations/0001_initial.py index 8b86718..e4e0f10 100644 --- a/evidence/migrations/0001_initial.py +++ b/evidence/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-07-27 16:23 +# Generated by Django 5.0.6 on 2024-10-04 13:16 import django.db.models.deletion from django.conf import settings @@ -10,6 +10,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ("user", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] @@ -30,12 +31,21 @@ class Migration(migrations.Migration): ("uuid", models.UUIDField()), ( "type", - models.SmallIntegerField(choices=[(0, "System"), (1, "User")]), + models.SmallIntegerField( + choices=[(0, "System"), (1, "User"), (2, "Document")] + ), ), ("key", models.CharField(max_length=256)), ("value", models.CharField(max_length=256)), ( "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="user.institution", + ), + ), + ( + "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, diff --git a/evidence/migrations/0002_alter_annotation_type.py b/evidence/migrations/0002_alter_annotation_type.py deleted file mode 100644 index df63e61..0000000 --- a/evidence/migrations/0002_alter_annotation_type.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-29 14:58 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("evidence", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="annotation", - name="type", - field=models.SmallIntegerField( - choices=[(0, "System"), (1, "User"), (2, "Document"), (3, "Action")] - ), - ), - ] diff --git a/evidence/migrations/0003_alter_annotation_type.py b/evidence/migrations/0003_alter_annotation_type.py deleted file mode 100644 index 4d18482..0000000 --- a/evidence/migrations/0003_alter_annotation_type.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-29 15:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("evidence", "0002_alter_annotation_type"), - ] - - operations = [ - migrations.AlterField( - model_name="annotation", - name="type", - field=models.SmallIntegerField( - choices=[(0, "System"), (1, "User"), (2, "Document")] - ), - ), - ] diff --git a/evidence/models.py b/evidence/models.py index dbb47a0..a30e935 100644 --- a/evidence/models.py +++ b/evidence/models.py @@ -4,7 +4,7 @@ from django.db import models from utils.constants import STR_SM_SIZE, STR_EXTEND_SIZE from evidence.xapian import search -from user.models import User +from user.models import User, Institution class Annotation(models.Model): @@ -15,7 +15,8 @@ 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) + user = models.ForeignKey(User, 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) @@ -51,8 +52,10 @@ class Evidence: def get_doc(self): self.doc = {} + if not self.owner: + self.get_owner() qry = 'uuid:"{}"'.format(self.uuid) - matches = search(qry, limit=1) + matches = search(self.owner, qry, limit=1) if matches.size() < 0: return @@ -73,6 +76,6 @@ class Evidence: @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..b329bcd 100644 --- a/evidence/parse.py +++ b/evidence/parse.py @@ -4,7 +4,7 @@ import shutil import hashlib from datetime import datetime -from evidence.xapian import search, index +from evidence.xapian import index from evidence.models import Evidence, Annotation from utils.constants import ALGOS @@ -25,7 +25,7 @@ class Build: def index(self): snap = json.dumps(self.json) - index(self.uuid, snap) + index(self.user.institution, self.uuid, snap) def generate_chids(self): self.algorithms = { @@ -47,7 +47,8 @@ class Build: for k, v in self.algorithms.items(): Annotation.objects.create( uuid=self.uuid, - owner=self.user, + owner=self.user.institution, + user=self.user, type=Annotation.Type.SYSTEM, key=k, value=v diff --git a/evidence/views.py b/evidence/views.py index 8794cef..695b4e7 100644 --- a/evidence/views.py +++ b/evidence/views.py @@ -92,7 +92,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() @@ -109,6 +109,7 @@ class EvidenceView(DashboardView, FormView): self.pk = self.kwargs.get('pk') kwargs = super().get_form_kwargs() kwargs['uuid'] = self.pk + kwargs['user'] = self.request.user return kwargs def form_valid(self, form): @@ -130,7 +131,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() @@ -156,7 +157,11 @@ class AnnotationDeleteView(DashboardView, DeleteView): # if is not possible resolve the reference path return 404 raise Http404 - 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 + ) self.object.delete() diff --git a/evidence/xapian.py b/evidence/xapian.py index e38a8ab..27c03c5 100644 --- a/evidence/xapian.py +++ b/evidence/xapian.py @@ -10,7 +10,7 @@ import xapian # indexer.set_stemmer(stemmer) -def search(qs, offset=0, limit=10): +def search(institution, qs, offset=0, limit=10): database = xapian.Database("db") qp = xapian.QueryParser() @@ -20,16 +20,20 @@ def search(qs, offset=0, limit=10): qp.add_prefix("uuid", "uuid") # qp.add_prefix("snapshot", "snapshot") query = qp.parse_query(qs) + institution_term = "U{}".format(institution.id) + final_query = xapian.Query( + xapian.Query.OP_AND, query, xapian.Query(institution_term) + ) enquire = xapian.Enquire(database) - enquire.set_query(query) + enquire.set_query(final_query) matches = enquire.get_mset(offset, limit) return matches -def index(uuid, snap): +def index(institution, uuid, snap): uuid = 'uuid:"{}"'.format(uuid) try: - matches = search(uuid, limit=1) + matches = search(institution, uuid, limit=1) if matches.size() > 0: return except (xapian.DatabaseNotFoundError, xapian.DatabaseOpeningError): @@ -47,5 +51,7 @@ def index(uuid, snap): indexer.index_text(snap) indexer.index_text(uuid, 10, "uuid") # indexer.index_text(snap, 1, "snapshot") + institution_term = "U{}".format(institution.id) + doc.add_term(institution_term) database.add_document(doc) diff --git a/utils/device.py b/utils/device.py index 2e41597..f177aae 100644 --- a/utils/device.py +++ b/utils/device.py @@ -69,7 +69,8 @@ def create_annotation(doc, user, commit=False): data = { 'uuid': doc['uuid'], - 'owner': user, + 'owner': user.institution, + 'user': user, 'type': Annotation.Type.SYSTEM, 'key': 'CUSTOMER_ID', 'value': doc['CUSTOMER_ID'], @@ -80,10 +81,10 @@ def create_annotation(doc, user, commit=False): return Annotation(**data) -def create_index(doc): +def create_index(doc, user): if not doc or not doc.get('uuid'): return [] _uuid = doc['uuid'] ev = json.dumps(doc) - index(_uuid, ev) + index(user, _uuid, ev)