aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/forms/response.py
blob: fbf8e9998a1e92ac5c7cefb8e636cdd1389a02c7 (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
"""
Returns or deletes form response by ID.
"""

from spectree import Response as RouteResponse
from starlette.authentication import requires
from starlette.requests import Request
from starlette.responses import JSONResponse

from backend import discord
from backend.models import FormResponse
from backend.route import Route
from backend.validation import ErrorMessage, OkayResponse, api


class Response(Route):
    """Get or delete single form response by ID."""

    name = "response"
    path = "/{form_id:str}/responses/{response_id:str}"

    @requires(["authenticated"])
    @api.validate(
        resp=RouteResponse(HTTP_200=FormResponse, HTTP_401=ErrorMessage, HTTP_404=ErrorMessage),
        tags=["forms", "responses"]
    )
    async def get(self, request: Request) -> JSONResponse:
        """Return a single form response by ID."""
        form_id = request.path_params["form_id"]

        try:
            if not await discord.verify_response_access(form_id, request):
                return JSONResponse({"error": "unauthorized"}, status_code=401)
        except discord.FormNotFoundError:
            return JSONResponse({"error": "form_not_found"}, status_code=404)

        if raw_response := await request.state.db.responses.find_one(
            {
                "_id": request.path_params["response_id"],
                "form_id": form_id
            }
        ):
            response = FormResponse(**raw_response)
            return JSONResponse(response.dict())
        else:
            return JSONResponse({"error": "response_not_found"}, status_code=404)

    @requires(["authenticated", "admin"])
    @api.validate(
        resp=RouteResponse(HTTP_200=OkayResponse, HTTP_404=ErrorMessage),
        tags=["forms", "responses"]
    )
    async def delete(self, request: Request) -> JSONResponse:
        """Delete a form response by ID."""
        if not await request.state.db.responses.find_one(
            {
                "_id": request.path_params["response_id"],
                "form_id": request.path_params["form_id"]
            }
        ):
            return JSONResponse({"error": "not_found"}, status_code=404)

        await request.state.db.responses.delete_one(
            {"_id": request.path_params["response_id"]}
        )
        return JSONResponse({"status": "ok"})