www-bocal/api/views.py
2017-09-24 18:41:31 +02:00

83 lines
2.7 KiB
Python

from django.http import response
from django.core.exceptions import ValidationError
from django.views.decorators.csrf import csrf_exempt
import json
import datetime
from . import models
import mainsite.models as mainModels
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')
normPayload = json.dumps(payload)
if not key.isCorrect(data['timestamp'], data['hmac'], normPayload):
return response.HttpResponseForbidden('Bad authentication')
def apiView(required=[]):
def decorator(fct):
@csrf_exempt
def wrap(request, *args, **kwargs):
try:
data = json.loads(request.body)
except json.decoder.JSONDecoreError:
return response.HttpResponseBadRequest("Bad json")
try:
authData = data['auth']
reqData = data['req']
except KeyError:
return response.HttpResponseBadRequest("Bad request format")
for field in required:
if field not in reqData:
return response.HttpResponseBadRequest(
"Missing field {}".format(field))
authVal = authentify(authData, reqData)
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:
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")