annotate sat_pubsub/pam.py @ 491:4e8e8788bc86

Bookmark compatibility layer: The new `bookmark_compat` module add a compatibility layer between XEP-0048 (with XEP-0049 private XML storage) and XEP-0402, i.e. it implements the `urn:xmpp:bookmarks:1#compat` feature.
author Goffi <goffi@goffi.org>
date Thu, 21 Nov 2024 11:03:51 +0100
parents 23a51b139024
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
478
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
2 #
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Copyright (c) 2015-2022 Jérôme Poisson
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
4
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
5
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
10
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
15
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
18
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
19 "This module implements XEP-0376 (Pubsub Account Management)"
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
20
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from typing import Optional
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
22
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from twisted.internet import defer
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from twisted.python import log
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import jid, xmlstream, error as jabber_error
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.words.xish import domish
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from wokkel import disco, iwokkel, pubsub, data_form
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from wokkel.iwokkel import IPubSubService
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from zope.interface import implementer
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
30
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from sat_pubsub import error
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
32
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
33 NS_PAM = "urn:xmpp:pam:0"
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
34 PAM_SUB_XPATH = (
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
35 f'/iq[@type="set"]/pam[@xmlns="{NS_PAM}"]/subscribe[@xmlns="{pubsub.NS_PUBSUB}"]'
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
36 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
37 PAM_UNSUB_XPATH = (
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
38 f'/iq[@type="set"]/pam[@xmlns="{NS_PAM}"]/unsubscribe[@xmlns="{pubsub.NS_PUBSUB}"]'
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
39 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
40 PAM_SUBSCRIPTIONS_XPATH = (
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
41 f'/iq[@type="get"]/subscriptions[@xmlns="{NS_PAM}"]'
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
42 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
43
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
44
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
45 @implementer(iwokkel.IDisco)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
46 class PAMHandler(disco.DiscoClientProtocol):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
47
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
48 def __init__(self, service_jid):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
49 super(PAMHandler, self).__init__()
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.backend = None
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
51
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
52 def connectionInitialized(self):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
53 for handler in self.parent.handlers:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
54 if IPubSubService.providedBy(handler):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
55 self._pubsub_service = handler
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
56 break
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
57 self.backend = self.parent.parent.getServiceNamed('backend')
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
58 self.xmlstream.addObserver(PAM_SUB_XPATH, self._onSubscribe)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
59 self.xmlstream.addObserver(PAM_UNSUB_XPATH, self._onUnsubscribe)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
60 self.xmlstream.addObserver(PAM_SUBSCRIPTIONS_XPATH, self._onSubscriptions)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
61
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
62 def getServerUser(self, iq_elt: domish.Element) -> Optional[jid.JID]:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
63 """Get JID of sender if it's a user from our server
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
64
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
65 If it's a user from an external server, None is returned and a message is log
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
66 """
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
67 from_jid = jid.JID(iq_elt["from"])
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
68 if not self.backend.isFromServer(from_jid):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
69 log.msg(f"ignoring PAM request from external user: {iq_elt.toXml()}")
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
70 else:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
71 return jid.JID(iq_elt["from"])
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
72
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
73 def onSubscribeResult(self, iq_req_elt, iq_result_elt, pam_iq_elt):
480
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
74 subscription_elt = iq_result_elt.pubsub.subscription
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
75 if subscription_elt is not None:
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
76 destinee_jid = jid.JID(iq_req_elt["from"])
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
77 sender_jid = jid.JID(iq_req_elt["to"])
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
78 message_elt = domish.Element((None, "message"))
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
79 message_elt["to"] = destinee_jid.userhost()
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
80 message_elt["from"] = destinee_jid.userhost()
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
81 # XXX: we explicitely store the notification to be sure that all clients get it
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
82 message_elt.addElement(("urn:xmpp:hints", "store"))
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
83 notify_elt = message_elt.addElement((NS_PAM, "notify"))
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
84 notify_elt["service"] = sender_jid.full()
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
85 notify_elt.addChild(subscription_elt)
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
86 self.backend.privilege.sendMessage(message_elt)
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
87 pam_iq_result_elt = xmlstream.toResponse(pam_iq_elt, 'result')
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
88 else:
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
89 # no <subscription> element, this must be an error
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
90 error_elt = iq_result_elt.error
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
91 if error_elt is None:
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
92 log.msg(f"Invalid reply received: {iq_result_elt.toXml()}")
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
93 error_elt = jabber_error.StanzaError(
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
94 "service-unavailable",
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
95 "received invalid reply from external pubsub service"
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
96 ).getElement()
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
97 pam_iq_result_elt = xmlstream.toResponse(pam_iq_elt, 'error')
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
98 pam_iq_result_elt.addChild(error_elt)
23a51b139024 pam: handle errors in onSubscribeResult
Goffi <goffi@goffi.org>
parents: 478
diff changeset
99
478
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
100 self.xmlstream.send(pam_iq_result_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
101
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
102 async def onSubRequest(self, from_jid, iq_elt, subscribe=True):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
103 try:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
104 service_jid = jid.JID(iq_elt.pam.getAttribute("jid"))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
105 except RuntimeError:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
106 log.msg(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
107 f'Invalid PAM element (missing "jid" attribute): {iq_elt.toXml()}'
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
108 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
109 return
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
110 iq_elt.handled = True
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
111 new_iq_elt = domish.Element((None, "iq"))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
112 new_iq_elt["from"] = from_jid.userhost()
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
113 new_iq_elt["to"] = service_jid.full()
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
114 new_iq_elt.addUniqueId()
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
115 new_iq_elt["type"] = "set"
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
116 new_pubsub_elt = new_iq_elt.addElement((pubsub.NS_PUBSUB, "pubsub"))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
117 new_pubsub_elt.addChild(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
118 iq_elt.pam.subscribe if subscribe else iq_elt.pam.unsubscribe
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
119 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
120 try:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
121 options_elt = next(iq_elt.pam.elements(pubsub.NS_PUBSUB, "options"))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
122 except StopIteration:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
123 options_elt = None
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
124 else:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
125 new_pubsub_elt.addChild(options_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
126
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
127 if self.backend.isFromServer(service_jid):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
128 # the request is handled locally
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
129 new_iq_elt.delegated = True
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
130 self.backend.delegation.registerSendHook(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
131 new_iq_elt, self.onSubscribeResult, iq_elt
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
132 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
133 self.xmlstream.dispatch(new_iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
134 else:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
135 # this is a (un)subscribe request to an external server
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
136 sub_result_elt = await self.backend.privilege.sendIQ(new_iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
137 if sub_result_elt["type"] == "result":
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
138 if subscribe:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
139 node = new_iq_elt.pubsub.subscribe["node"]
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
140 state = sub_result_elt.pubsub.subscription.getAttribute(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
141 "subscription", "subscribed"
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
142 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
143 public = False
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
144 if options_elt is not None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
145 options_form = data_form.findForm(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
146 options_elt, pubsub.NS_PUBSUB_SUBSCRIBE_OPTIONS
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
147 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
148 if options_form is not None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
149 public = options_form.get(f"{{{const.NS_PPS}}}public", False)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
150 await self.backend.storage.addExternalSubscription(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
151 from_jid.userhostJID(),
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
152 service_jid,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
153 node,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
154 state,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
155 public
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
156 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
157 else:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
158 node = new_iq_elt.pubsub.unsubscribe["node"]
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
159 try:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
160 await self.backend.storage.removeExternalSubscription(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
161 from_jid.userhostJID(),
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
162 service_jid,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
163 node,
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
164 )
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
165 except error.NotSubscribed:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
166 pass
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
167 self.onSubscribeResult(new_iq_elt, sub_result_elt, iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
168
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
169 def _onSubscribe(self, iq_elt: domish.Element) -> None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
170 if not iq_elt.delegated:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
171 return
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
172 from_jid = self.getServerUser(iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
173 if from_jid is not None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
174 defer.ensureDeferred(self.onSubRequest(from_jid, iq_elt))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
175
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
176 def _onUnsubscribe(self, iq_elt: domish.Element) -> None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
177 if not iq_elt.delegated:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
178 return
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
179 from_jid = self.getServerUser(iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
180 if from_jid is not None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
181 defer.ensureDeferred(self.onSubRequest(from_jid, iq_elt, subscribe=False))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
182
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
183 async def onSubscriptions(self, from_jid: jid.JID, iq_elt: domish.Element) -> None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
184 iq_elt.handled = True
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
185 try:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
186 subs = await self.backend.storage.getAllSubscriptions(from_jid)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
187 except Exception as e:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
188 error_elt = jabber_error.StanzaError(
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
189 "internal-server-error",
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
190 text=str(e)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
191 ).toResponse(iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
192 self.xmlstream.send(error_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
193 else:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
194 result_elt = xmlstream.toResponse(iq_elt, "result")
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
195 subscriptions_elt = result_elt.addElement((NS_PAM, "subscriptions"))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
196 for sub in subs:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
197 self.backend.addEltFromSubDict(subscriptions_elt, from_jid, sub)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
198 self.xmlstream.send(result_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
199
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
200 def _onSubscriptions(self, iq_elt: domish.Element) -> None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
201 if not iq_elt.delegated:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
202 return
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
203 from_jid = self.getServerUser(iq_elt)
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
204 if from_jid is not None:
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
205 defer.ensureDeferred(self.onSubscriptions(from_jid, iq_elt))
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
206
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
207 def getDiscoInfo(self, requestor, service, nodeIdentifier=''):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
208 return [disco.DiscoFeature(NS_PAM)]
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
209
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
210 def getDiscoItems(self, requestor, service, nodeIdentifier=''):
b544109ab4c4 Privileged Entity update + Pubsub Account Management partial implementation + Public Pubsub Subscription
Goffi <goffi@goffi.org>
parents:
diff changeset
211 return []