annotate libervia/backend/plugins/plugin_comp_ap_gateway/pubsub_service.py @ 4263:2109d864a3e7

plugin XEP-470: Don't file configuration on `feature-not-implemented`.
author Goffi <goffi@goffi.org>
date Wed, 12 Jun 2024 22:35:13 +0200
parents 49019947cc76
children 0d7bb4df2343
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia ActivityPub Gateway
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
19 from typing import Optional, Tuple, List, Dict, Any, Union
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
20 from urllib.parse import urlparse
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
21 from pathlib import Path
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
22 from base64 import b64encode
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
23 import tempfile
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
24
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
25 from twisted.internet import defer, threads
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
26 from twisted.words.protocols.jabber import jid, error
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
27 from twisted.words.xish import domish
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
28 from wokkel import rsm, pubsub, disco
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
29
4071
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
30 from libervia.backend.core.i18n import _
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
31 from libervia.backend.core import exceptions
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
32 from libervia.backend.core.core_types import SatXMPPEntity
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
33 from libervia.backend.core.log import getLogger
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
34 from libervia.backend.core.constants import Const as C
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
35 from libervia.backend.tools import image
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
36 from libervia.backend.tools.utils import ensure_deferred
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
37 from libervia.backend.tools.web import download_file
4b842c1fb686 refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents: 4037
diff changeset
38 from libervia.backend.memory.sqla_mapping import PubsubSub, SubscriptionState
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
39
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
40 from .constants import (
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
41 TYPE_ACTOR,
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
42 ST_AVATAR,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
43 MAX_AVATAR_SIZE
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
44 )
3682
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 log = getLogger(__name__)
7c990aaa49d3 comp AP Gateway: ActivityPub Component first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
49 # all nodes have the same config
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
50 NODE_CONFIG = [
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
51 {"var": "pubsub#persist_items", "type": "boolean", "value": True},
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
52 {"var": "pubsub#max_items", "value": "max"},
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
53 {"var": "pubsub#access_model", "type": "list-single", "value": "open"},
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
54 {"var": "pubsub#publish_model", "type": "list-single", "value": "open"},
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
55
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
56 ]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
57
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
58 NODE_CONFIG_VALUES = {c["var"]: c["value"] for c in NODE_CONFIG}
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
59 NODE_OPTIONS = {c["var"]: {} for c in NODE_CONFIG}
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
60 for c in NODE_CONFIG:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
61 NODE_OPTIONS[c["var"]].update({k:v for k,v in c.items() if k not in ("var", "value")})
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
62
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
63
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
64 class APPubsubService(rsm.PubSubService):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
65 """Pubsub service for XMPP requests"""
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
66
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
67 def __init__(self, apg):
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
68 super(APPubsubService, self).__init__()
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
69 self.host = apg.host
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
70 self.apg = apg
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
71 self.discoIdentity = {
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
72 "category": "pubsub",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
73 "type": "service",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
74 "name": "Libervia ActivityPub Gateway",
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
75 }
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
76
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
77 async def get_ap_actor_ids_and_inbox(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
78 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
79 requestor: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
80 recipient: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
81 ) -> Tuple[str, str, str]:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
82 """Get AP actor IDs from requestor and destinee JIDs
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
83
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
84 @param requestor: XMPP entity doing a request to an AP actor via the gateway
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
85 @param recipient: JID mapping an AP actor via the gateway
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
86 @return: requestor actor ID, recipient actor ID and recipient inbox
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
87 @raise error.StanzaError: "item-not-found" is raised if not user part is specified
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
88 in requestor
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
89 """
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
90 if not recipient.user:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
91 raise error.StanzaError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
92 "item-not-found",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
93 text="No user part specified"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
94 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
95 requestor_actor_id = self.apg.build_apurl(TYPE_ACTOR, requestor.userhost())
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
96 recipient_account = self.apg._e.unescape(recipient.user)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
97 recipient_actor_id = await self.apg.get_ap_actor_id_from_account(recipient_account)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
98 inbox = await self.apg.get_ap_inbox_from_id(recipient_actor_id, use_shared=False)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
99 return requestor_actor_id, recipient_actor_id, inbox
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
100
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
101
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
102 @ensure_deferred
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
103 async def publish(self, requestor, service, nodeIdentifier, items):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
104 if self.apg.local_only and not self.apg.is_local(requestor):
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
105 raise error.StanzaError(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
106 "forbidden",
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
107 "Only local users can publish on this gateway."
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
108 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
109 if not service.user:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
110 raise error.StanzaError(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
111 "bad-request",
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
112 "You must specify an ActivityPub actor account in JID user part."
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
113 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
114 ap_account = self.apg._e.unescape(service.user)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
115 if ap_account.count("@") != 1:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
116 raise error.StanzaError(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
117 "bad-request",
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
118 f"{ap_account!r} is not a valid ActivityPub actor account."
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
119 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
120
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
121 client = self.apg.client.get_virtual_client(requestor)
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
122 if self.apg._pa.is_attachment_node(nodeIdentifier):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
123 await self.apg.convert_and_post_attachments(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
124 client, ap_account, service, nodeIdentifier, items, publisher=requestor
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
125 )
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
126 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
127 await self.apg.convert_and_post_items(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
128 client, ap_account, service, nodeIdentifier, items
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
129 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
130 cached_node = await self.host.memory.storage.get_pubsub_node(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
131 client, service, nodeIdentifier, with_subscriptions=True, create=True
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
132 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
133 await self.host.memory.storage.cache_pubsub_items(
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
134 client,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
135 cached_node,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
136 items
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
137 )
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
138 for subscription in cached_node.subscriptions:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
139 if subscription.state != SubscriptionState.SUBSCRIBED:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
140 continue
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
141 self.notifyPublish(
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
142 service,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
143 nodeIdentifier,
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
144 [(subscription.subscriber, None, items)]
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
145 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
146
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
147 async def ap_following_2_elt(self, requestor_actor_id: str, ap_item: dict) -> domish.Element:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
148 """Convert actor ID from following collection to XMPP item
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
149
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
150 @param requestor_actor_id: ID of the actor doing the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
151 @param ap_item: AP item from which actor ID must be extracted.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
152 """
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
153 actor_id = ap_item["id"]
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
154 actor_jid = await self.apg.get_jid_from_id(requestor_actor_id, actor_id)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
155 subscription_elt = self.apg._pps.build_subscription_elt(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
156 self.apg._m.namespace, actor_jid
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
157 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
158 item_elt = pubsub.Item(id=actor_id, payload=subscription_elt)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
159 return item_elt
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
160
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
161 async def ap_follower_2_elt(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
162 self,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
163 requestor_actor_id: str,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
164 ap_item: dict
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
165 ) -> domish.Element:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
166 """Convert actor ID from followers collection to XMPP item
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
167
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
168 @param requestor_actor_id: ID of the actor doing the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
169 @param ap_item: AP item from which actor ID must be extracted.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
170 """
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
171 actor_id = ap_item["id"]
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
172 actor_jid = await self.apg.get_jid_from_id(requestor_actor_id, actor_id)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
173 subscriber_elt = self.apg._pps.build_subscriber_elt(actor_jid)
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
174 item_elt = pubsub.Item(id=actor_id, payload=subscriber_elt)
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
175 return item_elt
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
176
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
177 async def generate_v_card(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
178 self,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
179 requestor_actor_id: str,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
180 ap_account: str
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
181 ) -> domish.Element:
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
182 """Generate vCard4 (XEP-0292) item element from ap_account's metadata
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
183
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
184 @param requestor_actor_id: ID of the actor doing the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
185 @param ap_account: AP account from where the vcard must be retrieved.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
186 @return: <item> with the <vcard> element
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
187 """
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
188 actor_data = await self.apg.get_ap_actor_data_from_account(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
189 requestor_actor_id,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
190 ap_account
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
191 )
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
192 identity_data = {}
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
193
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
194 summary = actor_data.get("summary")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
195 # summary is HTML, we have to convert it to text
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
196 if summary:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
197 identity_data["description"] = await self.apg._t.convert(
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
198 summary,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
199 self.apg._t.SYNTAX_XHTML,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
200 self.apg._t.SYNTAX_TEXT,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
201 False,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
202 )
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
203
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
204 for field in ("name", "preferredUsername"):
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
205 value = actor_data.get(field)
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
206 if value:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
207 identity_data.setdefault("nicknames", []).append(value)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
208 vcard_elt = self.apg._v.dict_2_v_card(identity_data)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
209 item_elt = domish.Element((pubsub.NS_PUBSUB, "item"))
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
210 item_elt.addChild(vcard_elt)
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
211 item_elt["id"] = self.apg._p.ID_SINGLETON
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
212 return item_elt
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
213
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
214 async def get_avatar_data(
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
215 self,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
216 client: SatXMPPEntity,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
217 requestor_actor_id: str,
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
218 ap_account: str
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
219 ) -> dict[str, Any]:
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
220 """Retrieve actor's avatar if any, cache it and file actor_data
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
221
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
222 @param client: client to use for the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
223 @param requestor_actor_id: ID of the actor doing the request.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
224 @param ap_account: AP account from where the avatar data must be retrieved.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
225 @return: Avatar data.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
226 ``cache_uid``, `path``` and ``media_type`` keys are always filed.
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
227 ``base64`` key is only filled if the file was not already in cache.
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
228 """
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
229 actor_data = await self.apg.get_ap_actor_data_from_account(ap_account)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
230
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
231 for icon in await self.apg.ap_get_list(requestor_actor_id, actor_data, "icon"):
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
232 url = icon.get("url")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
233 if icon["type"] != "Image" or not url:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
234 continue
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
235 parsed_url = urlparse(url)
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
236 if not parsed_url.scheme in ("http", "https"):
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
237 log.warning(f"unexpected URL scheme: {url!r}")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
238 continue
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
239 filename = Path(parsed_url.path).name
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
240 if not filename:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
241 log.warning(f"ignoring URL with invald path: {url!r}")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
242 continue
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
243 break
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
244 else:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
245 raise error.StanzaError("item-not-found")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
246
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
247 key = f"{ST_AVATAR}{url}"
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
248 cache_uid = await client._ap_storage.get(key)
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
249
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
250 if cache_uid is None:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
251 cache = None
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
252 else:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
253 cache = self.apg.host.common_cache.get_metadata(cache_uid)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
254
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
255 if cache is None:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
256 with tempfile.TemporaryDirectory() as dir_name:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
257 dest_path = Path(dir_name, filename)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
258 await download_file(url, dest_path, max_size=MAX_AVATAR_SIZE)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
259 avatar_data = {
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
260 "path": dest_path,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
261 "filename": filename,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
262 'media_type': image.guess_type(dest_path),
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
263 }
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
264
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
265 await self.apg._i.cache_avatar(
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
266 self.apg.IMPORT_NAME,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
267 avatar_data
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
268 )
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
269 else:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
270 avatar_data = {
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
271 "cache_uid": cache["uid"],
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
272 "path": cache["path"],
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
273 "media_type": cache["mime_type"]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
274 }
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
275
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
276 return avatar_data
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
277
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
278 async def generate_avatar_metadata(
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
279 self,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
280 client: SatXMPPEntity,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
281 requestor_actor_id: str,
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
282 ap_account: str
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
283 ) -> domish.Element:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
284 """Generate the metadata element for user avatar
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
285
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
286 @param requestor_actor_id: ID of the actor doing the request.
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
287 @raise StanzaError("item-not-found"): no avatar is present in actor data (in
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
288 ``icon`` field)
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
289 """
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
290 avatar_data = await self.get_avatar_data(client, requestor_actor_id, ap_account)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
291 return self.apg._a.build_item_metadata_elt(avatar_data)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
292
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
293 def _blocking_b_6_4_encode_avatar(self, avatar_data: Dict[str, Any]) -> None:
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
294 with avatar_data["path"].open("rb") as f:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
295 avatar_data["base64"] = b64encode(f.read()).decode()
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
296
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
297 async def generate_avatar_data(
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
298 self,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
299 client: SatXMPPEntity,
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
300 requestor_actor_id: str,
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
301 ap_account: str,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
302 itemIdentifiers: Optional[List[str]],
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
303 ) -> domish.Element:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
304 """Generate the data element for user avatar
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
305
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
306 @param requestor_actor_id: ID of the actor doing the request.
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
307 @raise StanzaError("item-not-found"): no avatar cached with requested ID
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
308 """
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
309 if not itemIdentifiers:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
310 avatar_data = await self.get_avatar_data(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
311 client,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
312 requestor_actor_id,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
313 ap_account
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
314 )
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
315 if "base64" not in avatar_data:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
316 await threads.deferToThread(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
317 self._blocking_b_6_4_encode_avatar,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
318 avatar_data
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
319 )
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
320 else:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
321 if len(itemIdentifiers) > 1:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
322 # only a single item ID is supported
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
323 raise error.StanzaError("item-not-found")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
324 item_id = itemIdentifiers[0]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
325 # just to be sure that that we don't have an empty string
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
326 assert item_id
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
327 cache_data = self.apg.host.common_cache.get_metadata(item_id)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
328 if cache_data is None:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
329 raise error.StanzaError("item-not-found")
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
330 avatar_data = {
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
331 "cache_uid": item_id,
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
332 "path": cache_data["path"]
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
333 }
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
334 await threads.deferToThread(self._blocking_b_6_4_encode_avatar, avatar_data)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
335
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
336 return self.apg._a.build_item_data_elt(avatar_data)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
337
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
338 @ensure_deferred
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
339 async def items(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
340 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
341 requestor: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
342 service: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
343 node: str,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
344 maxItems: Optional[int],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
345 itemIdentifiers: Optional[List[str]],
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
346 rsm_req: Optional[rsm.RSMRequest]
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
347 ) -> Tuple[List[domish.Element], Optional[rsm.RSMResponse]]:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
348 if not service.user:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
349 return [], None
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
350 ap_account = self.host.plugins["XEP-0106"].unescape(service.user)
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
351 if ap_account.count("@") != 1:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
352 log.warning(f"Invalid AP account used by {requestor}: {ap_account!r}")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
353 return [], None
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
354
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
355 requestor_actor_id = self.apg.build_apurl(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
356 TYPE_ACTOR,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
357 await self.apg.get_ap_account_from_jid_and_node(service, node)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
358 )
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
359
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
360 # cached_node may be pre-filled with some nodes (e.g. attachments nodes),
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
361 # otherwise it is filled when suitable
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
362 cached_node = None
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
363 client = self.apg.client
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
364 kwargs = {}
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
365
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
366 if node == self.apg._pps.subscriptions_node:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
367 collection_name = "following"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
368 parser = self.ap_following_2_elt
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
369 kwargs["only_ids"] = True
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
370 use_cache = False
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
371 elif node.startswith(self.apg._pps.subscribers_node_prefix):
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
372 collection_name = "followers"
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
373 parser = self.ap_follower_2_elt
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
374 kwargs["only_ids"] = True
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
375 use_cache = False
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
376 elif node == self.apg._v.node:
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
377 # vCard4 request
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
378 item_elt = await self.generate_v_card(requestor_actor_id, ap_account)
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
379 return [item_elt], None
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
380 elif node == self.apg._a.namespace_metadata:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
381 item_elt = await self.generate_avatar_metadata(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
382 self.apg.client,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
383 requestor_actor_id,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
384 ap_account
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
385 )
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
386 return [item_elt], None
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
387 elif node == self.apg._a.namespace_data:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
388 item_elt = await self.generate_avatar_data(
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
389 self.apg.client,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
390 requestor_actor_id,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
391 ap_account,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
392 itemIdentifiers
3824
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
393 )
6329ee6b6df4 component AP: convert AP identity data to XMPP:
Goffi <goffi@goffi.org>
parents: 3792
diff changeset
394 return [item_elt], None
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
395 elif self.apg._pa.is_attachment_node(node):
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
396 use_cache = True
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
397 # we check cache here because we emit an item-not-found error if the node is
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
398 # not in cache, as we are not dealing with real AP items
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
399 cached_node = await self.host.memory.storage.get_pubsub_node(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
400 client, service, node
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
401 )
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
402 if cached_node is None:
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
403 raise error.StanzaError("item-not-found")
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
404 else:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
405 if node.startswith(self.apg._m.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
406 parser = self.apg.ap_item_2_mb_elt
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
407 elif node.startswith(self.apg._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
408 parser = self.apg.ap_events.ap_item_2_event_elt
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
409 else:
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
410 raise error.StanzaError(
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
411 "feature-not-implemented",
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
412 text=f"AP Gateway {C.APP_VERSION} only supports "
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
413 f"{self.apg._m.namespace} node for now"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
414 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
415 collection_name = "outbox"
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
416 use_cache = True
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
417
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
418 if use_cache:
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
419 if cached_node is None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
420 cached_node = await self.host.memory.storage.get_pubsub_node(
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
421 client, service, node
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
422 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
423 # TODO: check if node is synchronised
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
424 if cached_node is not None:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
425 # the node is cached, we return items from cache
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
426 log.debug(f"node {node!r} from {service} is in cache")
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
427 pubsub_items, metadata = await self.apg._c.get_items_from_cache(
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
428 client, cached_node, maxItems, itemIdentifiers, rsm_request=rsm_req
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
429 )
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
430 try:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
431 rsm_resp = rsm.RSMResponse(**metadata["rsm"])
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
432 except KeyError:
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
433 rsm_resp = None
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
434 return [i.data for i in pubsub_items], rsm_resp
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
435
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
436 if itemIdentifiers:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
437 items = []
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
438 for item_id in itemIdentifiers:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
439 item_data = await self.apg.ap_get(item_id, requestor_actor_id)
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
440 item_elt = await parser(requestor_actor_id, item_data)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
441 items.append(item_elt)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
442 return items, None
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
443 else:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
444 if rsm_req is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
445 if maxItems is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
446 maxItems = 20
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
447 kwargs.update({
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
448 "max_items": maxItems,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
449 "chronological_pagination": False,
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
450 })
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
451 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
452 if len(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
453 [v for v in (rsm_req.after, rsm_req.before, rsm_req.index)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
454 if v is not None]
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
455 ) > 1:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
456 raise error.StanzaError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
457 "bad-request",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
458 text="You can't use after, before and index at the same time"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
459 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
460 kwargs.update({"max_items": rsm_req.max})
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
461 if rsm_req.after is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
462 kwargs["after_id"] = rsm_req.after
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
463 elif rsm_req.before is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
464 kwargs["chronological_pagination"] = False
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
465 if rsm_req.before != "":
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
466 kwargs["after_id"] = rsm_req.before
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
467 elif rsm_req.index is not None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
468 kwargs["start_index"] = rsm_req.index
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
469
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
470 log.info(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
471 f"No cache found for node {node} at {service} (AP account {ap_account}), "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
472 "using Collection Paging to RSM translation"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
473 )
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
474 if self.apg._m.is_comment_node(node):
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
475 parent_item = self.apg._m.get_parent_item(node)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
476 try:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
477 parent_data = await self.apg.ap_get(parent_item, requestor_actor_id)
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
478 collection = await self.apg.ap_get_object(
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
479 requestor_actor_id,
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
480 parent_data.get("object", {}),
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
481 "replies"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
482 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
483 except Exception as e:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
484 raise error.StanzaError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
485 "item-not-found",
4190
92551baea115 component AP gateway: be sure to have a string for error message.
Goffi <goffi@goffi.org>
parents: 4071
diff changeset
486 text=str(e)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
487 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
488 else:
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
489 actor_data = await self.apg.get_ap_actor_data_from_account(
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
490 requestor_actor_id,
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
491 ap_account
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
492 )
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
493 collection = await self.apg.ap_get_object(requestor_actor_id, actor_data, collection_name)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
494 if not collection:
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
495 raise error.StanzaError(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
496 "item-not-found",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
497 text=f"No collection found for node {node!r} (account: {ap_account})"
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
498 )
3764
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
499
125c7043b277 comp AP gateway: publish, (un)subscribe/(un)follow, public subscription/following/followers:
Goffi <goffi@goffi.org>
parents: 3745
diff changeset
500 kwargs["parser"] = parser
4259
49019947cc76 component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents: 4190
diff changeset
501 return await self.apg.get_ap_items(requestor_actor_id, collection, **kwargs)
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
502
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
503 @ensure_deferred
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
504 async def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
3792
865167c34b82 comp AP gateway: convert pubsub item retractation to AP `Delete` activity:
Goffi <goffi@goffi.org>
parents: 3764
diff changeset
505 raise error.StanzaError("forbidden")
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
506
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
507 @ensure_deferred
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
508 async def subscribe(self, requestor, service, nodeIdentifier, subscriber):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
509 # TODO: handle comments nodes
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
510 client = self.apg.client
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
511 # we use PENDING state for microblog, it will be set to SUBSCRIBED once the Follow
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
512 # is accepted. Other nodes are directly set to subscribed, their subscriptions
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
513 # being internal.
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
514 if nodeIdentifier == self.apg._m.namespace:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
515 sub_state = SubscriptionState.PENDING
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
516 else:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
517 sub_state = SubscriptionState.SUBSCRIBED
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
518 node = await self.host.memory.storage.get_pubsub_node(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
519 client, service, nodeIdentifier, with_subscriptions=True
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
520 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
521 if node is None:
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
522 node = await self.host.memory.storage.set_pubsub_node(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
523 client,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
524 service,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
525 nodeIdentifier,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
526 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
527 subscription = None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
528 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
529 try:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
530 subscription = next(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
531 s for s in node.subscriptions
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
532 if s.subscriber == requestor.userhostJID()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
533 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
534 except StopIteration:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
535 subscription = None
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
536
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
537 if subscription is None:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
538 subscription = PubsubSub(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
539 subscriber=requestor.userhostJID(),
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
540 state=sub_state
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
541 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
542 node.subscriptions.append(subscription)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
543 await self.host.memory.storage.add(node)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
544 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
545 if subscription.state is None:
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
546 subscription.state = sub_state
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
547 await self.host.memory.storage.add(node)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
548 elif subscription.state == SubscriptionState.SUBSCRIBED:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
549 log.info(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
550 f"{requestor.userhostJID()} has already a subscription to {node!r} "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
551 f"at {service}. Doing the request anyway."
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
552 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
553 elif subscription.state == SubscriptionState.PENDING:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
554 log.info(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
555 f"{requestor.userhostJID()} has already a pending subscription to "
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
556 f"{node!r} at {service}. Doing the request anyway."
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
557 )
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
558 if sub_state != SubscriptionState.PENDING:
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
559 subscription.state = sub_state
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
560 await self.host.memory.storage.add(node)
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
561 else:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
562 raise exceptions.InternalError(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
563 f"unmanaged subscription state: {subscription.state}"
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
564 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
565
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
566 if nodeIdentifier in (self.apg._m.namespace, self.apg._events.namespace):
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
567 # if we subscribe to microblog or events node, we follow the corresponding
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
568 # account
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
569 req_actor_id, recip_actor_id, inbox = await self.get_ap_actor_ids_and_inbox(
3868
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
570 requestor, service
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
571 )
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
572
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
573 data = self.apg.create_activity("Follow", req_actor_id, recip_actor_id)
3868
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
574
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
575 resp = await self.apg.sign_and_post(inbox, req_actor_id, data)
3868
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
576 if resp.code >= 300:
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
577 text = await resp.text()
37d2c0282304 component AP gateway (pubsub): only emit a `Follow` activity for microblog subscription:
Goffi <goffi@goffi.org>
parents: 3865
diff changeset
578 raise error.StanzaError("service-unavailable", text=text)
3904
0aa7023dcd08 component AP gateway: events:
Goffi <goffi@goffi.org>
parents: 3888
diff changeset
579 return pubsub.Subscription(nodeIdentifier, requestor, "subscribed")
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
580
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
581 @ensure_deferred
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
582 async def unsubscribe(self, requestor, service, nodeIdentifier, subscriber):
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
583 req_actor_id, recip_actor_id, inbox = await self.get_ap_actor_ids_and_inbox(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
584 requestor, service
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
585 )
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
586 data = self.apg.create_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
587 "Undo",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
588 req_actor_id,
4023
78b5f356900c component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents: 3904
diff changeset
589 self.apg.create_activity(
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
590 "Follow",
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
591 req_actor_id,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
592 recip_actor_id
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
593 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
594 )
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
595
4037
524856bd7b19 massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents: 4023
diff changeset
596 resp = await self.apg.sign_and_post(inbox, req_actor_id, data)
3865
59fbb66b2923 component AP gateway: handle XMPP attachments -> AP likes conversion:
Goffi <goffi@goffi.org>
parents: 3824
diff changeset
597 if resp.code >= 300:
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
598 text = await resp.text()
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
599 raise error.StanzaError("service-unavailable", text=text)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
600
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
601 def getConfigurationOptions(self):
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
602 return NODE_OPTIONS
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
603
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
604 def getConfiguration(
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
605 self,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
606 requestor: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
607 service: jid.JID,
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
608 nodeIdentifier: str
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
609 ) -> defer.Deferred:
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
610 return defer.succeed(NODE_CONFIG_VALUES)
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
611
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
612 def getNodeInfo(
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
613 self,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
614 requestor: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
615 service: jid.JID,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
616 nodeIdentifier: str,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
617 pep: bool = False,
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
618 recipient: Optional[jid.JID] = None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
619 ) -> Optional[dict]:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
620 if not nodeIdentifier:
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
621 return None
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
622 info = {
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
623 "type": "leaf",
3745
a8c7e5cef0cb comp AP gateway: signature checking, caching and threads management:
Goffi <goffi@goffi.org>
parents: 3729
diff changeset
624 "meta-data": NODE_CONFIG
3728
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
625 }
b15644cae50d component AP gateway: JID/node ⟺ AP outbox conversion:
Goffi <goffi@goffi.org>
parents: 3684
diff changeset
626 return info