""" 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 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) aliasform.addField(var="salt",ftype="text-single", label="Salt", 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", "salt") 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) 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() else: reg.add_form() 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