diff --git a/slixmpp/plugins/__init__.py b/slixmpp/plugins/__init__.py index ab8f336d..df1e3150 100644 --- a/slixmpp/plugins/__init__.py +++ b/slixmpp/plugins/__init__.py @@ -87,6 +87,7 @@ __all__ = [ 'xep_0332', # HTTP Over XMPP Transport 'xep_0369', # MIX-CORE 'xep_0377', # Spam reporting + 'xep_0404', # MIX-Anon 'xep_0405', # MIX-PAM 'xep_0421', # Anonymous unique occupant identifiers for MUCs 'xep_0444', # Message Reactions diff --git a/slixmpp/plugins/xep_0404/__init__.py b/slixmpp/plugins/xep_0404/__init__.py new file mode 100644 index 00000000..21dd6814 --- /dev/null +++ b/slixmpp/plugins/xep_0404/__init__.py @@ -0,0 +1,13 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2020 Mathieu Pasquet + This file is part of Slixmpp. + + See the file LICENSE for copying permission. +""" + +from slixmpp.plugins.base import register_plugin +from slixmpp.plugins.xep_0404.stanza import Participant +from slixmpp.plugins.xep_0404.mix_anon import XEP_0404 + +register_plugin(XEP_0404) diff --git a/slixmpp/plugins/xep_0404/mix_anon.py b/slixmpp/plugins/xep_0404/mix_anon.py new file mode 100644 index 00000000..d8c42381 --- /dev/null +++ b/slixmpp/plugins/xep_0404/mix_anon.py @@ -0,0 +1,101 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2020 Mathieu Pasquet + This file is part of Slixmpp. + + See the file LICENSE for copying permission. +""" +from typing import ( + Dict, + Optional, + Set, + Tuple, +) + +from slixmpp import JID, Message, Iq +from slixmpp.exceptions import IqError, IqTimeout +from slixmpp.plugins import BasePlugin +from slixmpp.xmlstream import register_stanza_plugin +from slixmpp.xmlstream.matcher import MatchXPath +from slixmpp.xmlstream.handler import Callback +from slixmpp.plugins.xep_0404 import stanza +from slixmpp.plugins.xep_0004.stanza import Form + + +NODES = [ + 'urn:xmpp:mix:nodes:jidmap', +] + + +class XEP_0404(BasePlugin): + '''XEP-0404: MIX JID Hidden Channels''' + + name = 'xep_0404' + description = 'MIX-ANON' + dependencies = {'xep_0369'} + stanza = stanza + namespace = stanza.NS + + def plugin_init(self) -> None: + stanza.register_plugins() + + async def get_anon_raw(self, channel: JID, *, + ifrom: Optional[JID] = None, **pubsubkwargs) -> Iq: + """ + Get the jid-participant mapping result (raw). + :param JID channel: MIX channel JID + """ + return await self.xmpp['xep_0030'].get_items( + channel.bare, + ifrom=ifrom, + **pubsubkwargs + ) + + async def get_anon_by_jid(self, channel: JID, *, + ifrom: Optional[JID] = None, **pubsubkwargs) -> Dict[JID, str]: + """ + Get the jid-participant mapping, by JID + + :param JID channel: MIX channel JID + """ + raw = await self.get_anon_raw(channel, ifrom=ifrom, **pubsubkwargs) + mapping = {} + for item in raw['pubsub']['items']: + mapping[item['anon_participant']['jid']] = item['id'] + return mapping + + async def get_anon_by_id(self, channel: JID, *, + ifrom: Optional[JID] = None, **pubsubkwargs) -> Dict[str, JID]: + """ + Get the jid-participant mapping, by participant id + + :param JID channel: MIX channel JID + """ + raw = await self.get_anon_raw(channel, ifrom=ifrom, **pubsubkwargs) + mapping = {} + for item in raw['pubsub']['items']: + mapping[item['id']] = item['anon_participant']['jid'] + return mapping + + async def get_preferences(self, channel: JID, *, + ifrom: Optional[JID] = None, **iqkwargs) -> Form: + """ + Get channel preferences with default values. + :param JID channel: MIX channel JID + """ + iq = self.xmpp.make_iq_get(ito=channel.bare, ifrom=ifrom) + iq.enable('user_preference') + prefs_stanza = await iq.send(**iqkwargs) + return prefs_stanza['user_preference']['form'] + + async def set_preferences(self, channel: JID, form: Form, *, + ifrom: Optional[JID] = None, **iqkwargs) -> Form: + """ + Set channel preferences + :param JID channel: MIX channel JID + :param Form form: A 0004 form with updated preferences + """ + iq = self.xmpp.make_iq_set(ito=channel.bare, ifrom=ifrom) + iq['user_preference']['form'] = form + prefs_result = await iq.send(**iqkwargs) + return prefs_result['user_preference']['form'] diff --git a/slixmpp/plugins/xep_0404/stanza.py b/slixmpp/plugins/xep_0404/stanza.py new file mode 100644 index 00000000..9bb9308e --- /dev/null +++ b/slixmpp/plugins/xep_0404/stanza.py @@ -0,0 +1,43 @@ +""" + Slixmpp: The Slick XMPP Library + Copyright (C) 2020 Mathieu Pasquet + This file is part of Slixmpp. + + See the file LICENSE for copying permissio +""" + +from slixmpp.xmlstream import ( + ElementBase, + register_stanza_plugin, +) +from slixmpp import Iq + +from slixmpp.plugins.xep_0004.stanza import Form +from slixmpp.plugins.xep_0060.stanza import ( + EventItem, + Item, +) + +NS = 'urn:xmpp:mix:anon:0' + + +class Participant(ElementBase): + namespace = NS + name = 'participant' + plugin_attrib = 'anon_participant' + interfaces = {'jid'} + sub_interfaces = {'jid'} + + +class UserPreference(ElementBase): + namespace = NS + name = 'user-preference' + plugin_attrib = 'user_preference' + + +def register_plugins(): + register_stanza_plugin(EventItem, Participant) + register_stanza_plugin(Item, Participant) + + register_stanza_plugin(Iq, UserPreference) + register_stanza_plugin(UserPreference, Form)