aboutsummaryrefslogtreecommitdiffstats
path: root/backend/routes/forms
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2022-02-05 17:39:33 +0400
committerGravatar Hassan Abouelela <[email protected]>2022-02-05 18:27:11 +0400
commit513de6945d40b66368a061dff6a81646e8bda7a0 (patch)
tree64f3ad8670cc9c1fffb6c8c2c0a5e9a8da04582f /backend/routes/forms
parentOverhaul Scope System (diff)
Add Role Based Authorized Readers
Adds a new property on forms to declare which roles are authorized to access form responses. Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'backend/routes/forms')
-rw-r--r--backend/routes/forms/discover.py2
-rw-r--r--backend/routes/forms/response.py18
-rw-r--r--backend/routes/forms/responses.py17
3 files changed, 25 insertions, 12 deletions
diff --git a/backend/routes/forms/discover.py b/backend/routes/forms/discover.py
index d7351d5..b993075 100644
--- a/backend/routes/forms/discover.py
+++ b/backend/routes/forms/discover.py
@@ -29,7 +29,7 @@ EMPTY_FORM = Form(
features=__FEATURES,
questions=[__QUESTION],
name="Auth form",
- description="An empty form to help you get a token."
+ description="An empty form to help you get a token.",
)
diff --git a/backend/routes/forms/response.py b/backend/routes/forms/response.py
index d8d8d17..fbf8e99 100644
--- a/backend/routes/forms/response.py
+++ b/backend/routes/forms/response.py
@@ -1,11 +1,13 @@
"""
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
@@ -17,23 +19,31 @@ class Response(Route):
name = "response"
path = "/{form_id:str}/responses/{response_id:str}"
- @requires(["authenticated", "admin"])
+ @requires(["authenticated"])
@api.validate(
- resp=RouteResponse(HTTP_200=FormResponse, HTTP_404=ErrorMessage),
+ 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": request.path_params["form_id"]
+ "form_id": form_id
}
):
response = FormResponse(**raw_response)
return JSONResponse(response.dict())
else:
- return JSONResponse({"error": "not_found"}, status_code=404)
+ return JSONResponse({"error": "response_not_found"}, status_code=404)
@requires(["authenticated", "admin"])
@api.validate(
diff --git a/backend/routes/forms/responses.py b/backend/routes/forms/responses.py
index f3c4cd7..1c8ebe3 100644
--- a/backend/routes/forms/responses.py
+++ b/backend/routes/forms/responses.py
@@ -7,9 +7,10 @@ from starlette.authentication import requires
from starlette.requests import Request
from starlette.responses import JSONResponse
+from backend import discord
from backend.models import FormResponse, ResponseList
from backend.route import Route
-from backend.validation import api, ErrorMessage, OkayResponse
+from backend.validation import ErrorMessage, OkayResponse, api
class ResponseIdList(BaseModel):
@@ -24,20 +25,22 @@ class Responses(Route):
name = "form_responses"
path = "/{form_id:str}/responses"
- @requires(["authenticated", "admin"])
+ @requires(["authenticated"])
@api.validate(
- resp=Response(HTTP_200=ResponseList, HTTP_404=ErrorMessage),
+ resp=Response(HTTP_200=ResponseList, HTTP_401=ErrorMessage, HTTP_404=ErrorMessage),
tags=["forms", "responses"]
)
async def get(self, request: Request) -> JSONResponse:
"""Returns all form responses by form ID."""
- if not await request.state.db.forms.find_one(
- {"_id": request.path_params["form_id"]}
- ):
+ form_id = request.path_params["form_id"]
+ try:
+ if not await discord.verify_response_access(form_id, request):
+ return JSONResponse({"error": "unauthorized"}, 401)
+ except discord.FormNotFoundError:
return JSONResponse({"error": "not_found"}, 404)
cursor = request.state.db.responses.find(
- {"form_id": request.path_params["form_id"]}
+ {"form_id": form_id}
)
responses = [
FormResponse(**response) for response in await cursor.to_list(None)