annotate libervia/backend/plugins/plugin_comp_ap_gateway/__init__.py @ 4183:6784d07b99c8

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