2017-09-24 00:42:36 +02:00
|
|
|
from django.http import response
|
|
|
|
from django.core.exceptions import ValidationError
|
2017-09-24 18:20:10 +02:00
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
2017-09-24 00:42:36 +02:00
|
|
|
import json
|
|
|
|
import datetime
|
2017-09-23 21:40:45 +02:00
|
|
|
|
2017-09-24 00:42:36 +02:00
|
|
|
from . import models
|
|
|
|
import mainsite.models as mainModels
|
|
|
|
|
|
|
|
|
2017-09-24 18:20:10 +02:00
|
|
|
def authentify(data, payload):
|
2017-09-24 00:42:36 +02:00
|
|
|
''' 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:
|
2017-09-24 18:20:10 +02:00
|
|
|
key = models.ApiKey.objects.get(id=data['keyId'])
|
2017-09-24 00:42:36 +02:00
|
|
|
except models.ApiKey.DoesNotExist:
|
2017-09-24 18:20:10 +02:00
|
|
|
return response.HttpResponseForbidden('Bad authentication')
|
2017-09-24 00:42:36 +02:00
|
|
|
|
2017-10-16 20:02:36 +02:00
|
|
|
if not key.isCorrect(data['timestamp'], data['hmac'], payload):
|
2017-09-24 18:20:10 +02:00
|
|
|
return response.HttpResponseForbidden('Bad authentication')
|
2017-09-24 00:42:36 +02:00
|
|
|
|
|
|
|
|
2017-09-24 18:20:10 +02:00
|
|
|
def apiView(required=[]):
|
|
|
|
def decorator(fct):
|
|
|
|
@csrf_exempt
|
|
|
|
def wrap(request, *args, **kwargs):
|
|
|
|
try:
|
2017-10-16 20:02:36 +02:00
|
|
|
data = json.loads(request.body.decode('utf-8'))
|
|
|
|
except TypeError:
|
|
|
|
return response.HttpResponseBadRequest("Bad packet format")
|
|
|
|
except json.decoder.JSONDecodeError:
|
2017-09-24 18:20:10 +02:00
|
|
|
return response.HttpResponseBadRequest("Bad json")
|
2017-09-24 00:42:36 +02:00
|
|
|
|
2017-09-24 18:20:10 +02:00
|
|
|
try:
|
|
|
|
authData = data['auth']
|
2017-10-16 20:02:36 +02:00
|
|
|
reqDataOrig = data['req']
|
2017-09-24 18:20:10 +02:00
|
|
|
except KeyError:
|
|
|
|
return response.HttpResponseBadRequest("Bad request format")
|
2017-09-24 00:42:36 +02:00
|
|
|
|
2017-10-16 20:02:36 +02:00
|
|
|
try:
|
|
|
|
reqData = json.loads(reqDataOrig)
|
|
|
|
except TypeError:
|
|
|
|
return response.HttpResponseBadRequest("Bad packet format")
|
|
|
|
except json.decoder.JSONDecodeError:
|
|
|
|
return response.HttpResponseBadRequest("Bad inner json")
|
|
|
|
|
2017-09-24 18:20:10 +02:00
|
|
|
for field in required:
|
|
|
|
if field not in reqData:
|
|
|
|
return response.HttpResponseBadRequest(
|
|
|
|
"Missing field {}".format(field))
|
2017-09-24 00:42:36 +02:00
|
|
|
|
2017-10-16 20:02:36 +02:00
|
|
|
authVal = authentify(authData, reqDataOrig)
|
2017-09-24 18:20:10 +02:00
|
|
|
if authVal is not None:
|
|
|
|
return authVal
|
2017-09-24 00:42:36 +02:00
|
|
|
|
2017-09-24 18:20:10 +02:00
|
|
|
return fct(request, reqData, *args, **kwargs)
|
|
|
|
return wrap
|
|
|
|
return decorator
|
2017-09-24 00:42:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
@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:
|
|
|
|
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()
|
|
|
|
|
2017-09-24 18:41:31 +02:00
|
|
|
pub.createPubYear()
|
|
|
|
|
2017-09-24 00:42:36 +02:00
|
|
|
return response.HttpResponse("OK")
|