Coverage for slidge / core / dispatcher / registration.py: 71%
59 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
1from __future__ import annotations
3import logging
4from typing import TYPE_CHECKING
6from slixmpp import JID, Iq
7from slixmpp.exceptions import XMPPError
9from ...db import GatewayUser
10from .. import config
11from .util import DispatcherMixin
13if TYPE_CHECKING:
14 from slidge.core.gateway import BaseGateway
17class RegistrationMixin(DispatcherMixin):
18 __slots__: list[str] = []
20 def __init__(self, xmpp: BaseGateway) -> None:
21 super().__init__(xmpp)
22 xmpp["xep_0077"].api.register(
23 self.xmpp.make_registration_form, "make_registration_form"
24 )
25 xmpp["xep_0077"].api.register(self._user_get, "user_get")
26 xmpp["xep_0077"].api.register(self._user_validate, "user_validate")
27 xmpp["xep_0077"].api.register(self._user_modify, "user_modify")
28 # kept for slixmpp internal API compat
29 # TODO: either fully use slixmpp internal API or rewrite registration without it at all
30 xmpp["xep_0077"].api.register(lambda *a: None, "user_remove")
32 xmpp.add_event_handler("user_register", self._on_user_register)
33 xmpp.add_event_handler("user_unregister", self._on_user_unregister)
35 def get_user(self, jid: JID) -> GatewayUser | None:
36 session = self.xmpp.get_session_from_jid(jid)
37 if session is None:
38 return None
39 return session.user
41 async def _user_get(
42 self,
43 _gateway_jid: JID,
44 _node: str,
45 ifrom: JID,
46 iq: Iq,
47 ) -> GatewayUser | None:
48 if ifrom is None:
49 ifrom = iq.get_from()
50 return self.get_user(ifrom)
52 async def _user_validate(
53 self,
54 _gateway_jid: JID,
55 _node: str,
56 ifrom: JID,
57 iq: Iq,
58 ) -> None:
59 xmpp = self.xmpp
60 log.debug("User validate: %s", ifrom.bare)
61 form_dict = {f.var: iq.get(f.var) for f in xmpp.REGISTRATION_FIELDS}
62 xmpp.raise_if_not_allowed_jid(ifrom)
63 legacy_module_data = await xmpp.user_prevalidate(ifrom, form_dict)
64 if legacy_module_data is None:
65 legacy_module_data = form_dict
66 with self.xmpp.store.session() as orm:
67 user = GatewayUser(
68 jid=ifrom.bare,
69 legacy_module_data=legacy_module_data,
70 )
71 orm.add(user)
72 orm.commit()
73 log.info("New user: %s", user)
75 async def _user_modify(
76 self,
77 _gateway_jid: JID,
78 _node: str,
79 ifrom: JID,
80 form_dict: dict[str, str | None],
81 ) -> None:
82 await self.xmpp.user_prevalidate(ifrom, form_dict)
83 log.debug("Modify user: %s", ifrom)
84 with self.xmpp.store.session() as orm:
85 user = orm.query(GatewayUser).one_or_none()
86 if user is None:
87 raise XMPPError("internal-server-error", "User not found")
88 user.legacy_module_data.update(form_dict)
89 self.xmpp.store.users.update(user)
91 async def _on_user_register(self, iq: Iq) -> None:
92 session = await self._get_session(iq, wait_for_ready=False)
93 for jid in config.ADMINS:
94 self.xmpp.send_message(
95 mto=jid,
96 mbody=f"{iq.get_from()} has registered",
97 mtype="chat",
98 mfrom=self.xmpp.boundjid.bare,
99 )
100 session.send_gateway_message(self.xmpp.WELCOME_MESSAGE)
101 await self.xmpp.login_wrap(session)
103 async def _on_user_unregister(self, iq: Iq) -> None:
104 await self.xmpp.kill_session(iq.get_from())
107log = logging.getLogger(__name__)