diff options
-rw-r--r-- | backend/routes/forms/discover.py | 33 | ||||
-rw-r--r-- | backend/routes/forms/form.py | 17 | ||||
-rw-r--r-- | backend/routes/forms/index.py | 12 |
3 files changed, 50 insertions, 12 deletions
diff --git a/backend/routes/forms/discover.py b/backend/routes/forms/discover.py index c4711aa..d7351d5 100644 --- a/backend/routes/forms/discover.py +++ b/backend/routes/forms/discover.py @@ -5,10 +5,33 @@ from spectree.response import Response from starlette.requests import Request from starlette.responses import JSONResponse -from backend.models import Form, FormList +from backend import constants +from backend.models import Form, FormList, Question from backend.route import Route from backend.validation import api +__FEATURES = [ + constants.FormFeatures.DISCOVERABLE.value, + constants.FormFeatures.OPEN.value, + constants.FormFeatures.REQUIRES_LOGIN.value +] + +__QUESTION = Question( + id="description", + name="Check your cookies after pressing the button.", + type="section", + data={"text": "You can find cookies under \"Application\" in dev tools."}, + required=False +) + +EMPTY_FORM = Form( + id="empty_auth", + features=__FEATURES, + questions=[__QUESTION], + name="Auth form", + description="An empty form to help you get a token." +) + class DiscoverableFormsList(Route): """ @@ -31,6 +54,8 @@ class DiscoverableFormsList(Route): forms = [form.dict(admin=False) for form in forms] - return JSONResponse( - forms - ) + # Return an empty form in development environments to help with authentication. + if not forms and not constants.PRODUCTION: + forms.append(EMPTY_FORM.dict(admin=False)) + + return JSONResponse(forms) diff --git a/backend/routes/forms/form.py b/backend/routes/forms/form.py index 205b601..3ea3acb 100644 --- a/backend/routes/forms/form.py +++ b/backend/routes/forms/form.py @@ -1,6 +1,8 @@ """ Returns, updates or deletes a single form given an ID. """ +import json.decoder + import deepmerge from pydantic import ValidationError from spectree.response import Response @@ -8,8 +10,10 @@ from starlette.authentication import requires from starlette.requests import Request from starlette.responses import JSONResponse +from backend import constants from backend.models import Form from backend.route import Route +from backend.routes.forms.discover import EMPTY_FORM from backend.routes.forms.unittesting import filter_unittests from backend.validation import ErrorMessage, OkayResponse, api @@ -28,9 +32,10 @@ class SingleForm(Route): async def get(self, request: Request) -> JSONResponse: """Returns single form information by ID.""" admin = request.user.admin if request.user.is_authenticated else False + form_id = request.path_params["form_id"] filters = { - "_id": request.path_params["form_id"] + "_id": form_id } if not admin: @@ -43,11 +48,14 @@ class SingleForm(Route): return JSONResponse(form.dict(admin=admin)) + elif not constants.PRODUCTION and form_id == EMPTY_FORM.id: + # Empty form to help with authentication in development. + return JSONResponse(EMPTY_FORM.dict(admin=admin)) + return JSONResponse({"error": "not_found"}, status_code=404) @requires(["authenticated", "admin"]) @api.validate( - json=Form, resp=Response( HTTP_200=OkayResponse, HTTP_400=ErrorMessage, @@ -57,7 +65,10 @@ class SingleForm(Route): ) async def patch(self, request: Request) -> JSONResponse: """Updates form by ID.""" - data = await request.json() + try: + data = await request.json() + except json.decoder.JSONDecodeError: + return JSONResponse("Expected a JSON body.", 400) form_id = {"_id": request.path_params["form_id"]} if raw_form := await request.state.db.forms.find_one(form_id): diff --git a/backend/routes/forms/index.py b/backend/routes/forms/index.py index 5fd90ab..22171fa 100644 --- a/backend/routes/forms/index.py +++ b/backend/routes/forms/index.py @@ -51,12 +51,14 @@ class FormsList(Route): # Verify Webhook try: # Get url from request - url = form_data[WebHook.__name__.lower()][WebHook.URL.value] + webhook = form_data[WebHook.__name__.lower()] + if webhook is not None: + url = webhook[WebHook.URL.value] - # Validate URL - validation = await validate_hook_url(url) - if validation: - return JSONResponse(validation.errors(), status_code=422) + # Validate URL + validation = await validate_hook_url(url) + if validation: + return JSONResponse(validation.errors(), status_code=422) except KeyError: pass |