- core: 2 new convenient methods: getJidNStream and getClient - new param in plugin info: "handler" to know if there is a handler to plug on profiles clients - plugins with handler now use an other class which is returned to profile client with the new method "getHandler" and pluged when connecting
143 lines
6.1 KiB
Python
Executable file
143 lines
6.1 KiB
Python
Executable file
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
SAT plugin for managing xep-0077
|
|
Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org)
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
from logging import debug, info, error
|
|
from twisted.words.protocols.jabber import client, jid
|
|
from twisted.words.protocols.jabber import error as jab_error
|
|
from twisted.words.protocols.jabber.xmlstream import IQ
|
|
from twisted.internet import reactor
|
|
from tools.xml_tools import XMLTools
|
|
import pdb
|
|
|
|
from wokkel import data_form
|
|
|
|
NS_REG = 'jabber:iq:register'
|
|
|
|
PLUGIN_INFO = {
|
|
"name": "XEP 0077 Plugin",
|
|
"import_name": "XEP_0077",
|
|
"type": "XEP",
|
|
"protocols": ["XEP-0077"],
|
|
"dependencies": [],
|
|
"main": "XEP_0077",
|
|
"description": """Implementation of in-band registration"""
|
|
}
|
|
|
|
class XEP_0077():
|
|
|
|
def __init__(self, host):
|
|
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("in_band_register", ".communication", in_sign='ss', out_sign='s', method=self.in_band_register)
|
|
host.bridge.addMethod("in_band_submit", ".request", in_sign='sa(ss)', out_sign='s', method=self.in_band_submit)
|
|
|
|
def addTrigger(self, target, cb):
|
|
"""Add a callback which is called when registration to target is successful"""
|
|
self.triggers[target] = cb
|
|
|
|
def reg_ok(self, answer):
|
|
"""Called after the first get IQ"""
|
|
try:
|
|
x_elem = filter (lambda x:x.name == "x", answer.firstChildElement().elements())[0] #We only want the "x" element (data form)
|
|
except IndexError:
|
|
info("No data form found")
|
|
#TODO: manage registration without data form
|
|
answer_data = {}
|
|
answer_data={"reason": "unmanaged", "message":"This gateway can't be managed by SàT, sorry :("}
|
|
answer_type = "ERROR"
|
|
self.host.bridge.actionResult(answer_type, answer['id'], answer_data)
|
|
return
|
|
|
|
form = data_form.Form.fromElement(x_elem)
|
|
xml_data = XMLTools.dataForm2xml(form)
|
|
self.host.bridge.actionResult("FORM", answer['id'], {"target":answer["from"], "type":"registration", "xml":xml_data})
|
|
|
|
def reg_err(self, failure):
|
|
"""Called when something is wrong with registration"""
|
|
info ("Registration failure: %s" % str(failure.value))
|
|
answer_data = {}
|
|
answer_data['reason'] = 'unknown'
|
|
answer_data={"message":"%s [code: %s]" % (failure.value.condition, failure.value.code)}
|
|
answer_type = "ERROR"
|
|
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data)
|
|
|
|
def unregistrationAnswer(self, answer):
|
|
debug ("registration answer: %s" % answer.toXml())
|
|
answer_type = "SUCCESS"
|
|
answer_data={"message":"Your are now unregistred"}
|
|
self.host.bridge.actionResult(answer_type, answer['id'], answer_data)
|
|
|
|
def unregistrationFailure(self, failure):
|
|
info ("Unregistration failure: %s" % str(failure.value))
|
|
answer_type = "ERROR"
|
|
answer_data = {}
|
|
answer_data['reason'] = 'unknown'
|
|
answer_data={"message":"Unregistration failed: %s" % failure.value.condition}
|
|
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data)
|
|
|
|
def registrationAnswer(self, answer):
|
|
debug ("registration answer: %s" % answer.toXml())
|
|
answer_type = "SUCCESS"
|
|
answer_data={"message":"Registration successfull"}
|
|
self.host.bridge.actionResult(answer_type, answer['id'], answer_data)
|
|
if self.triggers.has_key(answer["from"]):
|
|
self.triggers[answer["from"]](answer["from"])
|
|
del self.triggers[answer["from"]]
|
|
|
|
def registrationFailure(self, failure):
|
|
info ("Registration failure: %s" % str(failure.value))
|
|
print failure.value.stanza.toXml()
|
|
answer_type = "ERROR"
|
|
answer_data = {}
|
|
if failure.value.condition == 'conflict':
|
|
answer_data['reason'] = 'conflict'
|
|
answer_data={"message":"Username already exists, please choose an other one"}
|
|
else:
|
|
answer_data['reason'] = 'unknown'
|
|
answer_data={"message":"Registration failed"}
|
|
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data)
|
|
if self.triggers.has_key(answer["from"]):
|
|
del self.triggers[answer["from"]]
|
|
|
|
def in_band_submit(self, action, target, fields):
|
|
"""Submit a form for registration, using data_form"""
|
|
id, deferred = self.host.submitForm(action, target, fields)
|
|
if action == 'CANCEL':
|
|
deferred.addCallbacks(self.unregistrationAnswer, self.unregistrationFailure)
|
|
else:
|
|
deferred.addCallbacks(self.registrationAnswer, self.registrationFailure)
|
|
return id
|
|
|
|
def in_band_register(self, target, profile_key='@DEFAULT@'):
|
|
"""register to a target JID"""
|
|
current_jid, xmlstream = self.host.getJidNStream(profile_key)
|
|
if not xmlstream:
|
|
error ('Asking profile for an non-existant or not connected profile')
|
|
return ""
|
|
to_jid = jid.JID(target)
|
|
debug("Asking registration for [%s]" % to_jid.full())
|
|
reg_request=IQ(xmlstream,'get')
|
|
reg_request["from"]=current_jid.full()
|
|
reg_request["to"] = to_jid.full()
|
|
query=reg_request.addElement('query', NS_REG)
|
|
reg_request.send(to_jid.full()).addCallbacks(self.reg_ok, self.reg_err)
|
|
return reg_request["id"]
|