aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2022-06-18 04:41:10 +0400
committerGravatar GitHub <[email protected]>2022-06-18 04:41:10 +0400
commitfe94892f573828a3c5bf61123d2dd9923e1e1986 (patch)
tree07782cc28afc74facfa8695b5660a865c0e8799f
parentuse Request to generate the state (diff)
parentMerge pull request #177 from python-discord/enable-login-in-prod (diff)
Merge branch 'main' into asgi-middleware
-rw-r--r--backend/discord.py2
-rw-r--r--backend/routes/forms/discover.py20
-rw-r--r--backend/routes/forms/form.py17
-rw-r--r--backend/routes/forms/submit.py16
-rw-r--r--poetry.lock38
-rw-r--r--pyproject.toml2
6 files changed, 48 insertions, 47 deletions
diff --git a/backend/discord.py b/backend/discord.py
index be12109..ff6c1bb 100644
--- a/backend/discord.py
+++ b/backend/discord.py
@@ -175,7 +175,7 @@ async def _verify_access_helper(
form = models.Form(**form)
- for role_id in getattr(form, attribute, []):
+ for role_id in getattr(form, attribute, None) or []:
role = await request.state.db.roles.find_one({"id": role_id})
if not role:
continue
diff --git a/backend/routes/forms/discover.py b/backend/routes/forms/discover.py
index b993075..75ff495 100644
--- a/backend/routes/forms/discover.py
+++ b/backend/routes/forms/discover.py
@@ -11,25 +11,27 @@ from backend.route import Route
from backend.validation import api
__FEATURES = [
- constants.FormFeatures.DISCOVERABLE.value,
constants.FormFeatures.OPEN.value,
constants.FormFeatures.REQUIRES_LOGIN.value
]
+if not constants.PRODUCTION:
+ __FEATURES.append(constants.FormFeatures.DISCOVERABLE.value)
__QUESTION = Question(
id="description",
- name="Check your cookies after pressing the button.",
+ name="Click the button below to log into the forms application.",
type="section",
- data={"text": "You can find cookies under \"Application\" in dev tools."},
+ data={"text": ""},
required=False
)
-EMPTY_FORM = Form(
- id="empty_auth",
+AUTH_FORM = Form(
+ id="login",
features=__FEATURES,
questions=[__QUESTION],
- name="Auth form",
- description="An empty form to help you get a token.",
+ name="Login",
+ description="Log into Python Discord Forms.",
+ submitted_text="This page can't be submitted."
)
@@ -55,7 +57,7 @@ class DiscoverableFormsList(Route):
forms = [form.dict(admin=False) for form in forms]
# Return an empty form in development environments to help with authentication.
- if not forms and not constants.PRODUCTION:
- forms.append(EMPTY_FORM.dict(admin=False))
+ if not constants.PRODUCTION:
+ forms.append(AUTH_FORM.dict(admin=False))
return JSONResponse(forms)
diff --git a/backend/routes/forms/form.py b/backend/routes/forms/form.py
index 567c197..8349d4e 100644
--- a/backend/routes/forms/form.py
+++ b/backend/routes/forms/form.py
@@ -13,7 +13,7 @@ from starlette.responses import JSONResponse
from backend import constants, discord
from backend.models import Form
from backend.route import Route
-from backend.routes.forms.discover import EMPTY_FORM
+from backend.routes.forms.discover import AUTH_FORM
from backend.routes.forms.unittesting import filter_unittests
from backend.validation import ErrorMessage, OkayResponse, api
@@ -35,14 +35,15 @@ class SingleForm(Route):
"""Returns single form information by ID."""
form_id = request.path_params["form_id"].lower()
+ if form_id == AUTH_FORM.id:
+ # Empty form for login purposes
+ return JSONResponse(AUTH_FORM.dict(admin=False))
+
try:
await discord.verify_edit_access(form_id, request)
admin = True
except discord.FormNotFoundError:
- if not constants.PRODUCTION and form_id == EMPTY_FORM.id:
- # Empty form to help with authentication in development.
- return JSONResponse(EMPTY_FORM.dict(admin=False))
- raise
+ return JSONResponse({"error": "not_found"}, status_code=404)
except discord.UnauthorizedError:
admin = False
@@ -53,7 +54,11 @@ class SingleForm(Route):
if not admin:
filters["features"] = {"$in": ["OPEN", "DISCOVERABLE"]}
- form = Form(**await request.state.db.forms.find_one(filters))
+ form = await request.state.db.forms.find_one(filters)
+ if not form:
+ return JSONResponse({"error": "not_found"}, status_code=404)
+
+ form = Form(**form)
if not admin:
form = filter_unittests(form)
diff --git a/backend/routes/forms/submit.py b/backend/routes/forms/submit.py
index baf403d..5c500b5 100644
--- a/backend/routes/forms/submit.py
+++ b/backend/routes/forms/submit.py
@@ -22,6 +22,7 @@ from backend.authentication.user import User
from backend.models import Form, FormResponse
from backend.route import Route
from backend.routes.auth.authorize import set_response_token
+from backend.routes.forms.discover import AUTH_FORM
from backend.routes.forms.unittesting import execute_unittest
from backend.validation import ErrorMessage, api
@@ -106,9 +107,18 @@ class SubmitForm(Route):
data = await request.json()
data["timestamp"] = None
- if form := await request.state.db.forms.find_one(
- {"_id": request.path_params["form_id"], "features": "OPEN"}
- ):
+ form_id = request.path_params["form_id"]
+
+ if form_id == AUTH_FORM.id:
+ response = FormResponse(
+ id="not-submitted",
+ form_id=AUTH_FORM.id,
+ response={question.id: None for question in AUTH_FORM.questions},
+ timestamp=datetime.datetime.now().isoformat()
+ ).dict()
+ return JSONResponse({"form": AUTH_FORM.dict(admin=False), "response": response})
+
+ if form := await request.state.db.forms.find_one({"_id": form_id, "features": "OPEN"}):
form = Form(**form)
response = data.copy()
response["id"] = str(uuid.uuid4())
diff --git a/poetry.lock b/poetry.lock
index f888575..5271c7d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -35,17 +35,6 @@ optional = false
python-versions = "*"
[[package]]
-name = "charset-normalizer"
-version = "2.0.11"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "main"
-optional = false
-python-versions = ">=3.5.0"
-
-[package.extras]
-unicode_backport = ["unicodedata2"]
-
-[[package]]
name = "click"
version = "8.0.3"
description = "Composable command line interface toolkit"
@@ -148,11 +137,11 @@ python-versions = ">=3.6"
[[package]]
name = "httpcore"
-version = "0.14.7"
+version = "0.15.0"
description = "A minimal low-level HTTP client."
category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
[package.dependencies]
anyio = ">=3.0.0,<4.0.0"
@@ -177,22 +166,21 @@ test = ["Cython (>=0.29.24,<0.30.0)"]
[[package]]
name = "httpx"
-version = "0.22.0"
+version = "0.23.0"
description = "The next generation HTTP client."
category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
[package.dependencies]
certifi = "*"
-charset-normalizer = "*"
-httpcore = ">=0.14.5,<0.15.0"
+httpcore = ">=0.15.0,<0.16.0"
rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
sniffio = "*"
[package.extras]
brotli = ["brotlicffi", "brotli"]
-cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10.0.0,<11.0.0)", "pygments (>=2.0.0,<3.0.0)"]
+cli = ["click (>=8.0.0,<9.0.0)", "rich (>=10,<13)", "pygments (>=2.0.0,<3.0.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (>=1.0.0,<2.0.0)"]
@@ -477,7 +465,7 @@ python-versions = ">=3.7"
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
-content-hash = "fe20bd8d4a5b82833c0d4389704874b45f2d7adabf4a3c850c03b930a8940afa"
+content-hash = "9f20721dc2e5196709693e7ffbc5fe2e7043afeeb40b790a15ccd94d9676b042"
[metadata.files]
anyio = [
@@ -492,10 +480,6 @@ certifi = [
{file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
{file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
]
-charset-normalizer = [
- {file = "charset-normalizer-2.0.11.tar.gz", hash = "sha256:98398a9d69ee80548c762ba991a4728bfc3836768ed226b3945908d1a688371c"},
- {file = "charset_normalizer-2.0.11-py3-none-any.whl", hash = "sha256:2842d8f5e82a1f6aa437380934d5e1cd4fcf2003b06fed6940769c164a480a45"},
-]
click = [
{file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
{file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"},
@@ -533,8 +517,8 @@ h11 = [
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
]
httpcore = [
- {file = "httpcore-0.14.7-py3-none-any.whl", hash = "sha256:47d772f754359e56dd9d892d9593b6f9870a37aeb8ba51e9a88b09b3d68cfade"},
- {file = "httpcore-0.14.7.tar.gz", hash = "sha256:7503ec1c0f559066e7e39bc4003fd2ce023d01cf51793e3c173b864eb456ead1"},
+ {file = "httpcore-0.15.0-py3-none-any.whl", hash = "sha256:1105b8b73c025f23ff7c36468e4432226cbb959176eab66864b8e31c4ee27fa6"},
+ {file = "httpcore-0.15.0.tar.gz", hash = "sha256:18b68ab86a3ccf3e7dc0f43598eaddcf472b602aba29f9aa6ab85fe2ada3980b"},
]
httptools = [
{file = "httptools-0.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcddfe70553be717d9745990dfdb194e22ee0f60eb8f48c0794e7bfeda30d2d5"},
@@ -573,8 +557,8 @@ httptools = [
{file = "httptools-0.4.0.tar.gz", hash = "sha256:2c9a930c378b3d15d6b695fb95ebcff81a7395b4f9775c4f10a076beb0b2c1ff"},
]
httpx = [
- {file = "httpx-0.22.0-py3-none-any.whl", hash = "sha256:e35e83d1d2b9b2a609ef367cc4c1e66fd80b750348b20cc9e19d1952fc2ca3f6"},
- {file = "httpx-0.22.0.tar.gz", hash = "sha256:d8e778f76d9bbd46af49e7f062467e3157a5a3d2ae4876a4bbfd8a51ed9c9cb4"},
+ {file = "httpx-0.23.0-py3-none-any.whl", hash = "sha256:42974f577483e1e932c3cdc3cd2303e883cbfba17fe228b0f63589764d7b9c4b"},
+ {file = "httpx-0.23.0.tar.gz", hash = "sha256:f28eac771ec9eb4866d3fb4ab65abd42d38c424739e80c08d8d20570de60b0ef"},
]
idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
diff --git a/pyproject.toml b/pyproject.toml
index 5b02228..a6ba3c7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -13,7 +13,7 @@ uvicorn = {extras = ["standard"], version = "^0.17.6"}
motor = "^2.4.0"
python-dotenv = "^0.19.2"
pyjwt = "^2.4.0"
-httpx = "^0.22.0"
+httpx = "^0.23.0"
gunicorn = "^20.1.0"
pydantic = "^1.8.2"
spectree = "^0.7.6"