Mercurial > libervia-backend
annotate sat/plugins/plugin_exp_invitation_pubsub.py @ 3758:b7cef1b24f83
plugins XEP-0060, XEP-0376, XEP-0465, CLI: PAM + PSS implementation:
- update psSubscriptionsGet to use serialised return value
- implement XEP-0376 Pubsub Account Management
- implement XEP-0465 Public Pubsub Subscriptions
- CLI `pubsub` commands updated accordingly, and added `--public` flags to `subscribe`,
`Subscriptions` and `node Subscriptions get`
⚠ `XEP-0465` is speculative, the XEP has been accepted by council but not published yet.
As is should be the next one, and current latest one is `XEP-0464`, `XEP-0465` has been
anticipated.
rel 365
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 13 May 2022 18:38:05 +0200 |
parents | edc79cefe968 |
children | 26c3e1bc7fb7 |
rev | line source |
---|---|
3462 | 1 #!/usr/bin/env python3 |
2 | |
3 # SàT plugin to send invitations for Pubsub | |
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) | |
5 | |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
19 from typing import Optional | |
20 from twisted.internet import defer | |
21 from twisted.words.protocols.jabber import jid | |
22 from twisted.words.xish import domish | |
23 from sat.core.i18n import _ | |
24 from sat.core.constants import Const as C | |
25 from sat.core.log import getLogger | |
26 from sat.core.xmpp import SatXMPPEntity | |
27 from sat.tools import utils | |
28 from sat.tools.common import data_format | |
29 | |
30 log = getLogger(__name__) | |
31 | |
32 | |
33 PLUGIN_INFO = { | |
34 C.PI_NAME: "Pubsub Invitation", | |
35 C.PI_IMPORT_NAME: "PUBSUB_INVITATION", | |
36 C.PI_TYPE: "EXP", | |
37 C.PI_PROTOCOLS: [], | |
38 C.PI_DEPENDENCIES: ["XEP-0060", "INVITATION"], | |
39 C.PI_RECOMMENDATIONS: [], | |
40 C.PI_MAIN: "PubsubInvitation", | |
41 C.PI_HANDLER: "no", | |
42 C.PI_DESCRIPTION: _("Invitations for pubsub based features"), | |
43 } | |
44 | |
45 | |
46 class PubsubInvitation: | |
47 | |
48 def __init__(self, host): | |
49 log.info(_("Pubsub Invitation plugin initialization")) | |
50 self.host = host | |
51 self._p = host.plugins["XEP-0060"] | |
52 # namespace to handler map | |
53 self._ns_handler = {} | |
54 host.bridge.addMethod( | |
55 "psInvite", | |
56 ".plugin", | |
57 in_sign="sssssss", | |
58 out_sign="", | |
59 method=self._sendPubsubInvitation, | |
60 async_=True | |
61 ) | |
62 | |
63 def register( | |
64 self, | |
65 namespace: str, | |
66 handler | |
67 ) -> None: | |
68 self._ns_handler[namespace] = handler | |
69 self.host.plugins["INVITATION"].registerNamespace(namespace, self.onInvitation) | |
70 | |
71 def _sendPubsubInvitation( | |
72 self, invitee_jid_s, service_s, node, item_id=None, | |
73 name=None, extra_s='', profile_key=C.PROF_KEY_NONE): | |
74 client = self.host.getClient(profile_key) | |
75 invitee_jid = jid.JID(invitee_jid_s) | |
76 service = jid.JID(service_s) | |
77 extra = data_format.deserialise(extra_s) | |
78 return defer.ensureDeferred( | |
79 self.invite( | |
80 client, | |
81 invitee_jid, | |
82 service, | |
83 node, | |
84 item_id or None, | |
85 name=name or None, | |
86 extra=extra | |
87 ) | |
88 ) | |
89 | |
90 async def invite( | |
91 self, | |
92 client: SatXMPPEntity, | |
93 invitee_jid: jid.JID, | |
94 service: jid.JID, | |
95 node: str, | |
96 item_id: Optional[str] = None, | |
97 name: str = '', | |
98 extra: Optional[dict] = None, | |
99 ) -> None: | |
100 if extra is None: | |
101 extra = {} | |
102 else: | |
103 namespace = extra.get("namespace") | |
104 if namespace: | |
105 try: | |
106 handler = self._ns_handler[namespace] | |
107 preflight = handler.invitePreflight | |
108 except KeyError: | |
109 pass | |
110 except AttributeError: | |
111 log.debug(f"no invitePreflight method found for {namespace!r}") | |
112 else: | |
113 await utils.asDeferred( | |
114 preflight, | |
115 client, invitee_jid, service, node, item_id, name, extra | |
116 ) | |
117 if item_id is None: | |
118 item_id = extra.pop("default_item_id", None) | |
119 | |
120 # we authorize our invitee to see the nodes of interest | |
121 await self._p.setNodeAffiliations(client, service, node, {invitee_jid: "member"}) | |
122 log.debug(f"affiliation set on {service}'s {node!r} node") | |
123 | |
124 # now we send the invitation | |
125 self.host.plugins["INVITATION"].sendPubsubInvitation( | |
126 client, | |
127 invitee_jid, | |
128 service, | |
129 node, | |
130 item_id, | |
131 name=name or None, | |
132 extra=extra | |
133 ) | |
134 | |
135 async def onInvitation( | |
136 self, | |
137 client: SatXMPPEntity, | |
138 namespace: str, | |
139 name: str, | |
140 extra: dict, | |
141 service: jid.JID, | |
142 node: str, | |
143 item_id: Optional[str], | |
144 item_elt: domish.Element | |
145 ) -> None: | |
146 if extra is None: | |
147 extra = {} | |
148 try: | |
149 handler = self._ns_handler[namespace] | |
150 preflight = handler.onInvitationPreflight | |
151 except KeyError: | |
152 pass | |
153 except AttributeError: | |
154 log.debug(f"no onInvitationPreflight method found for {namespace!r}") | |
155 else: | |
156 await utils.asDeferred( | |
157 preflight, | |
158 client, namespace, name, extra, service, node, item_id, item_elt | |
159 ) | |
160 if item_id is None: | |
161 item_id = extra.pop("default_item_id", None) | |
162 creator = extra.pop("creator", False) | |
163 element = extra.pop("element", None) | |
164 if not name: | |
165 name = extra.pop("name", "") | |
166 | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3462
diff
changeset
|
167 return await self.host.plugins['LIST_INTEREST'].registerPubsub( |
3462 | 168 client, namespace, service, node, item_id, creator, |
169 name, element, extra) |