annotate libervia/backend/plugins/plugin_comp_ap_gateway/http_server.py @ 4351:6a0a081485b8

plugin autocrypt: Autocrypt protocol implementation: Implementation of autocrypt: `autocrypt` header is checked, and if present and no public key is known for the peer, the key is imported. `autocrypt` header is also added to outgoing message (only if an email gateway is detected). For the moment, the JID is use as identifier, but the real email used by gateway should be used in the future. rel 456
author Goffi <goffi@goffi.org>
date Fri, 28 Feb 2025 09:23:35 +0100
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))