From f70165ef6229a92bf8cfa6f16eff980a4a7491fe Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Wed, 18 Jan 2012 12:27:37 -0500 Subject: Added setup.py and big reorg of the source tree this should fix tickets #10 and #11 --- alias_server/xep_0077.py | 154 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 alias_server/xep_0077.py (limited to 'alias_server/xep_0077.py') diff --git a/alias_server/xep_0077.py b/alias_server/xep_0077.py new file mode 100644 index 0000000..0608dc5 --- /dev/null +++ b/alias_server/xep_0077.py @@ -0,0 +1,154 @@ +""" +Creating a SleekXMPP Plugin + +This is a minimal implementation of XEP-0077 to serve +as a tutorial for creating SleekXMPP plugins. +""" + +from sleekxmpp.plugins.base import base_plugin +from sleekxmpp.xmlstream.handler.callback import Callback +from sleekxmpp.xmlstream.matcher.xpath import MatchXPath +from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin +from sleekxmpp import Iq +from user import User +from config import config +from sleekxmpp.plugins.xep_0004 import Form + +import logging +logger = logging.getLogger(__name__) + +class Registration(ElementBase): + namespace = 'jabber:iq:register' + name = 'query' + plugin_attrib = 'register' + interfaces = set(('registered', 'remove', 'instructions', 'form')) + sub_interfaces = interfaces + subitem = (Form,) + + def get_registered(self): + present = self.xml.find('{%s}registered' % self.namespace) + return present is not None + + def get_remove(self): + present = self.xml.find('{%s}remove' % self.namespace) + return present is not None + + def set_registered(self, registered): + if registered: + self.add_field('registered') + else: + del self['registered'] + + def set_remove(self, remove): + if remove: + self.addField('remove') + else: + del self['remove'] + + def add_field(self, name): + itemXML = ET.Element('{%s}%s' % (self.namespace, name)) + self.xml.append(itemXML) + + def add_form(self): + aliasform = Form(None, self) + aliasform.addField(ftype = "hidden", var = "FORM_TYPE", value = "alias:register") + aliasform.addField(var = "pubkey", ftype = "text-single", label = "Public Key", required = True) + aliasform.addField(var = "privkey", ftype = "text-single", label = "Private Key", required = True) + + def get_form(self): + return Form(self.xml.find('{jabber:x:data}x')).getValues() + + def set_form(self, values): + Form(self.xml.find('{jabber:x:data}x')).setValues(values) + +class xep_0077(base_plugin): + """ + XEP-0077 In-Band Registration + """ + + def plugin_init(self): + self.description = "In-Band Registration" + self.xep = "0077" + self.form_fields = ("privkey", "pubkey") + self.form_instructions = "Please provide the following information to register\ + an alias account" + + self.xmpp.register_handler( + Callback('In-Band Registration', + MatchXPath('{%s}iq/{jabber:iq:register}query' % self.xmpp.default_ns), + self.__handle_registration)) + register_stanza_plugin(Iq, Registration) + + def post_init(self): + base_plugin.post_init(self) + self.xmpp['xep_0030'].add_feature("jabber:iq:register") + + def __handle_registration(self, iq): + registrant = User(iq['from'].bare) + logger.info('User {} sent registration iq'.format(iq['from'].bare)) + if iq['type'] == 'get': + # Registration form requested + self.send_registration_form(iq, registrant) + elif iq['type'] == 'set': + if iq['register']['remove']: + # Remove an account + registrant.unregister() + self.xmpp.event('unregistered_user', iq) + iq.reply().send() + return + + registration_info = iq['register']['form'] + for field in self.form_fields: + if not registration_info[field]: + # Incomplete Registration + self._send_error(iq, '406', 'modify', 'not-acceptable', + "Please fill in all fields.") + return + + try: + registrant.register(registration_info) + # Successful registration + #self.xmpp.event('registered_user', iq) + iq.reply().setPayload(iq['register'].xml) + iq.send() + except: + return + else: + # Conflicting registration + self._send_error(iq, '409', 'cancel', 'conflict', + "That username is already taken.") + + def setForm(self, *fields): + self.form_fields = fields + + def set_instructions(self, instructions): + self.form_instructions = instructions + + def send_registration_form(self, iq, registrant): + reg = iq['register'] + reg.add_form() + if self.form_instructions: + reg['instructions'] = self.form_instructions + if registrant.is_registered(): + reg['registered'] = True + reg['form'] = registrant.get_registration() + + iq.reply().setPayload(reg.xml) + iq.send() + + def _send_error(self, iq, code, error_type, name, text = ''): + iq.reply().setPayload(iq['register'].xml) + iq.error() + iq['error']['code'] = code + iq['error']['type'] = error_type + iq['error']['condition'] = name + iq['error']['text'] = text + iq.send() + +if __name__ == '__main__': + test = Registration() + test.add_form() + print '{}\n'.format(test['form']) + values = {'privkey': 'pomme', 'pubkey': 'poire', 'salt': 'abricot'} + test['form']=values + print test -- cgit v1.2.3-70-g09d2