annotate libervia/backend/plugins/plugin_comp_ap_gateway/http_server.py @ 4283:23842a63ea00

plugin XEP-0060: add a `force` options for publish options in `send_items`: The new `force` option can be used to force the update of configuration is `publish-option` fails. Use this new `force` option in XEP-0384.
author Goffi <goffi@goffi.org>
date Sun, 14 Jul 2024 16:45:17 +0200
parents 0d7bb4df2343
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia ActivityPub Gateway
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
19 import time
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
20 import html
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
21 from typing import Optional, Dict, List, Any
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
22 import json
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
23 from urllib import parse
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
24 from collections import deque
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
25 import unicodedata
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
26
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
27 from twisted.web import http, resource as web_resource, server
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
28 from twisted.web import static
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
29 from twisted.web import util as web_util
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
30 from twisted.python import failure
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3826
diff changeset
31 from twisted.internet import defer
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
32 from twisted.words.protocols.jabber import jid, error
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
33 from wokkel import pubsub, rsm
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
34
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
35 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
36 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
37 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
38 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
39 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
40 from libervia.backend.tools.common import date_utils, uri
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
41 from libervia.backend.memory.sqla_mapping import SubscriptionState
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
42
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
43 from .constants import (
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
44 NS_AP,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
45 MEDIA_TYPE_AP,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
46 MEDIA_TYPE_AP_ALT,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
47 CONTENT_TYPE_WEBFINGER,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
48 CONTENT_TYPE_AP,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
49 TYPE_ACTOR,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
50 TYPE_INBOX,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
51 TYPE_SHARED_INBOX,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
52 TYPE_OUTBOX,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
53 TYPE_EVENT,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
54 AP_REQUEST_TYPES,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
55 PAGE_SIZE,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
56 ACTIVITY_TYPES_LOWER,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
57 ACTIVIY_NO_ACCOUNT_ALLOWED,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
58 SIGN_HEADERS,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
59 HS2019,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
60 SIGN_EXP,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
61 TYPE_FOLLOWERS,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
62 TYPE_FOLLOWING,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
63 TYPE_ITEM,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
64 TYPE_LIKE,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
65 TYPE_REACTION,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
66 ST_AP_CACHE,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
67 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
68 from .regex import RE_SIG_PARAM
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 log = getLogger(__name__)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
73 VERSION = unicodedata.normalize(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
74 "NFKD", f"{C.APP_NAME} ActivityPub Gateway {C.APP_VERSION}"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
75 )
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 class HTTPAPGServer(web_resource.Resource):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 """HTTP Server handling ActivityPub S2S protocol"""
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
80
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 isLeaf = True
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 def __init__(self, ap_gateway):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 self.apg = ap_gateway
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
85 self._seen_digest = deque(maxlen=50)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 super().__init__()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
88 def response_code(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
89 self, request: "HTTPRequest", http_code: int, msg: Optional[str] = None
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
90 ) -> None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
91 """Log and set HTTP return code and associated message"""
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3826
diff changeset
92 if msg is not None:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3826
diff changeset
93 log.warning(msg)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
94 request.setResponseCode(http_code, None if msg is None else msg.encode())
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
95
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
96 def _on_request_error(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
97 self, failure_: failure.Failure, request: "HTTPRequest"
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
98 ) -> None:
4014
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
99 exc = failure_.value
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
100 if isinstance(exc, exceptions.NotFound):
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
101 self.response_code(request, http.NOT_FOUND, str(exc))
4014
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
102 else:
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
103 log.exception(f"Internal error: {failure_.value}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
104 self.response_code(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
105 request, http.INTERNAL_SERVER_ERROR, f"internal error: {failure_.value}"
4014
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
106 )
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
107 request.finish()
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
108 raise failure_
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4009
diff changeset
109
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
110 request.finish()
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
111
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
112 async def webfinger(self, request):
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 url_parsed = parse.urlparse(request.uri.decode())
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 query = parse.parse_qs(url_parsed.query)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 resource = query.get("resource", [""])[0]
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 account = resource[5:].strip()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 if not resource.startswith("acct:") or not account:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 return web_resource.ErrorPage(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
119 http.BAD_REQUEST, "Bad Request", "Invalid webfinger resource"
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 ).render(request)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
122 actor_url = self.apg.build_apurl(TYPE_ACTOR, account)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 resp = {
3882
1bd44367337d component AP gateway: add `aliases` to webfinger data
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
125 "aliases": [actor_url],
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 "subject": resource,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 "links": [
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
128 {"rel": "self", "type": "application/activity+json", "href": actor_url}
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
129 ],
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 }
4104
58bbc100f13b component AP gateway: fix webfinger content type
Goffi <goffi@goffi.org>
parents: 4093
diff changeset
131 request.setHeader("content-type", CONTENT_TYPE_WEBFINGER)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
132 request.write(json.dumps(resp).encode())
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
133 request.finish()
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
134
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
135 async def handle_undo_activity(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
136 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
137 requestor_actor_id: str,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
138 request: "HTTPRequest",
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
139 data: dict,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
140 account_jid: jid.JID,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
141 node: Optional[str],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
142 ap_account: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
143 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
144 signing_actor: str,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
145 ) -> None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
146 if node is None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
147 node = self.apg._m.namespace
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
148 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
149 object_ = data.get("object")
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
150 if isinstance(object_, str):
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
151 # we check first if it's not a cached object
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
152 ap_cache_key = f"{ST_AP_CACHE}{object_}"
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
153 value = await self.apg.client._ap_storage.get(ap_cache_key)
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
154 else:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
155 value = None
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
156 if value is not None:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
157 objects = [value]
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
158 # because we'll undo the activity, we can remove it from cache
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
159 await self.apg.client._ap_storage.remove(ap_cache_key)
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
160 else:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
161 objects = await self.apg.ap_get_list(requestor_actor_id, data, "object")
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
162 for obj in objects:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
163 type_ = obj.get("type")
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
164 actor = await self.apg.ap_get_sender_actor(requestor_actor_id, obj)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
165 if actor != signing_actor:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
166 log.warning(f"ignoring object not attributed to signing actor: {data}")
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
167 continue
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
168
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
169 if type_ == "Follow":
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
170 try:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
171 target_account = obj["object"]
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
172 except KeyError:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
173 log.warning(f'ignoring invalid object, missing "object" key: {data}')
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
174 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
175 if not self.apg.is_local_url(target_account):
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
176 log.warning(f"ignoring unfollow request to non local actor: {data}")
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
177 continue
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
178 await self.apg._p.unsubscribe(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
179 client,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
180 account_jid,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
181 node,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
182 sender=client.jid,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
183 )
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
184 elif type_ == "Announce":
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
185 # we can use directly the Announce object, as only the "id" field is
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
186 # needed
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
187 await self.apg.new_ap_delete_item(client, None, node, obj)
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
188 elif type_ == TYPE_LIKE:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
189 await self.handle_attachment_item(client, obj, {"noticed": False})
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
190 elif type_ == TYPE_REACTION:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
191 await self.handle_attachment_item(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
192 client,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
193 obj,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
194 {"reactions": {"operation": "update", "remove": [obj["content"]]}},
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
195 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
196 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
197 log.warning(f"Unmanaged undo type: {type_!r}")
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
198
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
199 async def handle_follow_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
200 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
201 requestor_actor_id: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
202 request: "HTTPRequest",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
203 data: dict,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
204 account_jid: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
205 node: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
206 ap_account: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
207 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
208 signing_actor: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
209 ) -> None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
210 if node is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
211 node = self.apg._m.namespace
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
212 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
213 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
214 subscription = await self.apg._p.subscribe(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
215 client,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
216 account_jid,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
217 node,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
218 # subscriptions from AP are always public
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
219 options=self.apg._pps.set_public_opt(),
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
220 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
221 except pubsub.SubscriptionPending:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
222 log.info(f"subscription to node {node!r} of {account_jid} is pending")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
223 # TODO: manage SubscriptionUnconfigured
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
224 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
225 if subscription.state != "subscribed":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
226 # other states should raise an Exception
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
227 raise exceptions.InternalError('"subscribed" state was expected')
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
228 inbox = await self.apg.get_ap_inbox_from_id(signing_actor, use_shared=False)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
229 actor_id = self.apg.build_apurl(TYPE_ACTOR, ap_account)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
230 accept_data = self.apg.create_activity("Accept", actor_id, object_=data)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
231 await self.apg.sign_and_post(inbox, actor_id, accept_data)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
232 await self.apg._c.synchronise(client, account_jid, node, resync=False)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
233
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
234 async def handle_accept_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
235 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
236 requestor_actor_id: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
237 request: "HTTPRequest",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
238 data: dict,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
239 account_jid: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
240 node: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
241 ap_account: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
242 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
243 signing_actor: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
244 ) -> None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
245 if node is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
246 node = self.apg._m.namespace
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
247 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
248 objects = await self.apg.ap_get_list(requestor_actor_id, data, "object")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
249 for obj in objects:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
250 type_ = obj.get("type")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
251 if type_ == "Follow":
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
252 follow_node = await self.apg.host.memory.storage.get_pubsub_node(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
253 client, client.jid, node, with_subscriptions=True
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
254 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
255 if follow_node is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
256 log.warning(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
257 f"Received a follow accept on an unknown node: {node!r} at "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
258 f"{client.jid}. Ignoring it"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
259 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
260 continue
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
261 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
262 sub = next(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
263 s
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
264 for s in follow_node.subscriptions
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
265 if s.subscriber == account_jid
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
266 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
267 except StopIteration:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
268 log.warning(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
269 "Received a follow accept on a node without subscription: "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
270 f"{node!r} at {client.jid}. Ignoring it"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
271 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
272 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
273 if sub.state == SubscriptionState.SUBSCRIBED:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
274 log.warning(f"Already subscribed to {node!r} at {client.jid}")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
275 elif sub.state == SubscriptionState.PENDING:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
276 follow_node.subscribed = True
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
277 sub.state = SubscriptionState.SUBSCRIBED
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
278 await self.apg.host.memory.storage.add(follow_node)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
279 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
280 raise exceptions.InternalError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
281 f"Unhandled subscription state {sub.state!r}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
282 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
283 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
284 log.warning(f"Unmanaged accept type: {type_!r}")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
285
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
286 async def handle_delete_activity(
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
287 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
288 requestor_actor_id: str,
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
289 request: "HTTPRequest",
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
290 data: dict,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
291 account_jid: Optional[jid.JID],
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
292 node: Optional[str],
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
293 ap_account: Optional[str],
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
294 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
295 signing_actor: str,
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
296 ):
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
297 if node is None:
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
298 node = self.apg._m.namespace
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
299 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
300 objects = await self.apg.ap_get_list(requestor_actor_id, data, "object")
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
301 for obj in objects:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
302 await self.apg.new_ap_delete_item(client, account_jid, node, obj)
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
303
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
304 async def handle_new_ap_items(
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
305 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
306 requestor_actor_id: str,
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
307 request: "HTTPRequest",
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
308 data: dict,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
309 account_jid: Optional[jid.JID],
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
310 node: Optional[str],
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
311 signing_actor: str,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
312 repeated: bool = False,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
313 ):
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
314 """Helper method to handle workflow for new AP items
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
315
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
316 accept globally the same parameter as for handle_create_activity
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
317 @param repeated: if True, the item is an item republished from somewhere else
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
318 """
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
319 if "_repeated" in data:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
320 log.error(
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
321 '"_repeated" field already present in given AP item, this should not '
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
322 f"happen. Ignoring object from {signing_actor}\n{data}"
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
323 )
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
324 raise exceptions.DataError("unexpected field in item")
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
325 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
326 objects = await self.apg.ap_get_list(requestor_actor_id, data, "object")
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
327 for obj in objects:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
328 if node is None:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
329 if obj.get("type") == TYPE_EVENT:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
330 node = self.apg._events.namespace
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
331 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
332 node = self.apg._m.namespace
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
333 sender = await self.apg.ap_get_sender_actor(requestor_actor_id, obj)
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
334 if repeated:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
335 # we don't check sender when item is repeated, as it should be different
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
336 # from post author in this case
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
337 sender_jid = await self.apg.get_jid_from_id(requestor_actor_id, sender)
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
338 repeater_jid = await self.apg.get_jid_from_id(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
339 requestor_actor_id, signing_actor
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
340 )
3870
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
341 repeated_item_id = obj["id"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
342 if self.apg.is_local_url(repeated_item_id):
3870
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
343 # the repeated object is from XMPP, we need to parse the URL to find
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
344 # the right ID
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
345 url_type, url_args = self.apg.parse_apurl(repeated_item_id)
3870
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
346 if url_type != "item":
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
347 raise exceptions.DataError(
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
348 "local URI is not an item: {repeated_id}"
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
349 )
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
350 try:
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
351 url_account, url_item_id = url_args
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
352 if not url_account or not url_item_id:
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
353 raise ValueError
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
354 except (RuntimeError, ValueError):
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
355 raise exceptions.DataError("local URI is invalid: {repeated_id}")
3870
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
356 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
357 url_jid, url_node = await self.apg.get_jid_and_node(url_account)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
358 if (
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
359 url_jid != sender_jid
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
360 or url_node
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
361 and url_node != self.apg._m.namespace
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
362 ):
3870
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
363 raise exceptions.DataError(
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
364 "announced ID doesn't match sender ({sender}): "
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
365 f"[repeated_item_id]"
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
366 )
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
367
bd84d289fc94 component AP gateway: fix item ID for XMPP items on Announce:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
368 repeated_item_id = url_item_id
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
369
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
370 obj["_repeated"] = {
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
371 "by": repeater_jid.full(),
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
372 "at": data.get("published"),
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
373 "uri": uri.build_xmpp_uri(
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
374 "pubsub",
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
375 path=sender_jid.full(),
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
376 node=self.apg._m.namespace,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
377 item=repeated_item_id,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
378 ),
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
379 }
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
380 # we must use activity's id and targets, not the original item ones
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
381 for field in ("id", "to", "bto", "cc", "bcc"):
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
382 obj[field] = data.get(field)
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
383 else:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
384 if sender != signing_actor:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
385 log.warning("Ignoring object not attributed to signing actor: {obj}")
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
386 continue
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
387
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
388 await self.apg.new_ap_item(client, account_jid, node, obj)
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
389
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
390 async def handle_create_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
391 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
392 requestor_actor_id: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
393 request: "HTTPRequest",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
394 data: dict,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
395 account_jid: Optional[jid.JID],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
396 node: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
397 ap_account: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
398 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
399 signing_actor: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
400 ):
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
401 await self.handle_new_ap_items(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
402 requestor_actor_id, request, data, account_jid, node, signing_actor
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
403 )
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
404
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
405 async def handle_update_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
406 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
407 requestor_actor_id: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
408 request: "HTTPRequest",
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
409 data: dict,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
410 account_jid: Optional[jid.JID],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
411 node: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
412 ap_account: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
413 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
414 signing_actor: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
415 ):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
416 # Update is the same as create: the item ID stays the same, thus the item will be
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
417 # overwritten
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
418 await self.handle_new_ap_items(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
419 requestor_actor_id, request, data, account_jid, node, signing_actor
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
420 )
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
421
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
422 async def handle_announce_activity(
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
423 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
424 requestor_actor_id: str,
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
425 request: "HTTPRequest",
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
426 data: dict,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
427 account_jid: Optional[jid.JID],
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
428 node: Optional[str],
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
429 ap_account: Optional[str],
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
430 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
431 signing_actor: str,
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
432 ):
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
433 # we create a new item
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
434 await self.handle_new_ap_items(
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
435 requestor_actor_id,
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
436 request,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
437 data,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
438 account_jid,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
439 node,
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
440 signing_actor,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
441 repeated=True,
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
442 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
443
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
444 async def handle_attachment_item(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
445 self, client: SatXMPPEntity, data: dict, attachment_data: dict
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
446 ) -> None:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
447 target_ids = data.get("object")
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
448 if not target_ids:
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
449 raise exceptions.DataError("object should be set")
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
450 elif isinstance(target_ids, list):
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
451 try:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
452 target_ids = [o["id"] for o in target_ids]
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
453 except (KeyError, TypeError):
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
454 raise exceptions.DataError(f"invalid object: {target_ids!r}")
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
455 elif isinstance(target_ids, dict):
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
456 obj_id = target_ids.get("id")
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
457 if not obj_id or not isinstance(obj_id, str):
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
458 raise exceptions.DataError(f"invalid object: {target_ids!r}")
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
459 target_ids = [obj_id]
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
460 elif isinstance(target_ids, str):
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
461 target_ids = [target_ids]
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
462
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
463 # XXX: we have to cache AP items because some implementation (Pleroma notably)
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
464 # don't keep object accessible, and we need to be able to retrieve them for
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
465 # UNDO. Current implementation will grow, we need to add a way to flush it after
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
466 # a while.
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
467 # TODO: add a way to flush old cached AP items.
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
468 await client._ap_storage.aset(f"{ST_AP_CACHE}{data['id']}", data)
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
469
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
470 for target_id in target_ids:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
471 if not self.apg.is_local_url(target_id):
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
472 log.debug(f"ignoring non local target ID: {target_id}")
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
473 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
474 url_type, url_args = self.apg.parse_apurl(target_id)
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
475 if url_type != TYPE_ITEM:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
476 log.warning(f"unexpected local URL for attachment on item {target_id}")
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
477 continue
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
478 try:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
479 account, item_id = url_args
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
480 except ValueError:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
481 raise ValueError(f"invalid URL: {target_id}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
482 author_jid, item_node = await self.apg.get_jid_and_node(account)
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
483 if item_node is None:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
484 item_node = self.apg._m.namespace
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
485 attachment_node = self.apg._pa.get_attachment_node_name(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
486 author_jid, item_node, item_id
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
487 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
488 cached_node = await self.apg.host.memory.storage.get_pubsub_node(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
489 client, author_jid, attachment_node, with_subscriptions=True, create=True
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
490 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
491 found_items, __ = await self.apg.host.memory.storage.get_items(
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
492 cached_node, item_ids=[client.jid.userhost()]
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
493 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
494 if not found_items:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
495 old_item_elt = None
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
496 else:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
497 found_item = found_items[0]
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
498 old_item_elt = found_item.data
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
499
3980
9b5092225e46 component AP gateway: fix pubsub attachment plugin call following renaming.
Goffi <goffi@goffi.org>
parents: 3977
diff changeset
500 item_elt = await self.apg._pa.apply_set_handler(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
501 client, {"extra": attachment_data}, old_item_elt, None
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
502 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
503 # we reparse the element, as there can be other attachments
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
504 attachments_data = self.apg._pa.items_2_attachment_data(client, [item_elt])
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
505 # and we update the cache
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
506 await self.apg.host.memory.storage.cache_pubsub_items(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
507 client, cached_node, [item_elt], attachments_data or [{}]
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
508 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
509
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
510 if self.apg.is_virtual_jid(author_jid):
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
511 # the attachment is on t a virtual pubsub service (linking to an AP item),
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
512 # we notify all subscribers
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
513 for subscription in cached_node.subscriptions:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
514 if subscription.state != SubscriptionState.SUBSCRIBED:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
515 continue
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
516 self.apg.pubsub_service.notifyPublish(
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
517 author_jid,
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
518 attachment_node,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
519 [(subscription.subscriber, None, [item_elt])],
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
520 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
521 else:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
522 # the attachment is on an XMPP item, we publish it to the attachment node
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
523 await self.apg._p.send_items(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
524 client, author_jid, attachment_node, [item_elt]
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
525 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
526
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
527 async def handle_like_activity(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
528 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
529 requestor_actor_id: str,
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
530 request: "HTTPRequest",
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
531 data: dict,
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
532 account_jid: Optional[jid.JID],
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
533 node: Optional[str],
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
534 ap_account: Optional[str],
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
535 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
536 signing_actor: str,
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
537 ) -> None:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
538 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
539 await self.handle_attachment_item(client, data, {"noticed": True})
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
540
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
541 async def handle_emojireact_activity(
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
542 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
543 requestor_actor_id: str,
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
544 request: "HTTPRequest",
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
545 data: dict,
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
546 account_jid: Optional[jid.JID],
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
547 node: Optional[str],
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
548 ap_account: Optional[str],
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
549 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
550 signing_actor: str,
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3884
diff changeset
551 ) -> None:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
552 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
553 await self.handle_attachment_item(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
554 client, data, {"reactions": {"operation": "update", "add": [data["content"]]}}
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
555 )
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
556
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
557 async def handle_join_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
558 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
559 requestor_actor_id: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
560 request: "HTTPRequest",
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
561 data: dict,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
562 account_jid: Optional[jid.JID],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
563 node: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
564 ap_account: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
565 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
566 signing_actor: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
567 ) -> None:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
568 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
569 await self.handle_attachment_item(client, data, {"rsvp": {"attending": "yes"}})
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
570
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
571 async def handle_leave_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
572 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
573 requestor_actor_id: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
574 request: "HTTPRequest",
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
575 data: dict,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
576 account_jid: Optional[jid.JID],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
577 node: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
578 ap_account: Optional[str],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
579 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
580 signing_actor: str,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
581 ) -> None:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
582 client = await self.apg.get_virtual_client(requestor_actor_id, signing_actor)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
583 await self.handle_attachment_item(client, data, {"rsvp": {"attending": "no"}})
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
584
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
585 async def ap_actor_request(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
586 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
587 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
588 data: Optional[dict],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
589 account_jid: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
590 node: Optional[str],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
591 ap_account: str,
3826
81c79b7cafa7 tests (unit/ap-gateway): tests for XMPP identity/vCard4 <=> AP actor data conversion:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
592 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
593 signing_actor: Optional[str],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
594 ) -> dict:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
595 inbox = self.apg.build_apurl(TYPE_INBOX, ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
596 shared_inbox = self.apg.build_apurl(TYPE_SHARED_INBOX)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
597 outbox = self.apg.build_apurl(TYPE_OUTBOX, ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
598 followers = self.apg.build_apurl(TYPE_FOLLOWERS, ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
599 following = self.apg.build_apurl(TYPE_FOLLOWING, ap_account)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
600
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
601 # we have to use AP account as preferredUsername because it is used to retrieve
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
602 # actor handle (see https://socialhub.activitypub.rocks/t/how-to-retrieve-user-server-tld-handle-from-actors-url/2196)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
603 preferred_username = ap_account.split("@", 1)[0]
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
604
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
605 identity_data = await self.apg._i.get_identity(self.apg.client, account_jid)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
606 if node and node.startswith(self.apg._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
607 events = outbox
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
608 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
609 events_account = await self.apg.get_ap_account_from_jid_and_node(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
610 account_jid, self.apg._events.namespace
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
611 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
612 events = self.apg.build_apurl(TYPE_OUTBOX, events_account)
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
613
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
614 actor_data = {
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
615 "@context": [
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
616 "https://www.w3.org/ns/activitystreams",
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
617 "https://w3id.org/security/v1",
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
618 ],
3994
69d970f974ff component AP gateway: don't percent-encode `@`:
Goffi <goffi@goffi.org>
parents: 3992
diff changeset
619 # XXX: Mastodon doesn't like percent-encode arobas, so we have to unescape it
69d970f974ff component AP gateway: don't percent-encode `@`:
Goffi <goffi@goffi.org>
parents: 3992
diff changeset
620 # if it is escaped
69d970f974ff component AP gateway: don't percent-encode `@`:
Goffi <goffi@goffi.org>
parents: 3992
diff changeset
621 "id": ap_url.replace("%40", "@"),
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
622 "type": "Person",
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
623 "preferredUsername": preferred_username,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
624 "inbox": inbox,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
625 "outbox": outbox,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
626 "events": events,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
627 "followers": followers,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
628 "following": following,
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
629 "publicKey": {
3826
81c79b7cafa7 tests (unit/ap-gateway): tests for XMPP identity/vCard4 <=> AP actor data conversion:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
630 "id": f"{ap_url}#main-key",
81c79b7cafa7 tests (unit/ap-gateway): tests for XMPP identity/vCard4 <=> AP actor data conversion:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
631 "owner": ap_url,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
632 "publicKeyPem": self.apg.public_key_pem,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
633 },
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
634 "endpoints": {
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
635 "sharedInbox": shared_inbox,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
636 "events": events,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
637 },
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
638 }
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
639
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
640 if identity_data.get("nicknames"):
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
641 actor_data["name"] = identity_data["nicknames"][0]
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
642 if identity_data.get("description"):
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
643 # description is plain text while summary expects HTML
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
644 actor_data["summary"] = html.escape(identity_data["description"])
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
645 if identity_data.get("avatar"):
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
646 avatar_data = identity_data["avatar"]
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
647 try:
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
648 filename = avatar_data["filename"]
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
649 media_type = avatar_data["media_type"]
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
650 except KeyError:
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
651 log.error(f"incomplete avatar data: {identity_data!r}")
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
652 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
653 avatar_url = self.apg.build_apurl("avatar", filename)
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
654 actor_data["icon"] = {
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
655 "type": "Image",
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
656 "url": avatar_url,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
657 "mediaType": media_type,
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
658 }
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
659
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
660 return actor_data
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
661
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
662 def get_canonical_url(self, request: "HTTPRequest") -> str:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
663 return parse.urljoin(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
664 f"https://{self.apg.public_url}",
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
665 request.path.decode().rstrip("/"),
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
666 # we unescape "@" for the same reason as in [ap_actor_request]
3994
69d970f974ff component AP gateway: don't percent-encode `@`:
Goffi <goffi@goffi.org>
parents: 3992
diff changeset
667 ).replace("%40", "@")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
668
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
669 def query_data_2_rsm_request(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
670 self, query_data: Dict[str, List[str]]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
671 ) -> rsm.RSMRequest:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
672 """Get RSM kwargs to use with RSMRequest from query data"""
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
673 page = query_data.get("page")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
674
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
675 if page == ["first"]:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
676 return rsm.RSMRequest(max_=PAGE_SIZE, before="")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
677 elif page == ["last"]:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
678 return rsm.RSMRequest(max_=PAGE_SIZE)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
679 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
680 for query_key in ("index", "before", "after"):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
681 try:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
682 kwargs = {query_key: query_data[query_key][0], "max_": PAGE_SIZE}
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
683 except (KeyError, IndexError, ValueError):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
684 pass
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
685 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
686 return rsm.RSMRequest(**kwargs)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
687 raise ValueError(f"Invalid query data: {query_data!r}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
688
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
689 async def ap_outbox_page_request(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
690 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
691 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
692 data: Optional[dict],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
693 account_jid: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
694 node: Optional[str],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
695 ap_account: str,
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
696 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
697 query_data: Dict[str, List[str]],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
698 ) -> dict:
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
699 if node is None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
700 node = self.apg._m.namespace
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
701 # we only keep useful keys, and sort to have consistent URL which can
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
702 # be used as ID
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
703 url_keys = sorted(set(query_data) & {"page", "index", "before", "after"})
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
704 query_data = {k: query_data[k] for k in url_keys}
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
705 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
706 items, metadata = await self.apg._p.get_items(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
707 client=self.apg.client,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
708 service=account_jid,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
709 node=node,
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
710 rsm_request=self.query_data_2_rsm_request(query_data),
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
711 extra={C.KEY_USE_CACHE: False},
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
712 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
713 except error.StanzaError as e:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
714 log.warning(f"Can't get data from pubsub node {node} at {account_jid}: {e}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
715 return {}
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
716
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
717 base_url = self.get_canonical_url(request)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
718 url = f"{base_url}?{parse.urlencode(query_data, True)}"
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
719 if node and node.startswith(self.apg._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
720 ordered_items = [
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
721 await self.apg.ap_events.event_data_2_ap_item(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
722 self.apg._events.event_elt_2_event_data(item), account_jid
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
723 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
724 for item in reversed(items)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
725 ]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
726 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
727 ordered_items = [
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
728 await self.apg.mb_data_2_ap_item(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
729 self.apg.client,
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4016
diff changeset
730 await self.apg._m.item_2_mb_data(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
731 self.apg.client, item, account_jid, node
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
732 ),
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
733 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
734 for item in reversed(items)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
735 ]
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
736 ret_data = {
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
737 "@context": ["https://www.w3.org/ns/activitystreams"],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
738 "id": url,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
739 "type": "OrderedCollectionPage",
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
740 "partOf": base_url,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
741 "orderedItems": ordered_items,
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
742 }
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
743
4009
48e8b3dba793 component AP gateway (http/outbox): return data when no RSM is available
Goffi <goffi@goffi.org>
parents: 4005
diff changeset
744 if "rsm" not in metadata:
48e8b3dba793 component AP gateway (http/outbox): return data when no RSM is available
Goffi <goffi@goffi.org>
parents: 4005
diff changeset
745 # no RSM available, we return what we have
48e8b3dba793 component AP gateway (http/outbox): return data when no RSM is available
Goffi <goffi@goffi.org>
parents: 4005
diff changeset
746 return ret_data
48e8b3dba793 component AP gateway (http/outbox): return data when no RSM is available
Goffi <goffi@goffi.org>
parents: 4005
diff changeset
747
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
748 # AP OrderedCollection must be in reversed chronological order, thus the opposite
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
749 # of what we get with RSM (at least with Libervia Pubsub)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
750 if not metadata["complete"]:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
751 try:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
752 last = metadata["rsm"]["last"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
753 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
754 last = None
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
755 ret_data["prev"] = f"{base_url}?{parse.urlencode({'after': last})}"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
756 if metadata["rsm"]["index"] != 0:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
757 try:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
758 first = metadata["rsm"]["first"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
759 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
760 first = None
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
761 ret_data["next"] = f"{base_url}?{parse.urlencode({'before': first})}"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
762
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
763 return ret_data
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
764
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
765 async def ap_outbox_request(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
766 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
767 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
768 data: Optional[dict],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
769 account_jid: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
770 node: Optional[str],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
771 ap_account: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
772 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
773 signing_actor: Optional[str],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
774 ) -> dict:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
775 if node is None:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
776 node = self.apg._m.namespace
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
777
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
778 parsed_url = parse.urlparse(request.uri.decode())
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
779 query_data = parse.parse_qs(parsed_url.query)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
780 if query_data:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
781 return await self.ap_outbox_page_request(
3995
27e5294649c2 component AP gateway: fix missing argument when calling APOutboxPageRequest
Goffi <goffi@goffi.org>
parents: 3994
diff changeset
782 request, data, account_jid, node, ap_account, ap_url, query_data
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
783 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
784
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
785 # XXX: we can't use disco#info here because this request won't work on a bare jid
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
786 # due to security considerations of XEP-0030 (we don't have presence
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
787 # subscription).
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
788 # The current workaround is to do a request as if RSM was available, and actually
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
789 # check its availability according to result.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
790 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
791 __, metadata = await self.apg._p.get_items(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
792 client=self.apg.client,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
793 service=account_jid,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
794 node=node,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
795 max_items=0,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
796 rsm_request=rsm.RSMRequest(max_=0),
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
797 extra={C.KEY_USE_CACHE: False},
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
798 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
799 except error.StanzaError as e:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
800 log.warning(f"Can't get data from pubsub node {node} at {account_jid}: {e}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
801 return {}
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
802 try:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
803 items_count = metadata["rsm"]["count"]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
804 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
805 log.warning(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
806 f"No RSM metadata found when requesting pubsub node {node} at "
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
807 f"{account_jid}, defaulting to items_count=20"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
808 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
809 items_count = 20
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
810
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
811 url = self.get_canonical_url(request)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
812 url_first_page = f"{url}?{parse.urlencode({'page': 'first'})}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
813 url_last_page = f"{url}?{parse.urlencode({'page': 'last'})}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
814 return {
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
815 "@context": ["https://www.w3.org/ns/activitystreams"],
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
816 "id": url,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
817 "totalItems": items_count,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
818 "type": "OrderedCollection",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
819 "first": url_first_page,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
820 "last": url_last_page,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
821 }
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
822
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
823 async def ap_inbox_request(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
824 self,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
825 requestor_actor_id: str,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
826 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
827 data: Optional[dict],
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
828 account_jid: Optional[jid.JID],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
829 node: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
830 ap_account: Optional[str],
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
831 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
832 signing_actor: Optional[str],
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
833 ) -> None:
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
834 assert data is not None
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
835 if signing_actor is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
836 raise exceptions.InternalError("signing_actor must be set for inbox requests")
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
837 await self.check_signing_actor(requestor_actor_id, data, signing_actor)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
838 activity_type = (data.get("type") or "").lower()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
839 if not activity_type in ACTIVITY_TYPES_LOWER:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
840 return self.response_code(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
841 request,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
842 http.UNSUPPORTED_MEDIA_TYPE,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
843 f"request is not an activity, ignoring",
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
844 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
845
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
846 if account_jid is None and activity_type not in ACTIVIY_NO_ACCOUNT_ALLOWED:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
847 return self.response_code(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
848 request,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
849 http.UNSUPPORTED_MEDIA_TYPE,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
850 f"{activity_type.title()!r} activity must target an account",
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
851 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
852
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
853 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
854 method = getattr(self, f"handle_{activity_type}_activity")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
855 except AttributeError:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
856 return self.response_code(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
857 request,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
858 http.UNSUPPORTED_MEDIA_TYPE,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
859 f"{activity_type.title()} activity is not yet supported",
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
860 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
861 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
862 await method(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
863 requestor_actor_id,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
864 request,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
865 data,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
866 account_jid,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
867 node,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
868 ap_account,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
869 ap_url,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
870 signing_actor,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
871 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
872
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
873 async def ap_followers_request(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
874 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
875 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
876 data: Optional[dict],
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
877 account_jid: jid.JID,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
878 node: Optional[str],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
879 ap_account: Optional[str],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
880 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
881 signing_actor: Optional[str],
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
882 ) -> dict:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
883 if node is None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
884 node = self.apg._m.namespace
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
885 client = self.apg.client
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
886 subscribers = await self.apg._pps.get_public_node_subscriptions(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
887 client, account_jid, node
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
888 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
889 followers = []
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
890 for subscriber in subscribers.keys():
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
891 if self.apg.is_virtual_jid(subscriber):
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
892 # the subscriber is an AP user subscribed with this gateway
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
893 ap_account = self.apg._e.unescape(subscriber.user)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
894 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
895 # regular XMPP user
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
896 ap_account = await self.apg.get_ap_account_from_jid_and_node(
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
897 subscriber, node
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
898 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
899 followers.append(ap_account)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
900
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
901 url = self.get_canonical_url(request)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
902 return {
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
903 "@context": ["https://www.w3.org/ns/activitystreams"],
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
904 "type": "OrderedCollection",
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
905 "id": url,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
906 "totalItems": len(subscribers),
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
907 "first": {
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
908 "type": "OrderedCollectionPage",
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
909 "id": url,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
910 "orderedItems": followers,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
911 },
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
912 }
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
913
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
914 async def ap_following_request(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
915 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
916 request: "HTTPRequest",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
917 data: Optional[dict],
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
918 account_jid: jid.JID,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
919 node: Optional[str],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
920 ap_account: Optional[str],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
921 ap_url: str,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
922 signing_actor: Optional[str],
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
923 ) -> dict[str, Any]:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
924 client = self.apg.client
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
925 subscriptions = await self.apg._pps.subscriptions(client, account_jid, node)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
926 following = []
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
927 for sub_dict in subscriptions:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
928 service = jid.JID(sub_dict["service"])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
929 if self.apg.is_virtual_jid(service):
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
930 # the subscription is to an AP actor with this gateway
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
931 ap_account = self.apg._e.unescape(service.user)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
932 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
933 # regular XMPP user
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
934 ap_account = await self.apg.get_ap_account_from_jid_and_node(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
935 service, sub_dict["node"]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
936 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
937 following.append(ap_account)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
938
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
939 url = self.get_canonical_url(request)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
940 return {
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
941 "@context": ["https://www.w3.org/ns/activitystreams"],
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
942 "type": "OrderedCollection",
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
943 "id": url,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
944 "totalItems": len(subscriptions),
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
945 "first": {
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
946 "type": "OrderedCollectionPage",
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
947 "id": url,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
948 "orderedItems": following,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
949 },
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
950 }
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
951
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
952 def _get_to_log(
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
953 self,
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
954 request: "HTTPRequest",
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
955 data: Optional[dict] = None,
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
956 ) -> List[str]:
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
957 """Get base data to logs in verbose mode"""
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
958 from pprint import pformat
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
959
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
960 to_log = [
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
961 "",
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
962 f"<<< got {request.method.decode()} request - {request.uri.decode()}",
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
963 ]
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
964 if data is not None:
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
965 to_log.append(pformat(data))
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
966 if self.apg.verbose >= 3:
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
967 headers = "\n".join(
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
968 f" {k.decode()}: {v.decode()}"
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
969 for k, v in request.getAllHeaders().items()
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
970 )
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
971 to_log.append(f" headers:\n{headers}")
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
972 return to_log
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
973
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
974 def get_requestor_actor_id(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
975 self, data: dict | None = None, uri_extra_args: list[str] | None = None
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
976 ) -> str:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
977 """Find the actor ID of the requestor.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
978
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
979 The requestor here is actually the local actor which will do the requests to
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
980 achieve the task (e.g. retrieve external actor data), not the requestor of the
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
981 received AP request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
982
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
983 It will notably be used as requestor actor ID to sign HTTP requests. We need to
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
984 sign GET request too to access instance checking HTTP GET signature (e.g. Mastodon
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
985 instances set in "secure mode").
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
986
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
987 We look for the destinee of the request and check if it's a local actor, and
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
988 default to a generic one if we can't find it.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
989
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
990 Destinee is first checked in data if any, otherwise in request URI.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
991
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
992 @param data: parsed JSON data of original AP request, if any.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
993 @param uri_extra_args: arguments of the AP request as returned by
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
994 [self.apg.parse_apurl]. It is most of time the destinee of the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
995 @return: requestor_actor_id to use to sign HTTP request needed to answer the
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
996 original request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
997 """
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
998 # We first check for destinee in data.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
999 if data:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1000 try:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1001 for to_ in data["to"]:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1002 if self.apg.is_local_url(to_):
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1003 url_type, url_args = self.apg.parse_apurl(to_)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1004 if url_type != TYPE_ACTOR or not url_args:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1005 continue
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1006 ap_account = url_args[0]
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1007 if (
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1008 not ap_account.endswith(f"@{self.apg.public_url}")
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1009 or ap_account.count("@") != 1
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1010 ):
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1011 continue
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1012 return to_
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1013 except KeyError:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1014 pass
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1015
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1016 # If nothing relevant, we try URI arguments.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1017 if uri_extra_args:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1018 ap_account = uri_extra_args[0]
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1019 if (
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1020 ap_account.endswith(f"@{self.apg.public_url}")
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1021 and ap_account.count("@") == 1
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1022 ):
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1023 return self.apg.build_apurl(TYPE_ACTOR, ap_account)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1024
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1025 # Still nothing, we'll have to use a generic actor.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1026 log.warning(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1027 'Can\'t find destinee in "to" field, using generic requestor for signature.'
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1028 )
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1029 return self.apg.build_apurl(TYPE_ACTOR, f"libervia@{self.apg.public_url}")
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1030
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1031 async def ap_request(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1032 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1033 request: "HTTPRequest",
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1034 data: dict | None = None,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1035 signing_actor: str | None = None,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1036 requestor_actor_id: str | None = None,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1037 ) -> None:
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1038 if self.apg.verbose:
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1039 to_log = self._get_to_log(request, data)
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1040
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1041 path = request.path.decode()
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1042 ap_url = parse.urljoin(f"https://{self.apg.public_url}", path)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1043 request_type, extra_args = self.apg.parse_apurl(ap_url)
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1044
4109
7067b0d73183 component AP gateway: fix AP media type in GET and POST requests headers
Goffi <goffi@goffi.org>
parents: 4104
diff changeset
1045 header_accept = request.getHeader("accept") or ""
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1046 if (
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1047 MEDIA_TYPE_AP not in header_accept
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1048 and MEDIA_TYPE_AP_ALT not in header_accept
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1049 and request_type in self.apg.html_redirect
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1050 ):
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1051 # this is not a AP request, and we have a redirections for it
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1052 kw = {}
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1053 if extra_args:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1054 kw["jid"], kw["node"] = await self.apg.get_jid_and_node(extra_args[0])
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1055 kw["jid_user"] = kw["jid"].user
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1056 if kw["node"] is None:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1057 kw["node"] = self.apg._m.namespace
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1058 if len(extra_args) > 1:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1059 kw["item"] = extra_args[1]
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1060 else:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1061 kw["item"] = ""
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1062 else:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1063 kw["jid"], kw["jid_user"], kw["node"], kw["item"] = "", "", "", ""
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1064
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1065 redirections = self.apg.html_redirect[request_type]
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1066 for redirection in redirections:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1067 filters = redirection["filters"]
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1068 if not filters:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1069 break
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1070 # if we have filter, they must all match
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1071 elif all(v in kw[k] for k, v in filters.items()):
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1072 break
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1073 else:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1074 # no redirection is matching
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1075 redirection = None
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1076
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1077 if redirection is not None:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1078 kw = {k: parse.quote(str(v), safe="") for k, v in kw.items()}
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1079 target_url = redirection["url"].format(**kw)
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1080 content = web_util.redirectTo(target_url.encode(), request)
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1081 request.write(content)
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1082 request.finish()
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1083 return
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
1084
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1085 if requestor_actor_id is None:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1086 requestor_actor_id = self.get_requestor_actor_id(data, extra_args)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1087 if len(extra_args) == 0:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1088 if request_type != "shared_inbox":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1089 raise exceptions.DataError(f"Invalid request type: {request_type!r}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1090 ret_data = await self.ap_inbox_request(
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1091 requestor_actor_id, request, data, None, None, None, ap_url, signing_actor
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1092 )
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
1093 elif request_type == "avatar":
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
1094 if len(extra_args) != 1:
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
1095 raise exceptions.DataError("avatar argument expected in URL")
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
1096 avatar_filename = extra_args[0]
4212
5f2d496c633f core: get rid of `pickle`:
Goffi <goffi@goffi.org>
parents: 4109
diff changeset
1097 avatar_path = self.apg.host.common_cache.get_path(avatar_filename)
3821
0b1c30ff2cbb component AP: XMPP identity => AP actor data converstion:
Goffi <goffi@goffi.org>
parents: 3807
diff changeset
1098 return static.File(str(avatar_path)).render(request)
3846
cc13efdd8360 component AP gateway: return item when `item` URL is used:
Goffi <goffi@goffi.org>
parents: 3844
diff changeset
1099 elif request_type == "item":
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1100 ret_data = await self.apg.ap_get_local_object(ap_url)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1101 if "@context" not in ret_data:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1102 ret_data["@context"] = [NS_AP]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1103 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1104 if len(extra_args) > 1:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1105 log.warning(f"unexpected extra arguments: {extra_args!r}")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1106 ap_account = extra_args[0]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1107 account_jid, node = await self.apg.get_jid_and_node(ap_account)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1108 if request_type not in AP_REQUEST_TYPES.get(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1109 request.method.decode().upper(), []
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1110 ):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1111 raise exceptions.DataError(f"Invalid request type: {request_type!r}")
4093
13b1079c27ec component AP gateway: fix method retrieval in `ap_request`:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
1112 method = getattr(self, f"ap_{request_type}_request")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1113 ret_data = await method(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1114 requestor_actor_id,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1115 request,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1116 data,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1117 account_jid,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1118 node,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1119 ap_account,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1120 ap_url,
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1121 signing_actor,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1122 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1123 if ret_data is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1124 request.setHeader("content-type", CONTENT_TYPE_AP)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1125 request.write(json.dumps(ret_data).encode())
3881
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1126 if self.apg.verbose:
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1127 to_log.append(f"--- RET (code: {request.code})---")
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1128 if self.apg.verbose >= 2:
3881
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1129 if ret_data is not None:
4016
97df34151c6d component AP gateway (http): fix missing `pformat` module in verbose mode
Goffi <goffi@goffi.org>
parents: 4015
diff changeset
1130 from pprint import pformat
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1131
3881
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1132 to_log.append(f"{pformat(ret_data)}")
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1133 to_log.append("---")
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3870
diff changeset
1134 log.info("\n".join(to_log))
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1135 request.finish()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1136
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1137 async def ap_post_request(self, request: "HTTPRequest") -> None:
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1138 try:
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1139 data = json.load(request.content)
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1140 if not isinstance(data, dict):
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1141 log.warning(f"JSON data should be an object (uri={request.uri.decode()})")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1142 self.response_code(
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1143 request,
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1144 http.BAD_REQUEST,
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1145 f"invalid body, was expecting a JSON object",
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1146 )
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1147 request.finish()
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1148 return
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1149 except (json.JSONDecodeError, ValueError) as e:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1150 self.response_code(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1151 request, http.BAD_REQUEST, f"invalid json in inbox request: {e}"
3981
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1152 )
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1153 request.finish()
acc9dfc8ba8d component AP gateway: parse body immediately on `POST` request:
Goffi <goffi@goffi.org>
parents: 3980
diff changeset
1154 return
4005
54a6b44f173b component AP gateway: reset stream position after getting payload:
Goffi <goffi@goffi.org>
parents: 3996
diff changeset
1155 else:
54a6b44f173b component AP gateway: reset stream position after getting payload:
Goffi <goffi@goffi.org>
parents: 3996
diff changeset
1156 request.content.seek(0)
54a6b44f173b component AP gateway: reset stream position after getting payload:
Goffi <goffi@goffi.org>
parents: 3996
diff changeset
1157
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1158 requestor_actor_id = self.get_requestor_actor_id(data)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1159
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1160 try:
3983
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1161 if data["type"] == "Delete" and data["actor"] == data["object"]:
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1162 # we don't handle actor deletion
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1163 request.setResponseCode(http.ACCEPTED)
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1164 log.debug(f"ignoring actor deletion ({data['actor']})")
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1165 # TODO: clean data in cache coming from this actor, maybe with a tombstone
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1166 request.finish()
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1167 return
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1168 except KeyError:
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1169 pass
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1170
31c3d6652115 component AP gateway: ignore actor delection notifications:
Goffi <goffi@goffi.org>
parents: 3982
diff changeset
1171 try:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1172 signing_actor = await self.check_signature(requestor_actor_id, request)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1173 except exceptions.EncryptionError as e:
4015
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1174 if self.apg.verbose:
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1175 to_log = self._get_to_log(request)
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1176 to_log.append(f" body: {request.content.read()!r}")
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1177 request.content.seek(0)
2913313ca58f component AP gateway (http): add verbose log when signature verification fails on POST request
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
1178 log.info("\n".join(to_log))
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1179 self.response_code(request, http.FORBIDDEN, f"invalid signature: {e}")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1180 request.finish()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1181 return
3982
74f7c10a48bc component AP gateway: properly close the HTTP connection on `checkSignature` exception:
Goffi <goffi@goffi.org>
parents: 3981
diff changeset
1182 except Exception as e:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1183 self.response_code(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1184 request, http.INTERNAL_SERVER_ERROR, f"Can't check signature: {e}"
3982
74f7c10a48bc component AP gateway: properly close the HTTP connection on `checkSignature` exception:
Goffi <goffi@goffi.org>
parents: 3981
diff changeset
1185 )
74f7c10a48bc component AP gateway: properly close the HTTP connection on `checkSignature` exception:
Goffi <goffi@goffi.org>
parents: 3981
diff changeset
1186 request.finish()
74f7c10a48bc component AP gateway: properly close the HTTP connection on `checkSignature` exception:
Goffi <goffi@goffi.org>
parents: 3981
diff changeset
1187 return
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1188
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1189 request.setResponseCode(http.ACCEPTED)
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1190
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1191 digest = request.getHeader("digest")
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1192 if digest in self._seen_digest:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1193 log.debug(f"Ignoring duplicated request (digest: {digest!r})")
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1194 request.finish()
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1195 return
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1196 self._seen_digest.append(digest)
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
1197
3802
983df907d456 component AP gateway: set POST default response code to 202 (accepted)
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
1198 # default response code, may be changed, e.g. in case of exception
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1199 try:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1200 return await self.ap_request(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1201 request, data, signing_actor, requestor_actor_id=requestor_actor_id
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1202 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1203 except Exception as e:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1204 self._on_request_error(failure.Failure(e), request)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1205
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1206 async def check_signing_actor(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1207 self, requestor_actor_id: str, data: dict, signing_actor: str
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1208 ) -> None:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1209 """That that signing actor correspond to actor declared in data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1210
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1211 @param requestor_actor_id: ID of the actor doing the request.
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1212 @param data: request payload
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1213 @param signing_actor: actor ID of the signing entity, as returned by
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1214 check_signature
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1215 @raise exceptions.NotFound: no actor found in data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1216 @raise exceptions.EncryptionError: signing actor doesn't match actor in data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1217 """
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1218 actor = await self.apg.ap_get_sender_actor(requestor_actor_id, data)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1219
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1220 if signing_actor != actor:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1221 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1222 f"signing actor ({signing_actor}) doesn't match actor in data ({actor})"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1223 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1224
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1225 async def check_signature(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1226 self, requestor_actor_id: str, request: "HTTPRequest"
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1227 ) -> str:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1228 """Check and validate HTTP signature
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1229
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4212
diff changeset
1230 @param requestor_actor_id: ID of the actor doing the request.
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1231 @return: id of the signing actor
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1232
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1233 @raise exceptions.EncryptionError: signature is not present or doesn't match
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1234 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1235 signature = request.getHeader("Signature")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1236 if signature is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1237 raise exceptions.EncryptionError("No signature found")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1238 sign_data = {
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1239 m["key"]: m["uq_value"] or m["quoted_value"][1:-1]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1240 for m in RE_SIG_PARAM.finditer(signature)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1241 }
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1242 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1243 key_id = sign_data["keyId"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1244 except KeyError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1245 raise exceptions.EncryptionError('"keyId" is missing from signature')
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1246 algorithm = sign_data.get("algorithm", HS2019)
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1247 signed_headers = (
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1248 sign_data.get("headers", "(created)" if algorithm == HS2019 else "date")
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1249 .lower()
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1250 .split()
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1251 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1252 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1253 headers_to_check = SIGN_HEADERS[None] + SIGN_HEADERS[request.method]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1254 except KeyError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1255 raise exceptions.InternalError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1256 f"there should be a list of headers for {request.method} method"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1257 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1258 if not headers_to_check:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1259 raise exceptions.InternalError("headers_to_check must not be empty")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1260
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1261 for header in headers_to_check:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1262 if isinstance(header, tuple):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1263 if len(set(header).intersection(signed_headers)) == 0:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1264 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1265 f"at least one of following header must be signed: {header}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1266 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1267 elif header not in signed_headers:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1268 raise exceptions.EncryptionError(f"the {header!r} header must be signed")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1269
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1270 body = request.content.read()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1271 request.content.seek(0)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1272 headers = {}
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1273 for to_sign in signed_headers:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1274 if to_sign == "(request-target)":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1275 method = request.method.decode().lower()
3884
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1276 uri = request.uri.decode()
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1277 headers[to_sign] = f"{method} /{uri.lstrip('/')}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1278 elif to_sign in ("(created)", "(expires)"):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1279 if algorithm != HS2019:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1280 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1281 f"{to_sign!r} pseudo-header can only be used with {HS2019} "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1282 "algorithm"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1283 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1284 key = to_sign[1:-1]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1285 value = sign_data.get(key)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1286 if not value:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1287 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1288 "{key!r} parameter is missing from signature"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1289 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1290 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1291 if float(value) < 0:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1292 raise ValueError
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1293 except ValueError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1294 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1295 f"{to_sign} must be a Unix timestamp"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1296 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1297 headers[to_sign] = value
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1298 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1299 value = request.getHeader(to_sign)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1300 if not value:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1301 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1302 f"value of header {to_sign!r} is missing!"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1303 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1304 elif to_sign == "host":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1305 # we check Forwarded/X-Forwarded-Host headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1306 # as we need original host if a proxy has modified the header
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1307 forwarded = request.getHeader("forwarded")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1308 if forwarded is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1309 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1310 host = [
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1311 f[5:]
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1312 for f in forwarded.split(";")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1313 if f.startswith("host=")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1314 ][0] or None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1315 except IndexError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1316 host = None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1317 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1318 host = None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1319 if host is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1320 host = request.getHeader("x-forwarded-host")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1321 if host:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1322 value = host
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1323 elif to_sign == "digest":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1324 hashes = {
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1325 algo.lower(): hash_
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1326 for algo, hash_ in (
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1327 digest.split("=", 1) for digest in value.split(",")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1328 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1329 }
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1330 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1331 given_digest = hashes["sha-256"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1332 except KeyError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1333 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1334 "Only SHA-256 algorithm is currently supported for digest"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1335 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1336 __, computed_digest = self.apg.get_digest(body)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1337 if given_digest != computed_digest:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1338 raise exceptions.EncryptionError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1339 f"SHA-256 given and computed digest differ:\n"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1340 f"given: {given_digest!r}\ncomputed: {computed_digest!r}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1341 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1342 headers[to_sign] = value
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1343
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1344 # date check
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1345 limit_ts = time.time() + SIGN_EXP
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1346 if "(created)" in headers:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1347 created = float(headers["created"])
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1348 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1349 created = date_utils.date_parse(headers["date"])
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1350
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1351 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1352 expires = float(headers["expires"])
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1353 except KeyError:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1354 pass
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1355 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1356 if expires < created:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1357 log.warning(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1358 f"(expires) [{expires}] set in the past of (created) [{created}] "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1359 "ignoring it according to specs"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1360 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1361 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1362 limit_ts = min(limit_ts, expires)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1363
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1364 if created > limit_ts:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1365 raise exceptions.EncryptionError("Signature has expired")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1366
3884
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1367 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1368 return await self.apg.check_signature(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1369 requestor_actor_id, sign_data["signature"], key_id, headers
3884
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1370 )
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1371 except exceptions.EncryptionError:
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1372 method, url = headers["(request-target)"].rsplit(" ", 1)
3884
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1373 headers["(request-target)"] = f"{method} {parse.unquote(url)}"
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1374 log.debug(
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1375 "Using workaround for (request-target) encoding bug in signature, "
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1376 "see https://github.com/mastodon/mastodon/issues/18871"
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1377 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1378 return await self.apg.check_signature(
4270
0d7bb4df2343 Reformatted code base using black.
Goffi <goffi@goffi.org>
parents: 4259
diff changeset
1379 requestor_actor_id, sign_data["signature"], key_id, headers
3884
cea52400623d component AP gateway: work around encoding bug in Mastodon:
Goffi <goffi@goffi.org>
parents: 3882
diff changeset
1380 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1381
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1382 def render(self, request):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1383 request.setHeader("server", VERSION)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1384 return super().render(request)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1385
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1386 def render_GET(self, request):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1387 path = request.path.decode().lstrip("/")
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1388 if path.startswith(".well-known/webfinger"):
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1389 defer.ensureDeferred(self.webfinger(request))
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1390 return server.NOT_DONE_YET
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1391 elif path.startswith(self.apg.ap_path):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1392 d = defer.ensureDeferred(self.ap_request(request))
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1393 d.addErrback(self._on_request_error, request)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1394 return server.NOT_DONE_YET
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1395
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1396 return web_resource.NoResource().render(request)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1397
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1398 def render_POST(self, request):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1399 path = request.path.decode().lstrip("/")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1400 if not path.startswith(self.apg.ap_path):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1401 return web_resource.NoResource().render(request)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
1402 defer.ensureDeferred(self.ap_post_request(request))
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1403 return server.NOT_DONE_YET
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
1404
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1405
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1406 class HTTPRequest(server.Request):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1407 pass
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1408
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1409
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1410 class HTTPServer(server.Site):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1411 requestFactory = HTTPRequest
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1412
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1413 def __init__(self, ap_gateway):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1414 super().__init__(HTTPAPGServer(ap_gateway))