diff sat/plugins/plugin_comp_ap_gateway/http_server.py @ 3977:6fa4ca0c047e

component AP gateway: HTML redirection: when a request is done on AP endpoint and `Accept` header is not set to `application/json`, the request can now be redirected to a configurable URL.
author Goffi <goffi@goffi.org>
date Fri, 11 Nov 2022 13:51:20 +0100
parents 0aa7023dcd08
children 9b5092225e46
line wrap: on
line diff
--- a/sat/plugins/plugin_comp_ap_gateway/http_server.py	Thu Nov 10 15:16:43 2022 +0100
+++ b/sat/plugins/plugin_comp_ap_gateway/http_server.py	Fri Nov 11 13:51:20 2022 +0100
@@ -26,6 +26,7 @@
 
 from twisted.web import http, resource as web_resource, server
 from twisted.web import static
+from twisted.web import util as web_util
 from twisted.python import failure
 from twisted.internet import defer
 from twisted.words.protocols.jabber import jid, error
@@ -40,8 +41,8 @@
 from sat.memory.sqla_mapping import SubscriptionState
 
 from .constants import (
-    NS_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX, TYPE_OUTBOX,
-    TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER,
+    NS_AP, MEDIA_TYPE_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX,
+    TYPE_OUTBOX, TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER,
     ACTIVIY_NO_ACCOUNT_ALLOWED, SIGN_HEADERS, HS2019, SIGN_EXP, TYPE_FOLLOWERS,
     TYPE_FOLLOWING, TYPE_ITEM, TYPE_LIKE, TYPE_REACTION, ST_AP_CACHE
 )
@@ -949,6 +950,42 @@
             path
         )
         request_type, extra_args = self.apg.parseAPURL(ap_url)
+        if ((request.getHeader("accept") != MEDIA_TYPE_AP
+             and request_type in self.apg.html_redirect)):
+            # this is not a AP request, and we have a redirections for it
+            kw = {}
+            if extra_args:
+                kw["jid"], kw["node"] = await self.apg.getJIDAndNode(extra_args[0])
+                kw["jid_user"] = kw["jid"].user
+                if kw["node"] is None:
+                    kw["node"] = self.apg._m.namespace
+                if len(extra_args) > 1:
+                    kw["item"] = extra_args[1]
+                else:
+                    kw["item"] = ""
+            else:
+                kw["jid"], kw["jid_user"], kw["node"], kw["item"] = "", "", "", ""
+
+            redirections = self.apg.html_redirect[request_type]
+            for redirection in redirections:
+                filters = redirection["filters"]
+                if not filters:
+                    break
+                # if we have filter, they must all match
+                elif all(v in kw[k] for k,v in filters.items()):
+                    break
+            else:
+                # no redirection is matching
+                redirection = None
+
+            if redirection is not None:
+                kw = {k: parse.quote(str(v), safe="") for k,v in kw.items()}
+                target_url = redirection["url"].format(**kw)
+                content = web_util.redirectTo(target_url.encode(), request)
+                request.write(content)
+                request.finish()
+                return
+
         if len(extra_args) == 0:
             if request_type != "shared_inbox":
                 raise exceptions.DataError(f"Invalid request type: {request_type!r}")