Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions backend/models/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from backend.constants import FormFeatures
from .question import Question

PUBLIC_FIELDS = ["id", "features", "questions", "name", "description"]


class Form(BaseModel):
"""Schema model for form."""
Expand All @@ -31,3 +33,8 @@ def validate_features(cls, value: t.List[str]) -> t.Optional[t.List[str]]:
raise ValueError("COLLECT_EMAIL feature require REQUIRES_LOGIN feature.")

return value

def dict(self, admin: bool = True, **kwargs: t.Dict) -> t.Dict[str, t.Any]:
"""Wrapper for original function to exclude private data for public access."""
data = super().dict(**kwargs)
return {field: data[field] for field in PUBLIC_FIELDS} if admin else data
2 changes: 1 addition & 1 deletion backend/routes/forms/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async def get(self, request: Request) -> JSONResponse:
for form in await cursor.to_list(None):
forms.append(Form(**form))

forms = [form.dict() for form in forms]
forms = [form.dict(admin=False) for form in forms]

return JSONResponse(
forms
Expand Down
36 changes: 36 additions & 0 deletions backend/routes/forms/form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
Returns single form information by ID.
"""
from starlette.requests import Request
from starlette.responses import JSONResponse

from backend.route import Route
from backend.models import Form


class SingleForm(Route):
"""
Returns single form information by ID.

Returns all fields for admins, otherwise only public fields.
"""

name = "form"
path = "/{form_id:str}"

async def get(self, request: Request) -> JSONResponse:
"""Returns single form information by ID."""
admin = request.user.payload["admin"] if request.user.is_authenticated else False # noqa

filters = {
"_id": request.path_params["form_id"]
}

if not admin:
filters["features"] = "OPEN"

if raw_form := await request.state.db.forms.find_one(filters):
form = Form(**raw_form)
return JSONResponse(form.dict(admin=admin))

return JSONResponse({"error": "not_found"}, status_code=404)
19 changes: 18 additions & 1 deletion backend/routes/forms/index.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Return a list of all forms to authenticated users.
"""
from pydantic import ValidationError
from starlette.authentication import requires
from starlette.requests import Request
from starlette.responses import JSONResponse
Expand All @@ -14,7 +15,7 @@ class FormsList(Route):
List all available forms for administrator viewing.
"""

name = "forms_list"
name = "forms_list_create"
path = "/"

@requires(["authenticated", "admin"])
Expand All @@ -31,3 +32,19 @@ async def get(self, request: Request) -> JSONResponse:
return JSONResponse(
forms
)

@requires(["authenticated", "admin"])
async def post(self, request: Request) -> JSONResponse:
form_data = await request.json()
try:
form = Form(**form_data)
except ValidationError as e:
return JSONResponse(e.errors())

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())
35 changes: 0 additions & 35 deletions backend/routes/forms/new.py

This file was deleted.