aboutsummaryrefslogtreecommitdiff
path: root/webmentions_ssg/forms/validators.py
diff options
context:
space:
mode:
authorDennis Fink2026-08-09 14:15:29 +0200
committerDennis Fink2026-08-09 14:15:29 +0200
commite4a8194e6de25e8a48e2c61ce7f89a8159fd99d9 (patch)
tree234f63980aba8fe3c8d03e7bc8959598bce7e790 /webmentions_ssg/forms/validators.py
parentf53c1136184d2afabfb1e5974e527229aa71939a (diff)
downloadwebmentions-ssg-e4a8194e6de25e8a48e2c61ce7f89a8159fd99d9.tar.gz
webmentions-ssg-e4a8194e6de25e8a48e2c61ce7f89a8159fd99d9.zip
Implement received Webmention handling
Add the Flask application setup, database models and migrations, authentication, and configuration for development and testing. Implement asynchronous Webmention verification with Huey, including HTML and plain-text source validation, retries, status tracking, and size limits. Add status, login, and paginated received-Webmention views together with comprehensive tests for forms, views, and receiver tasks.
Diffstat (limited to 'webmentions_ssg/forms/validators.py')
-rw-r--r--webmentions_ssg/forms/validators.py62
1 files changed, 62 insertions, 0 deletions
diff --git a/webmentions_ssg/forms/validators.py b/webmentions_ssg/forms/validators.py
new file mode 100644
index 0000000..20d9ebf
--- /dev/null
+++ b/webmentions_ssg/forms/validators.py
@@ -0,0 +1,62 @@
+from urllib.parse import urlsplit
+
+from flask import current_app
+from wtforms import ValidationError
+
+
+class NotEqualTo:
+ """
+ Compares the values of two fields.
+
+ :param fieldname:
+ The name of the other field to compare to.
+ :param message:
+ Error message to raise in case of a validation error. Can be
+ interpolated with `%(other_label)s` and `%(other_name)s` to provide a
+ more helpful error.
+ """
+
+ def __init__(self, fieldname, message=None):
+ self.fieldname = fieldname
+ self.message = message
+
+ def __call__(self, form, field):
+ try:
+ other = form[self.fieldname]
+ except KeyError as exc:
+ raise ValidationError(
+ field.gettext("Invalid field name '%s'.") % self.fieldname
+ ) from exc
+
+ if field.data != other.data:
+ return
+
+ d = {
+ "other_label": hasattr(other, "label")
+ and other.label.text
+ or self.fieldname,
+ "other_name": self.fieldname,
+ }
+ message = self.message
+ if message is None:
+ message = field.gettext("Field must not be equal to %(other_name)s.")
+
+ raise ValidationError(message % d)
+
+
+class AllowedHostname:
+ def __init__(self, message=None):
+ self.message = message
+
+ def __call__(self, form, field):
+ if (
+ urlsplit(field.data).hostname
+ in current_app.config["WEBMENTIONS_SSG_ALLOWED_HOSTNAMES"]
+ ):
+ return
+
+ message = self.message
+ if self.message is None:
+ message = field.gettext("Invalid input.")
+
+ raise ValidationError(message)