annotate libervia/backend/plugins/plugin_comp_ap_gateway/__init__.py @ 4167:319a0e47dc8b

plugin ad-hoc D-Bus: fix deprecated use of python-dbus: the plugin was using python-dbus which is deprecated in the backend in the favor of TxDBus. Methods calls have been updated, and the plugin works again, but there seems to be still some issues (warnings in the logs). Those will be fixed later.
author Goffi <goffi@goffi.org>
date Fri, 01 Dec 2023 15:22:55 +0100
parents a1f7040b5a15
children e92c32014024
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
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import base64
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
20 import calendar
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import hashlib
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
22 import json
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from pathlib import Path
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
24 from pprint import pformat
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
25 import re
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
26 from typing import (
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
27 Any,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
28 Awaitable,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
29 Callable,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
30 Dict,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
31 List,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
32 Optional,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
33 Set,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
34 Tuple,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
35 Union,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
36 overload,
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
37 )
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
38 from urllib import parse
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
39
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
40 from cryptography.exceptions import InvalidSignature
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 from cryptography.hazmat.primitives import serialization
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 from cryptography.hazmat.primitives import hashes
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
43 from cryptography.hazmat.primitives.asymmetric import rsa
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 from cryptography.hazmat.primitives.asymmetric import padding
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
45 import dateutil
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
46 from dateutil.parser import parserinfo
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
47 import shortuuid
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
48 from sqlalchemy.exc import IntegrityError
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 import treq
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 from treq.response import _Response as TReqResponse
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
51 from twisted.internet import defer, reactor, threads
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
52 from twisted.web import http
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
53 from twisted.words.protocols.jabber import error, jid
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
54 from twisted.words.xish import domish
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
55 from wokkel import pubsub, rsm
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
56
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
57 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
58 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
59 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
60 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
61 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
62 from libervia.backend.memory import persistent
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
63 from libervia.backend.memory.sqla_mapping import History, SubscriptionState
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
64 from libervia.backend.tools import utils
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
65 from libervia.backend.tools.common import data_format, date_utils, tls, uri
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
66 from libervia.backend.tools.common.async_utils import async_lru
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
67
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
68 from .ad_hoc import APAdHocService
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
69 from .events import APEvents
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
70 from .constants import (
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
71 ACTIVITY_OBJECT_MANDATORY,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
72 ACTIVITY_TARGET_MANDATORY,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
73 ACTIVITY_TYPES,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
74 ACTIVITY_TYPES_LOWER,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
75 COMMENTS_MAX_PARENTS,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
76 CONF_SECTION,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
77 IMPORT_NAME,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
78 LRU_MAX_SIZE,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
79 MEDIA_TYPE_AP,
3846
cc13efdd8360 component AP gateway: return item when `item` URL is used:
Goffi <goffi@goffi.org>
parents: 3845
diff changeset
80 NS_AP,
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
81 NS_AP_PUBLIC,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
82 PUBLIC_TUPLE,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
83 TYPE_ACTOR,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
84 TYPE_EVENT,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
85 TYPE_FOLLOWERS,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
86 TYPE_ITEM,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
87 TYPE_LIKE,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
88 TYPE_MENTION,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
89 TYPE_REACTION,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
90 TYPE_TOMBSTONE,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
91 TYPE_JOIN,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
92 TYPE_LEAVE
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
93 )
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
94 from .http_server import HTTPServer
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
95 from .pubsub_service import APPubsubService
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
96 from .regex import RE_MENTION
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
97
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
98
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 log = getLogger(__name__)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
100
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 IMPORT_NAME = "ap-gateway"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 PLUGIN_INFO = {
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 C.PI_NAME: "ActivityPub Gateway component",
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 C.PI_IMPORT_NAME: IMPORT_NAME,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 C.PI_MODES: [C.PLUG_MODE_COMPONENT],
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 C.PI_PROTOCOLS: [],
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
109 C.PI_DEPENDENCIES: [
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
110 "XEP-0050", "XEP-0054", "XEP-0060", "XEP-0084", "XEP-0106", "XEP-0277",
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
111 "XEP-0292", "XEP-0329", "XEP-0372", "XEP-0424", "XEP-0465", "XEP-0470",
4027
26c3e1bc7fb7 plugin XEP-0471: renamed "events" plugin to XEP-0471 now that there is a XEP
Goffi <goffi@goffi.org>
parents: 4025
diff changeset
112 "XEP-0447", "XEP-0471", "PUBSUB_CACHE", "TEXT_SYNTAXES", "IDENTITY"
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
113 ],
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 C.PI_RECOMMENDATIONS: [],
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 C.PI_MAIN: "APGateway",
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
116 C.PI_HANDLER: C.BOOL_TRUE,
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 C.PI_DESCRIPTION: _(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 "Gateway for bidirectional communication between XMPP and ActivityPub."
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 ),
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 }
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
122 HEXA_ENC = r"(?P<hex>[0-9a-fA-f]{2})"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
123 RE_PERIOD_ENC = re.compile(f"\\.{HEXA_ENC}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
124 RE_PERCENT_ENC = re.compile(f"%{HEXA_ENC}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
125 RE_ALLOWED_UNQUOTED = re.compile(r"^[a-zA-Z0-9_-]+$")
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127
4094
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
128 class MissingLocalPartError(Exception):
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
129 """JID local part is missing"""
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
130
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
131
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 class APGateway:
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
133 IMPORT_NAME = IMPORT_NAME
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
134 # show data send or received through HTTP, used for debugging
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
135 # 1: log POST objects
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
136 # 2: log POST and GET objects
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
137 # 3: log POST and GET objects with HTTP headers for GET requests
4025
44abce96ac6b component AP gateway: revert forgotten verbose mode
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
138 verbose = 0
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
139
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 def __init__(self, host):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 self.host = host
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 self.initialised = False
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
143 self.client = None
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
144 self._p = host.plugins["XEP-0060"]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
145 self._a = host.plugins["XEP-0084"]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
146 self._e = host.plugins["XEP-0106"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
147 self._m = host.plugins["XEP-0277"]
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
148 self._v = host.plugins["XEP-0292"]
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
149 self._refs = host.plugins["XEP-0372"]
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
150 self._r = host.plugins["XEP-0424"]
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
151 self._sfs = host.plugins["XEP-0447"]
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
152 self._pps = host.plugins["XEP-0465"]
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
153 self._pa = host.plugins["XEP-0470"]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
154 self._c = host.plugins["PUBSUB_CACHE"]
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
155 self._t = host.plugins["TEXT_SYNTAXES"]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
156 self._i = host.plugins["IDENTITY"]
4027
26c3e1bc7fb7 plugin XEP-0471: renamed "events" plugin to XEP-0471 now that there is a XEP
Goffi <goffi@goffi.org>
parents: 4025
diff changeset
157 self._events = host.plugins["XEP-0471"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
158 self._p.add_managed_node(
3850
4479f6074bc8 component AP gateway: use the new `priority` argument of `addManagedNode`:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
159 "",
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
160 items_cb=self._items_received,
3850
4479f6074bc8 component AP gateway: use the new `priority` argument of `addManagedNode`:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
161 # we want to be sure that the callbacks are launched before pubsub cache's
4479f6074bc8 component AP gateway: use the new `priority` argument of `addManagedNode`:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
162 # one, as we need to inspect items before they are actually removed from cache
4479f6074bc8 component AP gateway: use the new `priority` argument of `addManagedNode`:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
163 # or updated
4479f6074bc8 component AP gateway: use the new `priority` argument of `addManagedNode`:
Goffi <goffi@goffi.org>
parents: 3847
diff changeset
164 priority=1000
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
165 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
166 self.pubsub_service = APPubsubService(self)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
167 self.ad_hoc = APAdHocService(self)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
168 self.ap_events = APEvents(self)
4051
c23cad65ae99 core: renamed `messageReceived` trigger to `message_received`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
169 host.trigger.add("message_received", self._message_received_trigger, priority=-1000)
4166
a1f7040b5a15 plugin XEP-0424: message retraction update:
Goffi <goffi@goffi.org>
parents: 4109
diff changeset
170 host.trigger.add("XEP-0424_retract_received", self._on_message_retract)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
171 host.trigger.add("XEP-0372_ref_received", self._on_reference_received)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
172
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
173 host.bridge.add_method(
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
174 "ap_send",
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 ".plugin",
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 in_sign="sss",
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 out_sign="",
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
178 method=self._publish_message,
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 async_=True,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
182 def get_handler(self, __):
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
183 return self.pubsub_service
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
184
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 async def init(self, client):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 if self.initialised:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 return
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 self.initialised = True
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 log.info(_("ActivityPub Gateway initialization"))
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 # RSA keys
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
193 stored_data = await self.host.memory.storage.get_privates(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 IMPORT_NAME, ["rsa_key"], profile=client.profile
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 private_key_pem = stored_data.get("rsa_key")
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 if private_key_pem is None:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 self.private_key = await threads.deferToThread(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 rsa.generate_private_key,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 public_exponent=65537,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 key_size=4096,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 private_key_pem = self.private_key.private_bytes(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 encoding=serialization.Encoding.PEM,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 format=serialization.PrivateFormat.PKCS8,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 encryption_algorithm=serialization.NoEncryption()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 ).decode()
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
208 await self.host.memory.storage.set_private_value(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 IMPORT_NAME, "rsa_key", private_key_pem, profile=client.profile
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 else:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 self.private_key = serialization.load_pem_private_key(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 private_key_pem.encode(),
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 password=None,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 self.public_key = self.private_key.public_key()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 self.public_key_pem = self.public_key.public_bytes(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 encoding=serialization.Encoding.PEM,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 format=serialization.PublicFormat.SubjectPublicKeyInfo
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 ).decode()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
222 # params
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
223 # URL and port
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
224 self.public_url = self.host.memory.config_get(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 CONF_SECTION, "public_url"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
226 ) or self.host.memory.config_get(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 CONF_SECTION, "xmpp_domain"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 if self.public_url is None:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 log.error(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 '"public_url" not set in configuration, this is mandatory to have'
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 "ActivityPub Gateway running. Please set this option it to public facing "
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 f"url in {CONF_SECTION!r} configuration section."
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 return
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 if parse.urlparse(self.public_url).scheme:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 log.error(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 "Scheme must not be specified in \"public_url\", please remove it from "
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 "\"public_url\" configuration option. ActivityPub Gateway won't be run."
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 return
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
242 self.http_port = int(self.host.memory.config_get(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 CONF_SECTION, 'http_port', 8123))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
244 connection_type = self.host.memory.config_get(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 CONF_SECTION, 'http_connection_type', 'https')
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 if connection_type not in ('http', 'https'):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 raise exceptions.ConfigError(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 'bad ap-gateay http_connection_type, you must use one of "http" or '
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 '"https"'
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
251 self.max_items = int(self.host.memory.config_get(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
252 CONF_SECTION, 'new_node_max_items', 50
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
253
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
254 ))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
255 self.comments_max_depth = int(self.host.memory.config_get(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
256 CONF_SECTION, 'comments_max_depth', 0
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
257 ))
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
258 self.ap_path = self.host.memory.config_get(CONF_SECTION, 'ap_path', '_ap')
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 self.base_ap_url = parse.urljoin(f"https://{self.public_url}", f"{self.ap_path}/")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
260 # True (default) if we provide gateway only to entities/services from our server
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
261 self.local_only = C.bool(
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
262 self.host.memory.config_get(CONF_SECTION, 'local_only', C.BOOL_TRUE)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
263 )
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
264 # if True (default), mention will be parsed in non-private content coming from
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
265 # XMPP. This is necessary as XEP-0372 are coming separately from item where the
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
266 # mention is done, which is hard to impossible to translate to ActivityPub (where
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
267 # mention specified inside the item directly). See documentation for details.
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
268 self.auto_mentions = C.bool(
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
269 self.host.memory.config_get(CONF_SECTION, "auto_mentions", C.BOOL_TRUE)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
270 )
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
271
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
272 html_redirect: Dict[str, Union[str, dict]] = self.host.memory.config_get(
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
273 CONF_SECTION, 'html_redirect_dict', {}
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
274 )
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
275 self.html_redirect: Dict[str, List[dict]] = {}
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
276 for url_type, target in html_redirect.items():
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
277 if isinstance(target, str):
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
278 target = {"url": target}
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
279 elif not isinstance(target, dict):
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
280 raise exceptions.ConfigError(
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
281 f"html_redirect target must be a URL or a dict, not {target!r}"
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
282 )
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
283 filters = target.setdefault("filters", {})
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
284 if "url" not in target:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
285 log.warning(f"invalid HTML redirection, missing target URL: {target}")
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
286 continue
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
287 # a slash in the url_type is a syntactic shortcut to have a node filter
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
288 if "/" in url_type:
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
289 url_type, node_filter = url_type.split("/", 1)
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
290 filters["node"] = node_filter
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
291 self.html_redirect.setdefault(url_type, []).append(target)
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
292
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
293 # HTTP server launch
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
294 self.server = HTTPServer(self)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
295 if connection_type == 'http':
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
296 reactor.listenTCP(self.http_port, self.server)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
297 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
298 options = tls.get_options_from_config(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
299 self.host.memory.config, CONF_SECTION)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
300 tls.tls_options_check(options)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
301 context_factory = tls.get_tls_context_factory(options)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
302 reactor.listenSSL(self.http_port, self.server, context_factory)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
303
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
304 async def profile_connecting(self, client):
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
305 self.client = client
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
306 client.sendHistory = True
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
307 client._ap_storage = persistent.LazyPersistentBinaryDict(
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
308 IMPORT_NAME,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
309 client.profile
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3821
diff changeset
310 )
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
311 await self.init(client)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
312
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
313 def profile_connected(self, client):
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
314 self.ad_hoc.init(client)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
315
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
316 async def _items_received(
3807
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
317 self,
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
318 client: SatXMPPEntity,
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
319 itemsEvent: pubsub.ItemsEvent
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
320 ) -> None:
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
321 """Callback called when pubsub items are received
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
322
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
323 if the items are adressed to a JID corresponding to an AP actor, they are
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
324 converted to AP items and sent to the corresponding AP server.
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
325
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
326 If comments nodes are linked, they are automatically subscribed to get new items
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
327 from there too.
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
328 """
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
329 if client != self.client:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
330 return
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
331 # we need recipient as JID and not gateway own JID to be able to use methods such
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
332 # as "subscribe"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
333 client = self.client.get_virtual_client(itemsEvent.sender)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
334 recipient = itemsEvent.recipient
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
335 if not recipient.user:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
336 log.debug("ignoring items event without local part specified")
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
337 return
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
338
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
339 ap_account = self._e.unescape(recipient.user)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
340
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
341 if self._pa.is_attachment_node(itemsEvent.nodeIdentifier):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
342 await self.convert_and_post_attachments(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
343 client, ap_account, itemsEvent.sender, itemsEvent.nodeIdentifier,
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
344 itemsEvent.items
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
345 )
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
346 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
347 await self.convert_and_post_items(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
348 client, ap_account, itemsEvent.sender, itemsEvent.nodeIdentifier,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
349 itemsEvent.items
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
350 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
351
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
352 async def get_virtual_client(self, actor_id: str) -> SatXMPPEntity:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
353 """Get client for this component with a specified jid
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
354
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
355 This is needed to perform operations with the virtual JID corresponding to the AP
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
356 actor instead of the JID of the gateway itself.
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
357 @param actor_id: ID of the actor
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
358 @return: virtual client
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
359 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
360 local_jid = await self.get_jid_from_id(actor_id)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
361 return self.client.get_virtual_client(local_jid)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
362
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
363 def is_activity(self, data: dict) -> bool:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
364 """Return True if the data has an activity type"""
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
365 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
366 return (data.get("type") or "").lower() in ACTIVITY_TYPES_LOWER
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
367 except (KeyError, TypeError):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
368 return False
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
369
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
370 async def ap_get(self, url: str) -> dict:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
371 """Retrieve AP JSON from given URL
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
372
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
373 @raise error.StanzaError: "service-unavailable" is sent when something went wrong
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
374 with AP server
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
375 """
3880
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
376 resp = await treq.get(
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
377 url,
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
378 headers = {
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
379 "Accept": [MEDIA_TYPE_AP],
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
380 }
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
381 )
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
382 if resp.code >= 300:
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
383 text = await resp.text()
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
384 if resp.code == 404:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
385 raise exceptions.NotFound(f"Can't find resource at {url}")
3880
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
386 else:
3977
6fa4ca0c047e component AP gateway: HTML redirection:
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
387 msg = f"HTTP error {resp.code} (url: {url}): {text}"
3880
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
388 raise exceptions.ExternalRequestError(msg)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
389 try:
3880
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
390 return await treq.json_content(resp)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
391 except Exception as e:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
392 raise error.StanzaError(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
393 "service-unavailable",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
394 text=f"Can't get AP data at {url}: {e}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
395 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
396
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
397 @overload
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
398 async def ap_get_object(self, data: dict, key: str) -> Optional[dict]:
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
399 ...
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
400
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
401 @overload
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
402 async def ap_get_object(
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
403 self, data: Union[str, dict], key: None = None
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
404 ) -> dict:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
405 ...
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
406
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
407 async def ap_get_object(self, data, key = None):
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
408 """Retrieve an AP object, dereferencing when necessary
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
409
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
410 This method is to be used with attributes marked as "Functional" in
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
411 https://www.w3.org/TR/activitystreams-vocabulary
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
412 @param data: AP object where an other object is looked for, or the object itself
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
413 @param key: name of the object to look for, or None if data is the object directly
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
414 @return: found object if any
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
415 """
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
416 if key is not None:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
417 value = data.get(key)
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
418 else:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
419 value = data
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
420 if value is None:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
421 if key is None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
422 raise ValueError("None can't be used with ap_get_object is key is None")
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
423 return None
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
424 elif isinstance(value, dict):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
425 return value
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
426 elif isinstance(value, str):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
427 if self.is_local_url(value):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
428 return await self.ap_get_local_object(value)
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
429 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
430 return await self.ap_get(value)
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
431 else:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
432 raise NotImplementedError(
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
433 "was expecting a string or a dict, got {type(value)}: {value!r}}"
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
434 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
435
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
436 async def ap_get_local_object(
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
437 self,
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
438 url: str
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
439 ) -> dict:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
440 """Retrieve or generate local object
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
441
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
442 for now, only handle XMPP items to convert to AP
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
443 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
444 url_type, url_args = self.parse_apurl(url)
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
445 if url_type == TYPE_ITEM:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
446 try:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
447 account, item_id = url_args
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
448 except ValueError:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
449 raise ValueError(f"invalid URL: {url}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
450 author_jid, node = await self.get_jid_and_node(account)
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
451 if node is None:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
452 node = self._m.namespace
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
453 cached_node = await self.host.memory.storage.get_pubsub_node(
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
454 self.client, author_jid, node
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
455 )
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
456 if not cached_node:
3851
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
457 log.debug(f"node {node!r} at {author_jid} is not found in cache")
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
458 found_item = None
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
459 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
460 cached_items, __ = await self.host.memory.storage.get_items(
3851
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
461 cached_node, item_ids=[item_id]
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
462 )
3851
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
463 if not cached_items:
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
464 log.debug(
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
465 f"item {item_id!r} of {node!r} at {author_jid} is not found in "
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
466 "cache"
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
467 )
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
468 found_item = None
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
469 else:
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
470 found_item = cached_items[0].data
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
471
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
472 if found_item is None:
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
473 # the node is not in cache, we have to make a request to retrieve the item
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
474 # If the node doesn't exist, get_items will raise a NotFound exception
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
475 found_items, __ = await self._p.get_items(
3851
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
476 self.client, author_jid, node, item_ids=[item_id]
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
477 )
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
478 try:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
479 found_item = found_items[0]
3880
03761f8ba8bb component AP gateway: raise exceptions on apGet + fix exceptions catching in apGetLocalObject:
Goffi <goffi@goffi.org>
parents: 3869
diff changeset
480 except IndexError:
4014
4ef473116499 component AP gateway (http): handle properly NotFound error:
Goffi <goffi@goffi.org>
parents: 4013
diff changeset
481 raise exceptions.NotFound(f"requested item at {url} can't be found")
3851
ef824b1091f3 component AP gateway: get items when not found in cache in `apGetLocalObject`:
Goffi <goffi@goffi.org>
parents: 3850
diff changeset
482
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
483 if node.startswith(self._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
484 # this is an event
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
485 event_data = self._events.event_elt_2_event_data(found_item)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
486 ap_item = await self.ap_events.event_data_2_ap_item(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
487 event_data, author_jid
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
488 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
489 # the URL must return the object and not the activity
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
490 ap_item["object"]["@context"] = ap_item["@context"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
491 return ap_item["object"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
492 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
493 # this is a blog item
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
494 mb_data = await self._m.item_2_mb_data(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
495 self.client, found_item, author_jid, node
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
496 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
497 ap_item = await self.mb_data_2_ap_item(self.client, mb_data)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
498 # the URL must return the object and not the activity
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
499 return ap_item["object"]
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
500 else:
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
501 raise NotImplementedError(
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
502 'only object from "item" URLs can be retrieved for now'
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
503 )
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
504
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
505 async def ap_get_list(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
506 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
507 data: dict,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
508 key: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
509 only_ids: bool = False
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
510 ) -> Optional[List[Dict[str, Any]]]:
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
511 """Retrieve a list of objects from AP data, dereferencing when necessary
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
512
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
513 This method is to be used with non functional vocabularies. Use ``ap_get_object``
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
514 otherwise.
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
515 If the value is a dictionary, it will be wrapped in a list
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
516 @param data: AP object where a list of objects is looked for
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
517 @param key: key of the list to look for
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
518 @param only_ids: if Trye, only items IDs are retrieved
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
519 @return: list of objects, or None if the key is not present
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
520 """
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
521 value = data.get(key)
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
522 if value is None:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
523 return None
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
524 elif isinstance(value, str):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
525 if self.is_local_url(value):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
526 value = await self.ap_get_local_object(value)
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
527 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
528 value = await self.ap_get(value)
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
529 if isinstance(value, dict):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
530 return [value]
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
531 if not isinstance(value, list):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
532 raise ValueError(f"A list was expected, got {type(value)}: {value!r}")
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
533 if only_ids:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
534 return [
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
535 {"id": v["id"]} if isinstance(v, dict) else {"id": v}
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
536 for v in value
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
537 ]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
538 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
539 return [await self.ap_get_object(i) for i in value]
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
540
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
541 async def ap_get_actors(
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
542 self,
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
543 data: dict,
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
544 key: str,
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
545 as_account: bool = True
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
546 ) -> List[str]:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
547 """Retrieve AP actors from data
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
548
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
549 @param data: AP object containing a field with actors
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
550 @param key: field to use to retrieve actors
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
551 @param as_account: if True returns account handles, otherwise will return actor
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
552 IDs
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
553 @raise exceptions.DataError: there is not actor data or it is invalid
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
554 """
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
555 value = data.get(key)
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
556 if value is None:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
557 raise exceptions.DataError(
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
558 f"no actor associated to object {data.get('id')!r}"
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
559 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
560 elif isinstance(value, dict):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
561 actor_id = value.get("id")
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
562 if actor_id is None:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
563 raise exceptions.DataError(
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
564 f"invalid actor associated to object {data.get('id')!r}: {value!r}"
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
565 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
566 value = [actor_id]
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
567 elif isinstance(value, str):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
568 value = [value]
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
569 elif isinstance(value, list):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
570 try:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
571 value = [a if isinstance(a, str) else a["id"] for a in value]
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
572 except (TypeError, KeyError):
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
573 raise exceptions.DataError(
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
574 f"invalid actors list to object {data.get('id')!r}: {value!r}"
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
575 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
576 if not value:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
577 raise exceptions.DataError(
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
578 f"list of actors is empty"
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
579 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
580 if as_account:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
581 return [await self.get_ap_account_from_id(actor_id) for actor_id in value]
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
582 else:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
583 return value
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
584
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
585 async def ap_get_sender_actor(
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
586 self,
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
587 data: dict,
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
588 ) -> str:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
589 """Retrieve actor who sent data
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
590
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
591 This is done by checking "actor" field first, then "attributedTo" field.
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
592 Only the first found actor is taken into account
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
593 @param data: AP object
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
594 @return: actor id of the sender
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
595 @raise exceptions.NotFound: no actor has been found in data
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
596 """
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
597 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
598 actors = await self.ap_get_actors(data, "actor", as_account=False)
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
599 except exceptions.DataError:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
600 actors = None
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
601 if not actors:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
602 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
603 actors = await self.ap_get_actors(data, "attributedTo", as_account=False)
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
604 except exceptions.DataError:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
605 raise exceptions.NotFound(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
606 'actor not specified in "actor" or "attributedTo"'
3742
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
607 )
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
608 try:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
609 return actors[0]
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
610 except IndexError:
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
611 raise exceptions.NotFound("list of actors is empty")
bf0505d41c09 comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
612
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
613 def must_encode(self, text: str) -> bool:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
614 """Indicate if a text must be period encoded"""
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
615 return (
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
616 not RE_ALLOWED_UNQUOTED.match(text)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
617 or text.startswith("___")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
618 or "---" in text
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
619 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
620
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
621 def period_encode(self, text: str) -> str:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
622 """Period encode a text
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
623
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
624 see [get_jid_and_node] for reasons of period encoding
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
625 """
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
626 return (
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
627 parse.quote(text, safe="")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
628 .replace("---", "%2d%2d%2d")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
629 .replace("___", "%5f%5f%5f")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
630 .replace(".", "%2e")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
631 .replace("~", "%7e")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
632 .replace("%", ".")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
633 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
634
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
635 async def get_ap_account_from_jid_and_node(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
636 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
637 jid_: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
638 node: Optional[str]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
639 ) -> str:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
640 """Construct AP account from JID and node
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
641
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
642 The account construction will use escaping when necessary
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
643 """
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
644 if not node or node == self._m.namespace:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
645 node = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
646
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
647 if self.client is None:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
648 raise exceptions.InternalError("Client is not set yet")
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
649
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
650 if self.is_virtual_jid(jid_):
3792
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
651 # this is an proxy JID to an AP Actor
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
652 return self._e.unescape(jid_.user)
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
653
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
654 if node and not jid_.user and not self.must_encode(node):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
655 is_pubsub = await self.is_pubsub(jid_)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
656 # when we have a pubsub service, the user part can be used to set the node
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
657 # this produces more user-friendly AP accounts
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
658 if is_pubsub:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
659 jid_.user = node
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
660 node = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
661
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
662 is_local = self.is_local(jid_)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
663 user = jid_.user if is_local else jid_.userhost()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
664 if user is None:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
665 user = ""
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
666 account_elts = []
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
667 if node and self.must_encode(node) or self.must_encode(user):
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
668 account_elts = ["___"]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
669 if node:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
670 node = self.period_encode(node)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
671 user = self.period_encode(user)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
672
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
673 if not user:
4094
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
674 raise MissingLocalPartError("there should be a local part")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
675
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
676 if node:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
677 account_elts.extend((node, "---"))
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
678
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
679 account_elts.extend((
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
680 user, "@", jid_.host if is_local else self.client.jid.userhost()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
681 ))
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
682 return "".join(account_elts)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
683
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
684 def is_local(self, jid_: jid.JID) -> bool:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
685 """Returns True if jid_ use a domain or subdomain of gateway's host"""
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
686 local_host = self.client.host.split(".")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
687 assert local_host
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
688 return jid_.host.split(".")[-len(local_host):] == local_host
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
689
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
690 async def is_pubsub(self, jid_: jid.JID) -> bool:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
691 """Indicate if a JID is a Pubsub service"""
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
692 host_disco = await self.host.get_disco_infos(self.client, jid_)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
693 return (
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
694 ("pubsub", "service") in host_disco.identities
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
695 and not ("pubsub", "pep") in host_disco.identities
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
696 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
697
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
698 async def get_jid_and_node(self, ap_account: str) -> Tuple[jid.JID, Optional[str]]:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
699 """Decode raw AP account handle to get XMPP JID and Pubsub Node
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
700
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
701 Username are case insensitive.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
702
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
703 By default, the username correspond to local username (i.e. username from
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
704 component's server).
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
705
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
706 If local name's domain is a pubsub service (and not PEP), the username is taken as
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
707 a pubsub node.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
708
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
709 If ``---`` is present in username, the part before is used as pubsub node, and the
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
710 rest as a JID user part.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
711
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
712 If username starts with ``___``, characters are encoded using period encoding
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
713 (i.e. percent encoding where a ``.`` is used instead of ``%``).
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
714
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
715 This horror is necessary due to limitation in some AP implementation (notably
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
716 Mastodon), cf. https://github.com/mastodon/mastodon/issues/17222
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
717
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
718 examples:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
719
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
720 ``toto@example.org`` => JID = toto@example.org, node = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
721
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
722 ``___toto.40example.net@example.org`` => JID = toto@example.net (this one is a
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
723 non-local JID, and will work only if setings ``local_only`` is False), node = None
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
724
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
725 ``toto@pubsub.example.org`` (with pubsub.example.org being a pubsub service) =>
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
726 JID = pubsub.example.org, node = toto
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
727
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
728 ``tata---toto@example.org`` => JID = toto@example.org, node = tata
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
729
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
730 ``___urn.3axmpp.3amicroblog.3a0@pubsub.example.org`` (with pubsub.example.org
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
731 being a pubsub service) ==> JID = pubsub.example.org, node = urn:xmpp:microblog:0
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
732
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
733 @param ap_account: ActivityPub account handle (``username@domain.tld``)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
734 @return: service JID and pubsub node
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
735 if pubsub node is None, default microblog pubsub node (and possibly other
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
736 nodes that plugins may hanlde) will be used
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
737 @raise ValueError: invalid account
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
738 @raise PermissionError: non local jid is used when gateway doesn't allow them
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
739 """
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
740 if ap_account.count("@") != 1:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
741 raise ValueError("Invalid AP account")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
742 if ap_account.startswith("___"):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
743 encoded = True
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
744 ap_account = ap_account[3:]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
745 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
746 encoded = False
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
747
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
748 username, domain = ap_account.split("@")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
749
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
750 if "---" in username:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
751 node, username = username.rsplit("---", 1)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
752 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
753 node = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
754
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
755 if encoded:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
756 username = parse.unquote(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
757 RE_PERIOD_ENC.sub(r"%\g<hex>", username),
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
758 errors="strict"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
759 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
760 if node:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
761 node = parse.unquote(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
762 RE_PERIOD_ENC.sub(r"%\g<hex>", node),
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
763 errors="strict"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
764 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
765
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
766 if "@" in username:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
767 username, domain = username.rsplit("@", 1)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
768
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
769 if not node:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
770 # we need to check host disco, because disco request to user may be
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
771 # blocked for privacy reason (see
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
772 # https://xmpp.org/extensions/xep-0030.html#security)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
773 is_pubsub = await self.is_pubsub(jid.JID(domain))
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
774
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
775 if is_pubsub:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
776 # if the host is a pubsub service and not a PEP, we consider that username
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
777 # is in fact the node name
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
778 node = username
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
779 username = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
780
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
781 jid_s = f"{username}@{domain}" if username else domain
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
782 try:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
783 jid_ = jid.JID(jid_s)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
784 except RuntimeError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
785 raise ValueError(f"Invalid jid: {jid_s!r}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
786
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
787 if self.local_only and not self.is_local(jid_):
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
788 raise exceptions.PermissionError(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
789 "This gateway is configured to map only local entities and services"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
790 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
791
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
792 return jid_, node
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
793
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
794 def get_local_jid_from_account(self, account: str) -> jid.JID:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
795 """Compute JID linking to an AP account
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
796
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
797 The local jid is computer by escaping AP actor handle and using it as local part
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
798 of JID, where domain part is this gateway own JID
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
799 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
800 return jid.JID(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
801 None,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
802 (
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
803 self._e.escape(account),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
804 self.client.jid.host,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
805 None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
806 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
807 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
808
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
809 async def get_jid_from_id(self, actor_id: str) -> jid.JID:
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
810 """Compute JID linking to an AP Actor ID
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
811
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
812 The local jid is computer by escaping AP actor handle and using it as local part
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
813 of JID, where domain part is this gateway own JID
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
814 If the actor_id comes from local server (checked with self.public_url), it means
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
815 that we have an XMPP entity, and the original JID is returned
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
816 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
817 if self.is_local_url(actor_id):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
818 request_type, extra_args = self.parse_apurl(actor_id)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
819 if request_type != TYPE_ACTOR or len(extra_args) != 1:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
820 raise ValueError(f"invalid actor id: {actor_id!r}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
821 actor_jid, __ = await self.get_jid_and_node(extra_args[0])
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
822 return actor_jid
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
823
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
824 account = await self.get_ap_account_from_id(actor_id)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
825 return self.get_local_jid_from_account(account)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
826
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
827 def parse_apurl(self, url: str) -> Tuple[str, List[str]]:
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
828 """Parse an URL leading to an AP endpoint
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
829
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
830 @param url: URL to parse (schema is not mandatory)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
831 @return: endpoint type and extra arguments
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
832 """
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
833 path = parse.urlparse(url).path.lstrip("/")
3842
943901372eba component AP gateway: `apGetObject` and `apGetList` now work with local object:
Goffi <goffi@goffi.org>
parents: 3833
diff changeset
834 type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
835 return type_, [parse.unquote(a) for a in extra_args]
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
836
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
837 def build_apurl(self, type_:str , *args: str) -> str:
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
838 """Build an AP endpoint URL
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
839
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
840 @param type_: type of AP endpoing
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
841 @param arg: endpoint dependant arguments
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
842 """
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
843 return parse.urljoin(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
844 self.base_ap_url,
3994
69d970f974ff component AP gateway: don't percent-encode `@`:
Goffi <goffi@goffi.org>
parents: 3979
diff changeset
845 str(Path(type_).joinpath(*(parse.quote_plus(a, safe="@") for a in args)))
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
846 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
847
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
848 def is_local_url(self, url: str) -> bool:
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
849 """Tells if an URL link to this component
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
850
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
851 ``public_url`` and ``ap_path`` are used to check the URL
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
852 """
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
853 return url.startswith(self.base_ap_url)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
854
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
855 def is_virtual_jid(self, jid_: jid.JID) -> bool:
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
856 """Tell if a JID is an AP actor mapped through this gateway"""
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
857 return jid_.host == self.client.jid.userhost()
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
858
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
859 def build_signature_header(self, values: Dict[str, str]) -> str:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
860 """Build key="<value>" signature header from signature data"""
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
861 fields = []
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
862 for key, value in values.items():
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
863 if key not in ("(created)", "(expired)"):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
864 if '"' in value:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
865 raise NotImplementedError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
866 "string escaping is not implemented, double-quote can't be used "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
867 f"in {value!r}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
868 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
869 value = f'"{value}"'
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
870 fields.append(f"{key}={value}")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
871
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
872 return ",".join(fields)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
873
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
874 def get_digest(self, body: bytes, algo="SHA-256") -> Tuple[str, str]:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
875 """Get digest data to use in header and signature
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
876
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
877 @param body: body of the request
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
878 @return: hash name and digest
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
879 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
880 if algo != "SHA-256":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
881 raise NotImplementedError("only SHA-256 is implemented for now")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
882 return algo, base64.b64encode(hashlib.sha256(body).digest()).decode()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
883
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
884 @async_lru(maxsize=LRU_MAX_SIZE)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
885 async def get_actor_data(self, actor_id) -> dict:
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
886 """Retrieve actor data with LRU cache"""
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
887 return await self.ap_get(actor_id)
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
888
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
889 @async_lru(maxsize=LRU_MAX_SIZE)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
890 async def get_actor_pub_key_data(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
891 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
892 actor_id: str
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
893 ) -> Tuple[str, str, rsa.RSAPublicKey]:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
894 """Retrieve Public Key data from actor ID
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
895
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
896 @param actor_id: actor ID (url)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
897 @return: key_id, owner and public_key
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
898 @raise KeyError: publicKey is missing from actor data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
899 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
900 actor_data = await self.get_actor_data(actor_id)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
901 pub_key_data = actor_data["publicKey"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
902 key_id = pub_key_data["id"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
903 owner = pub_key_data["owner"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
904 pub_key_pem = pub_key_data["publicKeyPem"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
905 pub_key = serialization.load_pem_public_key(pub_key_pem.encode())
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
906 return key_id, owner, pub_key
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
907
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
908 def create_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
909 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
910 activity: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
911 actor_id: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
912 object_: Optional[Union[str, dict]] = None,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
913 target: Optional[Union[str, dict]] = None,
3845
4f9d4650eab5 component AP gateway: use `createActivity` in `mbdata2APitem`
Goffi <goffi@goffi.org>
parents: 3844
diff changeset
914 activity_id: Optional[str] = None,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
915 **kwargs,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
916 ) -> Dict[str, Any]:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
917 """Generate base data for an activity
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
918
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
919 @param activity: one of ACTIVITY_TYPES
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
920 @param actor_id: AP actor ID of the sender
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
921 @param object_: content of "object" field
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
922 @param target: content of "target" field
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
923 @param activity_id: ID to use for the activity
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
924 if not set it will be automatically generated, but it is usually desirable to
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
925 set the ID manually so it can be retrieved (e.g. for Undo)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
926 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
927 if activity not in ACTIVITY_TYPES:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
928 raise exceptions.InternalError(f"invalid activity: {activity!r}")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
929 if object_ is None and activity in ACTIVITY_OBJECT_MANDATORY:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
930 raise exceptions.InternalError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
931 f'"object_" is mandatory for activity {activity!r}'
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
932 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
933 if target is None and activity in ACTIVITY_TARGET_MANDATORY:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
934 raise exceptions.InternalError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
935 f'"target" is mandatory for activity {activity!r}'
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
936 )
3845
4f9d4650eab5 component AP gateway: use `createActivity` in `mbdata2APitem`
Goffi <goffi@goffi.org>
parents: 3844
diff changeset
937 if activity_id is None:
4f9d4650eab5 component AP gateway: use `createActivity` in `mbdata2APitem`
Goffi <goffi@goffi.org>
parents: 3844
diff changeset
938 activity_id = f"{actor_id}#{activity.lower()}_{shortuuid.uuid()}"
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
939 data: Dict[str, Any] = {
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
940 "@context": [NS_AP],
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
941 "actor": actor_id,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
942 "id": activity_id,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
943 "type": activity,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
944 }
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
945 data.update(kwargs)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
946 if object_ is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
947 data["object"] = object_
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
948 if target is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
949 data["target"] = target
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
950
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
951 return data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
952
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
953 def get_key_id(self, actor_id: str) -> str:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
954 """Get local key ID from actor ID"""
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
955 return f"{actor_id}#main-key"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
956
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
957 async def check_signature(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
958 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
959 signature: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
960 key_id: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
961 headers: Dict[str, str]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
962 ) -> str:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
963 """Verify that signature matches given headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
964
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
965 see https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-06#section-3.1.2
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
966
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
967 @param signature: Base64 encoded signature
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
968 @param key_id: ID of the key used to sign the data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
969 @param headers: headers and their values, including pseudo-headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
970 @return: id of the signing actor
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
971
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
972 @raise InvalidSignature: signature doesn't match headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
973 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
974 to_sign = "\n".join(f"{k.lower()}: {v}" for k,v in headers.items())
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
975 if key_id.startswith("acct:"):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
976 actor = key_id[5:]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
977 actor_id = await self.get_ap_actor_id_from_account(actor)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
978 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
979 actor_id = key_id.split("#", 1)[0]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
980
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
981 pub_key_id, pub_key_owner, pub_key = await self.get_actor_pub_key_data(actor_id)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
982 if pub_key_id != key_id or pub_key_owner != actor_id:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
983 raise exceptions.EncryptionError("Public Key mismatch")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
984
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
985 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
986 pub_key.verify(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
987 base64.b64decode(signature),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
988 to_sign.encode(),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
989 # we have to use PKCS1v15 padding to be compatible with Mastodon
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
990 padding.PKCS1v15(), # type: ignore
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
991 hashes.SHA256() # type: ignore
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
992 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
993 except InvalidSignature:
3883
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
994 raise exceptions.EncryptionError(
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
995 "Invalid signature (using PKC0S1 v1.5 and SHA-256)"
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
996 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
997
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
998 return actor_id
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
999
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1000 def get_signature_data(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1001 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1002 key_id: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1003 headers: Dict[str, str]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1004 ) -> Tuple[Dict[str, str], Dict[str, str]]:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1005 """Generate and return signature and corresponding headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1006
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1007 @param parsed_url: URL where the request is sent/has been received
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1008 @param key_id: ID of the key (URL linking to the data with public key)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1009 @param date: HTTP datetime string of signature generation
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1010 @param body: body of the HTTP request
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1011 @param headers: headers to sign and their value:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1012 default value will be used if not specified
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1013
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1014 @return: headers and signature data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1015 ``headers`` is an updated copy of ``headers`` arguments, with pseudo-headers
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1016 removed, and ``Signature`` added.
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1017 """
3883
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1018 # headers must be lower case
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1019 l_headers: Dict[str, str] = {k.lower(): v for k, v in headers.items()}
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1020 to_sign = "\n".join(f"{k}: {v}" for k,v in l_headers.items())
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1021 signature = base64.b64encode(self.private_key.sign(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1022 to_sign.encode(),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1023 # we have to use PKCS1v15 padding to be compatible with Mastodon
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1024 padding.PKCS1v15(), # type: ignore
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1025 hashes.SHA256() # type: ignore
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1026 )).decode()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1027 sign_data = {
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1028 "keyId": key_id,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1029 "Algorithm": "rsa-sha256",
3883
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1030 "headers": " ".join(l_headers.keys()),
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1031 "signature": signature
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1032 }
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1033 new_headers = {k: v for k,v in headers.items() if not k.startswith("(")}
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1034 new_headers["Signature"] = self.build_signature_header(sign_data)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1035 return new_headers, sign_data
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1036
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1037 async def convert_and_post_items(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1038 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1039 client: SatXMPPEntity,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1040 ap_account: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1041 service: jid.JID,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1042 node: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1043 items: List[domish.Element],
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1044 subscribe_extra_nodes: bool = True,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1045 ) -> None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1046 """Convert XMPP items to AP items and post them to actor inbox
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1047
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1048 @param ap_account: account of ActivityPub actor receiving the item
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1049 @param service: JID of the (virtual) pubsub service where the item has been
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1050 published
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1051 @param node: (virtual) node corresponding where the item has been published
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1052 @param subscribe_extra_nodes: if True, extra data nodes will be automatically
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1053 subscribed, that is comment nodes if present and attachments nodes.
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1054 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1055 actor_id = await self.get_ap_actor_id_from_account(ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1056 inbox = await self.get_ap_inbox_from_id(actor_id)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1057 for item in items:
3792
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
1058 if item.name == "item":
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1059 cached_item = await self.host.memory.storage.search_pubsub_items({
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1060 "profiles": [self.client.profile],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1061 "services": [service],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1062 "nodes": [node],
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1063 "names": [item["id"]]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1064 })
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1065 is_new = not bool(cached_item)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1066 if node.startswith(self._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1067 # event item
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1068 event_data = self._events.event_elt_2_event_data(item)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1069 try:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1070 author_jid = jid.JID(item["publisher"]).userhostJID()
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1071 except (KeyError, RuntimeWarning):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1072 root_elt = item
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1073 while root_elt.parent is not None:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1074 root_elt = root_elt.parent
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1075 author_jid = jid.JID(root_elt["from"]).userhostJID()
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1076 if subscribe_extra_nodes and not self.is_virtual_jid(author_jid):
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1077 # we subscribe automatically to comment nodes if any
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1078 recipient_jid = self.get_local_jid_from_account(ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1079 recipient_client = self.client.get_virtual_client(recipient_jid)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1080 comments_data = event_data.get("comments")
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1081 if comments_data:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1082 comment_service = jid.JID(comments_data["jid"])
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1083 comment_node = comments_data["node"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1084 await self._p.subscribe(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1085 recipient_client, comment_service, comment_node
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1086 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1087 try:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1088 await self._pa.subscribe(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1089 recipient_client, service, node, event_data["id"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1090 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1091 except exceptions.NotFound:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1092 log.debug(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1093 f"no attachment node found for item {event_data['id']!r} "
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1094 f"on {node!r} at {service}"
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1095 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1096 ap_item = await self.ap_events.event_data_2_ap_item(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1097 event_data, author_jid, is_new=is_new
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1098 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1099 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1100 # blog item
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1101 mb_data = await self._m.item_2_mb_data(client, item, service, node)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1102 author_jid = jid.JID(mb_data["author_jid"])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1103 if subscribe_extra_nodes and not self.is_virtual_jid(author_jid):
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1104 # we subscribe automatically to comment nodes if any
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1105 recipient_jid = self.get_local_jid_from_account(ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1106 recipient_client = self.client.get_virtual_client(recipient_jid)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1107 for comment_data in mb_data.get("comments", []):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1108 comment_service = jid.JID(comment_data["service"])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1109 if self.is_virtual_jid(comment_service):
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1110 log.debug(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1111 f"ignoring virtual comment service: {comment_data}"
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1112 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1113 continue
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1114 comment_node = comment_data["node"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1115 await self._p.subscribe(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1116 recipient_client, comment_service, comment_node
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1117 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1118 try:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1119 await self._pa.subscribe(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1120 recipient_client, service, node, mb_data["id"]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1121 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1122 except exceptions.NotFound:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1123 log.debug(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1124 f"no attachment node found for item {mb_data['id']!r} on "
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1125 f"{node!r} at {service}"
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1126 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1127 ap_item = await self.mb_data_2_ap_item(client, mb_data, is_new=is_new)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1128
3852
384ad98ea9fe component AP gateway: we need to use `actor` and not `attributedTo` for activities:
Goffi <goffi@goffi.org>
parents: 3851
diff changeset
1129 url_actor = ap_item["actor"]
3792
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
1130 elif item.name == "retract":
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1131 url_actor, ap_item = await self.ap_delete_item(
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
1132 client.jid, node, item["id"]
3792
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
1133 )
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
1134 else:
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3784
diff changeset
1135 raise exceptions.InternalError(f"unexpected element: {item.toXml()}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1136 await self.sign_and_post(inbox, url_actor, ap_item)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1137
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1138 async def convert_and_post_attachments(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1139 self,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1140 client: SatXMPPEntity,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1141 ap_account: str,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1142 service: jid.JID,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1143 node: str,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1144 items: List[domish.Element],
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1145 publisher: Optional[jid.JID] = None
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1146 ) -> None:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1147 """Convert XMPP item attachments to AP activities and post them to actor inbox
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1148
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1149 @param ap_account: account of ActivityPub actor receiving the item
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1150 @param service: JID of the (virtual) pubsub service where the item has been
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1151 published
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1152 @param node: (virtual) node corresponding where the item has been published
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1153 subscribed, that is comment nodes if present and attachments nodes.
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1154 @param items: attachments items
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1155 @param publisher: publisher of the attachments item (it's NOT the PEP/Pubsub
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1156 service, it's the publisher of the item). To be filled only when the publisher
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1157 is known for sure, otherwise publisher will be determined either if
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1158 "publisher" attribute is set by pubsub service, or as a last resort, using
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1159 item's ID (which MUST be publisher bare JID according to pubsub-attachments
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1160 specification).
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1161 """
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1162 if len(items) != 1:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1163 log.warning(
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1164 "we should get exactly one attachment item for an entity, got "
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1165 f"{len(items)})"
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1166 )
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1167
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1168 actor_id = await self.get_ap_actor_id_from_account(ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1169 inbox = await self.get_ap_inbox_from_id(actor_id)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1170
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1171 item_elt = items[0]
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1172 item_id = item_elt["id"]
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1173
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1174 if publisher is None:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1175 item_pub_s = item_elt.getAttribute("publisher")
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1176 publisher = jid.JID(item_pub_s) if item_pub_s else jid.JID(item_id)
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1177
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1178 if publisher.userhost() != item_id:
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1179 log.warning(
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1180 "attachments item ID must be publisher's bare JID, ignoring: "
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1181 f"{item_elt.toXml()}"
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1182 )
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1183 return
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1184
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1185 if self.is_virtual_jid(publisher):
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1186 log.debug(f"ignoring item coming from local virtual JID {publisher}")
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1187 return
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1188
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1189 if publisher is not None:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1190 item_elt["publisher"] = publisher.userhost()
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1191
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1192 item_service, item_node, item_id = self._pa.attachment_node_2_item(node)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1193 item_account = await self.get_ap_account_from_jid_and_node(item_service, item_node)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1194 if self.is_virtual_jid(item_service):
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1195 # it's a virtual JID mapping to an external AP actor, we can use the
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1196 # item_id directly
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1197 item_url = item_id
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1198 if not item_url.startswith("https:"):
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1199 log.warning(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1200 "item ID of external AP actor is not an https link, ignoring: "
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1201 f"{item_id!r}"
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1202 )
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1203 return
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1204 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1205 item_url = self.build_apurl(TYPE_ITEM, item_account, item_id)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1206
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1207 old_attachment_pubsub_items = await self.host.memory.storage.search_pubsub_items({
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1208 "profiles": [self.client.profile],
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1209 "services": [service],
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1210 "nodes": [node],
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1211 "names": [item_elt["id"]]
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1212 })
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1213 if not old_attachment_pubsub_items:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1214 old_attachment = {}
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1215 else:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1216 old_attachment_items = [i.data for i in old_attachment_pubsub_items]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1217 old_attachments = self._pa.items_2_attachment_data(client, old_attachment_items)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1218 try:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1219 old_attachment = old_attachments[0]
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1220 except IndexError:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1221 # no known element was present in attachments
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1222 old_attachment = {}
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1223 publisher_account = await self.get_ap_account_from_jid_and_node(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1224 publisher,
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1225 None
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1226 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1227 publisher_actor_id = self.build_apurl(TYPE_ACTOR, publisher_account)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1228 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1229 attachments = self._pa.items_2_attachment_data(client, [item_elt])[0]
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1230 except IndexError:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1231 # no known element was present in attachments
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1232 attachments = {}
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1233
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1234 # noticed
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1235 if "noticed" in attachments:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1236 if not "noticed" in old_attachment:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1237 # new "noticed" attachment, we translate to "Like" activity
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1238 activity_id = self.build_apurl("like", item_account, item_id)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1239 activity = self.create_activity(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1240 TYPE_LIKE, publisher_actor_id, item_url, activity_id=activity_id
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1241 )
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1242 activity["to"] = [ap_account]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1243 activity["cc"] = [NS_AP_PUBLIC]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1244 await self.sign_and_post(inbox, publisher_actor_id, activity)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1245 else:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1246 if "noticed" in old_attachment:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1247 # "noticed" attachment has been removed, we undo the "Like" activity
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1248 activity_id = self.build_apurl("like", item_account, item_id)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1249 activity = self.create_activity(
3869
c0bcbcf5b4b7 component AP gateway: handle `Like` and `Undo`/`Like` activities:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
1250 TYPE_LIKE, publisher_actor_id, item_url, activity_id=activity_id
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1251 )
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1252 activity["to"] = [ap_account]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1253 activity["cc"] = [NS_AP_PUBLIC]
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1254 undo = self.create_activity("Undo", publisher_actor_id, activity)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1255 await self.sign_and_post(inbox, publisher_actor_id, undo)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1256
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1257 # reactions
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1258 new_reactions = set(attachments.get("reactions", {}).get("reactions", []))
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1259 old_reactions = set(old_attachment.get("reactions", {}).get("reactions", []))
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1260 reactions_remove = old_reactions - new_reactions
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1261 reactions_add = new_reactions - old_reactions
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1262 for reactions, undo in ((reactions_remove, True), (reactions_add, False)):
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1263 for reaction in reactions:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1264 activity_id = self.build_apurl(
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1265 "reaction", item_account, item_id, reaction.encode().hex()
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1266 )
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1267 reaction_activity = self.create_activity(
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1268 TYPE_REACTION, publisher_actor_id, item_url,
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1269 activity_id=activity_id
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1270 )
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1271 reaction_activity["content"] = reaction
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1272 reaction_activity["to"] = [ap_account]
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1273 reaction_activity["cc"] = [NS_AP_PUBLIC]
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1274 if undo:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1275 activy = self.create_activity(
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1276 "Undo", publisher_actor_id, reaction_activity
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1277 )
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1278 else:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1279 activy = reaction_activity
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1280 await self.sign_and_post(inbox, publisher_actor_id, activy)
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1281
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1282 # RSVP
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1283 if "rsvp" in attachments:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1284 attending = attachments["rsvp"].get("attending", "no")
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1285 old_attending = old_attachment.get("rsvp", {}).get("attending", "no")
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1286 if attending != old_attending:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1287 activity_type = TYPE_JOIN if attending == "yes" else TYPE_LEAVE
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1288 activity_id = self.build_apurl(activity_type.lower(), item_account, item_id)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1289 activity = self.create_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1290 activity_type, publisher_actor_id, item_url, activity_id=activity_id
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1291 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1292 activity["to"] = [ap_account]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1293 activity["cc"] = [NS_AP_PUBLIC]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1294 await self.sign_and_post(inbox, publisher_actor_id, activity)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1295 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1296 if "rsvp" in old_attachment:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1297 old_attending = old_attachment.get("rsvp", {}).get("attending", "no")
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1298 if old_attending == "yes":
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1299 activity_id = self.build_apurl(TYPE_LEAVE.lower(), item_account, item_id)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1300 activity = self.create_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1301 TYPE_LEAVE, publisher_actor_id, item_url, activity_id=activity_id
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1302 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1303 activity["to"] = [ap_account]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1304 activity["cc"] = [NS_AP_PUBLIC]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1305 await self.sign_and_post(inbox, publisher_actor_id, activity)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1306
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1307 if service.user and self.is_virtual_jid(service):
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1308 # the item is on a virtual service, we need to store it in cache
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1309 log.debug("storing attachments item in cache")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1310 cached_node = await self.host.memory.storage.get_pubsub_node(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1311 client, service, node, with_subscriptions=True, create=True
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1312 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1313 await self.host.memory.storage.cache_pubsub_items(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1314 self.client,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1315 cached_node,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1316 [item_elt],
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1317 [attachments]
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1318 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1319
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1320 async def sign_and_post(self, url: str, actor_id: str, doc: dict) -> TReqResponse:
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1321 """Sign a documentent and post it to AP server
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1322
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1323 @param url: AP server endpoint
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1324 @param actor_id: originating actor ID (URL)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1325 @param doc: document to send
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1326 """
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1327 if self.verbose:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1328 __, actor_args = self.parse_apurl(actor_id)
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1329 actor_account = actor_args[0]
3881
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1330 to_log = [
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1331 "",
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1332 f">>> {actor_account} is signing and posting to {url}:\n{pformat(doc)}"
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1333 ]
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1334
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1335 p_url = parse.urlparse(url)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1336 body = json.dumps(doc).encode()
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1337 digest_algo, digest_hash = self.get_digest(body)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1338 digest = f"{digest_algo}={digest_hash}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1339
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1340 headers = {
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1341 "(request-target)": f"post {p_url.path}",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1342 "Host": p_url.hostname,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1343 "Date": http.datetimeToString().decode(),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1344 "Digest": digest
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1345 }
3883
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1346 headers["Content-Type"] = (
4109
7067b0d73183 component AP gateway: fix AP media type in GET and POST requests headers
Goffi <goffi@goffi.org>
parents: 4094
diff changeset
1347 MEDIA_TYPE_AP
3883
6da749bbf320 component AP gateway: fix headers case in signature:
Goffi <goffi@goffi.org>
parents: 3881
diff changeset
1348 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1349 headers, __ = self.get_signature_data(self.get_key_id(actor_id), headers)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1350
3881
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1351 if self.verbose:
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1352 if self.verbose>=3:
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1353 h_to_log = "\n".join(f" {k}: {v}" for k,v in headers.items())
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1354 to_log.append(f" headers:\n{h_to_log}")
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1355 to_log.append("---")
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1356 log.info("\n".join(to_log))
2e4a0f6050bd component AP gateway: better verbose logging:
Goffi <goffi@goffi.org>
parents: 3880
diff changeset
1357
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1358 resp = await treq.post(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1359 url,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1360 body,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1361 headers=headers,
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1362 )
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
1363 if resp.code >= 300:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1364 text = await resp.text()
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
1365 log.warning(f"POST request to {url} failed [{resp.code}]: {text}")
3847
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1366 elif self.verbose:
aaa4e7815ba8 component AP gateway: new `verbose` attribute in AP gateway to activate debug logs:
Goffi <goffi@goffi.org>
parents: 3846
diff changeset
1367 log.info(f"==> response code: {resp.code}")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1368 return resp
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1369
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1370 def _publish_message(self, mess_data_s: str, service_s: str, profile: str):
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1371 mess_data: dict = data_format.deserialise(mess_data_s) # type: ignore
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1372 service = jid.JID(service_s)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1373 client = self.host.get_client(profile)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1374 return defer.ensureDeferred(self.publish_message(client, mess_data, service))
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1375
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1376 @async_lru(maxsize=LRU_MAX_SIZE)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1377 async def get_ap_actor_id_from_account(self, account: str) -> str:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1378 """Retrieve account ID from it's handle using WebFinger
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1379
3807
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
1380 Don't use this method to get local actor id from a local account derivated for
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
1381 JID: in this case, the actor ID is retrieve with
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1382 ``self.build_apurl(TYPE_ACTOR, ap_account)``
3807
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
1383
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1384 @param account: AP handle (user@domain.tld)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1385 @return: Actor ID (which is an URL)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1386 """
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1387 if account.count("@") != 1 or "/" in account:
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
1388 raise ValueError(f"Invalid account: {account!r}")
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1389 host = account.split("@")[1]
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1390 try:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1391 finger_data = await treq.json_content(await treq.get(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1392 f"https://{host}/.well-known/webfinger?"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1393 f"resource=acct:{parse.quote_plus(account)}",
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1394 ))
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1395 except Exception as e:
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
1396 raise exceptions.DataError(f"Can't get webfinger data for {account!r}: {e}")
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1397 for link in finger_data.get("links", []):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1398 if (
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1399 link.get("type") == "application/activity+json"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1400 and link.get("rel") == "self"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1401 ):
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1402 href = link.get("href", "").strip()
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1403 if not href:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1404 raise ValueError(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1405 f"Invalid webfinger data for {account:r}: missing href"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1406 )
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1407 break
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1408 else:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1409 raise ValueError(
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1410 f"No ActivityPub link found for {account!r}"
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1411 )
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1412 return href
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1413
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1414 async def get_ap_actor_data_from_account(self, account: str) -> dict:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1415 """Retrieve ActivityPub Actor data
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1416
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1417 @param account: ActivityPub Actor identifier
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1418 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1419 href = await self.get_ap_actor_id_from_account(account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1420 return await self.ap_get(href)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1421
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1422 async def get_ap_inbox_from_id(self, actor_id: str, use_shared: bool = True) -> str:
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1423 """Retrieve inbox of an actor_id
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1424
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1425 @param use_shared: if True, and a shared inbox exists, it will be used instead of
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1426 the user inbox
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1427 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1428 data = await self.get_actor_data(actor_id)
3888
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1429 if use_shared:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1430 try:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1431 return data["endpoints"]["sharedInbox"]
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1432 except KeyError:
aa7197b67c26 component AP gateway: AP <=> XMPP reactions conversions:
Goffi <goffi@goffi.org>
parents: 3883
diff changeset
1433 pass
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1434 return data["inbox"]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1435
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1436 @async_lru(maxsize=LRU_MAX_SIZE)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1437 async def get_ap_account_from_id(self, actor_id: str) -> str:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1438 """Retrieve AP account from the ID URL
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1439
3843
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1440 Works with external or local actor IDs.
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1441 @param actor_id: AP ID of the actor (URL to the actor data)
3843
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1442 @return: AP handle
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1443 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1444 if self.is_local_url(actor_id):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1445 url_type, url_args = self.parse_apurl(actor_id)
3843
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1446 if url_type != "actor" or not url_args:
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1447 raise exceptions.DataError(
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1448 f"invalid local actor ID: {actor_id}"
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1449 )
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1450 account = url_args[0]
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1451 try:
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1452 account_user, account_host = account.split('@')
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1453 except ValueError:
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1454 raise exceptions.DataError(
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1455 f"invalid account from url: {actor_id}"
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1456 )
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1457 if not account_user or account_host != self.public_url:
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1458 raise exceptions.DataError(
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1459 f"{account!r} is not a valid local account (from {actor_id})"
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1460 )
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1461 return account
17c757bd74bc component AP gateway: `getAPAccountFromId` now works with local IDs:
Goffi <goffi@goffi.org>
parents: 3842
diff changeset
1462
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1463 url_parsed = parse.urlparse(actor_id)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1464 actor_data = await self.get_actor_data(actor_id)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1465 username = actor_data.get("preferredUsername")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1466 if not username:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1467 raise exceptions.DataError(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1468 'No "preferredUsername" field found, can\'t retrieve actor account'
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1469 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1470 account = f"{username}@{url_parsed.hostname}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1471 # we try to retrieve the actor ID from the account to check it
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1472 found_id = await self.get_ap_actor_id_from_account(account)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1473 if found_id != actor_id:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1474 # cf. 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
1475 msg = (
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1476 f"Account ID found on WebFinger {found_id!r} doesn't match our actor ID "
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1477 f"({actor_id!r}). This AP instance doesn't seems to use "
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1478 '"preferredUsername" as we expect.'
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1479 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1480 log.warning(msg)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1481 raise exceptions.DataError(msg)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1482 return account
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1483
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1484 async def get_ap_items(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1485 self,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1486 collection: dict,
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1487 max_items: Optional[int] = None,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1488 chronological_pagination: bool = True,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1489 after_id: Optional[str] = None,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1490 start_index: Optional[int] = None,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1491 parser: Optional[Callable[[dict], Awaitable[domish.Element]]] = None,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1492 only_ids: bool = False,
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1493 ) -> Tuple[List[domish.Element], rsm.RSMResponse]:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1494 """Retrieve AP items and convert them to XMPP items
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1495
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1496 @param account: AP account handle to get items from
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1497 @param max_items: maximum number of items to retrieve
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1498 retrieve all items by default
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1499 @param chronological_pagination: get pages in chronological order
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1500 AP use reversed chronological order for pagination, "first" page returns more
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1501 recent items. If "chronological_pagination" is True, "last" AP page will be
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1502 retrieved first.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1503 @param after_id: if set, retrieve items starting from given ID
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1504 Due to ActivityStream Collection Paging limitations, this is inefficient and
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1505 if ``after_id`` is not already in cache, we have to retrieve every page until
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1506 we find it.
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1507 In most common cases, ``after_id`` should be in cache though (client usually
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1508 use known ID when in-order pagination is used).
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1509 @param start_index: start retrieving items from the one with given index
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1510 Due to ActivityStream Collection Paging limitations, this is inefficient and
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1511 all pages before the requested index will be retrieved to count items.
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1512 @param parser: method to use to parse AP items and get XMPP item elements
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1513 if None, use default generic parser
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1514 @param only_ids: if True, only retrieve items IDs
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1515 Retrieving only item IDs avoid HTTP requests to retrieve items, it may be
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1516 sufficient in some use cases (e.g. when retrieving following/followers
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1517 collections)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1518 @return: XMPP Pubsub items and corresponding RSM Response
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1519 Items are always returned in chronological order in the result
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1520 """
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1521 if parser is None:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1522 parser = self.ap_item_2_mb_elt
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1523
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1524 rsm_resp: Dict[str, Union[bool, int]] = {}
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1525 try:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1526 count = collection["totalItems"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1527 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1528 log.warning(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1529 f'"totalItems" not found in collection {collection.get("id")}, '
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1530 "defaulting to 20"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1531 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1532 count = 20
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1533 else:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1534 log.info(f"{collection.get('id')} has {count} item(s)")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1535
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1536 rsm_resp["count"] = count
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1537
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1538 if start_index is not None:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1539 assert chronological_pagination and after_id is None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1540 if start_index >= count:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1541 return [], rsm_resp
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1542 elif start_index == 0:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1543 # this is the default behaviour
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1544 pass
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1545 elif start_index > 5000:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1546 raise error.StanzaError(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1547 "feature-not-implemented",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1548 text="Maximum limit for previous_index has been reached, this limit"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1549 "is set to avoid DoS"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1550 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1551 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1552 # we'll convert "start_index" to "after_id", thus we need the item just
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1553 # before "start_index"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1554 previous_index = start_index - 1
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1555 retrieved_items = 0
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1556 current_page = collection["last"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1557 while retrieved_items < count:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1558 page_data, items = await self.parse_ap_page(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1559 current_page, parser, only_ids
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1560 )
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1561 if not items:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1562 log.warning(f"found an empty AP page at {current_page}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1563 return [], rsm_resp
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1564 page_start_idx = retrieved_items
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1565 retrieved_items += len(items)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1566 if previous_index <= retrieved_items:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1567 after_id = items[previous_index - page_start_idx]["id"]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1568 break
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1569 try:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1570 current_page = page_data["prev"]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1571 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1572 log.warning(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1573 f"missing previous page link at {current_page}: {page_data!r}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1574 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1575 raise error.StanzaError(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1576 "service-unavailable",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1577 "Error while retrieving previous page from AP service at "
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1578 f"{current_page}"
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1579 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1580
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1581 init_page = "last" if chronological_pagination else "first"
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1582 page = collection.get(init_page)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1583 if not page:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1584 raise exceptions.DataError(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1585 f"Initial page {init_page!r} not found for collection "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1586 f"{collection.get('id')})"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1587 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1588 items = []
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1589 page_items = []
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1590 retrieved_items = 0
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1591 found_after_id = False
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1592
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1593 while retrieved_items < count:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1594 __, page_items = await self.parse_ap_page(page, parser, only_ids)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1595 if not page_items:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1596 break
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1597 retrieved_items += len(page_items)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1598 if after_id is not None and not found_after_id:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1599 # if we have an after_id, we ignore all items until the requested one is
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1600 # found
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1601 try:
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1602 limit_idx = [i["id"] for i in page_items].index(after_id)
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1603 except ValueError:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1604 # if "after_id" is not found, we don't add any item from this page
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1605 page_id = page.get("id") if isinstance(page, dict) else page
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1606 log.debug(f"{after_id!r} not found at {page_id}, skipping")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1607 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1608 found_after_id = True
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1609 if chronological_pagination:
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1610 start_index = retrieved_items - len(page_items) + limit_idx + 1
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1611 page_items = page_items[limit_idx+1:]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1612 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1613 start_index = count - (retrieved_items - len(page_items) +
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1614 limit_idx + 1)
3729
86eea17cafa7 component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents: 3728
diff changeset
1615 page_items = page_items[:limit_idx]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1616 items.extend(page_items)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1617 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1618 items.extend(page_items)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1619 if max_items is not None and len(items) >= max_items:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1620 if chronological_pagination:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1621 items = items[:max_items]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1622 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1623 items = items[-max_items:]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1624 break
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1625 page = collection.get("prev" if chronological_pagination else "next")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1626 if not page:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1627 break
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1628
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1629 if after_id is not None and not found_after_id:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1630 raise error.StanzaError("item-not-found")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1631
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1632 if items:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1633 if after_id is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1634 rsm_resp["index"] = 0 if chronological_pagination else count - len(items)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1635 if start_index is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1636 rsm_resp["index"] = start_index
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1637 elif after_id is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1638 log.warning("Can't determine index of first element")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1639 elif chronological_pagination:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1640 rsm_resp["index"] = 0
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1641 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1642 rsm_resp["index"] = count - len(items)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1643 rsm_resp.update({
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1644 "first": items[0]["id"],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1645 "last": items[-1]["id"]
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1646 })
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1647
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1648 return items, rsm.RSMResponse(**rsm_resp)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1649
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1650 async def ap_item_2_mb_data_and_elt(self, ap_item: dict) -> Tuple[dict, domish.Element]:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1651 """Convert AP item to parsed microblog data and corresponding item element"""
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1652 mb_data = await self.ap_item_2_mb_data(ap_item)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1653 item_elt = await self._m.mb_data_2_entry_elt(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1654 self.client, mb_data, mb_data["id"], None, self._m.namespace
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1655 )
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1656 if "repeated" in mb_data["extra"]:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1657 item_elt["publisher"] = mb_data["extra"]["repeated"]["by"]
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1658 else:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1659 item_elt["publisher"] = mb_data["author_jid"]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1660 return mb_data, item_elt
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1661
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1662 async def ap_item_2_mb_elt(self, ap_item: dict) -> domish.Element:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1663 """Convert AP item to XMPP item element"""
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1664 __, item_elt = await self.ap_item_2_mb_data_and_elt(ap_item)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1665 return item_elt
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1666
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1667 async def parse_ap_page(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1668 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1669 page: Union[str, dict],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1670 parser: Callable[[dict], Awaitable[domish.Element]],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1671 only_ids: bool = False
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1672 ) -> Tuple[dict, List[domish.Element]]:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1673 """Convert AP objects from an AP page to XMPP items
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1674
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1675 @param page: Can be either url linking and AP page, or the page data directly
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1676 @param parser: method to use to parse AP items and get XMPP item elements
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1677 @param only_ids: if True, only retrieve items IDs
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1678 @return: page data, pubsub items
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1679 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1680 page_data = await self.ap_get_object(page)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1681 if page_data is None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1682 log.warning('No data found in collection')
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1683 return {}, []
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1684 ap_items = await self.ap_get_list(page_data, "orderedItems", only_ids=only_ids)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1685 if ap_items is None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1686 ap_items = await self.ap_get_list(page_data, "items", only_ids=only_ids)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1687 if not ap_items:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1688 log.warning(f'No item field found in collection: {page_data!r}')
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1689 return page_data, []
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1690 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1691 log.warning(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1692 "Items are not ordered, this is not spec compliant"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1693 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1694 items = []
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1695 # AP Collections are in antichronological order, but we expect chronological in
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1696 # Pubsub, thus we reverse it
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1697 for ap_item in reversed(ap_items):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1698 try:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1699 items.append(await parser(ap_item))
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1700 except (exceptions.DataError, NotImplementedError, error.StanzaError):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1701 continue
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1702
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1703 return page_data, items
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1704
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1705 async def get_comments_nodes(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1706 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1707 item_id: str,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1708 parent_id: Optional[str]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1709 ) -> Tuple[Optional[str], Optional[str]]:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1710 """Get node where this item is and node to use for comments
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1711
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1712 if config option "comments_max_depth" is set, a common node will be used below the
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1713 given depth
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1714 @param item_id: ID of the reference item
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1715 @param parent_id: ID of the parent item if any (the ID set in "inReplyTo")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1716 @return: a tuple with parent_node_id, comments_node_id:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1717 - parent_node_id is the ID of the node where reference item must be. None is
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1718 returned when the root node (i.e. not a comments node) must be used.
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1719 - comments_node_id: is the ID of the node to use for comments. None is
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1720 returned when no comment node must be used (happens when we have reached
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1721 "comments_max_depth")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1722 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1723 if parent_id is None or not self.comments_max_depth:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1724 return (
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1725 self._m.get_comments_node(parent_id) if parent_id is not None else None,
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1726 self._m.get_comments_node(item_id)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1727 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1728 parent_url = parent_id
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1729 parents = []
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1730 for __ in range(COMMENTS_MAX_PARENTS):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1731 parent_item = await self.ap_get(parent_url)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1732 parents.insert(0, parent_item)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1733 parent_url = parent_item.get("inReplyTo")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1734 if parent_url is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1735 break
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1736 parent_limit = self.comments_max_depth-1
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1737 if len(parents) <= parent_limit:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1738 return (
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1739 self._m.get_comments_node(parents[-1]["id"]),
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1740 self._m.get_comments_node(item_id)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1741 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1742 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1743 last_level_item = parents[parent_limit]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1744 return (
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1745 self._m.get_comments_node(last_level_item["id"]),
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1746 None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1747 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1748
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1749 async def ap_item_2_mb_data(self, ap_item: dict) -> dict:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1750 """Convert AP activity or object to microblog data
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1751
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1752 @param ap_item: ActivityPub item to convert
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1753 Can be either an activity of an object
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1754 @return: AP Item's Object and microblog data
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1755 @raise exceptions.DataError: something is invalid in the AP item
3853
a56d5ad466b3 component AP gateway: fix wrong exception + use of mb_data["xml"] when it may be absent
Goffi <goffi@goffi.org>
parents: 3852
diff changeset
1756 @raise NotImplementedError: some AP data is not handled yet
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1757 @raise error.StanzaError: error while contacting the AP server
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1758 """
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1759 is_activity = self.is_activity(ap_item)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1760 if is_activity:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1761 ap_object = await self.ap_get_object(ap_item, "object")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1762 if not ap_object:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1763 log.warning(f'No "object" found in AP item {ap_item!r}')
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1764 raise exceptions.DataError
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1765 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1766 ap_object = ap_item
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1767 item_id = ap_object.get("id")
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1768 if not item_id:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1769 log.warning(f'No "id" found in AP item: {ap_object!r}')
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1770 raise exceptions.DataError
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1771 mb_data = {"id": item_id, "extra": {}}
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1772
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1773 # content
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1774 try:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1775 language, content_xhtml = ap_object["contentMap"].popitem()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1776 except (KeyError, AttributeError):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1777 try:
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1778 mb_data["content_xhtml"] = ap_object["content"]
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1779 except KeyError:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1780 log.warning(f"no content found:\n{ap_object!r}")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1781 raise exceptions.DataError
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1782 else:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1783 mb_data["language"] = language
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1784 mb_data["content_xhtml"] = content_xhtml
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1785
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1786 mb_data["content"] = await self._t.convert(
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1787 mb_data["content_xhtml"],
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1788 self._t.SYNTAX_XHTML,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1789 self._t.SYNTAX_TEXT,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1790 False,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
1791 )
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1792
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1793 if "attachment" in ap_object:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1794 attachments = mb_data["extra"][C.KEY_ATTACHMENTS] = []
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1795 for ap_attachment in ap_object["attachment"]:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1796 try:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1797 url = ap_attachment["url"]
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1798 except KeyError:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1799 log.warning(
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1800 f'"url" missing in AP attachment, ignoring: {ap_attachment}'
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1801 )
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1802 continue
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1803
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1804 if not url.startswith("http"):
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1805 log.warning(f"non HTTP URL in attachment, ignoring: {ap_attachment}")
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1806 continue
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1807 attachment = {"url": url}
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1808 for ap_key, key in (
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1809 ("mediaType", "media_type"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1810 # XXX: as weird as it seems, "name" is actually used for description
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1811 # in AP world
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1812 ("name", "desc"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1813 ):
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1814 value = ap_attachment.get(ap_key)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1815 if value:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1816 attachment[key] = value
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1817 attachments.append(attachment)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1818
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1819 # author
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1820 if is_activity:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1821 authors = await self.ap_get_actors(ap_item, "actor")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1822 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1823 authors = await self.ap_get_actors(ap_object, "attributedTo")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1824 if len(authors) > 1:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1825 # we only keep first item as author
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1826 # TODO: handle multiple actors
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1827 log.warning("multiple actors are not managed")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1828
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1829 account = authors[0]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1830 author_jid = self.get_local_jid_from_account(account).full()
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1831
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1832 mb_data["author"] = account.split("@", 1)[0]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1833 mb_data["author_jid"] = author_jid
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1834
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1835 # published/updated
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1836 for field in ("published", "updated"):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1837 value = ap_object.get(field)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1838 if not value and field == "updated":
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1839 value = ap_object.get("published")
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1840 if value:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1841 try:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1842 mb_data[field] = calendar.timegm(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1843 dateutil.parser.parse(str(value)).utctimetuple()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1844 )
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1845 except dateutil.parser.ParserError as e:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1846 log.warning(f"Can't parse {field!r} field: {e}")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1847
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1848 # repeat
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1849 if "_repeated" in ap_item:
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1850 mb_data["extra"]["repeated"] = ap_item["_repeated"]
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
1851
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1852 # comments
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1853 in_reply_to = ap_object.get("inReplyTo")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1854 __, comments_node = await self.get_comments_nodes(item_id, in_reply_to)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1855 if comments_node is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1856 comments_data = {
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1857 "service": author_jid,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1858 "node": comments_node,
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1859 "uri": uri.build_xmpp_uri(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1860 "pubsub",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1861 path=author_jid,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1862 node=comments_node
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1863 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1864 }
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1865 mb_data["comments"] = [comments_data]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1866
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
1867 return mb_data
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
1868
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1869 async def get_reply_to_id_from_xmpp_node(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1870 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1871 client: SatXMPPEntity,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1872 ap_account: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1873 parent_item: str,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1874 mb_data: dict
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1875 ) -> str:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1876 """Get URL to use for ``inReplyTo`` field in AP item.
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1877
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1878 There is currently no way to know the parent service of a comment with XEP-0277.
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1879 To work around that, we try to check if we have this item in the cache (we
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1880 should). If there is more that one item with this ID, we first try to find one
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1881 with this author_jid. If nothing is found, we use ap_account to build `inReplyTo`.
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1882
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1883 @param ap_account: AP account corresponding to the publication author
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1884 @param parent_item: ID of the node where the publication this item is replying to
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1885 has been posted
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1886 @param mb_data: microblog data of the publication
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1887 @return: URL to use in ``inReplyTo`` field
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1888 """
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1889 # FIXME: propose a protoXEP to properly get parent item, node and service
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1890
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1891 found_items = await self.host.memory.storage.search_pubsub_items({
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1892 "profiles": [client.profile],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1893 "names": [parent_item]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1894 })
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1895 if not found_items:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1896 log.warning(f"parent item {parent_item!r} not found in cache")
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1897 parent_ap_account = ap_account
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1898 elif len(found_items) == 1:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1899 cached_node = found_items[0].node
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1900 parent_ap_account = await self.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
1901 cached_node.service,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1902 cached_node.name
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1903 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1904 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1905 # we found several cached item with given ID, we check if there is one
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1906 # corresponding to this author
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1907 try:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1908 author = jid.JID(mb_data["author_jid"]).userhostJID()
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1909 cached_item = next(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1910 i for i in found_items
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1911 if jid.JID(i.data["publisher"]).userhostJID()
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1912 == author
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1913 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1914 except StopIteration:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1915 # no item corresponding to this author, we use ap_account
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1916 log.warning(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1917 "Can't find a single cached item for parent item "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1918 f"{parent_item!r}"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1919 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1920 parent_ap_account = ap_account
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1921 else:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1922 cached_node = cached_item.node
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1923 parent_ap_account = await self.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
1924 cached_node.service,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1925 cached_node.name
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1926 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1927
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1928 return self.build_apurl(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1929 TYPE_ITEM, parent_ap_account, parent_item
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1930 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
1931
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1932 async def repeated_mb_2_ap_item(
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1933 self,
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1934 mb_data: dict
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1935 ) -> dict:
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1936 """Convert repeated blog item to suitable AP Announce activity
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1937
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1938 @param mb_data: microblog metadata of an item repeating an other blog post
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1939 @return: Announce activity linking to the repeated item
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1940 """
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1941 repeated = mb_data["extra"]["repeated"]
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1942 repeater = jid.JID(repeated["by"])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1943 repeater_account = await self.get_ap_account_from_jid_and_node(
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1944 repeater,
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1945 None
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1946 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1947 repeater_id = self.build_apurl(TYPE_ACTOR, repeater_account)
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1948 repeated_uri = repeated["uri"]
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1949
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1950 if not repeated_uri.startswith("xmpp:"):
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1951 log.warning(
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1952 "Only xmpp: URL are handled for repeated item at the moment, ignoring "
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1953 f"item {mb_data}"
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1954 )
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1955 raise NotImplementedError
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1956 parsed_url = uri.parse_xmpp_uri(repeated_uri)
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1957 if parsed_url["type"] != "pubsub":
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1958 log.warning(
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1959 "Only pubsub URL are handled for repeated item at the moment, ignoring "
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1960 f"item {mb_data}"
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1961 )
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1962 raise NotImplementedError
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1963 rep_service = jid.JID(parsed_url["path"])
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1964 rep_item = parsed_url["item"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1965 activity_id = self.build_apurl("item", repeater.userhost(), mb_data["id"])
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1966
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1967 if self.is_virtual_jid(rep_service):
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1968 # it's an AP actor linked through this gateway
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1969 # in this case we can simply use the item ID
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1970 if not rep_item.startswith("https:"):
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1971 log.warning(
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1972 f"Was expecting an HTTPS url as item ID and got {rep_item!r}\n"
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1973 f"{mb_data}"
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1974 )
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1975 announced_uri = rep_item
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1976 repeated_account = self._e.unescape(rep_service.user)
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1977 else:
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1978 # the repeated item is an XMPP publication, we build the corresponding ID
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1979 rep_node = parsed_url["node"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1980 repeated_account = await self.get_ap_account_from_jid_and_node(
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1981 rep_service, rep_node
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1982 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1983 announced_uri = self.build_apurl("item", repeated_account, rep_item)
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1984
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
1985 announce = self.create_activity(
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1986 "Announce", repeater_id, announced_uri, activity_id=activity_id
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1987 )
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1988 announce["to"] = [NS_AP_PUBLIC]
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1989 announce["cc"] = [
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1990 self.build_apurl(TYPE_FOLLOWERS, repeater_account),
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
1991 await self.get_ap_actor_id_from_account(repeated_account)
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1992 ]
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1993 return announce
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
1994
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1995 async def mb_data_2_ap_item(
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
1996 self,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
1997 client: SatXMPPEntity,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
1998 mb_data: dict,
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
1999 public: bool =True,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2000 is_new: bool = True,
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2001 ) -> dict:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2002 """Convert Libervia Microblog Data to ActivityPub item
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2003
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2004 @param mb_data: microblog data (as used in plugin XEP-0277) to convert
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2005 If ``public`` is True, ``service`` and ``node`` keys must be set.
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2006 If ``published`` is not set, current datetime will be used
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2007 @param public: True if the message is not a private/direct one
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2008 if True, the AP Item will be marked as public, and AP followers of target AP
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2009 account (which retrieve from ``service``) will be put in ``cc``.
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2010 ``inReplyTo`` will also be set if suitable
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2011 if False, no destinee will be set (i.e., no ``to`` or ``cc`` or public flag).
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2012 This is usually used for direct messages.
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2013 @param is_new: if True, the item is a new one (no instance has been found in
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2014 cache).
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2015 If True, a "Create" activity will be generated, otherwise an "Update" one will
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2016 be.
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
2017 @return: Activity item
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2018 """
3855
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
2019 extra = mb_data.get("extra", {})
54305ebf5b94 component AP gateway: "repeat" to "Announce" conversion:
Goffi <goffi@goffi.org>
parents: 3853
diff changeset
2020 if "repeated" in extra:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2021 return await self.repeated_mb_2_ap_item(mb_data)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2022 if not mb_data.get("id"):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2023 mb_data["id"] = shortuuid.uuid()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2024 if not mb_data.get("author_jid"):
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2025 mb_data["author_jid"] = client.jid.userhost()
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2026 ap_account = await self.get_ap_account_from_jid_and_node(
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2027 jid.JID(mb_data["author_jid"]),
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2028 None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
2029 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2030 url_actor = self.build_apurl(TYPE_ACTOR, ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2031 url_item = self.build_apurl(TYPE_ITEM, ap_account, mb_data["id"])
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2032 ap_object = {
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2033 "id": url_item,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2034 "type": "Note",
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2035 "published": utils.xmpp_date(mb_data.get("published")),
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2036 "attributedTo": url_actor,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2037 "content": mb_data.get("content_xhtml") or mb_data["content"],
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2038 }
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2039
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2040 language = mb_data.get("language")
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2041 if language:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2042 ap_object["contentMap"] = {language: ap_object["content"]}
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2043
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2044 attachments = extra.get(C.KEY_ATTACHMENTS)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2045 if attachments:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2046 ap_attachments = ap_object["attachment"] = []
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2047 for attachment in attachments:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2048 try:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2049 url = next(
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2050 s['url'] for s in attachment["sources"] if 'url' in s
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2051 )
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2052 except (StopIteration, KeyError):
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2053 log.warning(
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2054 f"Ignoring attachment without URL: {attachment}"
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2055 )
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2056 continue
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2057 ap_attachment = {
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2058 "url": url
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2059 }
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2060 for key, ap_key in (
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2061 ("media_type", "mediaType"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2062 # XXX: yes "name", cf. [ap_item_2_mb_data]
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2063 ("desc", "name"),
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2064 ):
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2065 value = attachment.get(key)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2066 if value:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2067 ap_attachment[ap_key] = value
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2068 ap_attachments.append(ap_attachment)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2069
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2070 if public:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2071 ap_object["to"] = [NS_AP_PUBLIC]
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2072 if self.auto_mentions:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2073 for m in RE_MENTION.finditer(ap_object["content"]):
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2074 mention = m.group()
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2075 mentioned = mention[1:]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2076 __, m_host = mentioned.split("@", 1)
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2077 if m_host in (self.public_url, self.client.jid.host):
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2078 # we ignore mention of local users, they should be sent as XMPP
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2079 # references
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2080 continue
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2081 try:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2082 mentioned_id = await self.get_ap_actor_id_from_account(mentioned)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2083 except Exception as e:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2084 log.warning(f"Can't add mention to {mentioned!r}: {e}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2085 else:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2086 ap_object["to"].append(mentioned_id)
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2087 ap_object.setdefault("tag", []).append({
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2088 "type": TYPE_MENTION,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2089 "href": mentioned_id,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2090 "name": mention,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2091 })
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2092 try:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2093 node = mb_data["node"]
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2094 service = jid.JID(mb_data["service"])
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2095 except KeyError:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2096 # node and service must always be specified when this method is used
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2097 raise exceptions.InternalError(
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2098 "node or service is missing in mb_data"
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2099 )
4094
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2100 try:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2101 target_ap_account = await self.get_ap_account_from_jid_and_node(
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2102 service, node
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2103 )
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2104 except MissingLocalPartError:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2105 # we have no local part, this is probably a comment
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2106 try:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2107 service = jid.JID(mb_data["author_jid"])
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2108 if not mb_data["author_jid_verified"]:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2109 raise KeyError
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2110 except KeyError:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2111 raise exceptions.DataError(
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2112 "Can't identify post author. Be sure to use a pubsub service "
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2113 "setting the 'publisher' attribute."
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2114 )
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2115 else:
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2116 target_ap_account = await self.get_ap_account_from_jid_and_node(
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2117 service, node
c3b68fdc2de7 component AP gateway: fix handling of XMPP comments authors:
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
2118 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2119 if self.is_virtual_jid(service):
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2120 # service is a proxy JID for AP account
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2121 actor_data = await self.get_ap_actor_data_from_account(target_ap_account)
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2122 followers = actor_data.get("followers")
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2123 else:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2124 # service is a real XMPP entity
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2125 followers = self.build_apurl(TYPE_FOLLOWERS, target_ap_account)
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2126 if followers:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2127 ap_object["cc"] = [followers]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2128 if self._m.is_comment_node(node):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2129 parent_item = self._m.get_parent_item(node)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2130 if self.is_virtual_jid(service):
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2131 # the publication is on a virtual node (i.e. an XMPP node managed by
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2132 # this gateway and linking to an ActivityPub actor)
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2133 ap_object["inReplyTo"] = parent_item
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2134 else:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2135 # the publication is from a followed real XMPP node
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2136 ap_object["inReplyTo"] = await self.get_reply_to_id_from_xmpp_node(
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2137 client,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2138 ap_account,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2139 parent_item,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2140 mb_data
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2141 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2142
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2143 return self.create_activity(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2144 "Create" if is_new else "Update", url_actor, ap_object, activity_id=url_item
3845
4f9d4650eab5 component AP gateway: use `createActivity` in `mbdata2APitem`
Goffi <goffi@goffi.org>
parents: 3844
diff changeset
2145 )
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2146
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2147 async def publish_message(
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2148 self,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2149 client: SatXMPPEntity,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2150 mess_data: dict,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2151 service: jid.JID
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2152 ) -> None:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2153 """Send an AP message
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2154
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2155 .. note::
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2156
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2157 This is a temporary method used for development only
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2158
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2159 @param mess_data: message data. Following keys must be set:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2160
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2161 ``node``
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2162 identifier of message which is being replied (this will
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2163 correspond to pubsub node in the future)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2164
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2165 ``content_xhtml`` or ``content``
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2166 message body (respectively in XHTML or plain text)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2167
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2168 @param service: JID corresponding to the AP actor.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2169 """
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2170 if not service.user:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2171 raise ValueError("service must have a local part")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2172 account = self._e.unescape(service.user)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2173 ap_actor_data = await self.get_ap_actor_data_from_account(account)
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2174
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2175 try:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2176 inbox_url = ap_actor_data["endpoints"]["sharedInbox"]
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2177 except KeyError:
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2178 raise exceptions.DataError("Can't get ActivityPub actor inbox")
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2179
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2180 item_data = await self.mb_data_2_ap_item(client, mess_data)
3852
384ad98ea9fe component AP gateway: we need to use `actor` and not `attributedTo` for activities:
Goffi <goffi@goffi.org>
parents: 3851
diff changeset
2181 url_actor = item_data["actor"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2182 resp = await self.sign_and_post(inbox_url, url_actor, item_data)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2183
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2184 async def ap_delete_item(
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2185 self,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2186 jid_: jid.JID,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2187 node: Optional[str],
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2188 item_id: str,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2189 public: bool = True
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2190 ) -> Tuple[str, Dict[str, Any]]:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2191 """Build activity to delete an AP item
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2192
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2193 @param jid_: JID of the entity deleting an item
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2194 @param node: node where the item is deleted
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2195 None if it's microblog or a message
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2196 @param item_id: ID of the item to delete
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2197 it's the Pubsub ID or message's origin ID
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2198 @param public: if True, the activity will be addressed to public namespace
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2199 @return: actor_id of the entity deleting the item, activity to send
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2200 """
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2201 if node is None:
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2202 node = self._m.namespace
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2203
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2204 author_account = await self.get_ap_account_from_jid_and_node(jid_, node)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2205 author_actor_id = self.build_apurl(TYPE_ACTOR, author_account)
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2206
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2207 items = await self.host.memory.storage.search_pubsub_items({
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2208 "profiles": [self.client.profile],
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2209 "services": [jid_],
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2210 "names": [item_id]
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2211 })
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2212 if not items:
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2213 log.warning(
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2214 f"Deleting an unknown item at service {jid_}, node {node} and id "
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2215 f"{item_id}"
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2216 )
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2217 else:
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2218 try:
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2219 mb_data = await self._m.item_2_mb_data(self.client, items[0].data, jid_, node)
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2220 if "repeated" in mb_data["extra"]:
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2221 # we are deleting a repeated item, we must translate this to an
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2222 # "Undo" of the "Announce" activity instead of a "Delete" one
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2223 announce = await self.repeated_mb_2_ap_item(mb_data)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2224 undo = self.create_activity("Undo", author_actor_id, announce)
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2225 return author_actor_id, undo
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2226 except Exception as e:
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2227 log.debug(
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2228 f"Can't parse item, maybe it's not a blog item: {e}\n"
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2229 f"{items[0].toXml()}"
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2230 )
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2231
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2232 url_item = self.build_apurl(TYPE_ITEM, author_account, item_id)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2233 ap_item = self.create_activity(
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2234 "Delete",
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2235 author_actor_id,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2236 {
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2237 "id": url_item,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2238 "type": TYPE_TOMBSTONE
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2239 }
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2240 )
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2241 if public:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2242 ap_item["to"] = [NS_AP_PUBLIC]
3856
bc7f9d0a404f component AP gateway: when a repeated blog post is retracted, it converted to suitable Activity:
Goffi <goffi@goffi.org>
parents: 3855
diff changeset
2243 return author_actor_id, ap_item
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2244
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2245 def _message_received_trigger(
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2246 self,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2247 client: SatXMPPEntity,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2248 message_elt: domish.Element,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2249 post_treat: defer.Deferred
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2250 ) -> bool:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2251 """add the gateway workflow on post treatment"""
3979
996e0f84935e component AP gateway: log at debug level instead of warning when no client is set
Goffi <goffi@goffi.org>
parents: 3977
diff changeset
2252 if self.client is None:
996e0f84935e component AP gateway: log at debug level instead of warning when no client is set
Goffi <goffi@goffi.org>
parents: 3977
diff changeset
2253 log.debug(f"no client set, ignoring message: {message_elt.toXml()}")
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2254 return True
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2255 post_treat.addCallback(
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2256 lambda mess_data: defer.ensureDeferred(self.onMessage(client, mess_data))
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2257 )
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2258 return True
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2259
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2260 async def onMessage(self, client: SatXMPPEntity, mess_data: dict) -> dict:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2261 """Called once message has been parsed
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2262
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2263 this method handle the conversion to AP items and posting
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2264 """
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2265 if client != self.client:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2266 return mess_data
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2267 if mess_data["type"] not in ("chat", "normal"):
3853
a56d5ad466b3 component AP gateway: fix wrong exception + use of mb_data["xml"] when it may be absent
Goffi <goffi@goffi.org>
parents: 3852
diff changeset
2268 log.warning(f"ignoring message with unexpected type: {mess_data}")
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2269 return mess_data
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2270 if not self.is_local(mess_data["from"]):
3853
a56d5ad466b3 component AP gateway: fix wrong exception + use of mb_data["xml"] when it may be absent
Goffi <goffi@goffi.org>
parents: 3852
diff changeset
2271 log.warning(f"ignoring non local message: {mess_data}")
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2272 return mess_data
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2273 if not mess_data["to"].user:
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2274 log.warning(
3853
a56d5ad466b3 component AP gateway: fix wrong exception + use of mb_data["xml"] when it may be absent
Goffi <goffi@goffi.org>
parents: 3852
diff changeset
2275 f"ignoring message addressed to gateway itself: {mess_data}"
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2276 )
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2277 return mess_data
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2278
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2279 actor_account = self._e.unescape(mess_data["to"].user)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2280 actor_id = await self.get_ap_actor_id_from_account(actor_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2281 inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False)
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2282
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2283 try:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2284 language, message = next(iter(mess_data["message"].items()))
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2285 except (KeyError, StopIteration):
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2286 log.warning(f"ignoring empty message: {mess_data}")
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2287 return mess_data
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2288
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2289 mb_data = {
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2290 "content": message,
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2291 }
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2292 if language:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2293 mb_data["language"] = language
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2294 origin_id = mess_data["extra"].get("origin_id")
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2295 if origin_id:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2296 # we need to use origin ID when present to be able to retract the message
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2297 mb_data["id"] = origin_id
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2298 attachments = mess_data["extra"].get(C.KEY_ATTACHMENTS)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2299 if attachments:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2300 mb_data["extra"] = {
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2301 C.KEY_ATTACHMENTS: attachments
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2302 }
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2303
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2304 client = self.client.get_virtual_client(mess_data["from"])
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2305 ap_item = await self.mb_data_2_ap_item(client, mb_data, public=False)
4017
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2306 ap_object = ap_item["object"]
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2307 ap_object["to"] = ap_item["to"] = [actor_id]
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2308 # we add a mention to direct message, otherwise peer is not notified in some AP
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2309 # implementations (notably Mastodon), and the message may be missed easily.
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2310 ap_object.setdefault("tag", []).append({
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2311 "type": TYPE_MENTION,
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2312 "href": actor_id,
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2313 "name": f"@{actor_account}",
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2314 })
4a2c261646b6 component AP gateway: add mention to direct messages:
Goffi <goffi@goffi.org>
parents: 4014
diff changeset
2315
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2316 await self.sign_and_post(inbox, ap_item["actor"], ap_item)
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2317 return mess_data
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2318
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2319 async def _on_message_retract(
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2320 self,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2321 client: SatXMPPEntity,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2322 message_elt: domish.Element,
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2323 retract_elt: domish.Element,
4166
a1f7040b5a15 plugin XEP-0424: message retraction update:
Goffi <goffi@goffi.org>
parents: 4109
diff changeset
2324 history: History
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2325 ) -> bool:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2326 if client != self.client:
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2327 return True
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2328 from_jid = jid.JID(message_elt["from"])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2329 if not self.is_local(from_jid):
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2330 log.debug(
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2331 f"ignoring retract request from non local jid {from_jid}"
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2332 )
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2333 return False
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2334 to_jid = jid.JID(message_elt["to"])
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2335 if (to_jid.host != self.client.jid.full() or not to_jid.user):
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2336 # to_jid should be a virtual JID from this gateway
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2337 raise exceptions.InternalError(
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2338 f"Invalid destinee's JID: {to_jid.full()}"
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2339 )
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2340 ap_account = self._e.unescape(to_jid.user)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2341 actor_id = await self.get_ap_actor_id_from_account(ap_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2342 inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2343 url_actor, ap_item = await self.ap_delete_item(
4166
a1f7040b5a15 plugin XEP-0424: message retraction update:
Goffi <goffi@goffi.org>
parents: 4109
diff changeset
2344 from_jid.userhostJID(), None, retract_elt["id"], public=False
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2345 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2346 resp = await self.sign_and_post(inbox, url_actor, ap_item)
3803
d5f343939239 component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents: 3793
diff changeset
2347 return False
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2348
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2349 async def _on_reference_received(
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2350 self,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2351 client: SatXMPPEntity,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2352 message_elt: domish.Element,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2353 reference_data: Dict[str, Union[str, int]]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2354 ) -> bool:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2355 parsed_uri: dict = reference_data.get("parsed_uri")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2356 if not parsed_uri:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2357 log.warning(f"no parsed URI available in reference {reference_data}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2358 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2359
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2360 try:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2361 mentioned = jid.JID(parsed_uri["path"])
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2362 except RuntimeError:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2363 log.warning(f"invalid target: {reference_data['uri']}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2364 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2365
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2366 if mentioned.host != self.client.jid.full() or not mentioned.user:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2367 log.warning(
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2368 f"ignoring mentioned user {mentioned}, it's not a JID mapping an AP "
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2369 "account"
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2370 )
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2371 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2372
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2373 ap_account = self._e.unescape(mentioned.user)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2374 actor_id = await self.get_ap_actor_id_from_account(ap_account)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2375
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2376 parsed_anchor: dict = reference_data.get("parsed_anchor")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2377 if not parsed_anchor:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2378 log.warning(f"no XMPP anchor, ignoring reference {reference_data!r}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2379 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2380
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2381 if parsed_anchor["type"] != "pubsub":
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2382 log.warning(
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2383 f"ignoring reference with non pubsub anchor, this is not supported: "
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2384 "{reference_data!r}"
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2385 )
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2386 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2387
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2388 try:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2389 pubsub_service = jid.JID(parsed_anchor["path"])
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2390 except RuntimeError:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2391 log.warning(f"invalid anchor: {reference_data['anchor']}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2392 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2393 pubsub_node = parsed_anchor.get("node")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2394 if not pubsub_node:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2395 log.warning(f"missing pubsub node in anchor: {reference_data['anchor']}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2396 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2397 pubsub_item = parsed_anchor.get("item")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2398 if not pubsub_item:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2399 log.warning(f"missing pubsub item in anchor: {reference_data['anchor']}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2400 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2401
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2402 cached_node = await self.host.memory.storage.get_pubsub_node(
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2403 client, pubsub_service, pubsub_node
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2404 )
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2405 if not cached_node:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2406 log.warning(f"Anchored node not found in cache: {reference_data['anchor']}")
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2407 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2408
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2409 cached_items, __ = await self.host.memory.storage.get_items(
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2410 cached_node, item_ids=[pubsub_item]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2411 )
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2412 if not cached_items:
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2413 log.warning(
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2414 f"Anchored pubsub item not found in cache: {reference_data['anchor']}"
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2415 )
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2416 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2417
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2418 cached_item = cached_items[0]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2419
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2420 mb_data = await self._m.item_2_mb_data(
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2421 client, cached_item.data, pubsub_service, pubsub_node
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2422 )
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2423 ap_item = await self.mb_data_2_ap_item(client, mb_data)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2424 ap_object = ap_item["object"]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2425 ap_object["to"] = [actor_id]
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2426 ap_object.setdefault("tag", []).append({
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2427 "type": TYPE_MENTION,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2428 "href": actor_id,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2429 "name": ap_account,
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2430 })
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2431
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2432 inbox = await self.get_ap_inbox_from_id(actor_id, use_shared=False)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2433
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2434 resp = await self.sign_and_post(inbox, ap_item["actor"], ap_item)
3833
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2435
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2436 return False
381340b9a9ee component AP gateway: convert XMPP mentions to AP:
Goffi <goffi@goffi.org>
parents: 3832
diff changeset
2437
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2438 async def new_reply_to_xmpp_item(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2439 self,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2440 client: SatXMPPEntity,
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2441 ap_item: dict,
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2442 targets: Dict[str, Set[str]],
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2443 mentions: List[Dict[str, str]],
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2444 ) -> None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2445 """We got an AP item which is a reply to an XMPP item"""
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2446 in_reply_to = ap_item["inReplyTo"]
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2447 url_type, url_args = self.parse_apurl(in_reply_to)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2448 if url_type != "item":
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2449 log.warning(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2450 "Ignoring AP item replying to an XMPP item with an unexpected URL "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2451 f"type({url_type!r}):\n{pformat(ap_item)}"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2452 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2453 return
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2454 try:
4013
b13673d998dc component AP gateway: fix bad use of `parseAPURL` return data:
Goffi <goffi@goffi.org>
parents: 3994
diff changeset
2455 parent_item_account, parent_item_id = url_args[0], '/'.join(url_args[1:])
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2456 except (IndexError, ValueError):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2457 log.warning(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2458 "Ignoring AP item replying to an XMPP item with invalid inReplyTo URL "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2459 f"({in_reply_to!r}):\n{pformat(ap_item)}"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2460 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2461 return
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2462 parent_item_service, parent_item_node = await self.get_jid_and_node(
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2463 parent_item_account
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2464 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2465 if parent_item_node is None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2466 parent_item_node = self._m.namespace
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2467 items, __ = await self._p.get_items(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2468 client, parent_item_service, parent_item_node, item_ids=[parent_item_id]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2469 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2470 try:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2471 parent_item_elt = items[0]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2472 except IndexError:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2473 log.warning(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2474 f"Can't find parent item at {parent_item_service} (node "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2475 f"{parent_item_node!r})\n{pformat(ap_item)}")
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2476 return
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2477 parent_item_parsed = await self._m.item_2_mb_data(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2478 client, parent_item_elt, parent_item_service, parent_item_node
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2479 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2480 try:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2481 comment_service = jid.JID(parent_item_parsed["comments"][0]["service"])
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2482 comment_node = parent_item_parsed["comments"][0]["node"]
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2483 except (KeyError, IndexError):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2484 # we don't have a comment node set for this item
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4051
diff changeset
2485 from libervia.backend.tools.xml_tools import pp_elt
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2486 log.info(f"{pp_elt(parent_item_elt.toXml())}")
3853
a56d5ad466b3 component AP gateway: fix wrong exception + use of mb_data["xml"] when it may be absent
Goffi <goffi@goffi.org>
parents: 3852
diff changeset
2487 raise NotImplementedError()
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2488 else:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2489 __, item_elt = await self.ap_item_2_mb_data_and_elt(ap_item)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2490 await self._p.publish(client, comment_service, comment_node, [item_elt])
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2491 await self.notify_mentions(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2492 targets, mentions, comment_service, comment_node, item_elt["id"]
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2493 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2494
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2495 def get_ap_item_targets(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2496 self,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2497 item: Dict[str, Any]
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2498 ) -> Tuple[bool, Dict[str, Set[str]], List[Dict[str, str]]]:
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2499 """Retrieve targets of an AP item, and indicate if it's a public one
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2500
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2501 @param item: AP object payload
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2502 @return: Are returned:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2503 - is_public flag, indicating if the item is world-readable
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2504 - a dict mapping target type to targets
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2505 """
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2506 targets: Dict[str, Set[str]] = {}
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2507 is_public = False
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2508 # TODO: handle "audience"
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2509 for key in ("to", "bto", "cc", "bcc"):
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2510 values = item.get(key)
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2511 if not values:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2512 continue
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2513 if isinstance(values, str):
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2514 values = [values]
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2515 for value in values:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2516 if value in PUBLIC_TUPLE:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2517 is_public = True
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2518 continue
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2519 if not value:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2520 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2521 if not self.is_local_url(value):
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2522 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2523 target_type = self.parse_apurl(value)[0]
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2524 if target_type != TYPE_ACTOR:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2525 log.debug(f"ignoring non actor type as a target: {href}")
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2526 else:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2527 targets.setdefault(target_type, set()).add(value)
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2528
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2529 mentions = []
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2530 tags = item.get("tag")
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2531 if tags:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2532 for tag in tags:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2533 if tag.get("type") != TYPE_MENTION:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2534 continue
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2535 href = tag.get("href")
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2536 if not href:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2537 log.warning('Missing "href" field from mention object: {tag!r}')
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2538 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2539 if not self.is_local_url(href):
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2540 continue
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2541 uri_type = self.parse_apurl(href)[0]
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2542 if uri_type != TYPE_ACTOR:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2543 log.debug(f"ignoring non actor URI as a target: {href}")
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2544 continue
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2545 mention = {"uri": href}
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2546 mentions.append(mention)
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2547 name = tag.get("name")
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2548 if name:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2549 mention["content"] = name
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2550
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2551 return is_public, targets, mentions
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2552
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2553 async def new_ap_item(
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2554 self,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2555 client: SatXMPPEntity,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2556 destinee: Optional[jid.JID],
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2557 node: str,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2558 item: dict,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2559 ) -> None:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2560 """Analyse, cache and send notification for received AP item
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2561
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2562 @param destinee: jid of the destinee,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2563 @param node: XMPP pubsub node
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2564 @param item: AP object payload
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2565 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2566 is_public, targets, mentions = self.get_ap_item_targets(item)
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2567 if not is_public and targets.keys() == {TYPE_ACTOR}:
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2568 # this is a direct message
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2569 await self.handle_message_ap_item(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2570 client, targets, mentions, destinee, item
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2571 )
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2572 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2573 await self.handle_pubsub_ap_item(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2574 client, targets, mentions, destinee, node, item, is_public
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2575 )
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2576
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2577 async def handle_message_ap_item(
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2578 self,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2579 client: SatXMPPEntity,
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2580 targets: Dict[str, Set[str]],
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2581 mentions: List[Dict[str, str]],
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2582 destinee: Optional[jid.JID],
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2583 item: dict,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2584 ) -> None:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2585 """Parse and deliver direct AP items translating to XMPP messages
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2586
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2587 @param targets: actors where the item must be delivered
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2588 @param destinee: jid of the destinee,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2589 @param item: AP object payload
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2590 """
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2591 targets_jids = {
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2592 await self.get_jid_from_id(t)
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2593 for t_set in targets.values()
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2594 for t in t_set
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2595 }
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2596 if destinee is not None:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2597 targets_jids.add(destinee)
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2598 mb_data = await self.ap_item_2_mb_data(item)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2599 extra = {
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2600 "origin_id": mb_data["id"]
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2601 }
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2602 attachments = mb_data["extra"].get(C.KEY_ATTACHMENTS)
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2603 if attachments:
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2604 extra[C.KEY_ATTACHMENTS] = attachments
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2605
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2606 defer_l = []
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2607 for target_jid in targets_jids:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2608 defer_l.append(
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2609 client.sendMessage(
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2610 target_jid,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2611 {'': mb_data.get("content", "")},
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2612 mb_data.get("title"),
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 4017
diff changeset
2613 extra=extra
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2614 )
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2615 )
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2616 await defer.DeferredList(defer_l)
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2617
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2618 async def notify_mentions(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2619 self,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2620 targets: Dict[str, Set[str]],
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2621 mentions: List[Dict[str, str]],
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2622 service: jid.JID,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2623 node: str,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2624 item_id: str,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2625 ) -> None:
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2626 """Send mention notifications to recipients and mentioned entities
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2627
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2628 XEP-0372 (References) is used.
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2629
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2630 Mentions are also sent to recipients as they are primary audience (see
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2631 https://www.w3.org/TR/activitystreams-vocabulary/#microsyntaxes).
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2632
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2633 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2634 anchor = uri.build_xmpp_uri("pubsub", path=service.full(), node=node, item=item_id)
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2635 seen = set()
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2636 # we start with explicit mentions because mentions' content will be used in the
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2637 # future to fill "begin" and "end" reference attributes (we can't do it at the
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2638 # moment as there is no way to specify the XML element to use in the blog item).
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2639 for mention in mentions:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2640 mentioned_jid = await self.get_jid_from_id(mention["uri"])
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2641 self._refs.send_reference(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2642 self.client,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2643 to_jid=mentioned_jid,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2644 anchor=anchor
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2645 )
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2646 seen.add(mentioned_jid)
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2647
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2648 remaining = {
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2649 await self.get_jid_from_id(t)
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2650 for t_set in targets.values()
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2651 for t in t_set
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2652 } - seen
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2653 for target in remaining:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2654 self._refs.send_reference(
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2655 self.client,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2656 to_jid=target,
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2657 anchor=anchor
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2658 )
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2659
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2660 async def handle_pubsub_ap_item(
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2661 self,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2662 client: SatXMPPEntity,
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2663 targets: Dict[str, Set[str]],
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2664 mentions: List[Dict[str, str]],
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2665 destinee: Optional[jid.JID],
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2666 node: str,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2667 item: dict,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2668 public: bool
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2669 ) -> None:
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2670 """Analyse, cache and deliver AP items translating to Pubsub
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2671
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2672 @param targets: actors/collections where the item must be delivered
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2673 @param destinee: jid of the destinee,
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2674 @param node: XMPP pubsub node
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2675 @param item: AP object payload
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2676 @param public: True if the item is public
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2677 """
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2678 # XXX: "public" is not used for now
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2679 service = client.jid
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2680 in_reply_to = item.get("inReplyTo")
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2681
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2682 if in_reply_to and isinstance(in_reply_to, list):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2683 in_reply_to = in_reply_to[0]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2684 if in_reply_to and isinstance(in_reply_to, str):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2685 if self.is_local_url(in_reply_to):
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2686 # this is a reply to an XMPP item
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2687 await self.new_reply_to_xmpp_item(client, item, targets, mentions)
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2688 return
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2689
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2690 # this item is a reply to an AP item, we use or create a corresponding node
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2691 # for comments
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2692 parent_node, __ = await self.get_comments_nodes(item["id"], in_reply_to)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2693 node = parent_node or node
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2694 cached_node = await self.host.memory.storage.get_pubsub_node(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
2695 client, service, node, with_subscriptions=True, create=True,
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3856
diff changeset
2696 create_kwargs={"subscribed": True}
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2697 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2698 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2699 # it is a root item (i.e. not a reply to an other item)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2700 create = node == self._events.namespace
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2701 cached_node = await self.host.memory.storage.get_pubsub_node(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2702 client, service, node, with_subscriptions=True, create=create
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2703 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2704 if cached_node is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2705 log.warning(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2706 f"Received item in unknown node {node!r} at {service}. This may be "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
2707 f"due to a cache purge. We synchronise the node\n{item}"
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2708
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2709 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2710 return
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2711 if item.get("type") == TYPE_EVENT:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2712 data, item_elt = await self.ap_events.ap_item_2_event_data_and_elt(item)
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2713 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2714 data, item_elt = await self.ap_item_2_mb_data_and_elt(item)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2715 await self.host.memory.storage.cache_pubsub_items(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2716 client,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2717 cached_node,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2718 [item_elt],
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
2719 [data]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2720 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2721
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2722 for subscription in cached_node.subscriptions:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2723 if subscription.state != SubscriptionState.SUBSCRIBED:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2724 continue
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2725 self.pubsub_service.notifyPublish(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2726 service,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2727 node,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2728 [(subscription.subscriber, None, [item_elt])]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3742
diff changeset
2729 )
3784
efc34a89e70b comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
2730
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2731 await self.notify_mentions(targets, mentions, service, node, item_elt["id"])
3832
201a22bfbb74 component AP gateway: convert AP mention to XEP-0372 mentions:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
2732
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2733 async def new_ap_delete_item(
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2734 self,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2735 client: SatXMPPEntity,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2736 destinee: Optional[jid.JID],
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2737 node: str,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2738 item: dict,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2739 ) -> None:
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2740 """Analyse, cache and send notification for received AP item
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2741
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2742 @param destinee: jid of the destinee,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2743 @param node: XMPP pubsub node
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2744 @param activity: parent AP activity
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2745 @param item: AP object payload
3844
65e5718e7710 component AP gateway: `Announce` activity implementation:
Goffi <goffi@goffi.org>
parents: 3843
diff changeset
2746 only the "id" field is used
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2747 """
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2748 item_id = item.get("id")
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2749 if not item_id:
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2750 raise exceptions.DataError('"id" attribute is missing in item')
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2751 if not item_id.startswith("http"):
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2752 raise exceptions.DataError(f"invalid id: {item_id!r}")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2753 if self.is_local_url(item_id):
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2754 raise ValueError("Local IDs should not be used")
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2755
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2756 # we have no way to know if a deleted item is a direct one (thus a message) or one
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2757 # converted to pubsub. We check if the id is in message history to decide what to
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2758 # do.
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2759 history = await self.host.memory.storage.get(
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2760 client,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2761 History,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2762 History.origin_id,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2763 item_id,
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2764 (History.messages, History.subjects)
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2765 )
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2766
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2767 if history is not None:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2768 # it's a direct message
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2769 if history.source_jid != client.jid:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2770 log.warning(
3807
2032826cfbcf component AP gateway typing + remove unused `activity` arg from `newAPDeleteItem`
Goffi <goffi@goffi.org>
parents: 3804
diff changeset
2771 f"retraction received from an entity ''{client.jid}) which is "
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2772 f"not the original sender of the message ({history.source_jid}), "
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2773 "hack attemps?"
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2774 )
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2775 raise exceptions.PermissionError("forbidden")
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2776
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2777 await self._r.retract_by_history(client, history)
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2778 else:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2779 # no history in cache with this ID, it's probably a pubsub item
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2780 cached_node = await self.host.memory.storage.get_pubsub_node(
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2781 client, client.jid, node, with_subscriptions=True
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2782 )
3804
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2783 if cached_node is None:
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2784 log.warning(
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2785 f"Received an item retract for node {node!r} at {client.jid} "
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2786 "which is not cached"
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2787 )
36b167ddbfca component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents: 3803
diff changeset
2788 raise exceptions.NotFound
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4027
diff changeset
2789 await self.host.memory.storage.delete_pubsub_items(cached_node, [item_id])
3793
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2790 # notifyRetract is expecting domish.Element instances
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2791 item_elt = domish.Element((None, "item"))
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2792 item_elt["id"] = item_id
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2793 for subscription in cached_node.subscriptions:
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2794 if subscription.state != SubscriptionState.SUBSCRIBED:
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2795 continue
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2796 self.pubsub_service.notifyRetract(
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2797 client.jid,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2798 node,
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2799 [(subscription.subscriber, None, [item_elt])]
b5c9021020df component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
2800 )