aboutsummaryrefslogtreecommitdiff
path: root/webmentions_ssg/views.py
diff options
context:
space:
mode:
authorDennis Fink2026-08-10 23:28:03 +0200
committerDennis Fink2026-08-10 23:28:03 +0200
commitb3e12b975064f0873bdb4d2834cae75925387d6b (patch)
tree92a7ce50f9a3e2b0a49aa32addd9c7e35062d91e /webmentions_ssg/views.py
parent5b39f70aa14cac635b6084170e9d0bd3f548b911 (diff)
downloadwebmentions-ssg-b3e12b975064f0873bdb4d2834cae75925387d6b.tar.gz
webmentions-ssg-b3e12b975064f0873bdb4d2834cae75925387d6b.zip
feat(core): add received webmention admin actions
Add authenticated delete and reverify actions to the received webmentions admin view and protect them with CSRF validation. Enable CSRF protection globally while exempting the public Webmention endpoint.
Diffstat (limited to 'webmentions_ssg/views.py')
-rw-r--r--webmentions_ssg/views.py72
1 files changed, 70 insertions, 2 deletions
diff --git a/webmentions_ssg/views.py b/webmentions_ssg/views.py
index 5408fa4..b52ae07 100644
--- a/webmentions_ssg/views.py
+++ b/webmentions_ssg/views.py
@@ -17,8 +17,8 @@ from flask import (
from flask.typing import ResponseReturnValue
from flask_login import current_user, login_required, login_user, logout_user
+from . import CSRF, forms
from . import DATABASE as db
-from . import forms
from .models import ReceivedWebmention, User
from .tasks.receiver import verify_webmention
@@ -74,10 +74,78 @@ def received() -> ResponseReturnValue:
"received.html",
title="Received Webmentions",
webmentions=webmentions,
+ action_form=forms.AdminActionForm(),
)
-@root_page.route("/endpoint", methods=["POST"])
+@root_page.post("/received/<uuid:identifier>/delete")
+@login_required
+def delete_received_webmention(
+ identifier: uuid.UUID,
+) -> ResponseReturnValue:
+ form = forms.AdminActionForm()
+
+ if not form.validate_on_submit():
+ return abort(400)
+
+ webmention = db.session.get(
+ ReceivedWebmention,
+ identifier,
+ )
+
+ if webmention is None:
+ return abort(404)
+
+ db.session.delete(webmention)
+ db.session.commit()
+
+ flash(f"Webmention {webmention.uuid} deleted.", "success")
+
+ return redirect(
+ url_for(
+ "root.received",
+ page=request.args.get("page", 1, type=int),
+ )
+ )
+
+
+@root_page.post("/received/<uuid:identifier>/reverify")
+@login_required
+def reverify_received_webmention(
+ identifier: uuid.UUID,
+) -> ResponseReturnValue:
+ form = forms.AdminActionForm()
+
+ if not form.validate_on_submit():
+ return abort(400)
+
+ webmention = db.session.get(
+ ReceivedWebmention,
+ identifier,
+ )
+
+ if webmention is None:
+ return abort(404)
+
+ webmention.status = "received"
+ webmention.failure_reason = None
+
+ db.session.commit()
+
+ verify_webmention(identifier)
+
+ flash(f"Webmention {webmention.uuid} queued for reverification.", "success")
+
+ return redirect(
+ url_for(
+ "root.received",
+ page=request.args.get("page", 1, type=int),
+ )
+ )
+
+
+@root_page.post("/endpoint")
+@CSRF.exempt
def endpoint() -> ResponseReturnValue:
form = forms.EndpointForm(meta={"csrf": False})