import datetime import json from django.core.exceptions import ValidationError from django.http import response from django.views.decorators.csrf import csrf_exempt import mainsite.models as mainModels from . import models def authentify(data, payload): """returns whether the request's authentification is correct""" required = ["keyId", "timestamp", "hmac"] for field in required: if field not in data: return response.HttpResponseForbidden( 'Missing required field "{}"'.format(field) ) try: key = models.ApiKey.objects.get(id=data["keyId"]) except models.ApiKey.DoesNotExist: return response.HttpResponseForbidden("Bad authentication") if not key.isCorrect(data["timestamp"], data["hmac"], payload): return response.HttpResponseForbidden("Bad authentication") def apiView(required=[]): def decorator(fct): @csrf_exempt def wrap(request, *args, **kwargs): try: data = json.loads(request.body.decode("utf-8")) except TypeError: return response.HttpResponseBadRequest("Bad packet format") except json.decoder.JSONDecodeError: return response.HttpResponseBadRequest("Bad json") try: authData = data["auth"] reqDataOrig = data["req"] except KeyError: return response.HttpResponseBadRequest("Bad request format") try: reqData = json.loads(reqDataOrig) except TypeError: return response.HttpResponseBadRequest("Bad packet format") except json.decoder.JSONDecodeError: return response.HttpResponseBadRequest("Bad inner json") for field in required: if field not in reqData: return response.HttpResponseBadRequest( "Missing field {}".format(field) ) authVal = authentify(authData, reqDataOrig) if authVal is not None: return authVal return fct(request, reqData, *args, **kwargs) return wrap return decorator @apiView(required=["id", "url", "date"]) def publishApiView(request, data): """Publish a BOcal, and create the corresponding year if needed""" if mainModels.Publication.objects.filter(num=data["id"]).count() > 0: return response.HttpResponseBadRequest( "Un BOcal du même numéro est déjà présent ! Ajoutez celui-ci à la " "main si vous voulez vraiment faire ça." ) try: year, month, day = [int(x) for x in data["date"].split("-")] date = datetime.date(year, month, day) except Exception: return response.HttpResponseBadRequest("Bad date") pub = mainModels.Publication(num=data["id"], url=data["url"], date=date) try: pub.full_clean() except ValidationError as e: return response.HttpResponseBadRequest("Invalid data: {}".format(e)) pub.save() pub.createPubYear() return response.HttpResponse("OK")