comparison 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
comparison
equal deleted inserted replaced
3976:db45d49518f6 3977:6fa4ca0c047e
24 from collections import deque 24 from collections import deque
25 import unicodedata 25 import unicodedata
26 26
27 from twisted.web import http, resource as web_resource, server 27 from twisted.web import http, resource as web_resource, server
28 from twisted.web import static 28 from twisted.web import static
29 from twisted.web import util as web_util
29 from twisted.python import failure 30 from twisted.python import failure
30 from twisted.internet import defer 31 from twisted.internet import defer
31 from twisted.words.protocols.jabber import jid, error 32 from twisted.words.protocols.jabber import jid, error
32 from wokkel import pubsub, rsm 33 from wokkel import pubsub, rsm
33 34
38 from sat.core.log import getLogger 39 from sat.core.log import getLogger
39 from sat.tools.common import date_utils, uri 40 from sat.tools.common import date_utils, uri
40 from sat.memory.sqla_mapping import SubscriptionState 41 from sat.memory.sqla_mapping import SubscriptionState
41 42
42 from .constants import ( 43 from .constants import (
43 NS_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX, TYPE_OUTBOX, 44 NS_AP, MEDIA_TYPE_AP, CONTENT_TYPE_AP, TYPE_ACTOR, TYPE_INBOX, TYPE_SHARED_INBOX,
44 TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER, 45 TYPE_OUTBOX, TYPE_EVENT, AP_REQUEST_TYPES, PAGE_SIZE, ACTIVITY_TYPES_LOWER,
45 ACTIVIY_NO_ACCOUNT_ALLOWED, SIGN_HEADERS, HS2019, SIGN_EXP, TYPE_FOLLOWERS, 46 ACTIVIY_NO_ACCOUNT_ALLOWED, SIGN_HEADERS, HS2019, SIGN_EXP, TYPE_FOLLOWERS,
46 TYPE_FOLLOWING, TYPE_ITEM, TYPE_LIKE, TYPE_REACTION, ST_AP_CACHE 47 TYPE_FOLLOWING, TYPE_ITEM, TYPE_LIKE, TYPE_REACTION, ST_AP_CACHE
47 ) 48 )
48 from .regex import RE_SIG_PARAM 49 from .regex import RE_SIG_PARAM
49 50
947 ap_url = parse.urljoin( 948 ap_url = parse.urljoin(
948 f"https://{self.apg.public_url}", 949 f"https://{self.apg.public_url}",
949 path 950 path
950 ) 951 )
951 request_type, extra_args = self.apg.parseAPURL(ap_url) 952 request_type, extra_args = self.apg.parseAPURL(ap_url)
953 if ((request.getHeader("accept") != MEDIA_TYPE_AP
954 and request_type in self.apg.html_redirect)):
955 # this is not a AP request, and we have a redirections for it
956 kw = {}
957 if extra_args:
958 kw["jid"], kw["node"] = await self.apg.getJIDAndNode(extra_args[0])
959 kw["jid_user"] = kw["jid"].user
960 if kw["node"] is None:
961 kw["node"] = self.apg._m.namespace
962 if len(extra_args) > 1:
963 kw["item"] = extra_args[1]
964 else:
965 kw["item"] = ""
966 else:
967 kw["jid"], kw["jid_user"], kw["node"], kw["item"] = "", "", "", ""
968
969 redirections = self.apg.html_redirect[request_type]
970 for redirection in redirections:
971 filters = redirection["filters"]
972 if not filters:
973 break
974 # if we have filter, they must all match
975 elif all(v in kw[k] for k,v in filters.items()):
976 break
977 else:
978 # no redirection is matching
979 redirection = None
980
981 if redirection is not None:
982 kw = {k: parse.quote(str(v), safe="") for k,v in kw.items()}
983 target_url = redirection["url"].format(**kw)
984 content = web_util.redirectTo(target_url.encode(), request)
985 request.write(content)
986 request.finish()
987 return
988
952 if len(extra_args) == 0: 989 if len(extra_args) == 0:
953 if request_type != "shared_inbox": 990 if request_type != "shared_inbox":
954 raise exceptions.DataError(f"Invalid request type: {request_type!r}") 991 raise exceptions.DataError(f"Invalid request type: {request_type!r}")
955 ret_data = await self.APInboxRequest( 992 ret_data = await self.APInboxRequest(
956 request, None, None, None, ap_url, signing_actor 993 request, None, None, None, ap_url, signing_actor