summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/admin.py45
-rw-r--r--ishtar_common/migrations/0217_auto_20211006_1526.py177
-rw-r--r--ishtar_common/models.py5
-rw-r--r--ishtar_common/models_rest.py32
-rw-r--r--ishtar_common/rest.py31
5 files changed, 288 insertions, 2 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 07750ffe7..0b73f5708 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -554,8 +554,12 @@ admin_site.register(models.Person, PersonAdmin)
class AuthorAdmin(admin.ModelAdmin):
list_display = ["person", "author_type"]
list_filter = ("author_type",)
- search_fields = ("person__name", "person__surname", "person__attached_to__name",
- "author_type__label")
+ search_fields = (
+ "person__name",
+ "person__surname",
+ "person__attached_to__name",
+ "author_type__label",
+ )
model = models.Author
autocomplete_fields = ["person"]
@@ -2082,3 +2086,40 @@ class DocumentTemplateAdmin(admin.ModelAdmin):
admin_site.register(models.DocumentTemplate, DocumentTemplateAdmin)
+
+class ApiUserAdmin(admin.ModelAdmin):
+ list_display = ("user_ptr", "ip")
+
+
+admin_site.register(models.ApiUser, ApiUserAdmin)
+
+
+def get_main_content_types_query():
+ CONTENT_TYPES = (
+ ("archaeological_operations", "operation"),
+ )
+ pks = []
+ for app_label, model_name in CONTENT_TYPES:
+ try:
+ ct = ContentType.objects.get(app_label=app_label, model=model_name)
+ pks.append(ct.pk)
+ except ContentType.DoesNotExist:
+ pass
+ return ContentType.objects.filter(pk__in=pks)
+
+
+class ApiSearchModelAdminForm(forms.ModelForm):
+ class Meta:
+ model = models.ApiUser
+ exclude = []
+ content_type = forms.ModelChoiceField(
+ label=_("Content type"), queryset=get_main_content_types_query()
+ )
+
+
+class ApiSearchModelAdmin(admin.ModelAdmin):
+ form = ApiSearchModelAdminForm
+ list_display = ("user", "content_type")
+
+
+admin_site.register(models.ApiSearchModel, ApiSearchModelAdmin)
diff --git a/ishtar_common/migrations/0217_auto_20211006_1526.py b/ishtar_common/migrations/0217_auto_20211006_1526.py
new file mode 100644
index 000000000..33299b4c3
--- /dev/null
+++ b/ishtar_common/migrations/0217_auto_20211006_1526.py
@@ -0,0 +1,177 @@
+# Generated by Django 2.2.24 on 2021-10-06 15:26
+
+from django.conf import settings
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('contenttypes', '0002_remove_content_type_name'),
+ ('auth', '0011_update_proxy_permissions'),
+ ('ishtar_common', '0216_auto_20210805_1703'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='ApiUser',
+ fields=[
+ ('user_ptr', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='apiuser', serialize=False, to=settings.AUTH_USER_MODEL)),
+ ('ip', models.GenericIPAddressField(verbose_name='IP')),
+ ],
+ options={
+ 'verbose_name': 'Api - User',
+ 'verbose_name_plural': 'Api - Users',
+ },
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='author_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='ishtar_common.AuthorType', verbose_name='Author type'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='data',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='history_m2m',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='language',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Language', verbose_name='Language'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='publisher',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='publish', to='ishtar_common.Organization', verbose_name='Publisher'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='source',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='ishtar_common.Document', verbose_name='Source'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='data',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='history_m2m',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='data',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='history_m2m',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='default_language',
+ field=models.ForeignKey(blank=True, help_text='If set, by default the selected language will be set for localized documents.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Language', verbose_name='Default language for documentation'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='display_srs',
+ field=models.ForeignKey(blank=True, help_text='Spatial Reference System used for display when no SRS is defined', null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.SpatialReferenceSystem', verbose_name='Spatial Reference System for display'),
+ ),
+ migrations.AlterField(
+ model_name='itemkey',
+ name='group',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.TargetKeyGroup'),
+ ),
+ migrations.AlterField(
+ model_name='itemkey',
+ name='importer',
+ field=models.ForeignKey(blank=True, help_text='Specific key to an import', null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Import'),
+ ),
+ migrations.AlterField(
+ model_name='itemkey',
+ name='user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.IshtarUser'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='data',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='history_m2m',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='organization_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='ishtar_common.OrganizationType', verbose_name='Type'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='precise_town',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Town', verbose_name='Town (precise)'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='data',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='history_m2m',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='precise_town',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Town', verbose_name='Town (precise)'),
+ ),
+ migrations.AlterField(
+ model_name='statscache',
+ name='values',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='associated_group',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.TargetKeyGroup'),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='associated_import',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.Import'),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='associated_user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='ishtar_common.IshtarUser'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='profile_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='ishtar_common.ProfileType', verbose_name='Profile type'),
+ ),
+ migrations.CreateModel(
+ name='ApiSearchModel',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('limit_query', models.TextField(blank=True, help_text='Search query add to each request', null=True, verbose_name='Limit query')),
+ ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.ApiUser')),
+ ],
+ options={
+ 'verbose_name': 'Api - Search model',
+ 'verbose_name_plural': 'Api - Search models',
+ },
+ ),
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 6783a89b5..59248fa43 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -113,6 +113,11 @@ from ishtar_common.models_imports import (
TargetKeyGroup,
ValueFormater,
)
+from ishtar_common.models_rest import (
+ ApiUser,
+ ApiSearchModel
+)
+
from ishtar_common.utils import (
get_cache,
create_slug,
diff --git a/ishtar_common/models_rest.py b/ishtar_common/models_rest.py
new file mode 100644
index 000000000..7d321ca92
--- /dev/null
+++ b/ishtar_common/models_rest.py
@@ -0,0 +1,32 @@
+from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.gis.db import models
+
+from ishtar_common.utils import ugettext_lazy as _
+
+
+class ApiUser(models.Model):
+ user_ptr = models.OneToOneField(
+ User, primary_key=True, related_name="apiuser", on_delete=models.CASCADE
+ )
+ ip = models.GenericIPAddressField(verbose_name=_("IP"))
+
+ class Meta:
+ verbose_name = _("Api - User")
+ verbose_name_plural = _("Api - Users")
+
+ def __str__(self):
+ return self.user_ptr.username
+
+
+class ApiSearchModel(models.Model):
+ user = models.ForeignKey(ApiUser, on_delete=models.CASCADE)
+ content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
+ limit_query = models.TextField(
+ verbose_name=_("Limit query"), blank=True, null=True,
+ help_text=_("Search query add to each request")
+ )
+
+ class Meta:
+ verbose_name = _("Api - Search model")
+ verbose_name_plural = _("Api - Search models")
diff --git a/ishtar_common/rest.py b/ishtar_common/rest.py
new file mode 100644
index 000000000..9354a943d
--- /dev/null
+++ b/ishtar_common/rest.py
@@ -0,0 +1,31 @@
+from rest_framework import authentication, permissions
+from rest_framework.response import Response
+from rest_framework.views import APIView
+
+from ishtar_common.models import ApiSearchModel
+
+
+class IpModelPermission(permissions.BasePermission):
+ def has_permission(self, request, view):
+ if not request.user or not getattr(request.user, "apiuser", None):
+ return False
+ ip_addr = request.META['REMOTE_ADDR']
+ q = ApiSearchModel.objects.filter(
+ user=request.user.apiuser,
+ user__ip=ip_addr,
+ content_type__app_label=view.model._meta.app_label,
+ content_type__model=view.model._meta.model_name)
+ return bool(q.count())
+
+
+class SearchAPIView(APIView):
+ model = None
+ authentication_classes = (authentication.TokenAuthentication,)
+ permission_classes = (permissions.IsAuthenticated, IpModelPermission)
+
+ def __init__(self, **kwargs):
+ assert self.model is not None
+ super(SearchAPIView, self).__init__(**kwargs)
+
+ def get(self, request, format=None):
+ return Response({})