Coverage for slidge / core / dispatcher / muc / owner.py: 98%
52 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-06 05:07 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-06 05:07 +0000
1import typing
3from slixmpp import CoroutineCallback, Iq, StanzaPath
4from slixmpp.exceptions import XMPPError
5from slixmpp.plugins.xep_0004.stanza.form import Form
6from slixmpp.xmlstream import StanzaBase
8from ..util import DispatcherMixin, exceptions_to_xmpp_errors
10if typing.TYPE_CHECKING:
11 from slidge.core.gateway import BaseGateway
14class MucOwnerMixin(DispatcherMixin):
15 __slots__: list[str] = []
17 def __init__(self, xmpp: "BaseGateway") -> None:
18 super().__init__(xmpp)
19 xmpp.register_handler(
20 CoroutineCallback(
21 "MUCOwnerGet",
22 StanzaPath("iq@type=get/mucowner_query"),
23 self.on_muc_owner_query,
24 )
25 )
26 xmpp.register_handler(
27 CoroutineCallback(
28 "MUCOwnerSet",
29 StanzaPath("iq@type=set/mucowner_query"),
30 self.on_muc_owner_set,
31 )
32 )
34 @exceptions_to_xmpp_errors
35 async def on_muc_owner_query(self, iq: StanzaBase) -> None:
36 assert isinstance(iq, Iq)
37 muc = await self.get_muc_from_stanza(iq)
39 reply = iq.reply()
41 form = Form(title="Slidge room configuration")
42 form["instructions"] = (
43 "Complete this form to modify the configuration of your room."
44 )
45 form.add_field(
46 var="FORM_TYPE",
47 type="hidden",
48 value="http://jabber.org/protocol/muc#roomconfig",
49 )
50 form.add_field(
51 var="muc#roomconfig_roomname",
52 label="Natural-Language Room Name",
53 type="text-single",
54 value=muc.name,
55 )
56 if muc.HAS_DESCRIPTION:
57 form.add_field(
58 var="muc#roomconfig_roomdesc",
59 label="Short Description of Room",
60 type="text-single",
61 value=muc.description,
62 )
64 muc_owner = iq["mucowner_query"]
65 muc_owner.append(form)
66 reply.append(muc_owner)
67 reply.send()
69 @exceptions_to_xmpp_errors
70 async def on_muc_owner_set(self, iq: StanzaBase) -> None:
71 assert isinstance(iq, Iq)
72 muc = await self.get_muc_from_stanza(iq)
73 query = iq["mucowner_query"]
75 if form := query.get_plugin("form", check=True):
76 values = form.get_values()
77 await muc.on_set_config(
78 name=values.get("muc#roomconfig_roomname"),
79 description=(
80 values.get("muc#roomconfig_roomdesc")
81 if muc.HAS_DESCRIPTION
82 else None
83 ),
84 )
85 form["type"] = "result"
86 clear = False
87 elif destroy := query.get_plugin("destroy", check=True):
88 reason = destroy["reason"] or None
89 await muc.on_destroy_request(reason)
90 user_participant = await muc.get_user_participant()
91 user_participant.stored.affiliation = "none"
92 user_participant.stored.role = "none"
93 presence = user_participant._make_presence(ptype="unavailable", force=True)
94 presence["muc"].enable("destroy")
95 if reason is not None:
96 presence["muc"]["destroy"]["reason"] = reason
97 user_participant._send(presence)
98 await muc.session.bookmarks.remove(muc, kick=False)
99 clear = True
100 else:
101 raise XMPPError("bad-request")
103 iq.reply(clear=clear).send()