Coverage for slidge/slixfix/xep_0100/gateway.py: 59%
69 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
1import logging
2import warnings
4from slixmpp import JID, Iq, Message, Presence, register_stanza_plugin
5from slixmpp.exceptions import XMPPError
6from slixmpp.plugins.base import BasePlugin
8from slidge.core import config
10from . import stanza
12log = logging.getLogger(__name__)
15class XEP_0100(BasePlugin):
16 name = "xep_0100"
17 description = "XEP-0100: Gateway interaction (slidge)"
18 dependencies = {
19 "xep_0030", # Service discovery
20 "xep_0077", # In band registration
21 "xep_0356", # Privileged entities
22 }
24 default_config = {
25 "component_name": "SliXMPP gateway",
26 "type": "xmpp",
27 "needs_registration": True,
28 }
30 def plugin_init(self):
31 if not self.xmpp.is_component:
32 log.error("Only components can be gateways, aborting plugin load")
33 return
35 self.xmpp["xep_0030"].add_identity(
36 name=self.component_name, category="gateway", itype=self.type
37 )
39 # Without that BaseXMPP sends unsub/unavailable on sub requests, and we don't want that
40 self.xmpp.client_roster.auto_authorize = False
41 self.xmpp.client_roster.auto_subscribe = False
43 self.xmpp.add_event_handler("user_register", self.on_user_register)
44 self.xmpp.add_event_handler("user_unregister", self.on_user_unregister)
45 self.xmpp.add_event_handler(
46 "presence_unsubscribe", self.on_presence_unsubscribe
47 )
49 self.xmpp.add_event_handler("message", self.on_message)
51 register_stanza_plugin(Iq, stanza.Gateway)
53 def plugin_end(self):
54 if not self.xmpp.is_component:
55 self.xmpp.remove_event_handler("user_register", self.on_user_register)
56 self.xmpp.remove_event_handler("user_unregister", self.on_user_unregister)
57 self.xmpp.remove_event_handler(
58 "presence_unsubscribe", self.on_presence_unsubscribe
59 )
61 self.xmpp.remove_event_handler("message", self.on_message)
63 async def get_user(self, stanza):
64 return await self.xmpp["xep_0077"].api["user_get"](None, None, None, stanza)
66 async def on_user_unregister(self, iq: Iq):
67 self.xmpp.send_presence(pto=iq.get_from().bare, ptype="unavailable")
68 self.xmpp.send_presence(pto=iq.get_from().bare, ptype="unsubscribe")
69 self.xmpp.send_presence(pto=iq.get_from().bare, ptype="unsubscribed")
71 async def on_user_register(self, iq: Iq):
72 self.xmpp.client_roster[iq.get_from()].load()
73 await self.add_component_to_roster(jid=iq.get_from())
75 async def add_component_to_roster(self, jid: JID):
76 if config.NO_ROSTER_PUSH:
77 return
78 items = {
79 self.xmpp.boundjid.bare: {
80 "name": self.component_name,
81 "subscription": "both",
82 "groups": ["Slidge"],
83 }
84 }
85 try:
86 await self._set_roster(jid, items)
87 except PermissionError:
88 warnings.warn(
89 "Slidge does not have the privilege to manage users' rosters. "
90 "Users should add the slidge component to their rosters manually."
91 )
92 if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
93 self.xmpp.send_presence(ptype="subscribe", pto=jid.bare)
95 async def _set_roster(self, jid, items):
96 try:
97 await self.xmpp["xep_0356"].set_roster(jid=jid.bare, roster_items=items)
98 except PermissionError:
99 await self.xmpp["xep_0356_old"].set_roster(jid=jid.bare, roster_items=items)
101 def on_presence_unsubscribe(self, p: Presence):
102 if p.get_to() == self.xmpp.boundjid.bare:
103 log.debug("REMOVE: Our roster: %s", self.xmpp.client_roster)
104 self.xmpp["xep_0077"].api["user_remove"](None, None, p["from"], p)
105 self.xmpp.event("user_unregister", p)
107 async def on_message(self, msg: Message):
108 if msg["type"] == "groupchat":
109 return # groupchat messages are out of scope of XEP-0100
111 if msg["to"] == self.xmpp.boundjid.bare:
112 # It may be useful to exchange direct messages with the component
113 self.xmpp.event("gateway_message", msg)
114 return
116 if self.needs_registration and await self.get_user(msg) is None:
117 raise XMPPError(
118 "registration-required", text="You are not registered to this gateway"
119 )
121 self.xmpp.event("legacy_message", msg)