frontend: add an HTTP API method to import results

This commit is contained in:
Pierre Bourdon
2023-01-27 06:54:01 +01:00
parent 5cc67c52a7
commit b2e8291d65
5 changed files with 70 additions and 9 deletions

View File

@@ -28,6 +28,8 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
# application restart.
SECRET_KEY = os.urandom(32)
IMPORT_API_KEY = os.urandom(32)
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True

View File

@@ -1 +1,3 @@
from .base import *
IMPORT_API_KEY = "TestKey"

View File

@@ -7,6 +7,9 @@ DEBUG = TEMPLATE_DEBUG = False
if "SECRET_KEY_FILE" in os.environ:
SECRET_KEY = open(os.environ["SECRET_KEY_FILE"]).read()
if "IMPORT_API_KEY_FILE" in os.environ:
IMPORT_API_KEY = open(os.environ["IMPORT_API_KEY_FILE"]).read()
if "STATIC_ROOT" in os.environ:
STATIC_ROOT = os.environ["STATIC_ROOT"]

View File

@@ -10,18 +10,12 @@ from django.urls import include, path, re_path
from . import views
urlpatterns = [
# Examples:
# HTML pages for human consumption.
re_path(r"^$", views.home, name="home"),
re_path(r"^dff/$", views.dffs_to_test),
re_path(r"^dff/(?P<name>[a-zA-Z0-9-]+)/$", views.dff_view, name="dff-view"),
re_path(
r"^version/(?P<hash>[0-9a-f]{40})/$", views.version_view, name="version-view"
),
re_path(
r"^version/(?P<hash>[0-9a-f]{40})/json/$",
views.version_view_json,
name="version-view-json",
),
re_path(r"^result/(?P<id>\d+)/$", views.result_view, name="result-view"),
re_path(
r"^compare/(?P<curr_id>\d+)-(?P<old_id>\d+)/$",
@@ -29,8 +23,16 @@ urlpatterns = [
name="compare-view",
),
re_path(r"^about/$", views.about_view, name="about-view"),
re_path(r"^existing-images/$", views.existing_images),
re_path(r"^admin/", admin.site.urls),
# API endpoints.
re_path(r"^dff/$", views.dffs_to_test),
re_path(
r"^version/(?P<hash>[0-9a-f]{40})/json/$",
views.version_view_json,
name="version-view-json",
),
re_path(r"^result/import/$", views.import_result, name="import-result"),
re_path(r"^existing-images/$", views.existing_images),
]
if settings.DEBUG:

View File

@@ -4,12 +4,21 @@
from django.conf import settings
from django.db.models import Q
from django.http import JsonResponse
from django.http import (
HttpResponse,
HttpResponseBadRequest,
HttpResponseForbidden,
JsonResponse,
)
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from . import importer
from .models import FifoTest, Version, Result, Type
import json
import os
import os.path
@@ -176,3 +185,46 @@ def existing_images(request):
img = []
hashes = [i[:-4] for i in img if i.endswith(".png")]
return JsonResponse(hashes, safe=False)
@require_POST
@csrf_exempt
def import_result(request):
if "HTTP_AUTHORIZATION" not in request.META:
return HttpResponseForbidden("Missing 'Authorization' header")
parts = request.META["HTTP_AUTHORIZATION"].split(" ", 1)
if len(parts) < 2:
return HttpResponseForbidden("Invalid 'Authorization' header format")
if parts[0].lower() != "bearer":
return HttpResponseForbidden("Unknown 'Authorization' header type")
if parts[1] != settings.IMPORT_API_KEY:
return HttpResponseForbidden("Wrong bearer token")
if "meta" not in request.FILES:
return HttpResponseBadRequest("No 'meta' found in uploaded files")
try:
meta = json.load(request.FILES["meta"])
except json.JSONDecodeError as e:
return HttpResponseBadRequest(f"Could not parse meta JSON: {e}")
for key in ("type", "rev", "results"):
if key not in meta:
return HttpResponseBadRequest(f"{key!r} not present in meta JSON")
type, _ = Type.objects.get_or_create(type=meta["type"])
ver, parent = importer.get_or_create_ver(meta["rev"])
for dff_short_name, result in meta["results"].items():
try:
dff = FifoTest.objects.get(shortname=dff_short_name)
except FifoTest.DoesNotExist:
continue
images = {}
for f in request.FILES.getlist("image"):
images[f.name.removesuffix(".png")] = f
importer.import_result(dff, type, ver, parent, result, images)
return HttpResponse("OK")