Mercurial > libervia-backend
annotate sat/plugins/plugin_comp_ap_gateway/__init__.py @ 3804:36b167ddbfca
component AP gateway: AP delete activity => message retract:
handle retractation of messages. As it is not possible to know from the AP item alone if
we need to to a message retractation (XEP-0424) or a pubsub retractation (XEP-0060), we
now cache sent message, and decide which method to use according to how the item is cached
(i.e. in message history or in pubsub cache).
rel 367
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 17 Jun 2022 14:15:23 +0200 |
parents | d5f343939239 |
children | 2032826cfbcf |
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 ( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
27 Any, Dict, List, Set, Optional, Tuple, Union, Callable, Awaitable, overload |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
28 ) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
29 from urllib import parse |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
30 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
31 from cryptography.exceptions import InvalidSignature |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 from cryptography.hazmat.primitives import serialization |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
33 from cryptography.hazmat.primitives import hashes |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
34 from cryptography.hazmat.primitives.asymmetric import rsa |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 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
|
36 import dateutil |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
37 import shortuuid |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
38 from sqlalchemy.exc import IntegrityError |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 import treq |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 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
|
41 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
|
42 from twisted.web import http |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
43 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
|
44 from twisted.words.xish import domish |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
45 from wokkel import rsm |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
46 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
47 from sat.core import exceptions |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 from sat.core.constants import Const as C |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
49 from sat.core.core_types import SatXMPPEntity |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
50 from sat.core.i18n import _ |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 from sat.core.log import getLogger |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
52 from sat.memory.sqla_mapping import SubscriptionState, History |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 from sat.tools import utils |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
54 from sat.tools.common import data_format, tls, uri |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
55 from sat.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
|
56 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
57 from .constants import ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
58 ACTIVITY_OBJECT_MANDATORY, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
59 ACTIVITY_TARGET_MANDATORY, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
60 ACTIVITY_TYPES, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
61 ACTIVITY_TYPES_LOWER, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
62 AP_MB_MAP, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
63 COMMENTS_MAX_PARENTS, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
64 CONF_SECTION, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
65 IMPORT_NAME, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
66 LRU_MAX_SIZE, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
67 MEDIA_TYPE_AP, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
68 TYPE_ACTOR, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
69 TYPE_ITEM, |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
70 TYPE_FOLLOWERS, |
3792
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
71 TYPE_TOMBSTONE, |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
72 NS_AP_PUBLIC, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
73 PUBLIC_TUPLE |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
74 ) |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
75 from .http_server import HTTPServer |
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
76 from .pubsub_service import APPubsubService |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
78 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
79 log = getLogger(__name__) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
81 IMPORT_NAME = "ap-gateway" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
82 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
83 PLUGIN_INFO = { |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
84 C.PI_NAME: "ActivityPub Gateway component", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
85 C.PI_IMPORT_NAME: IMPORT_NAME, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
86 C.PI_MODES: [C.PLUG_MODE_COMPONENT], |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
88 C.PI_PROTOCOLS: [], |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
89 C.PI_DEPENDENCIES: [ |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
90 "XEP-0060", "XEP-0106", "XEP-0277", "XEP-0329", "XEP-0424", "XEP-0465", |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
91 "PUBSUB_CACHE", "TEXT_SYNTAXES" |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
92 ], |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
93 C.PI_RECOMMENDATIONS: [], |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
94 C.PI_MAIN: "APGateway", |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
95 C.PI_HANDLER: C.BOOL_TRUE, |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
96 C.PI_DESCRIPTION: _( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
97 "Gateway for bidirectional communication between XMPP and ActivityPub." |
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 } |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
100 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 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
|
105 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
106 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
107 class APGateway: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
108 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
109 def __init__(self, host): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
110 self.host = host |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
111 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
|
112 self.client = None |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
113 self._m = host.plugins["XEP-0277"] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
114 self._p = host.plugins["XEP-0060"] |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
115 self._e = host.plugins["XEP-0106"] |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
116 self._r = host.plugins["XEP-0424"] |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
117 self._pps = host.plugins["XEP-0465"] |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
118 self._c = host.plugins["PUBSUB_CACHE"] |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
119 self._p.addManagedNode( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
120 "", items_cb=self._itemsReceived |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
121 ) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
122 self._t = host.plugins["TEXT_SYNTAXES"] |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
123 self.pubsub_service = APPubsubService(self) |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
124 host.trigger.add("messageReceived", self._messageReceivedTrigger, priority=-1000) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
125 host.trigger.add("XEP-0424_retractReceived", self._onMessageRetract) |
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 host.bridge.addMethod( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
128 "APSend", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
129 ".plugin", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
130 in_sign="sss", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
131 out_sign="", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
132 method=self._publishMessage, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
133 async_=True, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
134 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
135 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
136 def getHandler(self, __): |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
137 return self.pubsub_service |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
138 |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
139 async def init(self, client): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
140 if self.initialised: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
141 return |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
142 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
143 self.initialised = True |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
144 log.info(_("ActivityPub Gateway initialization")) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
145 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
146 # RSA keys |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
147 stored_data = await self.host.memory.storage.getPrivates( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
148 IMPORT_NAME, ["rsa_key"], profile=client.profile |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
149 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
150 private_key_pem = stored_data.get("rsa_key") |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
151 if private_key_pem is None: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
152 self.private_key = await threads.deferToThread( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
153 rsa.generate_private_key, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
154 public_exponent=65537, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
155 key_size=4096, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
156 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
157 private_key_pem = self.private_key.private_bytes( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
158 encoding=serialization.Encoding.PEM, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
159 format=serialization.PrivateFormat.PKCS8, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
160 encryption_algorithm=serialization.NoEncryption() |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
161 ).decode() |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
162 await self.host.memory.storage.setPrivateValue( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
163 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
|
164 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
165 else: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
166 self.private_key = serialization.load_pem_private_key( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
167 private_key_pem.encode(), |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
168 password=None, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
169 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
170 self.public_key = self.private_key.public_key() |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
171 self.public_key_pem = self.public_key.public_bytes( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
172 encoding=serialization.Encoding.PEM, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
173 format=serialization.PublicFormat.SubjectPublicKeyInfo |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
174 ).decode() |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
175 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
176 # params |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
177 # URL and port |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
178 self.public_url = self.host.memory.getConfig( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
179 CONF_SECTION, "public_url" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
180 ) or self.host.memory.getConfig( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
181 CONF_SECTION, "xmpp_domain" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
182 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
183 if self.public_url is None: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
184 log.error( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
185 '"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
|
186 "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
|
187 f"url in {CONF_SECTION!r} configuration section." |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
188 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
189 return |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
190 if parse.urlparse(self.public_url).scheme: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
191 log.error( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
192 "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
|
193 "\"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
|
194 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
195 return |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
196 self.http_port = int(self.host.memory.getConfig( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
197 CONF_SECTION, 'http_port', 8123)) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
198 connection_type = self.host.memory.getConfig( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
199 CONF_SECTION, 'http_connection_type', 'https') |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
200 if connection_type not in ('http', 'https'): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
201 raise exceptions.ConfigError( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
202 '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
|
203 '"https"' |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
204 ) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
205 self.max_items = int(self.host.memory.getConfig( |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
206 CONF_SECTION, 'new_node_max_items', 50 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
207 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
208 )) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
209 self.comments_max_depth = int(self.host.memory.getConfig( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
210 CONF_SECTION, 'comments_max_depth', 0 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
211 )) |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
212 self.ap_path = self.host.memory.getConfig(CONF_SECTION, 'ap_path', '_ap') |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
213 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
|
214 # 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
|
215 self.local_only = C.bool( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
216 self.host.memory.getConfig(CONF_SECTION, 'local_only', C.BOOL_TRUE) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
217 ) |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
218 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
219 # HTTP server launch |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 self.server = HTTPServer(self) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
221 if connection_type == 'http': |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
222 reactor.listenTCP(self.http_port, self.server) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
223 else: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
224 options = tls.getOptionsFromConfig( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
225 self.host.memory.config, CONF_SECTION) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
226 tls.TLSOptionsCheck(options) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
227 context_factory = tls.getTLSContextFactory(options) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
228 reactor.listenSSL(self.http_port, self.server, context_factory) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
229 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
230 async def profileConnecting(self, client): |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
231 self.client = client |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
232 client.sendHistory = True |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
233 await self.init(client) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
234 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
235 async def _itemsReceived(self, client, itemsEvent): |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
236 """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
|
237 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
238 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
|
239 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
|
240 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
241 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
|
242 from there too. |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
243 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
244 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
|
245 return |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
246 # 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
|
247 # as "subscribe" |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
248 client = self.client.getVirtualClient(itemsEvent.sender) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
249 recipient = itemsEvent.recipient |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
250 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
|
251 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
|
252 return |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
253 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
254 ap_account = self._e.unescape(recipient.user) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
255 await self.convertAndPostItems( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
256 client, ap_account, recipient, itemsEvent.nodeIdentifier, itemsEvent.items |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
257 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
258 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
259 async def getVirtualClient(self, actor_id: str) -> SatXMPPEntity: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
260 """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
|
261 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
262 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
|
263 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
|
264 @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
|
265 @return: virtual client |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
266 """ |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
267 local_jid = await self.getJIDFromId(actor_id) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
268 return self.client.getVirtualClient(local_jid) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
269 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
270 def isActivity(self, data: dict) -> bool: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
271 """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
|
272 try: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
273 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
|
274 except (KeyError, TypeError): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
275 return False |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
276 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
277 async def apGet(self, url: str) -> dict: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
278 """Retrieve AP JSON from given URL |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
279 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
280 @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
|
281 with AP server |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
282 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
283 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
284 return await treq.json_content(await treq.get( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
285 url, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
286 headers = { |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
287 "Accept": [MEDIA_TYPE_AP], |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
288 "Content-Type": [MEDIA_TYPE_AP], |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
289 } |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
290 )) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
291 except Exception as e: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
292 raise error.StanzaError( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
293 "service-unavailable", |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
294 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
|
295 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
296 |
3742
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
297 @overload |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
298 async def apGetObject(self, data: dict, key: str) -> Optional[dict]: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
299 ... |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
300 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
301 @overload |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
302 async def apGetObject( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
303 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
|
304 ) -> dict: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
305 ... |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
306 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
307 async def apGetObject(self, data, key = None): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
308 """Retrieve an AP object, dereferencing when necessary |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
309 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
310 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
|
311 https://www.w3.org/TR/activitystreams-vocabulary |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
312 @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
|
313 @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
|
314 @return: found object if any |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
315 """ |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
316 if key is not None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
317 value = data.get(key) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
318 else: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
319 value = data |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
320 if value is None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
321 if key is None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
322 raise ValueError("None can't be used with apGetObject is key is None") |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
323 return None |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
324 elif isinstance(value, dict): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
325 return value |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
326 elif isinstance(value, str): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
327 return await self.apGet(value) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
328 else: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
329 raise NotImplementedError( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
330 "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
|
331 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
332 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
333 async def apGetList( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
334 self, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
335 data: dict, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
336 key: str, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
337 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
|
338 ) -> Optional[List[Dict[str, Any]]]: |
3742
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
339 """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
|
340 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
341 This method is to be used with non functional vocabularies. Use ``apGetObject`` |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
342 otherwise. |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
343 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
|
344 @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
|
345 @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
|
346 @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
|
347 @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
|
348 """ |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
349 value = data.get(key) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
350 if value is None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
351 return None |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
352 elif isinstance(value, str): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
353 value = await self.apGet(value) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
354 if isinstance(value, dict): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
355 return [value] |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
356 if not isinstance(value, list): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
357 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
|
358 if only_ids: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
359 return [ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
360 {"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
|
361 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
|
362 ] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
363 else: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
364 return [await self.apGetObject(i) for i in value] |
3742
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
365 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
366 async def apGetActors( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
367 self, |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
368 data: dict, |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
369 key: str, |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
370 as_account: bool = True |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
371 ) -> List[str]: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
372 """Retrieve AP actors from data |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
373 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
374 @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
|
375 @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
|
376 @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
|
377 IDs |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
378 @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
|
379 """ |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
380 value = data.get(key) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
381 if value is None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
382 raise exceptions.DataError( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
383 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
|
384 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
385 elif isinstance(value, dict): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
386 actor_id = value.get("id") |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
387 if actor_id is None: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
388 raise exceptions.DataError( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
389 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
|
390 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
391 value = [actor_id] |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
392 elif isinstance(value, str): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
393 value = [value] |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
394 elif isinstance(value, list): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
395 try: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
396 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
|
397 except (TypeError, KeyError): |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
398 raise exceptions.DataError( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
399 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
|
400 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
401 if not value: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
402 raise exceptions.DataError( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
403 f"list of actors is empty" |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
404 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
405 if as_account: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
406 return [await self.getAPAccountFromId(actor_id) for actor_id in value] |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
407 else: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
408 return value |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
409 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
410 async def apGetSenderActor( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
411 self, |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
412 data: dict, |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
413 ) -> str: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
414 """Retrieve actor who sent data |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
415 |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
416 This is done by checking "attributedTo" field first, then "actor" field. |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
417 Only the first found actor is taken into accoun |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
418 @param data: AP object |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
419 @return: actor id of the sender |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
420 @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
|
421 """ |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
422 try: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
423 actors = await self.apGetActors(data, "attributedTo", as_account=False) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
424 except exceptions.DataError: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
425 actors = None |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
426 if not actors: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
427 try: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
428 actors = await self.apGetActors(data, "actor", as_account=False) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
429 except exceptions.DataError: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
430 raise exceptions.NotFound( |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
431 'actor not specified in "attributedTo" or "actor"' |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
432 ) |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
433 try: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
434 return actors[0] |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
435 except IndexError: |
bf0505d41c09
comp AP: helper methods to get AP objects:
Goffi <goffi@goffi.org>
parents:
3729
diff
changeset
|
436 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
|
437 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
438 def mustEncode(self, text: str) -> bool: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
439 """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
|
440 return ( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
441 not RE_ALLOWED_UNQUOTED.match(text) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
442 or text.startswith("___") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
443 or "---" in text |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
444 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
445 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
446 def periodEncode(self, text: str) -> str: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
447 """Period encode a text |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
448 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
449 see [getJIDAndNode] for reasons of period encoding |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
450 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
451 return ( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
452 parse.quote(text, safe="") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
453 .replace("---", "%2d%2d%2d") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
454 .replace("___", "%5f%5f%5f") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
455 .replace(".", "%2e") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
456 .replace("~", "%7e") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
457 .replace("%", ".") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
458 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
459 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
460 async def getAPAccountFromJidAndNode( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
461 self, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
462 jid_: jid.JID, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
463 node: Optional[str] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
464 ) -> str: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
465 """Construct AP account from JID and node |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
466 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
467 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
|
468 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
469 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
|
470 node = None |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
471 |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
472 if self.client is None: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
473 raise exceptions.InternalError("Client is not set yet") |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
474 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
475 if jid_.host == self.client.jid.userhost(): |
3792
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
476 # this is an proxy JID to an AP Actor |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
477 return self._e.unescape(jid_.user) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
478 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
479 if node and not jid_.user and not self.mustEncode(node): |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
480 is_pubsub = await self.isPubsub(jid_) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
481 # 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
|
482 # this produces more user-friendly AP accounts |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
483 if is_pubsub: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
484 jid_.user = node |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
485 node = None |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
486 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
487 is_local = self.isLocal(jid_) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
488 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
|
489 if user is None: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
490 user = "" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
491 account_elts = [] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
492 if node and self.mustEncode(node) or self.mustEncode(user): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
493 account_elts = ["___"] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
494 if node: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
495 node = self.periodEncode(node) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
496 user = self.periodEncode(user) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
497 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
498 if not user: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
499 raise exceptions.InternalError("there should be a user part") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
500 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
501 if node: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
502 account_elts.extend((node, "---")) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
503 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
504 account_elts.extend(( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
505 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
|
506 )) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
507 return "".join(account_elts) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
508 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
509 def isLocal(self, jid_: jid.JID) -> bool: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
510 """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
|
511 local_host = self.client.host.split(".") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
512 assert local_host |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
513 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
|
514 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
515 async def isPubsub(self, jid_: jid.JID) -> bool: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
516 """Indicate if a JID is a Pubsub service""" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
517 host_disco = await self.host.getDiscoInfos(self.client, jid_) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
518 return ( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
519 ("pubsub", "service") in host_disco.identities |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
520 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
|
521 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
522 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
523 async def getJIDAndNode(self, ap_account: str) -> Tuple[jid.JID, Optional[str]]: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
524 """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
|
525 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
526 Username are case insensitive. |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
527 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
528 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
|
529 component's server). |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
530 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
531 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
|
532 a pubsub node. |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
533 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
534 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
|
535 rest as a JID user part. |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
536 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
537 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
|
538 (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
|
539 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
540 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
|
541 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
|
542 |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
543 examples: |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
544 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
545 ``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
|
546 |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
547 ``___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
|
548 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
|
549 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
550 ``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
|
551 JID = pubsub.example.org, node = toto |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
552 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
553 ``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
|
554 |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
555 ``___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
|
556 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
|
557 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
558 @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
|
559 @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
|
560 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
|
561 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
|
562 @raise ValueError: invalid account |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
563 @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
|
564 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
565 if ap_account.count("@") != 1: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
566 raise ValueError("Invalid AP account") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
567 if ap_account.startswith("___"): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
568 encoded = True |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
569 ap_account = ap_account[3:] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
570 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
571 encoded = False |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
572 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
573 username, domain = ap_account.split("@") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
574 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
575 if "---" in username: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
576 node, username = username.rsplit("---", 1) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
577 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
578 node = None |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
579 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
580 if encoded: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
581 username = parse.unquote( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
582 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
|
583 errors="strict" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
584 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
585 if node: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
586 node = parse.unquote( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
587 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
|
588 errors="strict" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
589 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
590 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
591 if "@" in username: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
592 username, domain = username.rsplit("@", 1) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
593 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
594 if not node: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
595 # 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
|
596 # blocked for privacy reason (see |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
597 # https://xmpp.org/extensions/xep-0030.html#security) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
598 is_pubsub = await self.isPubsub(jid.JID(domain)) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
599 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
600 if is_pubsub: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
601 # 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
|
602 # is in fact the node name |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
603 node = username |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
604 username = None |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
605 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
606 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
|
607 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
608 jid_ = jid.JID(jid_s) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
609 except RuntimeError: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
610 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
|
611 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
612 if self.local_only and not self.isLocal(jid_): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
613 raise exceptions.PermissionError( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
614 "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
|
615 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
616 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
617 return jid_, node |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
618 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
619 def getLocalJIDFromAccount(self, account: str) -> jid.JID: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
620 """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
|
621 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
622 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
|
623 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
|
624 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
625 return jid.JID( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
626 None, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
627 ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
628 self._e.escape(account), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
629 self.client.jid.host, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
630 None |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
631 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
632 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
633 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
634 async def getJIDFromId(self, actor_id: str) -> jid.JID: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
635 """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
|
636 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
637 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
|
638 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
|
639 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
|
640 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
|
641 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
642 if self.isLocalURL(actor_id): |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
643 request_type, extra_args = self.parseAPURL(actor_id) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
644 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
|
645 raise ValueError(f"invalid actor id: {actor_id!r}") |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
646 actor_jid, __ = await self.getJIDAndNode(extra_args[0]) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
647 return actor_jid |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
648 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
649 account = await self.getAPAccountFromId(actor_id) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
650 return self.getLocalJIDFromAccount(account) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
651 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
652 def parseAPURL(self, url: str) -> Tuple[str, List[str]]: |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
653 """Parse an URL leading to an AP endpoint |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
654 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
655 @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
|
656 @return: endpoint type and extra arguments |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
657 """ |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
658 path = parse.urlparse(url).path.lstrip("/") |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
659 type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/", 1) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
660 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
|
661 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
662 def buildAPURL(self, type_:str , *args: str) -> str: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
663 """Build an AP endpoint URL |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
664 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
665 @param type_: type of AP endpoing |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
666 @param arg: endpoint dependant arguments |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
667 """ |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
668 return parse.urljoin( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
669 self.base_ap_url, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
670 str(Path(type_).joinpath(*(parse.quote_plus(a) for a in args))) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
671 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
672 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
673 def isLocalURL(self, url: str) -> bool: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
674 """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
|
675 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
676 ``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
|
677 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
678 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
|
679 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
680 def buildSignatureHeader(self, values: Dict[str, str]) -> str: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
681 """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
|
682 fields = [] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
683 for key, value in values.items(): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
684 if key not in ("(created)", "(expired)"): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
685 if '"' in value: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
686 raise NotImplementedError( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
687 "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
|
688 f"in {value!r}" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
689 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
690 value = f'"{value}"' |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
691 fields.append(f"{key}={value}") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
692 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
693 return ",".join(fields) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
694 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
695 def getDigest(self, body: bytes, algo="SHA-256") -> Tuple[str, str]: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
696 """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
|
697 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
698 @param body: body of the request |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
699 @return: hash name and digest |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
700 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
701 if algo != "SHA-256": |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
702 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
|
703 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
|
704 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
705 @async_lru(maxsize=LRU_MAX_SIZE) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
706 async def getActorData(self, actor_id) -> dict: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
707 """Retrieve actor data with LRU cache""" |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
708 return await self.apGet(actor_id) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
709 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
710 @async_lru(maxsize=LRU_MAX_SIZE) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
711 async def getActorPubKeyData( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
712 self, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
713 actor_id: str |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
714 ) -> Tuple[str, str, rsa.RSAPublicKey]: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
715 """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
|
716 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
717 @param actor_id: actor ID (url) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
718 @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
|
719 @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
|
720 """ |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
721 actor_data = await self.getActorData(actor_id) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
722 pub_key_data = actor_data["publicKey"] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
723 key_id = pub_key_data["id"] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
724 owner = pub_key_data["owner"] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
725 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
|
726 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
|
727 return key_id, owner, pub_key |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
728 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
729 def createActivity( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
730 self, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
731 activity: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
732 actor_id: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
733 object_: Optional[Union[str, dict]] = None, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
734 target: Optional[Union[str, dict]] = None, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
735 **kwargs, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
736 ) -> Dict[str, Any]: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
737 """Generate base data for an activity |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
738 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
739 @param activity: one of ACTIVITY_TYPES |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
740 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
741 if activity not in ACTIVITY_TYPES: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
742 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
|
743 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
|
744 raise exceptions.InternalError( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
745 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
|
746 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
747 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
|
748 raise exceptions.InternalError( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
749 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
|
750 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
751 activity_id = f"{actor_id}#{activity.lower()}_{shortuuid.uuid()}" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
752 data: Dict[str, Any] = { |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
753 "@context": "https://www.w3.org/ns/activitystreams", |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
754 "actor": actor_id, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
755 "id": activity_id, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
756 "type": activity, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
757 } |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
758 data.update(kwargs) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
759 if object_ is not None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
760 data["object"] = object_ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
761 if target is not None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
762 data["target"] = target |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
763 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
764 return data |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
765 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
766 def getKeyId(self, actor_id: str) -> str: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
767 """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
|
768 return f"{actor_id}#main-key" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
769 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
770 async def checkSignature( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
771 self, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
772 signature: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
773 key_id: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
774 headers: Dict[str, str] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
775 ) -> str: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
776 """Verify that signature matches given headers |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
777 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
778 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
|
779 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
780 @param signature: Base64 encoded signature |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
781 @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
|
782 @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
|
783 @return: id of the signing actor |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
784 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
785 @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
|
786 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
787 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
|
788 if key_id.startswith("acct:"): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
789 actor = key_id[5:] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
790 actor_id = await self.getAPActorIdFromAccount(actor) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
791 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
792 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
|
793 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
794 pub_key_id, pub_key_owner, pub_key = await self.getActorPubKeyData(actor_id) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
795 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
|
796 raise exceptions.EncryptionError("Public Key mismatch") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
797 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
798 try: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
799 pub_key.verify( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
800 base64.b64decode(signature), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
801 to_sign.encode(), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
802 # 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
|
803 padding.PKCS1v15(), # type: ignore |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
804 hashes.SHA256() # type: ignore |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
805 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
806 except InvalidSignature: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
807 raise exceptions.EncryptionError("Invalid signature (using PKC0S1 v1.5 and SHA-256)") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
808 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
809 return actor_id |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
810 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
811 def getSignatureData( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
812 self, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
813 key_id: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
814 headers: Dict[str, str] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
815 ) -> 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
|
816 """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
|
817 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
818 @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
|
819 @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
|
820 @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
|
821 @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
|
822 @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
|
823 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
|
824 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
825 @return: headers and signature data |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
826 ``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
|
827 removed, and ``Signature`` added. |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
828 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
829 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
|
830 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
|
831 to_sign.encode(), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
832 # 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
|
833 padding.PKCS1v15(), # type: ignore |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
834 hashes.SHA256() # type: ignore |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
835 )).decode() |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
836 sign_data = { |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
837 "keyId": key_id, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
838 "Algorithm": "rsa-sha256", |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
839 "headers": " ".join(headers.keys()), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
840 "signature": signature |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
841 } |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
842 new_headers = {k: v for k,v in headers.items() if not k.startswith("(")} |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
843 new_headers["Signature"] = self.buildSignatureHeader(sign_data) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
844 return new_headers, sign_data |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
845 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
846 async def convertAndPostItems( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
847 self, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
848 client: SatXMPPEntity, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
849 ap_account: str, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
850 service: jid.JID, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
851 node: str, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
852 items: List[domish.Element], |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
853 subscribe_comments_nodes: bool = False, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
854 ) -> None: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
855 """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
|
856 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
857 @param ap_account: account of ActivityPub actor |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
858 @param service: JID of the virtual pubsub service corresponding to the AP actor |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
859 @param node: virtual node corresponding to the AP actor and items |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
860 @param subscribe_comments_nodes: if True, comment nodes present in given items, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
861 they will be automatically subscribed |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
862 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
863 actor_id = await self.getAPActorIdFromAccount(ap_account) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
864 inbox = await self.getAPInboxFromId(actor_id) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
865 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
|
866 if item.name == "item": |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
867 mb_data = await self._m.item2mbdata(client, item, service, node) |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
868 if subscribe_comments_nodes: |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
869 # we subscribe automatically to comment nodes if any |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
870 for comment_data in mb_data.get("comments", []): |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
871 comment_service = jid.JID(comment_data["service"]) |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
872 comment_node = comment_data["node"] |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
873 await self._p.subscribe(client, comment_service, comment_node) |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
874 ap_item = await self.mbdata2APitem(client, mb_data) |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
875 url_actor = ap_item["object"]["attributedTo"] |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
876 elif item.name == "retract": |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
877 url_actor, ap_item = await self.apDeleteItem( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
878 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
|
879 ) |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
880 else: |
865167c34b82
comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents:
3784
diff
changeset
|
881 raise exceptions.InternalError(f"unexpected element: {item.toXml()}") |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
882 resp = await self.signAndPost(inbox, url_actor, ap_item) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
883 if resp.code >= 300: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
884 text = await resp.text() |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
885 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
886 f"unexpected return code while sending AP item: {resp.code}\n{text}\n" |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
887 f"{pformat(ap_item)}" |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
888 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
889 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
890 async def signAndPost(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
|
891 """Sign a documentent and post it to AP server |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
892 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
893 @param url: AP server endpoint |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
894 @param actor_id: originating actor ID (URL) |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
895 @param doc: document to send |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
896 """ |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
897 p_url = parse.urlparse(url) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
898 body = json.dumps(doc).encode() |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
899 digest_algo, digest_hash = self.getDigest(body) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
900 digest = f"{digest_algo}={digest_hash}" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
901 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
902 headers = { |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
903 "(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
|
904 "Host": p_url.hostname, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
905 "Date": http.datetimeToString().decode(), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
906 "Digest": digest |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
907 } |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
908 headers, __ = self.getSignatureData(self.getKeyId(actor_id), headers) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
909 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
910 headers["Content-Type"] = ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
911 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
912 ) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
913 resp = await treq.post( |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
914 url, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
915 body, |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
916 headers=headers, |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
917 ) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
918 if resp.code >= 400: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
919 text = await resp.text() |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
920 log.warning(f"POST request to {url} failed [{resp.code}]: {text}") |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
921 return resp |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
922 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
923 def _publishMessage(self, mess_data_s: str, service_s: str, profile: str): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
924 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
|
925 service = jid.JID(service_s) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
926 client = self.host.getClient(profile) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
927 return defer.ensureDeferred(self.publishMessage(client, mess_data, service)) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
928 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
929 @async_lru(maxsize=LRU_MAX_SIZE) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
930 async def getAPActorIdFromAccount(self, account: str) -> str: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
931 """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
|
932 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
933 @param account: AP handle (user@domain.tld) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
934 @return: Actor ID (which is an URL) |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
935 """ |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
936 if account.count("@") != 1 or "/" in account: |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
937 raise ValueError(f"Invalid account: {account!r}") |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
938 host = account.split("@")[1] |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
939 try: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
940 finger_data = await treq.json_content(await treq.get( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
941 f"https://{host}/.well-known/webfinger?" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
942 f"resource=acct:{parse.quote_plus(account)}", |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
943 )) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
944 except Exception as e: |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
945 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
|
946 for link in finger_data.get("links", []): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
947 if ( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
948 link.get("type") == "application/activity+json" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
949 and link.get("rel") == "self" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
950 ): |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
951 href = link.get("href", "").strip() |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
952 if not href: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
953 raise ValueError( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
954 f"Invalid webfinger data for {account:r}: missing href" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
955 ) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
956 break |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
957 else: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
958 raise ValueError( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
959 f"No ActivityPub link found for {account!r}" |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
960 ) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
961 return href |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
962 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
963 async def getAPActorDataFromAccount(self, account: str) -> dict: |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
964 """Retrieve ActivityPub Actor data |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
965 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
966 @param account: ActivityPub Actor identifier |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
967 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
968 href = await self.getAPActorIdFromAccount(account) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
969 return await self.apGet(href) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
970 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
971 async def getAPInboxFromId(self, actor_id: str) -> str: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
972 """Retrieve inbox of an actor_id""" |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
973 data = await self.getActorData(actor_id) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
974 return data["inbox"] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
975 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
976 @async_lru(maxsize=LRU_MAX_SIZE) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
977 async def getAPAccountFromId(self, actor_id: str) -> str: |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
978 """Retrieve AP account from the ID URL |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
979 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
980 @param actor_id: AP ID of the actor (URL to the actor data) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
981 """ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
982 url_parsed = parse.urlparse(actor_id) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
983 actor_data = await self.getActorData(actor_id) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
984 username = actor_data.get("preferredUsername") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
985 if not username: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
986 raise exceptions.DataError( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
987 '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
|
988 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
989 account = f"{username}@{url_parsed.hostname}" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
990 # we try to retrieve the actor ID from the account to check it |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
991 found_id = await self.getAPActorIdFromAccount(account) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
992 if found_id != actor_id: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
993 # 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
|
994 msg = ( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
995 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
|
996 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
|
997 '"preferredUsername" as we expect.' |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
998 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
999 log.warning(msg) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1000 raise exceptions.DataError(msg) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1001 return account |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1002 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1003 async def getAPItems( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1004 self, |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1005 collection: dict, |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1006 max_items: Optional[int] = None, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1007 chronological_pagination: bool = True, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1008 after_id: Optional[str] = None, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1009 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
|
1010 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
|
1011 only_ids: bool = False, |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1012 ) -> Tuple[List[domish.Element], rsm.RSMResponse]: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1013 """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
|
1014 |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
1015 @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
|
1016 @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
|
1017 retrieve all items by default |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1018 @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
|
1019 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
|
1020 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
|
1021 retrieved first. |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1022 @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
|
1023 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
|
1024 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
|
1025 we find it. |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1026 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
|
1027 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
|
1028 @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
|
1029 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
|
1030 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
|
1031 @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
|
1032 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
|
1033 @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
|
1034 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
|
1035 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
|
1036 collections) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1037 @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
|
1038 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
|
1039 """ |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1040 if parser is None: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1041 parser = self.apItem2Elt |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1042 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1043 rsm_resp: Dict[str, Union[bool, int]] = {} |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1044 try: |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1045 count = collection["totalItems"] |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1046 except KeyError: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1047 log.warning( |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1048 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
|
1049 "defaulting to 20" |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1050 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1051 count = 20 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1052 else: |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1053 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
|
1054 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1055 rsm_resp["count"] = count |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1056 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1057 if start_index is not None: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1058 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
|
1059 if start_index >= count: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1060 return [], rsm_resp |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1061 elif start_index == 0: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1062 # this is the default behaviour |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1063 pass |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1064 elif start_index > 5000: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1065 raise error.StanzaError( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1066 "feature-not-implemented", |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1067 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
|
1068 "is set to avoid DoS" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1069 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1070 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1071 # 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
|
1072 # before "start_index" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1073 previous_index = start_index - 1 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1074 retrieved_items = 0 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1075 current_page = collection["last"] |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1076 while retrieved_items < count: |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1077 page_data, items = await self.parseAPPage( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1078 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
|
1079 ) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1080 if not items: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1081 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
|
1082 return [], rsm_resp |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1083 page_start_idx = retrieved_items |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1084 retrieved_items += len(items) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1085 if previous_index <= retrieved_items: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1086 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
|
1087 break |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1088 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1089 current_page = page_data["prev"] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1090 except KeyError: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1091 log.warning( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1092 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
|
1093 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1094 raise error.StanzaError( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1095 "service-unavailable", |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1096 "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
|
1097 f"{current_page}" |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1098 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1099 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1100 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
|
1101 page = collection.get(init_page) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1102 if not page: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1103 raise exceptions.DataError( |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1104 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
|
1105 f"{collection.get('id')})" |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1106 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1107 items = [] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1108 page_items = [] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1109 retrieved_items = 0 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1110 found_after_id = False |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1111 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1112 while retrieved_items < count: |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1113 __, page_items = await self.parseAPPage(page, parser, only_ids) |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1114 if not page_items: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1115 break |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1116 retrieved_items += len(page_items) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1117 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
|
1118 # 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
|
1119 # found |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
1120 try: |
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
1121 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
|
1122 except ValueError: |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1123 # 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
|
1124 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
|
1125 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
|
1126 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1127 found_after_id = True |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1128 if chronological_pagination: |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
1129 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
|
1130 page_items = page_items[limit_idx+1:] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1131 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1132 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
|
1133 limit_idx + 1) |
3729
86eea17cafa7
component AP gateway: split plugin in several files:
Goffi <goffi@goffi.org>
parents:
3728
diff
changeset
|
1134 page_items = page_items[:limit_idx] |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1135 items.extend(page_items) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1136 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1137 items.extend(page_items) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1138 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
|
1139 if chronological_pagination: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1140 items = items[:max_items] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1141 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1142 items = items[-max_items:] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1143 break |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1144 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
|
1145 if not page: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1146 break |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1147 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1148 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
|
1149 raise error.StanzaError("item-not-found") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1150 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1151 if items: |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1152 if after_id is None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1153 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
|
1154 if start_index is not None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1155 rsm_resp["index"] = start_index |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1156 elif after_id is not None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1157 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
|
1158 elif chronological_pagination: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1159 rsm_resp["index"] = 0 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1160 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1161 rsm_resp["index"] = count - len(items) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1162 rsm_resp.update({ |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1163 "first": items[0]["id"], |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1164 "last": items[-1]["id"] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1165 }) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1166 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1167 return items, rsm.RSMResponse(**rsm_resp) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1168 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1169 async def apItem2MbDataAndElt(self, ap_item: dict) -> Tuple[dict, domish.Element]: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1170 """Convert AP item to parsed microblog data and corresponding item element""" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1171 mb_data = await self.apItem2MBdata(ap_item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1172 item_elt = await self._m.data2entry( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1173 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
|
1174 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1175 item_elt["publisher"] = mb_data["author_jid"] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1176 return mb_data, item_elt |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1177 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1178 async def apItem2Elt(self, ap_item: dict) -> domish.Element: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1179 """Convert AP item to XMPP item element""" |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1180 __, item_elt = await self.apItem2MbDataAndElt(ap_item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1181 return item_elt |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1182 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1183 async def parseAPPage( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1184 self, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1185 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
|
1186 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
|
1187 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
|
1188 ) -> 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
|
1189 """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
|
1190 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1191 @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
|
1192 @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
|
1193 @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
|
1194 @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
|
1195 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1196 page_data = await self.apGetObject(page) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1197 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
|
1198 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
|
1199 return {}, [] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1200 ap_items = await self.apGetList(page_data, "orderedItems", only_ids=only_ids) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1201 if ap_items is None: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1202 ap_items = await self.apGetList(page_data, "items", only_ids=only_ids) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1203 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
|
1204 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
|
1205 return page_data, [] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1206 else: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1207 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1208 "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
|
1209 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1210 items = [] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1211 # 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
|
1212 # 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
|
1213 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
|
1214 try: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1215 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
|
1216 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
|
1217 continue |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1218 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1219 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
|
1220 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1221 async def getCommentsNodes( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1222 self, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1223 item_id: str, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1224 parent_id: Optional[str] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1225 ) -> Tuple[Optional[str], Optional[str]]: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1226 """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
|
1227 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1228 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
|
1229 given depth |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1230 @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
|
1231 @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
|
1232 @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
|
1233 - 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
|
1234 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
|
1235 - 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
|
1236 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
|
1237 "comments_max_depth") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1238 """ |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1239 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
|
1240 return ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1241 self._m.getCommentsNode(parent_id) if parent_id is not None else None, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1242 self._m.getCommentsNode(item_id) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1243 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1244 parent_url = parent_id |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1245 parents = [] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1246 for __ in range(COMMENTS_MAX_PARENTS): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1247 parent_item = await self.apGet(parent_url) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1248 parents.insert(0, parent_item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1249 parent_url = parent_item.get("inReplyTo") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1250 if parent_url is None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1251 break |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1252 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
|
1253 if len(parents) <= parent_limit: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1254 return ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1255 self._m.getCommentsNode(parents[-1]["id"]), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1256 self._m.getCommentsNode(item_id) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1257 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1258 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1259 last_level_item = parents[parent_limit] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1260 return ( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1261 self._m.getCommentsNode(last_level_item["id"]), |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1262 None |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1263 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1264 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1265 async def apItem2MBdata(self, ap_item: dict) -> dict: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1266 """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
|
1267 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1268 @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
|
1269 @raise exceptions.DataError: something is invalid in the AP item |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1270 @raise NotImplemented: some AP data is not handled yet |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1271 @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
|
1272 """ |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1273 is_activity = self.isActivity(ap_item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1274 if is_activity: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1275 ap_object = await self.apGetObject(ap_item, "object") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1276 if not ap_object: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1277 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
|
1278 raise exceptions.DataError |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1279 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1280 ap_object = ap_item |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1281 item_id = ap_object.get("id") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1282 if not item_id: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1283 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
|
1284 raise exceptions.DataError |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1285 mb_data = {"id": item_id} |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1286 for ap_key, mb_key in AP_MB_MAP.items(): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1287 data = ap_object.get(ap_key) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1288 if data is None: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1289 continue |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1290 mb_data[mb_key] = data |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1291 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1292 # content |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1293 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1294 language, content_xhtml = ap_object["contentMap"].popitem() |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1295 except (KeyError, AttributeError): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1296 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1297 mb_data["content_xhtml"] = mb_data["content"] |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1298 except KeyError: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1299 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
|
1300 raise exceptions.DataError |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1301 else: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1302 mb_data["language"] = language |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1303 mb_data["content_xhtml"] = content_xhtml |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1304 if not mb_data.get("content"): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1305 mb_data["content"] = await self._t.convert( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1306 content_xhtml, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1307 self._t.SYNTAX_XHTML, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1308 self._t.SYNTAX_TEXT, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1309 False, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1310 ) |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1311 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1312 # author |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1313 if is_activity: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1314 authors = await self.apGetActors(ap_item, "actor") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1315 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1316 authors = await self.apGetActors(ap_object, "attributedTo") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1317 if len(authors) > 1: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1318 # 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
|
1319 # TODO: handle multiple actors |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1320 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
|
1321 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1322 account = authors[0] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1323 author_jid = self.getLocalJIDFromAccount(account).full() |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1324 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1325 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
|
1326 mb_data["author_jid"] = author_jid |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1327 |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1328 # published/updated |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1329 for field in ("published", "updated"): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1330 value = ap_object.get(field) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1331 if not value and field == "updated": |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1332 value = ap_object.get("published") |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1333 if value: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1334 try: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1335 mb_data[field] = calendar.timegm( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1336 dateutil.parser.parse(str(value)).utctimetuple() |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1337 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1338 except dateutil.parser.ParserError as e: |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1339 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
|
1340 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1341 # comments |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1342 in_reply_to = ap_object.get("inReplyTo") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1343 __, comments_node = await self.getCommentsNodes(item_id, in_reply_to) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1344 if comments_node is not None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1345 comments_data = { |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1346 "service": author_jid, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1347 "node": comments_node, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1348 "uri": uri.buildXMPPUri( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1349 "pubsub", |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1350 path=author_jid, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1351 node=comments_node |
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 } |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1354 mb_data["comments"] = [comments_data] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1355 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1356 return mb_data |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1357 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1358 async def getReplyToIdFromXMPPNode( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1359 self, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1360 client: SatXMPPEntity, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1361 ap_account: str, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1362 parent_item: str, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1363 mb_data: dict |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1364 ) -> str: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1365 """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
|
1366 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1367 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
|
1368 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
|
1369 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
|
1370 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
|
1371 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1372 @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
|
1373 @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
|
1374 has been posted |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1375 @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
|
1376 @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
|
1377 """ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1378 # 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
|
1379 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1380 found_items = await self.host.memory.storage.searchPubsubItems({ |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1381 "profiles": [client.profile], |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1382 "names": [parent_item] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1383 }) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1384 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
|
1385 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
|
1386 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
|
1387 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
|
1388 cached_node = found_items[0].node |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1389 parent_ap_account = await self.getAPAccountFromJidAndNode( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1390 cached_node.service, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1391 cached_node.name |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1392 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1393 else: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1394 # 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
|
1395 # 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
|
1396 try: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1397 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
|
1398 cached_item = next( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1399 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
|
1400 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
|
1401 == author |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1402 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1403 except StopIteration: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1404 # 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
|
1405 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1406 "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
|
1407 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
|
1408 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1409 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
|
1410 else: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1411 cached_node = cached_item.node |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1412 parent_ap_account = await self.getAPAccountFromJidAndNode( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1413 cached_node.service, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1414 cached_node.name |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1415 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1416 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1417 return self.buildAPURL( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1418 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
|
1419 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1420 |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1421 async def mbdata2APitem( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1422 self, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1423 client: SatXMPPEntity, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1424 mb_data: dict, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1425 public=True |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1426 ) -> dict: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1427 """Convert Libervia Microblog Data to ActivityPub item |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1428 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1429 @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
|
1430 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
|
1431 If ``published`` is not set, current datetime will be used |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1432 @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
|
1433 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
|
1434 account (which retrieve from ``service``) will be put in ``cc``. |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1435 ``inReplyTo`` will also be set if suitable |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1436 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
|
1437 This is usually used for direct messages. |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1438 @return: AP item |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1439 """ |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1440 if not mb_data.get("id"): |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1441 mb_data["id"] = shortuuid.uuid() |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1442 if not mb_data.get("author_jid"): |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1443 mb_data["author_jid"] = client.jid.userhost() |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1444 ap_account = await self.getAPAccountFromJidAndNode( |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1445 jid.JID(mb_data["author_jid"]), |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1446 None |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1447 ) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1448 url_actor = self.buildAPURL(TYPE_ACTOR, ap_account) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1449 url_item = self.buildAPURL(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
|
1450 ap_object = { |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1451 "id": url_item, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1452 "type": "Note", |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1453 "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
|
1454 "attributedTo": url_actor, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1455 "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
|
1456 } |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1457 |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1458 language = mb_data.get("language") |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1459 if language: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1460 ap_object["contentMap"] = {language: ap_object["content"]} |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1461 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1462 if public: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1463 ap_object["to"] = [NS_AP_PUBLIC] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1464 try: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1465 node = mb_data["node"] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1466 service = jid.JID(mb_data["service"]) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1467 except KeyError: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1468 # 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
|
1469 raise exceptions.InternalError( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1470 "node or service is missing in mb_data" |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1471 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1472 target_ap_account = await self.getAPAccountFromJidAndNode( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1473 service, node |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1474 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1475 if service.host == self.client.jid.userhost: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1476 # service is a proxy JID for AP account |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1477 actor_data = await self.getAPActorDataFromAccount(target_ap_account) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1478 followers = actor_data.get("followers") |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1479 else: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1480 # service is a real XMPP entity |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1481 followers = self.buildAPURL(TYPE_FOLLOWERS, target_ap_account) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1482 if followers: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1483 ap_object["cc"] = [followers] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1484 if self._m.isCommentNode(node): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1485 parent_item = self._m.getParentItem(node) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1486 if service.host == self.client.jid.userhost(): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1487 # 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
|
1488 # this gateway and linking to an ActivityPub actor) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1489 ap_object["inReplyTo"] = parent_item |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1490 else: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1491 # the publication is from a followed real XMPP node |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1492 ap_object["inReplyTo"] = await self.getReplyToIdFromXMPPNode( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1493 client, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1494 ap_account, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1495 parent_item, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1496 mb_data |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1497 ) |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1498 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1499 ap_item = { |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1500 "@context": "https://www.w3.org/ns/activitystreams", |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1501 "id": url_item, |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1502 "type": "Create", |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1503 "actor": url_actor, |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1504 "object": ap_object |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1505 } |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1506 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1507 return ap_item |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1508 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1509 async def publishMessage( |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1510 self, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1511 client: SatXMPPEntity, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1512 mess_data: dict, |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1513 service: jid.JID |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1514 ) -> None: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1515 """Send an AP message |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1516 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1517 .. note:: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1518 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1519 This is a temporary method used for development only |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1520 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1521 @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
|
1522 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1523 ``node`` |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1524 identifier of message which is being replied (this will |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1525 correspond to pubsub node in the future) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1526 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1527 ``content_xhtml`` or ``content`` |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1528 message body (respectively in XHTML or plain text) |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1529 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1530 @param service: JID corresponding to the AP actor. |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1531 """ |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1532 if not service.user: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1533 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
|
1534 account = self._e.unescape(service.user) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1535 ap_actor_data = await self.getAPActorDataFromAccount(account) |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1536 |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1537 try: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1538 inbox_url = ap_actor_data["endpoints"]["sharedInbox"] |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1539 except KeyError: |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1540 raise exceptions.DataError("Can't get ActivityPub actor inbox") |
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1541 |
3728
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1542 item_data = await self.mbdata2APitem(client, mess_data) |
b15644cae50d
component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents:
3684
diff
changeset
|
1543 url_actor = item_data["object"]["attributedTo"] |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1544 resp = await self.signAndPost(inbox_url, url_actor, item_data) |
3684
8353cc3b8db9
component AP gateway: fix wrong operator when testing HTTP code
Goffi <goffi@goffi.org>
parents:
3682
diff
changeset
|
1545 if resp.code != 202: |
3682
7c990aaa49d3
comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1546 raise exceptions.NetworkError(f"unexpected return code: {resp.code}") |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1547 |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1548 async def apDeleteItem( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1549 self, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1550 jid_: jid.JID, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1551 node: Optional[str], |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1552 item_id: str, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1553 public: bool = True |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1554 ) -> Tuple[str, Dict[str, Any]]: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1555 """Build activity to delete an AP item |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1556 |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1557 @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
|
1558 @param node: node where the item is deleted |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1559 None if it's microblog or a message |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1560 @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
|
1561 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
|
1562 @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
|
1563 @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
|
1564 """ |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1565 author_account = await self.getAPAccountFromJidAndNode(jid_, node) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1566 author_actor_id = self.buildAPURL(TYPE_ACTOR, author_account) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1567 url_item = self.buildAPURL(TYPE_ITEM, author_account, item_id) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1568 ap_item = self.createActivity( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1569 "Delete", |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1570 author_actor_id, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1571 { |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1572 "id": url_item, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1573 "type": TYPE_TOMBSTONE |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1574 } |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1575 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1576 if public: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1577 ap_item["to"] = [NS_AP_PUBLIC] |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1578 url_actor = author_actor_id |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1579 return url_actor, ap_item |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1580 |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1581 def _messageReceivedTrigger( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1582 self, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1583 client: SatXMPPEntity, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1584 message_elt: domish.Element, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1585 post_treat: defer.Deferred |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1586 ) -> bool: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1587 """add the gateway workflow on post treatment""" |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1588 if not self.client: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1589 log.warning(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
|
1590 return True |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1591 post_treat.addCallback( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1592 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
|
1593 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1594 return True |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1595 |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1596 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
|
1597 """Called once message has been parsed |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1598 |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1599 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
|
1600 """ |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1601 if client != self.client: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1602 return mess_data |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1603 if mess_data["type"] not in ("chat", "normal"): |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1604 log.warning(f"ignoring message with unexpected type: {mess_data['xml'].toXml()}") |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1605 return mess_data |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1606 if not self.isLocal(mess_data["from"]): |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1607 log.warning(f"ignoring non local message: {mess_data['xml'].toXml()}") |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1608 return mess_data |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1609 if not mess_data["to"].user: |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1610 log.warning( |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1611 f"ignoring message addressed to gateway itself: {mess_data['xml'].toXml()}" |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1612 ) |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1613 return mess_data |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1614 |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1615 actor_account = self._e.unescape(mess_data["to"].user) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1616 actor_id = await self.getAPActorIdFromAccount(actor_account) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1617 inbox = await self.getAPInboxFromId(actor_id) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1618 |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1619 try: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1620 language, message = next(iter(mess_data["message"].items())) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1621 except (KeyError, StopIteration): |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1622 log.warning(f"ignoring empty message: {mess_data}") |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1623 return mess_data |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1624 |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1625 mb_data = { |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1626 "content": message, |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1627 } |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1628 if language: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1629 mb_data["language"] = language |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1630 origin_id = mess_data["extra"].get("origin_id") |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1631 if origin_id: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1632 # 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
|
1633 mb_data["id"] = origin_id |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1634 client = self.client.getVirtualClient(mess_data["from"]) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1635 ap_item = await self.mbdata2APitem(client, mb_data, public=False) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1636 ap_item["object"]["to"] = ap_item["to"] = [actor_id] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1637 await self.signAndPost(inbox, ap_item["actor"], ap_item) |
3803
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1638 return mess_data |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1639 |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1640 async def _onMessageRetract( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1641 self, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1642 client: SatXMPPEntity, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1643 message_elt: domish.Element, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1644 retract_elt: domish.Element, |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1645 fastened_elts |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1646 ) -> bool: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1647 if client != self.client: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1648 return True |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1649 from_jid = jid.JID(message_elt["from"]) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1650 if not self.isLocal(from_jid): |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1651 log.debug( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1652 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
|
1653 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1654 return False |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1655 to_jid = jid.JID(message_elt["to"]) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1656 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
|
1657 # 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
|
1658 raise exceptions.InternalError( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1659 f"Invalid destinee's JID: {to_jid.full()}" |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1660 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1661 ap_account = self._e.unescape(to_jid.user) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1662 actor_id = await self.getAPActorIdFromAccount(ap_account) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1663 inbox = await self.getAPInboxFromId(actor_id) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1664 url_actor, ap_item = await self.apDeleteItem( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1665 from_jid.userhostJID(), None, fastened_elts.id, public=False |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1666 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1667 resp = await self.signAndPost(inbox, url_actor, ap_item) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1668 if resp.code >= 300: |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1669 text = await resp.text() |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1670 log.warning( |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1671 f"unexpected return code while sending AP item: {resp.code}\n{text}\n" |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1672 f"{pformat(ap_item)}" |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1673 ) |
d5f343939239
component AP gateway: message retractation => AP deletion
Goffi <goffi@goffi.org>
parents:
3793
diff
changeset
|
1674 return False |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1675 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1676 async def newReplyToXMPPItem( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1677 self, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1678 client: SatXMPPEntity, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1679 ap_item: dict, |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1680 ) -> None: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1681 """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
|
1682 in_reply_to = ap_item["inReplyTo"] |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1683 url_type, url_args = self.parseAPURL(in_reply_to) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1684 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
|
1685 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1686 "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
|
1687 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
|
1688 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1689 return |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1690 try: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1691 parent_item_account, parent_item_id = url_args[0].split("/", 1) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1692 except (IndexError, ValueError): |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1693 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1694 "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
|
1695 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
|
1696 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1697 return |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1698 parent_item_service, parent_item_node = await self.getJIDAndNode( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1699 parent_item_account |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1700 ) |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1701 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
|
1702 parent_item_node = self._m.namespace |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1703 items, __ = await self._p.getItems( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1704 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
|
1705 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1706 try: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1707 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
|
1708 except IndexError: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1709 log.warning( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1710 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
|
1711 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
|
1712 return |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1713 parent_item_parsed = await self._m.item2mbdata( |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1714 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
|
1715 ) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1716 try: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1717 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
|
1718 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
|
1719 except (KeyError, IndexError): |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1720 # we don't have a comment node set for this item |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1721 from sat.tools.xml_tools import ppElt |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1722 log.info(f"{ppElt(parent_item_elt.toXml())}") |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1723 raise NotImplemented() |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1724 else: |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1725 __, item_elt = await self.apItem2MbDataAndElt(ap_item) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1726 await self._p.publish(client, comment_service, comment_node, [item_elt]) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1727 |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1728 def getAPItemTargets(self, item: Dict[str, Any]) -> Tuple[bool, Set[str], Set[str]]: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1729 """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
|
1730 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1731 @param item: AP object payload |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1732 @return: Are returned: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1733 - is_public flag, indicating if the item is world-readable |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1734 - targets of the item |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1735 - targets of the items |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1736 """ |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1737 targets: Set[str] = set() |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1738 is_public = False |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1739 # TODO: handle "audience" |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1740 for key in ("to", "bto", "cc", "bcc"): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1741 values = item.get(key) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1742 if not values: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1743 continue |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1744 if isinstance(values, str): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1745 values = [values] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1746 for value in values: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1747 if value in PUBLIC_TUPLE: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1748 is_public = True |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1749 continue |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1750 if not value: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1751 continue |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1752 if not self.isLocalURL(value): |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1753 continue |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1754 targets.add(value) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1755 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1756 targets_types = {self.parseAPURL(t)[0] for t in targets} |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1757 return is_public, targets, targets_types |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1758 |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1759 async def newAPItem( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1760 self, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1761 client: SatXMPPEntity, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1762 destinee: Optional[jid.JID], |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1763 node: str, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1764 item: dict, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1765 ) -> None: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1766 """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
|
1767 |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1768 @param destinee: jid of the destinee, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1769 @param node: XMPP pubsub node |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1770 @param item: AP object payload |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1771 """ |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1772 is_public, targets, targets_types = self.getAPItemTargets(item) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1773 if not is_public and targets_types == {TYPE_ACTOR}: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1774 # this is a direct message |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1775 await self.handleMessageAPItem( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1776 client, targets, destinee, item |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1777 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1778 else: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1779 await self.handlePubsubAPItem( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1780 client, targets, destinee, node, item, is_public |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1781 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1782 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1783 async def handleMessageAPItem( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1784 self, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1785 client: SatXMPPEntity, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1786 targets: Set[str], |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1787 destinee: Optional[jid.JID], |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1788 item: dict, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1789 ) -> None: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1790 """Parse and deliver direct AP items translating to XMPP messages |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1791 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1792 @param targets: actors where the item must be delivered |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1793 @param destinee: jid of the destinee, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1794 @param item: AP object payload |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1795 """ |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1796 targets_jids = {await self.getJIDFromId(t) for t in targets} |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1797 if destinee is not None: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1798 targets_jids.add(destinee) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1799 mb_data = await self.apItem2MBdata(item) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1800 defer_l = [] |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1801 for target_jid in targets_jids: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1802 defer_l.append( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1803 client.sendMessage( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1804 target_jid, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1805 {'': mb_data.get("content", "")}, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1806 mb_data.get("title"), |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1807 extra={"origin_id": mb_data["id"]} |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1808 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1809 ) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1810 await defer.DeferredList(defer_l) |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1811 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1812 async def handlePubsubAPItem( |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1813 self, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1814 client: SatXMPPEntity, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1815 targets: Set[str], |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1816 destinee: Optional[jid.JID], |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1817 node: str, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1818 item: dict, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1819 public: bool |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1820 ) -> None: |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1821 """Analyse, cache and deliver AP items translating to Pubsub |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1822 |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1823 @param targets: actors/collections where the item must be delivered |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1824 @param destinee: jid of the destinee, |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1825 @param node: XMPP pubsub node |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1826 @param item: AP object payload |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1827 @param public: True if the item is public |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1828 """ |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1829 # XXX: "public" is not used for now |
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1830 |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1831 service = client.jid |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1832 in_reply_to = item.get("inReplyTo") |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1833 |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1834 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
|
1835 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
|
1836 if in_reply_to and isinstance(in_reply_to, str): |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1837 if self.isLocalURL(in_reply_to): |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1838 # this 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
|
1839 return await self.newReplyToXMPPItem(client, item) |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1840 |
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1841 # 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
|
1842 # for comments |
3745
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1843 parent_node, __ = await self.getCommentsNodes(item["id"], in_reply_to) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1844 node = parent_node or node |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1845 cached_node = await self.host.memory.storage.getPubsubNode( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1846 client, service, node, with_subscriptions=True |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1847 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1848 if cached_node is None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1849 try: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1850 cached_node = await self.host.memory.storage.setPubsubNode( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1851 client, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1852 service, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1853 node, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1854 subscribed=True |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1855 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1856 except IntegrityError as e: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1857 if "unique" in str(e.orig).lower(): |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1858 # the node may already exist, if it has been created just after |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1859 # getPubsubNode above |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1860 log.debug("ignoring UNIQUE constraint error") |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1861 cached_node = await self.host.memory.storage.getPubsubNode( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1862 client, service, node, with_subscriptions=True |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1863 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1864 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1865 raise e |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1866 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1867 else: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1868 # it is a root item (i.e. not a reply to an other item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1869 cached_node = await self.host.memory.storage.getPubsubNode( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1870 client, service, node, with_subscriptions=True |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1871 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1872 if cached_node is None: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1873 log.warning( |
3764
125c7043b277
comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents:
3745
diff
changeset
|
1874 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
|
1875 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
|
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 return |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1879 mb_data, item_elt = await self.apItem2MbDataAndElt(item) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1880 await self.host.memory.storage.cachePubsubItems( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1881 client, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1882 cached_node, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1883 [item_elt], |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1884 [mb_data] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1885 ) |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1886 |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1887 for subscription in cached_node.subscriptions: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1888 if subscription.state != SubscriptionState.SUBSCRIBED: |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1889 continue |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1890 self.pubsub_service.notifyPublish( |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1891 service, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1892 node, |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1893 [(subscription.subscriber, None, [item_elt])] |
a8c7e5cef0cb
comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents:
3742
diff
changeset
|
1894 ) |
3784
efc34a89e70b
comp AP gateway: message conversion:
Goffi <goffi@goffi.org>
parents:
3764
diff
changeset
|
1895 |
3793
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1896 async def newAPDeleteItem( |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1897 self, |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1898 client: SatXMPPEntity, |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1899 destinee: Optional[jid.JID], |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1900 node: str, |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1901 activity: dict, |
3793
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1902 item: dict, |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1903 ) -> None: |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1904 """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
|
1905 |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1906 @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
|
1907 @param node: XMPP pubsub node |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1908 @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
|
1909 @param item: AP object payload |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1910 """ |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1911 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
|
1912 if not item_id: |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1913 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
|
1914 if not item_id.startswith("http"): |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1915 raise exceptions.DataError(f"invalid id: {item_id!r}") |
3793
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1916 if self.isLocalURL(item_id): |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1917 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
|
1918 |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1919 # 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
|
1920 # 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
|
1921 # do. |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1922 history = await self.host.memory.storage.get( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1923 client, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1924 History, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1925 History.origin_id, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1926 item_id, |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1927 (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
|
1928 ) |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1929 |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1930 if history is not None: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1931 # it's a direct message |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1932 if history.source_jid != client.jid: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1933 log.warning( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1934 f"retractation received from an entity ''{client.jid}) which is " |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1935 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
|
1936 "hack attemps?" |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1937 ) |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1938 raise exceptions.PermissionError("forbidden") |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1939 |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1940 await self._r.retractByHistory(client, history) |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1941 else: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1942 # no history in cache with this ID, it's probably a pubsub item |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1943 cached_node = await self.host.memory.storage.getPubsubNode( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1944 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
|
1945 ) |
3804
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1946 if cached_node is None: |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1947 log.warning( |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1948 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
|
1949 "which is not cached" |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1950 ) |
36b167ddbfca
component AP gateway: AP delete activity => message retract:
Goffi <goffi@goffi.org>
parents:
3803
diff
changeset
|
1951 raise exceptions.NotFound |
3793
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1952 await self.host.memory.storage.deletePubsubItems(cached_node, [item_id]) |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1953 # 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
|
1954 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
|
1955 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
|
1956 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
|
1957 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
|
1958 continue |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1959 self.pubsub_service.notifyRetract( |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1960 client.jid, |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1961 node, |
b5c9021020df
component AP gateway: convert `Delete` AP activities to corresponding Pubsub `retract`:
Goffi <goffi@goffi.org>
parents:
3792
diff
changeset
|
1962 [(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
|
1963 ) |