aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/forms/submit.py
diff options
context:
space:
mode:
authorGravatar ks129 <[email protected]>2021-03-09 08:48:58 +0200
committerGravatar GitHub <[email protected]>2021-03-09 08:48:58 +0200
commit0ec4a370d476f3f8b7453c887b0b02fe83aced9c (patch)
treee7fb0e7a71369affd79222445a35438815ad4cd3 /backend/routes/forms/submit.py
parentAdd missing "is" to error message (diff)
parentFixes Production URL Constant (diff)
Merge branch 'main' into ks123/role-assigning
Diffstat (limited to 'backend/routes/forms/submit.py')
-rw-r--r--backend/routes/forms/submit.py58
1 files changed, 53 insertions, 5 deletions
diff --git a/backend/routes/forms/submit.py b/backend/routes/forms/submit.py
index 37f76e0..23444a0 100644
--- a/backend/routes/forms/submit.py
+++ b/backend/routes/forms/submit.py
@@ -4,6 +4,7 @@ Submit a form.
import asyncio
import binascii
+import datetime
import hashlib
import uuid
from typing import Any, Optional
@@ -17,10 +18,12 @@ from starlette.requests import Request
from starlette.responses import JSONResponse
from backend import constants
-from backend.authentication import User
+from backend.authentication.user import User
from backend.models import Form, FormResponse
from backend.route import Route
-from backend.validation import AuthorizationHeaders, ErrorMessage, api
+from backend.routes.auth.authorize import set_response_token
+from backend.routes.forms.unittesting import execute_unittest
+from backend.validation import ErrorMessage, api
HCAPTCHA_VERIFY_URL = "https://hcaptcha.com/siteverify"
HCAPTCHA_HEADERS = {
@@ -57,13 +60,37 @@ class SubmitForm(Route):
HTTP_404=ErrorMessage,
HTTP_400=ErrorMessage
),
- headers=AuthorizationHeaders,
tags=["forms", "responses"]
)
async def post(self, request: Request) -> JSONResponse:
"""Submit a response to the form."""
- data = await request.json()
+ response = await self.submit(request)
+
+ # Silently try to update user data
+ try:
+ if hasattr(request.user, User.refresh_data.__name__):
+ old = request.user.token
+ await request.user.refresh_data()
+
+ if old != request.user.token:
+ try:
+ expiry = datetime.datetime.fromisoformat(
+ request.user.decoded_token.get("expiry")
+ )
+ except ValueError:
+ expiry = None
+
+ expiry_seconds = (expiry - datetime.datetime.now()).seconds
+ await set_response_token(response, request, request.user.token, expiry_seconds)
+
+ except httpx.HTTPStatusError:
+ pass
+ return response
+
+ async def submit(self, request: Request) -> JSONResponse:
+ """Helper method for handling submission logic."""
+ data = await request.json()
data["timestamp"] = None
if form := await request.state.db.forms.find_one(
@@ -104,8 +131,12 @@ class SubmitForm(Route):
if constants.FormFeatures.REQUIRES_LOGIN.value in form.features:
if request.user.is_authenticated:
response["user"] = request.user.payload
+ response["user"]["admin"] = request.user.admin
- if constants.FormFeatures.COLLECT_EMAIL.value in form.features and "email" not in response["user"]: # noqa
+ if (
+ constants.FormFeatures.COLLECT_EMAIL.value in form.features
+ and "email" not in response["user"]
+ ):
return JSONResponse({
"error": "email_required"
}, status_code=400)
@@ -133,6 +164,23 @@ class SubmitForm(Route):
except ValidationError as e:
return JSONResponse(e.errors(), status_code=422)
+ # Run unittests if needed
+ if any("unittests" in question.data for question in form.questions):
+ unittest_results = await execute_unittest(response_obj, form)
+
+ if not all(test.passed for test in unittest_results):
+ # Return 500 if we encountered an internal error (code 99).
+ status_code = 500 if any(
+ test.return_code == 99 for test in unittest_results
+ ) else 403
+
+ return JSONResponse({
+ "error": "failed_tests",
+ "test_results": [
+ test._asdict() for test in unittest_results if not test.passed
+ ]
+ }, status_code=status_code)
+
await request.state.db.responses.insert_one(
response_obj.dict(by_alias=True)
)