aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/forms/index.py
blob: 22171fae6f7906ac80aa41a3a85a90729fedcc15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""
Return a list of all forms to authenticated users.
"""
from spectree.response import Response
from starlette.authentication import requires
from starlette.requests import Request
from starlette.responses import JSONResponse

from backend.constants import WebHook
from backend.models import Form, FormList
from backend.models.form import validate_hook_url
from backend.route import Route
from backend.validation import ErrorMessage, OkayResponse, api


class FormsList(Route):
    """
    List all available forms for administrator viewing.
    """

    name = "forms_list_create"
    path = "/"

    @requires(["authenticated", "admin"])
    @api.validate(resp=Response(HTTP_200=FormList), tags=["forms"])
    async def get(self, request: Request) -> JSONResponse:
        """Return a list of all forms to authenticated users."""
        forms = []
        cursor = request.state.db.forms.find()

        for form in await cursor.to_list(None):
            forms.append(Form(**form))  # For converting _id to id

        # Covert them back to dictionaries
        forms = [form.dict() for form in forms]

        return JSONResponse(
            forms
        )

    @requires(["authenticated", "admin"])
    @api.validate(
        json=Form,
        resp=Response(HTTP_200=OkayResponse, HTTP_400=ErrorMessage),
        tags=["forms"]
    )
    async def post(self, request: Request) -> JSONResponse:
        """Create a new form."""
        form_data = await request.json()

        # Verify Webhook
        try:
            # Get url from request
            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)

        except KeyError:
            pass

        form = Form(**form_data)

        if await request.state.db.forms.find_one({"_id": form.id}):
            return JSONResponse({
                "error": "id_taken"
            }, status_code=400)

        await request.state.db.forms.insert_one(form.dict(by_alias=True))
        return JSONResponse(form.dict())