aboutsummaryrefslogtreecommitdiffstats
path: root/backend/models/form.py
diff options
context:
space:
mode:
Diffstat (limited to 'backend/models/form.py')
-rw-r--r--backend/models/form.py87
1 files changed, 55 insertions, 32 deletions
diff --git a/backend/models/form.py b/backend/models/form.py
index 9a3a8a2..96362d4 100644
--- a/backend/models/form.py
+++ b/backend/models/form.py
@@ -2,8 +2,9 @@ import typing as t
import httpx
from pydantic import BaseModel, Field, validator
+from pydantic.error_wrappers import ErrorWrapper, ValidationError
-from backend.constants import FormFeatures
+from backend.constants import FormFeatures, Meta, WebHook
from .question import Question
PUBLIC_FIELDS = ["id", "features", "questions", "name", "description"]
@@ -16,40 +17,10 @@ class _WebHook(BaseModel):
@validator("url")
def validate_url(cls, url: str) -> str:
- """Checks if discord webhook urls are valid."""
- if not isinstance(url, str):
- raise ValueError("Webhook URL must be a string.")
-
+ """Validates URL parameter."""
if "discord.com/api/webhooks/" not in url:
raise ValueError("URL must be a discord webhook.")
- # Attempt to connect to URL
- try:
- httpx.get(url).raise_for_status()
-
- except httpx.RequestError as e:
- # Catch exceptions in request format
- raise ValueError(
- f"Encountered error while trying to connect to url: `{e}`"
- )
-
- except httpx.HTTPStatusError as e:
- # Catch exceptions in response
- status = e.response.status_code
-
- if status == 401:
- raise ValueError(
- "Could not authenticate with target. Please check the webhook url."
- )
- elif status == 404:
- raise ValueError(
- "Target could not find webhook url. Please check the webhook url."
- )
- else:
- raise ValueError(
- f"Unknown error ({status}) while connecting to target: {e}"
- )
-
return url
@@ -107,3 +78,55 @@ class Form(BaseModel):
class FormList(BaseModel):
__root__: t.List[Form]
+
+
+async def validate_hook_url(url: str) -> t.Optional[ValidationError]:
+ """Validator for discord webhook urls."""
+ async def validate():
+ if not isinstance(url, str):
+ raise ValueError("Webhook URL must be a string.")
+
+ if "discord.com/api/webhooks/" not in url:
+ raise ValueError("URL must be a discord webhook.")
+
+ try:
+ async with httpx.AsyncClient() as client:
+ response = await client.get(url)
+ response.raise_for_status()
+
+ except httpx.RequestError as error:
+ # Catch exceptions in request format
+ raise ValueError(
+ f"Encountered error while trying to connect to url: `{error}`"
+ )
+
+ except httpx.HTTPStatusError as error:
+ # Catch exceptions in response
+ status = error.response.status_code
+
+ if status == 401:
+ raise ValueError(
+ "Could not authenticate with target. Please check the webhook url."
+ )
+ elif status == 404:
+ raise ValueError(
+ "Target could not find webhook url. Please check the webhook url."
+ )
+ else:
+ raise ValueError(
+ f"Unknown error ({status}) while connecting to target: {error}"
+ )
+
+ return url
+
+ # Validate, and return errors, if any
+ try:
+ await validate()
+ except Exception as e:
+ loc = (
+ Meta.__name__.lower(),
+ WebHook.__name__.lower(),
+ WebHook.URL.value
+ )
+
+ return ValidationError([ErrorWrapper(e, loc=loc)], _WebHook)