Merge pull request 'admin-users' (#7) from admin-users into main

Reviewed-on: #7
This commit is contained in:
cayop 2024-10-07 14:59:24 +00:00
commit 355355dcfc
30 changed files with 348 additions and 81 deletions

0
admin/__init__.py Normal file
View File

3
admin/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
admin/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AdminConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "admin"

View File

3
admin/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col">
<h3>{{ subtitle }}</h3>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,39 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col">
<h3>{{ subtitle }}</h3>
</div>
<div class="col-2">
<a href="{% url 'admin:new_user' %}" class="btn btn-green-admin">{% translate "Add new user" %}</a>
</div>
</div>
<div class="row">
<div class="col">
<table class="table">
<thead>
<tr>
<th scope="col">Email</th>
<th>is Admin</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
{% for u in users %}
<td>{{ u.email }}</td>
<td>{{ u.is_admin }}</td>
<td><a href="{% url 'admin:edit_user' u.pk %}"><i class="bi bi-eye"></i></td>
<td><a href="{% url 'admin:delete_user' u.pk %}" class="text-danger" title="Remove"><i class="bi bi-trash"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,38 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col">
<h3>{{ subtitle }}</h3>
</div>
</div>
{% load django_bootstrap5 %}
<div class="row mb-3">
<div class="col">
Are you sure than want remove the lot {{ object.name }} with {{ object.devices.count }} devices.
</div>
</div>
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
{% bootstrap_form form %}
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'admin:users' %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Delete' %}" />
</div>
</form>
{% endblock %}

32
admin/templates/user.html Normal file
View File

@ -0,0 +1,32 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col">
<h3>{{ subtitle }}</h3>
</div>
</div>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
{% bootstrap_form form %}
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'admin:users' %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

3
admin/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

12
admin/urls.py Normal file
View File

@ -0,0 +1,12 @@
from django.urls import path
from admin import views
app_name = 'admin'
urlpatterns = [
path("panel/", views.PanelView.as_view(), name="panel"),
path("users/", views.UsersView.as_view(), name="users"),
path("users/new", views.CreateUserView.as_view(), name="new_user"),
path("users/edit/<int:pk>", views.EditUserView.as_view(), name="edit_user"),
path("users/delete/<int:pk>", views.DeleteUserView.as_view(), name="delete_user"),
]

89
admin/views.py Normal file
View File

@ -0,0 +1,89 @@
from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateView
from django.views.generic.edit import (
CreateView,
UpdateView,
DeleteView,
)
from dashboard.mixins import DashboardView
from user.models import User
class PanelView(DashboardView, TemplateView):
template_name = "admin_panel.html"
title = _("Admin")
breadcrumb = _("admin") + " /"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
class UsersView(DashboardView, TemplateView):
template_name = "admin_users.html"
title = _("Users")
breadcrumb = _("admin / Users") + " /"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
"users": User.objects.filter()
})
return context
class CreateUserView(DashboardView, CreateView):
template_name = "user.html"
title = _("User")
breadcrumb = _("admin / User") + " /"
success_url = reverse_lazy('admin:users')
model = User
fields = (
"email",
"password",
"is_admin",
)
def form_valid(self, form):
form.instance.institution = self.request.user.institution
form.instance.set_password(form.instance.password)
response = super().form_valid(form)
return response
class DeleteUserView(DashboardView, DeleteView):
template_name = "delete_user.html"
title = _("Delete user")
breadcrumb = "admin / Delete user"
success_url = reverse_lazy('admin:users')
model = User
fields = (
"email",
"password",
"is_admin",
)
def form_valid(self, form):
response = super().form_valid(form)
return response
class EditUserView(DashboardView, UpdateView):
template_name = "user.html"
title = _("Edit user")
breadcrumb = "admin / Edit user"
success_url = reverse_lazy('admin:users')
model = User
fields = (
"email",
"is_admin",
)
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
self.object = get_object_or_404(self.model, pk=pk)
#self.object.set_password(self.object.password)
kwargs = super().get_form_kwargs()
return kwargs

View File

@ -47,7 +47,9 @@ class DashboardView(LoginRequiredMixin):
dev_ids = self.request.session.pop("devices", []) dev_ids = self.request.session.pop("devices", [])
self._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)) self._devices.append(Device(id=x.value))
return self._devices return self._devices

View File

@ -79,6 +79,26 @@
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse"> <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
<div class="position-sticky pt-5"> <div class="position-sticky pt-5">
<ul class="nav flex-column"> <ul class="nav flex-column">
{% if user.is_admin %}
<li class="nav-item">
<a class="admin {% if path in 'panel users' %}active {% endif %}nav-link fw-bold" data-bs-toggle="collapse" data-bs-target="#ul_admin" aria-expanded="false" aria-controls="ul_admin" href="javascript:void()">
<i class="bi bi-person-fill-gear icon_sidebar"></i>
{% trans 'Admin' %}
</a>
<ul class="flex-column mb-2 ul_sidebar accordion-collapse {% if path in 'panel users' %}expanded{% else %}collapse{% endif %}" id="ul_admin" data-bs-parent="#sidebarMenu">
<li class="nav-item">
<a class="nav-link{% if path == 'panel' %} active2{% endif %}" href="{% url 'admin:panel' %}">
{% trans 'Panel' %}
</a>
</li>
<li class="nav-item">
<a class="nav-link{% if path == 'users' %} active2{% endif %}" href="{% url 'admin:users' %}">
{% trans 'Users' %}
</a>
</li>
</ul>
</li>
{% endif %}
<li class="nav-item"> <li class="nav-item">
<a class="admin {% if path == 'unassigned_devices' %}active {% endif %}nav-link fw-bold" data-bs-toggle="collapse" data-bs-target="#ul_devices" aria-expanded="false" aria-controls="ul_devices" href="javascript:void()"> <a class="admin {% if path == 'unassigned_devices' %}active {% endif %}nav-link fw-bold" data-bs-toggle="collapse" data-bs-target="#ul_devices" aria-expanded="false" aria-controls="ul_devices" href="javascript:void()">
<i class="bi bi-laptop icon_sidebar"></i> <i class="bi bi-laptop icon_sidebar"></i>

View File

@ -13,7 +13,7 @@ class UnassignedDevicesView(InventaryMixin):
breadcrumb = "Devices / Unassigned Devices" breadcrumb = "Devices / Unassigned Devices"
def get_devices(self, user, offset, limit): def get_devices(self, user, offset, limit):
return Device.get_unassigned(self.request.user, offset, limit) return Device.get_unassigned(self.request.user.institution, offset, limit)
class LotDashboardView(InventaryMixin, DetailsMixin): class LotDashboardView(InventaryMixin, DetailsMixin):

View File

@ -56,7 +56,7 @@ class BaseDeviceFormSet(forms.BaseFormSet):
if not commit: if not commit:
return doc return doc
create_index(doc) create_index(doc, self.user)
create_annotation(doc, user, commit=commit) create_annotation(doc, user, commit=commit)
return doc return doc

View File

@ -9,9 +9,8 @@ from django.views.generic.edit import (
FormView, FormView,
) )
from django.views.generic.base import TemplateView 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.models import Annotation
from evidence.xapian import search
from lot.models import LotTag from lot.models import LotTag
from device.models import Device from device.models import Device
from device.forms import DeviceFormSet from device.forms import DeviceFormSet
@ -72,7 +71,11 @@ class EditDeviceView(DashboardView, UpdateView):
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') 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]) self.success_url = reverse_lazy('device:details', args=[pk])
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
return kwargs return kwargs
@ -87,6 +90,9 @@ class DetailsView(DashboardView, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.pk = kwargs['pk'] self.pk = kwargs['pk']
self.object = Device(id=self.pk) self.object = Device(id=self.pk)
if self.object.owner != self.request.user.institution:
raise Http403
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -110,7 +116,9 @@ class AddAnnotationView(DashboardView, CreateView):
fields = ("key", "value") fields = ("key", "value")
def form_valid(self, form): 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.uuid = self.annotation.uuid
form.instance.type = Annotation.Type.USER form.instance.type = Annotation.Type.USER
response = super().form_valid(form) response = super().form_valid(form)
@ -119,10 +127,12 @@ class AddAnnotationView(DashboardView, CreateView):
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
self.annotation = Annotation.objects.filter( 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() ).first()
if not self.annotation: 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]) self.success_url = reverse_lazy('device:details', args=[pk])
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
return kwargs return kwargs
@ -137,7 +147,8 @@ class AddDocumentView(DashboardView, CreateView):
fields = ("key", "value") fields = ("key", "value")
def form_valid(self, form): 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.DOCUMENT form.instance.type = Annotation.Type.DOCUMENT
response = super().form_valid(form) response = super().form_valid(form)
@ -146,10 +157,10 @@ class AddDocumentView(DashboardView, CreateView):
def get_form_kwargs(self): def get_form_kwargs(self):
pk = self.kwargs.get('pk') pk = self.kwargs.get('pk')
self.annotation = Annotation.objects.filter( 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() ).first()
if not self.annotation: 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]) self.success_url = reverse_lazy('device:details', args=[pk])
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
return kwargs return kwargs

View File

@ -35,7 +35,7 @@ ALLOWED_HOSTS = []
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"django.contrib.admin", # "django.contrib.admin",
"django.contrib.auth", "django.contrib.auth",
"django.contrib.contenttypes", "django.contrib.contenttypes",
"django.contrib.sessions", "django.contrib.sessions",
@ -53,6 +53,7 @@ INSTALLED_APPS = [
"lot", "lot",
"documents", "documents",
"dashboard", "dashboard",
"admin",
] ]

View File

@ -23,5 +23,6 @@ urlpatterns = [
path("dashboard/", include("dashboard.urls")), path("dashboard/", include("dashboard.urls")),
path("evidence/", include("evidence.urls")), path("evidence/", include("evidence.urls")),
path("device/", include("device.urls")), path("device/", include("device.urls")),
path("admin/", include("admin.urls")),
path("lot/", include("lot.urls")), path("lot/", include("lot.urls")),
] ]

View File

@ -57,10 +57,12 @@ class UserTagForm(forms.Form):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.pk = None self.pk = None
self.uuid = kwargs.pop('uuid', None) self.uuid = kwargs.pop('uuid', None)
self.user = kwargs.pop('user')
instance = Annotation.objects.filter( instance = Annotation.objects.filter(
uuid=self.uuid, uuid=self.uuid,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key='CUSTOM_ID' key='CUSTOM_ID',
owner=self.user.institution
).first() ).first()
if instance: if instance:
@ -77,7 +79,8 @@ class UserTagForm(forms.Form):
self.instance = Annotation.objects.filter( self.instance = Annotation.objects.filter(
uuid=self.uuid, uuid=self.uuid,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key='CUSTOM_ID' key='CUSTOM_ID',
owner=self.user.institution
).first() ).first()
return True return True
@ -95,10 +98,11 @@ class UserTagForm(forms.Form):
Annotation.objects.create( Annotation.objects.create(
uuid=self.uuid, uuid=self.uuid,
owner=user,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key='CUSTOM_ID', 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: if commit:
for doc, cred in table: for doc, cred in table:
cred.save() cred.save()
create_index(doc) create_index(doc, self.user)
return table return table
return return

View File

@ -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-07 11:38
import django.db.models.deletion import django.db.models.deletion
from django.conf import settings from django.conf import settings
@ -10,6 +10,7 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
("user", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
@ -30,7 +31,9 @@ class Migration(migrations.Migration):
("uuid", models.UUIDField()), ("uuid", models.UUIDField()),
( (
"type", "type",
models.SmallIntegerField(choices=[(0, "System"), (1, "User")]), models.SmallIntegerField(
choices=[(0, "System"), (1, "User"), (2, "Document")]
),
), ),
("key", models.CharField(max_length=256)), ("key", models.CharField(max_length=256)),
("value", models.CharField(max_length=256)), ("value", models.CharField(max_length=256)),
@ -38,6 +41,15 @@ class Migration(migrations.Migration):
"owner", "owner",
models.ForeignKey( models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, on_delete=django.db.models.deletion.CASCADE,
to="user.institution",
),
),
(
"user",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL, to=settings.AUTH_USER_MODEL,
), ),
), ),

View File

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

View File

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

View File

@ -4,7 +4,7 @@ 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
from evidence.xapian import search from evidence.xapian import search
from user.models import User from user.models import User, Institution
class Annotation(models.Model): class Annotation(models.Model):
@ -15,7 +15,8 @@ class Annotation(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
uuid = models.UUIDField() 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.SET_NULL, null=True, blank=True)
type = models.SmallIntegerField(choices=Type) type = models.SmallIntegerField(choices=Type)
key = models.CharField(max_length=STR_EXTEND_SIZE) key = models.CharField(max_length=STR_EXTEND_SIZE)
value = 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): def get_doc(self):
self.doc = {} self.doc = {}
if not self.owner:
self.get_owner()
qry = 'uuid:"{}"'.format(self.uuid) qry = 'uuid:"{}"'.format(self.uuid)
matches = search(qry, limit=1) matches = search(self.owner, qry, limit=1)
if matches.size() < 0: if matches.size() < 0:
return return
@ -73,6 +76,6 @@ class Evidence:
@classmethod @classmethod
def get_all(cls, user): def get_all(cls, user):
return Annotation.objects.filter( return Annotation.objects.filter(
owner=user, owner=user.institution,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
).order_by("-created").values_list("uuid", flat=True).distinct() ).order_by("-created").values_list("uuid", flat=True).distinct()

View File

@ -4,7 +4,7 @@ import shutil
import hashlib import hashlib
from datetime import datetime from datetime import datetime
from evidence.xapian import search, index from evidence.xapian import index
from evidence.models import Evidence, Annotation from evidence.models import Evidence, Annotation
from utils.constants import ALGOS from utils.constants import ALGOS
@ -25,7 +25,7 @@ class Build:
def index(self): def index(self):
snap = json.dumps(self.json) snap = json.dumps(self.json)
index(self.uuid, snap) index(self.user.institution, self.uuid, snap)
def generate_chids(self): def generate_chids(self):
self.algorithms = { self.algorithms = {
@ -47,7 +47,8 @@ class Build:
for k, v in self.algorithms.items(): for k, v in self.algorithms.items():
Annotation.objects.create( Annotation.objects.create(
uuid=self.uuid, uuid=self.uuid,
owner=self.user, owner=self.user.institution,
user=self.user,
type=Annotation.Type.SYSTEM, type=Annotation.Type.SYSTEM,
key=k, key=k,
value=v value=v

View File

@ -92,7 +92,7 @@ class EvidenceView(DashboardView, FormView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.pk = kwargs['pk'] self.pk = kwargs['pk']
self.object = Evidence(self.pk) self.object = Evidence(self.pk)
if self.object.owner != self.request.user: if self.object.owner != self.request.user.institution:
raise Http403 raise Http403
self.object.get_annotations() self.object.get_annotations()
@ -109,6 +109,7 @@ class EvidenceView(DashboardView, FormView):
self.pk = self.kwargs.get('pk') self.pk = self.kwargs.get('pk')
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs['uuid'] = self.pk kwargs['uuid'] = self.pk
kwargs['user'] = self.request.user
return kwargs return kwargs
def form_valid(self, form): def form_valid(self, form):
@ -130,7 +131,7 @@ class DownloadEvidenceView(DashboardView, TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
pk = kwargs['pk'] pk = kwargs['pk']
evidence = Evidence(pk) evidence = Evidence(pk)
if evidence.owner != self.request.user: if evidence.owner != self.request.user.institution:
raise Http403() raise Http403()
evidence.get_doc() evidence.get_doc()
@ -156,7 +157,11 @@ class AnnotationDeleteView(DashboardView, DeleteView):
# if is not possible resolve the reference path return 404 # if is not possible resolve the reference path return 404
raise Http404 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() self.object.delete()

View File

@ -10,7 +10,7 @@ import xapian
# indexer.set_stemmer(stemmer) # indexer.set_stemmer(stemmer)
def search(qs, offset=0, limit=10): def search(institution, qs, offset=0, limit=10):
database = xapian.Database("db") database = xapian.Database("db")
qp = xapian.QueryParser() qp = xapian.QueryParser()
@ -20,16 +20,20 @@ def search(qs, offset=0, limit=10):
qp.add_prefix("uuid", "uuid") qp.add_prefix("uuid", "uuid")
# qp.add_prefix("snapshot", "snapshot") # qp.add_prefix("snapshot", "snapshot")
query = qp.parse_query(qs) 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 = xapian.Enquire(database)
enquire.set_query(query) enquire.set_query(final_query)
matches = enquire.get_mset(offset, limit) matches = enquire.get_mset(offset, limit)
return matches return matches
def index(uuid, snap): def index(institution, uuid, snap):
uuid = 'uuid:"{}"'.format(uuid) uuid = 'uuid:"{}"'.format(uuid)
try: try:
matches = search(uuid, limit=1) matches = search(institution, uuid, limit=1)
if matches.size() > 0: if matches.size() > 0:
return return
except (xapian.DatabaseNotFoundError, xapian.DatabaseOpeningError): except (xapian.DatabaseNotFoundError, xapian.DatabaseOpeningError):
@ -47,5 +51,7 @@ def index(uuid, snap):
indexer.index_text(snap) indexer.index_text(snap)
indexer.index_text(uuid, 10, "uuid") indexer.index_text(uuid, 10, "uuid")
# indexer.index_text(snap, 1, "snapshot") # indexer.index_text(snap, 1, "snapshot")
institution_term = "U{}".format(institution.id)
doc.add_term(institution_term)
database.add_document(doc) database.add_document(doc)

View File

@ -1,5 +1,5 @@
rm db/* rm db/*
python3 manage.py migrate python3 manage.py migrate
python3 manage.py add_institution Pangea python3 manage.py add_institution Pangea
python3 manage.py add_user Pangea user@example.org 1234 python3 manage.py add_user Pangea user@example.org 1234 True
python3 manage.py up_snapshots example/snapshots/ user@example.org python3 manage.py up_snapshots example/snapshots/ user@example.org

View File

@ -14,19 +14,22 @@ class Command(BaseCommand):
parser.add_argument('institution', type=str, help='institution') parser.add_argument('institution', type=str, help='institution')
parser.add_argument('email', type=str, help='email') parser.add_argument('email', type=str, help='email')
parser.add_argument('password', type=str, help='password') parser.add_argument('password', type=str, help='password')
parser.add_argument('is_admin', nargs='?', default=False, type=str, help='is admin')
def handle(self, *args, **kwargs): def handle(self, *args, **kwargs):
email = kwargs['email'] email = kwargs['email']
password = kwargs['password'] password = kwargs['password']
is_admin = kwargs['is_admin']
institution = Institution.objects.get(name=kwargs['institution']) institution = Institution.objects.get(name=kwargs['institution'])
self.create_user(institution, email, password) self.create_user(institution, email, password, is_admin)
self.create_lot_tags() self.create_lot_tags()
def create_user(self, institution, email, password): def create_user(self, institution, email, password, is_admin):
self.u = User.objects.create( self.u = User.objects.create(
institution=institution, institution=institution,
email=email, email=email,
password=password password=password,
is_admin=is_admin,
) )
self.u.set_password(password) self.u.set_password(password)
self.u.save() self.u.save()

View File

@ -69,7 +69,8 @@ def create_annotation(doc, user, commit=False):
data = { data = {
'uuid': doc['uuid'], 'uuid': doc['uuid'],
'owner': user, 'owner': user.institution,
'user': user,
'type': Annotation.Type.SYSTEM, 'type': Annotation.Type.SYSTEM,
'key': 'CUSTOMER_ID', 'key': 'CUSTOMER_ID',
'value': doc['CUSTOMER_ID'], 'value': doc['CUSTOMER_ID'],
@ -80,10 +81,10 @@ def create_annotation(doc, user, commit=False):
return Annotation(**data) return Annotation(**data)
def create_index(doc): def create_index(doc, user):
if not doc or not doc.get('uuid'): if not doc or not doc.get('uuid'):
return [] return []
_uuid = doc['uuid'] _uuid = doc['uuid']
ev = json.dumps(doc) ev = json.dumps(doc)
index(_uuid, ev) index(user, _uuid, ev)