Mercurial > libervia-backend
diff src/plugins/plugin_xep_0077.py @ 2172:545a1261ac3b
core, plugin XEP-0077: in-band registration fix and move:
in-band was partially in core for historical reason, it has been moved to XEP-0077, and fixed. It is still incomplete, but should work for basic accounts creation.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 08 Mar 2017 20:59:31 +0100 |
parents | 33c8c4973743 |
children | 75002ac33801 |
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0077.py Wed Mar 08 20:44:28 2017 +0100 +++ b/src/plugins/plugin_xep_0077.py Wed Mar 08 20:59:31 2017 +0100 @@ -23,10 +23,11 @@ from sat.core.log import getLogger log = getLogger(__name__) from twisted.words.protocols.jabber import jid -from twisted.words.protocols.jabber.xmlstream import IQ +from twisted.words.protocols.jabber import xmlstream +from twisted.internet import defer, reactor from sat.tools import xml_tools -from wokkel import data_form, compat +from wokkel import data_form NS_REG = 'jabber:iq:register' @@ -40,18 +41,60 @@ C.PI_DESCRIPTION: _("""Implementation of in-band registration""") } +# FIXME: this implementation is incomplete + +class RegisteringAuthenticator(xmlstream.ConnectAuthenticator): + # FIXME: request IQ is not send to check available fields, while XEP recommand to use it + # FIXME: doesn't handle data form or oob + + def __init__(self, jid_, password, email=None): + xmlstream.ConnectAuthenticator.__init__(self, jid_.host) + self.jid = jid_ + self.password = password + self.email = email + self.registered = defer.Deferred() + log.debug(_(u"Registration asked for {jid}").format( + jid = jid_)) + + def connectionMade(self): + log.debug(_(u"Connection made with {server}".format(server=self.jid.host))) + self.xmlstream.otherEntity = jid.JID(self.jid.host) + self.xmlstream.namespace = C.NS_CLIENT + self.xmlstream.sendHeader() + + iq = xmlstream.IQ(self.xmlstream, 'set') + iq["to"] = self.jid.host + query_elt = iq.addElement(('jabber:iq:register', 'query')) + username_elt = query_elt.addElement('username') + username_elt.addContent(self.jid.user) + password_elt = query_elt.addElement('password') + password_elt.addContent(self.password) + if self.email is not None: + email_elt = query_elt.addElement('email') + email_elt.addContent(self.email) + d = iq.send(self.jid.host).addCallbacks(self.registrationCb, self.registrationEb) + d.chainDeferred(self.registered) + + def registrationCb(self, answer): + log.debug(_(u"Registration answer: {}").format(answer.toXml())) + self.xmlstream.sendFooter() + + def registrationEb(self, failure_): + log.info(_("Registration failure: {}").format(unicode(failure_.value))) + self.xmlstream.sendFooter() + raise failure_.value + class XEP_0077(object): def __init__(self, host): log.info(_("Plugin XEP_0077 initialization")) self.host = host - self.triggers = {} # used by other protocol (e.g. XEP-0100) to finish registration. key = target_jid host.bridge.addMethod("inBandRegister", ".plugin", in_sign='ss', out_sign='s', method=self._inBandRegister, async=True) - def _regOk(self, answer, client, post_treat_cb): + def _regCb(self, answer, client, post_treat_cb): """Called after the first get IQ""" try: query_elt = answer.elements(NS_REG, 'query').next() @@ -68,7 +111,7 @@ def submitForm(data, profile): form_elt = xml_tools.XMLUIResultToElt(data) - iq_elt = compat.IQ(client.xmlstream, 'set') + iq_elt = client.IQ() iq_elt['id'] = answer['id'] iq_elt['to'] = answer['from'] query_elt = iq_elt.addElement("query", NS_REG) @@ -82,7 +125,7 @@ submit_reg_id = self.host.registerCallback(submitForm, with_data=True, one_shot=True) return xml_tools.dataForm2XMLUI(form, submit_reg_id) - def _regErr(self, failure, client): + def _regEb(self, failure, client): """Called when something is wrong with registration""" log.info(_("Registration failure: %s") % unicode(failure.value)) raise failure @@ -105,10 +148,26 @@ def inBandRegister(self, to_jid, post_treat_cb=None, profile_key=C.PROF_KEY_NONE): """register to a target JID""" client = self.host.getClient(profile_key) - log.debug(_(u"Asking registration for [%s]") % to_jid.full()) - reg_request = IQ(client.xmlstream, 'get') + log.debug(_(u"Asking registration for {}").format(to_jid.full())) + reg_request = client.IQ(u'get') reg_request["from"] = client.jid.full() reg_request["to"] = to_jid.full() reg_request.addElement('query', NS_REG) - d = reg_request.send(to_jid.full()).addCallbacks(self._regOk, self._regErr, callbackArgs=[client, post_treat_cb], errbackArgs=[client]) + d = reg_request.send(to_jid.full()).addCallbacks(self._regCb, self._regEb, callbackArgs=[client, post_treat_cb], errbackArgs=[client]) return d + + def registerNewAccount(self, client, jid_, password, email=None, host="127.0.0.1", port=C.XMPP_C2S_PORT): + """register a new account on a XMPP server + + @param jid_(jid.JID): request jid to register + @param password(unicode): password of the account + @param email(unicode): email of the account + @param host(unicode): host of the server to register to + @param port(int): port of the server to register to + """ + authenticator = RegisteringAuthenticator(jid_, password, email) + registered_d = authenticator.registered + serverRegistrer = xmlstream.XmlStreamFactory(authenticator) + connector = reactor.connectTCP(host, port, serverRegistrer) + serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect() + return registered_d