Token authentication + send file endpoint
This commit is contained in:
parent
81c83e3313
commit
d8c49b1bd7
@ -1,2 +0,0 @@
|
||||
MethodNotAllowed = {"message": "Error: Method not allowed",
|
||||
"statusCode": 405}
|
@ -1,6 +0,0 @@
|
||||
class UserAuthFailed(Exception):
|
||||
def __init__(self, message, payload = None):
|
||||
self.message = message
|
||||
self.payload = payload
|
||||
def __str__(self):
|
||||
return str(self.message)
|
29
backend/webapp/prototype/filehandler/fileModule.py
Normal file
29
backend/webapp/prototype/filehandler/fileModule.py
Normal file
@ -0,0 +1,29 @@
|
||||
from prototype.filehandler.statusCodes import DatabaseAddSuccess, DatabaseAddFail
|
||||
from prototype.filehandler.models import Forum, Discussion, Post, Paragraph
|
||||
|
||||
def addDataToDatabase(data, file_id):
|
||||
try:
|
||||
out = {}
|
||||
para_id = []
|
||||
messages = []
|
||||
forum = Forum(forum_id = data['id'], name = data['name'], document_id = file_id)
|
||||
print(forum)
|
||||
forum.save()
|
||||
for discussion_ in data['discussions']:
|
||||
discussion = Discussion(discussion_id = discussion_['id'], title = discussion_['title'], first_post = discussion_['first_post'], forum_id = forum.pk)
|
||||
discussion.save()
|
||||
for post_ in discussion_['posts']:
|
||||
post = Post(post_id = post_['id'], parent = post_['parent'], author = post_['author'], discussion_id = discussion.pk)
|
||||
post.save()
|
||||
for paragraph_ in post_['message']:
|
||||
paragraph = Paragraph(message = paragraph_, label = '', post_id = post.pk)
|
||||
paragraph.save()
|
||||
para_id.append(paragraph.pk)
|
||||
messages.append(paragraph_)
|
||||
out['para_id'] = para_id
|
||||
out['messages'] = messages
|
||||
result = DatabaseAddSuccess
|
||||
except:
|
||||
result = UnknownError
|
||||
finally:
|
||||
return result
|
@ -4,4 +4,4 @@ from prototype.filehandler.models import Document
|
||||
class DocumentForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Document
|
||||
fields = ('file', )
|
||||
fields = ('file', 'user_id',)
|
||||
|
@ -4,6 +4,7 @@ from django.db import models
|
||||
class Document(models.Model):
|
||||
file = models.FileField(upload_to='documents/')
|
||||
uploaded_at = models.DateTimeField(auto_now_add=True)
|
||||
user_id = models.IntegerField()
|
||||
|
||||
class Forum(models.Model):
|
||||
forum_id = models.IntegerField()
|
||||
|
12
backend/webapp/prototype/filehandler/tokenAuthModule.py
Normal file
12
backend/webapp/prototype/filehandler/tokenAuthModule.py
Normal file
@ -0,0 +1,12 @@
|
||||
import time
|
||||
def verifyExpiration(payload):
|
||||
if "exp" not in payload or int(time.time()) > int(payload["exp"]):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def verifyContent(payload):
|
||||
expectedKeys = ["iss", "iat", "sub"]
|
||||
actualKeys = [*payload]
|
||||
isProperStructure = all([True if key in actualKeys else False for key in expectedKeys])
|
||||
return all([isProperStructure, payload["iss"] == "NKADF"])
|
@ -3,7 +3,7 @@ import time
|
||||
from django.contrib.auth import authenticate
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from prototype.filehandler.exceptions import UserAuthFailed
|
||||
from prototype.filehandler.tokenAuthModule import verifyExpiration, verifyContent
|
||||
|
||||
def registerNewUser(login, password):
|
||||
try:
|
||||
@ -42,13 +42,25 @@ def loginUser(login, password):
|
||||
finally:
|
||||
return result
|
||||
|
||||
def decodeToken(token):
|
||||
def checkUserToken(request):
|
||||
try:
|
||||
payload = jwt.decode(token, settings.SECRET_KEY, algorith = "HS256")
|
||||
result = payload
|
||||
return payload
|
||||
if "HTTP_BEARER" not in request.META:
|
||||
raise Exception("Error: Token is missing", 401)
|
||||
payload = jwt.decode(request.META["HTTP_BEARER"], settings.SECRET_KEY, algorithm = "HS256")
|
||||
if not verifyExpiration(payload):
|
||||
raise Exception("Error: Token has expired", 401)
|
||||
if not verifyContent(payload):
|
||||
raise Exception("Error: Token payload is invalid", 401)
|
||||
result = {"message": "Token authenticated successfully",
|
||||
"statusCode": 200}
|
||||
user_id = payload["sub"]
|
||||
except jwt.exceptions.DecodeError:
|
||||
result = {"messege": "Error: Invalid token given",
|
||||
"statusCode": 400}
|
||||
user_id = None
|
||||
except Exception as error:
|
||||
result = {"message": str(error),
|
||||
"statusCode": 500}
|
||||
result = {"message": str(error.args[0]),
|
||||
"statusCode": int(error.args[1])}
|
||||
user_id = None
|
||||
finally:
|
||||
return result
|
||||
return result, user_id
|
||||
|
@ -1,16 +1,23 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from django.conf import settings
|
||||
from django.core import serializers
|
||||
from django.core.files.storage import FileSystemStorage
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.forms.models import model_to_dict
|
||||
from django.http import JsonResponse, HttpResponse
|
||||
import json
|
||||
|
||||
from prototype.filehandler.serializers import ExtendedEncoder
|
||||
from prototype.filehandler.models import Document, Forum
|
||||
from prototype.filehandler.forms import DocumentForm
|
||||
from prototype.filehandler.xmlParser import parseData
|
||||
from prototype.filehandler.functions import addToDatabase, listDiscussionsFromFile, listParagraphsFromDiscussion, createLabels, listPostsFromDiscussion, updateLabelsByParagraphId
|
||||
from prototype.filehandler.userModule import registerNewUser, loginUser, decodeToken
|
||||
from prototype.filehandler.errorCodes import MethodNotAllowed
|
||||
|
||||
from prototype.filehandler.userModule import registerNewUser, loginUser, checkUserToken
|
||||
from prototype.filehandler.fileModule import addDataToDatabase
|
||||
|
||||
from prototype.filehandler.exceptions import InvalidForm, CouldNotParse, InvalidMethod, KnownError
|
||||
from prototype.filehandler.statusCodes import MethodNotAllowed, FileUploadSuccess, UnknownError, ParseFailed
|
||||
|
||||
|
||||
def home(request):
|
||||
@ -95,7 +102,55 @@ def login(request):
|
||||
@csrf_exempt
|
||||
def testToken(request):
|
||||
if request.method == 'POST':
|
||||
result = decodeToken(request.POST["token"])
|
||||
result = testToken(request)
|
||||
return JsonResponse(result, status = 200)
|
||||
else:
|
||||
return JsonResponse(MethodNotAllowed, status = MethodNotAllowed["statusCode"])
|
||||
|
||||
@csrf_exempt
|
||||
def file(request):
|
||||
try:
|
||||
noStatus = False
|
||||
if request.method == 'POST':
|
||||
result, user_id = checkUserToken(request)
|
||||
if result["statusCode"] != 200:
|
||||
raise KnownError
|
||||
form = DocumentForm({"user_id": user_id}, request.FILES)
|
||||
if not form.is_valid():
|
||||
raise InvalidForm
|
||||
data = parseData(request.FILES["file"])
|
||||
if data == False:
|
||||
raise CouldNotParse
|
||||
file_id = (form.save()).pk
|
||||
result = addDataToDatabase(data, file_id)
|
||||
if result["statusCode"] != 200:
|
||||
raise KnownError
|
||||
else:
|
||||
result = FileUploadSuccess
|
||||
|
||||
elif request.method == 'GET':
|
||||
result, user_id = checkUserToken(request)
|
||||
if result["statusCode"] != 200:
|
||||
raise KnownError
|
||||
data = list(Document.objects.filter(user_id = user_id).values("id", "file", "uploaded_at"))
|
||||
noStatus = True
|
||||
|
||||
except InvalidForm:
|
||||
result = UnknownError
|
||||
|
||||
except InvalidMethod:
|
||||
result = MethodNotAllowed
|
||||
|
||||
except CouldNotParse:
|
||||
result = ParseFailed
|
||||
|
||||
except KnownError:
|
||||
pass
|
||||
|
||||
except:
|
||||
result = UnknownError
|
||||
|
||||
finally:
|
||||
if noStatus:
|
||||
return JsonResponse({"files": data}, safe=False, status=200)
|
||||
return JsonResponse(result, status = result["statusCode"])
|
||||
|
@ -8,44 +8,47 @@ import html
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
def parseData(file):
|
||||
# arguments
|
||||
parser = argparse.ArgumentParser(description='Process some xml files.')
|
||||
parser.add_argument('filename', help='xml forum file')
|
||||
args = parser.parse_args()
|
||||
|
||||
# write file first
|
||||
fd = tempfile.NamedTemporaryFile()
|
||||
f = open(fd.name, "wb+")
|
||||
for chunk in file.chunks():
|
||||
f.write(chunk)
|
||||
f.close()
|
||||
|
||||
# make a soup:
|
||||
with open(fd.name) as forum:
|
||||
soup = BeautifulSoup(forum, "xml")
|
||||
def parseData(file):
|
||||
try:
|
||||
# arguments
|
||||
parser = argparse.ArgumentParser(description='Process some xml files.')
|
||||
parser.add_argument('filename', help='xml forum file')
|
||||
args = parser.parse_args()
|
||||
|
||||
# put json together
|
||||
out = {}
|
||||
out['id'] = soup.forum.get('id')
|
||||
out['name'] = soup.forum.find('name').text
|
||||
out['discussions'] = []
|
||||
for d in soup.forum.find_all('discussion'):
|
||||
posts = []
|
||||
for p in d.find_all('post'):
|
||||
post_soup = BeautifulSoup(html.unescape(str(p.message)), "lxml")
|
||||
paragraphs = [render_bbcode(x.text) for x in post_soup.find_all('p')]
|
||||
posts.append({
|
||||
'id': p.get('id'),
|
||||
'parent': p.find('parent').text,
|
||||
'author': p.userid.text,
|
||||
'message': [x for x in paragraphs if x]
|
||||
# write file first
|
||||
fd = tempfile.NamedTemporaryFile()
|
||||
f = open(fd.name, "wb+")
|
||||
for chunk in file.chunks():
|
||||
f.write(chunk)
|
||||
f.close()
|
||||
|
||||
# make a soup:
|
||||
with open(fd.name) as forum:
|
||||
soup = BeautifulSoup(forum, "xml")
|
||||
|
||||
# put json together
|
||||
out = {}
|
||||
out['id'] = soup.forum.get('id')
|
||||
out['name'] = soup.forum.find('name').text
|
||||
out['discussions'] = []
|
||||
for d in soup.forum.find_all('discussion'):
|
||||
posts = []
|
||||
for p in d.find_all('post'):
|
||||
post_soup = BeautifulSoup(html.unescape(str(p.message)), "lxml")
|
||||
paragraphs = [render_bbcode(x.text) for x in post_soup.find_all('p')]
|
||||
posts.append({
|
||||
'id': p.get('id'),
|
||||
'parent': p.find('parent').text,
|
||||
'author': p.userid.text,
|
||||
'message': [x for x in paragraphs if x]
|
||||
})
|
||||
out['discussions'].append({
|
||||
'id': d.get('id'),
|
||||
'title': d.find('name').text,
|
||||
'first_post': d.firstpost.text,
|
||||
'posts': posts
|
||||
})
|
||||
out['discussions'].append({
|
||||
'id': d.get('id'),
|
||||
'title': d.find('name').text,
|
||||
'first_post': d.firstpost.text,
|
||||
'posts': posts
|
||||
})
|
||||
fd.close()
|
||||
return(out)
|
||||
fd.close()
|
||||
return(out)
|
||||
except:
|
||||
return False
|
||||
|
@ -28,7 +28,8 @@ urlpatterns = [
|
||||
path('visualize/<int:id>', views.visualize),
|
||||
path('user/', views.user),
|
||||
path('login/', views.login),
|
||||
path('testToken/', views.testToken)
|
||||
path('testToken/', views.testToken),
|
||||
path('file/', views.file),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
Loading…
Reference in New Issue
Block a user