plugin XEP-0166: sendError now manage jingle conditions

This commit is contained in:
Goffi 2015-11-17 19:37:09 +01:00
commit 2f561bec34

View file

@ -24,17 +24,12 @@ from sat.tools import xml_tools
log = getLogger(__name__)
from sat.core import exceptions
from twisted.words.protocols.jabber import jid
# from twisted.words.protocols import jabber
# from twisted.words.xish import domish
from twisted.internet import defer
# from wokkel import disco, iwokkel, data_form, compat
from wokkel import disco, iwokkel
from twisted.words.protocols.jabber import error
from twisted.words.protocols.jabber import xmlstream
# from sat.core import exceptions
# from sat.memory.memory import Sessions
# from uuid import uuid4
# from sat.tools import xml_tools
from twisted.python import failure
from collections import namedtuple
import uuid
import time
@ -45,6 +40,7 @@ from zope.interface import implements
IQ_SET = '/iq[@type="set"]'
NS_JINGLE = "urn:xmpp:jingle:1"
NS_JINGLE_ERROR = "urn:xmpp:jingle:errors:1"
JINGLE_REQUEST = IQ_SET + '/jingle[@xmlns="' + NS_JINGLE + '"]'
STATE_PENDING = "PENDING"
STATE_ACTIVE = "ACTIVE"
@ -121,16 +117,19 @@ class XEP_0166(object):
jingle_elt['action'] = action
return iq_elt, jingle_elt
def sendError(self, error_condition, sid, request, profile):
def sendError(self, error_condition, sid, request, jingle_condition=None, profile=C.PROF_KEY_NONE):
"""Send error stanza
@param error_condition: one of twisted.words.protocols.jabber.error.STANZA_CONDITIONS keys
@param sid(unicode,None): jingle session id, or None, if session must not be destroyed
@param request(domish.Element): original request
@param jingle_condition(None, unicode): if not None, additional jingle-specific error information
@param profile: %(doc_profile)s
"""
client = self.host.getClient(profile)
iq_elt = error.StanzaError(error_condition).toResponse(request)
if jingle_condition is not None:
iq_elt.error.addElement((NS_JINGLE_ERROR, jingle_condition))
if error.STANZA_CONDITIONS[error_condition]['type'] == 'cancel' and sid:
self._delSession(client, sid)
log.warning(u"Error while managing jingle session, cancelling: {condition}".format(error_condition))
@ -159,14 +158,14 @@ class XEP_0166(object):
## errors which doesn't imply a stanza sending ##
def _iqError(self, failure, sid, client):
def _iqError(self, failure_, sid, client):
"""Called when we got an <iq/> error
@param failure(failure.Failure): the exceptions raised
@param failure_(failure.Failure): the exceptions raised
@param sid(unicode): jingle session id
@param profile: %(doc_client)s
"""
log.warning(u"Error while sending jingle <iq/> stanza: {failure}".format(failure=failure.value))
log.warning(u"Error while sending jingle <iq/> stanza: {failure_}".format(failure_=failure_.value))
self._delSession(client, sid)
def _jingleErrorCb(self, fail, sid, request, client):
@ -181,7 +180,7 @@ class XEP_0166(object):
"""
log.warning("Error while processing jingle request")
if isinstance(fail, exceptions.DataError):
self.sendError('bad-request', sid, request, client.profile)
self.sendError('bad-request', sid, request, profile=client.profile)
else:
log.error("Unmanaged jingle exception")
self._delSession(client, sid)
@ -236,7 +235,7 @@ class XEP_0166(object):
@param action(unicode): a jingle action (see XEP-0166 §7.2),
session-* actions are not managed here
@param session(dict): jingle session data
@param content_name(unicode): name of the content terminated
@param content_name(unicode): name of the content
@param profile: %(doc_profile)s
@return (tuple[domish.Element, domish.Element]): parent <iq> element, <transport> or <description> element, according to action
"""
@ -393,7 +392,7 @@ class XEP_0166(object):
raise KeyError
except KeyError:
log.warning(u"Received jingle request has no sid attribute")
self.sendError('bad-request', None, request, profile)
self.sendError('bad-request', None, request, profile=profile)
return
# then the action
@ -403,7 +402,7 @@ class XEP_0166(object):
raise KeyError
except KeyError:
log.warning(u"Received jingle request has no action")
self.sendError('bad-request', None, request, profile)
self.sendError('bad-request', None, request, profile=profile)
return
peer_jid = jid.JID(request['from'])
@ -422,11 +421,11 @@ class XEP_0166(object):
else:
if session['peer_jid'] != peer_jid:
log.warning(u"sid conflict ({}), the jid doesn't match. Can be a collision, a hack attempt, or a bad sid generation".format(sid))
self.sendError('service-unavailable', sid, request, profile)
self.sendError('service-unavailable', sid, request, profile=profile)
return
if session['id'] != sid:
log.error(u"session id doesn't match")
self.sendError('service-unavailable', sid, request, profile)
self.sendError('service-unavailable', sid, request, profile=profile)
raise exceptions.InternalError
if action == XEP_0166.A_SESSION_INITIATE:
@ -466,7 +465,7 @@ class XEP_0166(object):
if new:
# the content must not exist, we check it
if not name or name in contents_dict:
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
content_data = contents_dict[name] = {'creator': creator,
'senders': content_elt.attributes.get('senders', 'both'),
@ -477,28 +476,28 @@ class XEP_0166(object):
content_data = contents_dict[name]
except KeyError:
log.warning(u"Other peer try to access an unknown content")
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
# application
if with_application:
desc_elt = content_elt.description
if not desc_elt:
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
if new:
# the content is new, we need to check and link the application
app_ns = desc_elt.uri
if not app_ns or app_ns == NS_JINGLE:
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
try:
application = self._applications[app_ns]
except KeyError:
log.warning(u"Unmanaged application namespace [{}]".format(app_ns))
self.sendError('service-unavailable', session['id'], request, client.profile)
self.sendError('service-unavailable', session['id'], request, profile=client.profile)
raise exceptions.CancelError
content_data['application'] = application
@ -514,14 +513,14 @@ class XEP_0166(object):
if with_transport:
transport_elt = content_elt.transport
if not transport_elt:
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
if new:
# the content is new, we need to check and link the transport
transport_ns = transport_elt.uri
if not app_ns or app_ns == NS_JINGLE:
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
raise exceptions.CancelError
try:
@ -607,7 +606,7 @@ class XEP_0166(object):
if not contents_dict:
# there MUST be at least one content
self.sendError('bad-request', session['id'], request, client.profile)
self.sendError('bad-request', session['id'], request, profile=client.profile)
return
# at this point we can send the <iq/> result to confirm reception of the request