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

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

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

logger = logging.getLogger(__name__)


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

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

    @requires(["authenticated", "admin"])
    @api.validate(
        resp=RouteResponse(HTTP_200=FormResponse, HTTP_404=ErrorMessage),
        tags=["forms", "responses"]
    )
    async def get(self, request: Request) -> JSONResponse:
        """Return a single form response by ID."""
        if raw_response := await request.state.db.responses.find_one(
            {
                "_id": request.path_params["response_id"],
                "form_id": request.path_params["form_id"]
            }
        ):
            response = FormResponse(**raw_response)
            return JSONResponse(response.dict())
        else:
            return JSONResponse({"error": "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."""
        ids = {
            "_id": request.path_params["response_id"],
            "form_id": request.path_params["form_id"]
        }

        logger.info(
            f"Attempting to delete a response from {ids.get('form_id')} with ID: {ids.get('_id')}"
        )

        if not await request.state.db.responses.find_one(ids):
            return JSONResponse({"error": "not_found"}, status_code=404)

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