diff options
Diffstat (limited to 'sleekxmpp/plugins/xep_0095/stream_initiation.py')
-rw-r--r-- | sleekxmpp/plugins/xep_0095/stream_initiation.py | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/sleekxmpp/plugins/xep_0095/stream_initiation.py b/sleekxmpp/plugins/xep_0095/stream_initiation.py deleted file mode 100644 index 927248a5..00000000 --- a/sleekxmpp/plugins/xep_0095/stream_initiation.py +++ /dev/null @@ -1,214 +0,0 @@ -""" - SleekXMPP: The Sleek XMPP Library - Copyright (C) 2013 Nathanael C. Fritz, Lance J.T. Stout - This file is part of SleekXMPP. - - See the file LICENSE for copying permission. -""" - -import logging -import threading - -from uuid import uuid4 - -from sleekxmpp import Iq, Message -from sleekxmpp.exceptions import XMPPError -from sleekxmpp.plugins import BasePlugin -from sleekxmpp.xmlstream.handler import Callback -from sleekxmpp.xmlstream.matcher import StanzaPath -from sleekxmpp.xmlstream import register_stanza_plugin, JID -from sleekxmpp.plugins.xep_0095 import stanza, SI - - -log = logging.getLogger(__name__) - - -SOCKS5 = 'http://jabber.org/protocol/bytestreams' -IBB = 'http://jabber.org/protocol/ibb' - - -class XEP_0095(BasePlugin): - - name = 'xep_0095' - description = 'XEP-0095: Stream Initiation' - dependencies = set(['xep_0020', 'xep_0030', 'xep_0047', 'xep_0065']) - stanza = stanza - - def plugin_init(self): - self._profiles = {} - self._methods = {} - self._methods_order = [] - self._pending_lock = threading.Lock() - self._pending= {} - - self.register_method(SOCKS5, 'xep_0065', 100) - self.register_method(IBB, 'xep_0047', 50) - - register_stanza_plugin(Iq, SI) - register_stanza_plugin(SI, self.xmpp['xep_0020'].stanza.FeatureNegotiation) - - self.xmpp.register_handler( - Callback('SI Request', - StanzaPath('iq@type=set/si'), - self._handle_request)) - - self.api.register(self._add_pending, 'add_pending', default=True) - self.api.register(self._get_pending, 'get_pending', default=True) - self.api.register(self._del_pending, 'del_pending', default=True) - - def session_bind(self, jid): - self.xmpp['xep_0030'].add_feature(SI.namespace) - - def plugin_end(self): - self.xmpp.remove_handler('SI Request') - self.xmpp['xep_0030'].del_feature(feature=SI.namespace) - - def register_profile(self, profile_name, plugin): - self._profiles[profile_name] = plugin - - def unregister_profile(self, profile_name): - try: - del self._profiles[profile_name] - except KeyError: - pass - - def register_method(self, method, plugin_name, order=50): - self._methods[method] = (plugin_name, order) - self._methods_order.append((order, method, plugin_name)) - self._methods_order.sort() - - def unregister_method(self, method): - if method in self._methods: - plugin_name, order = self._methods[method] - del self._methods[method] - self._methods_order.remove((order, method, plugin_name)) - self._methods_order.sort() - - def _handle_request(self, iq): - profile = iq['si']['profile'] - sid = iq['si']['id'] - - if not sid: - raise XMPPError(etype='modify', condition='bad-request') - if profile not in self._profiles: - raise XMPPError( - etype='modify', - condition='bad-request', - extension='bad-profile', - extension_ns=SI.namespace) - - neg = iq['si']['feature_neg']['form']['fields'] - options = neg['stream-method']['options'] or [] - methods = [] - for opt in options: - methods.append(opt['value']) - for method in methods: - if method in self._methods: - supported = True - break - else: - raise XMPPError('bad-request', - extension='no-valid-streams', - extension_ns=SI.namespace) - - selected_method = None - log.debug('Available: %s', methods) - for order, method, plugin in self._methods_order: - log.debug('Testing: %s', method) - if method in methods: - selected_method = method - break - - receiver = iq['to'] - sender = iq['from'] - - self.api['add_pending'](receiver, sid, sender, { - 'response_id': iq['id'], - 'method': selected_method, - 'profile': profile - }) - self.xmpp.event('si_request', iq) - - def offer(self, jid, sid=None, mime_type=None, profile=None, - methods=None, payload=None, ifrom=None, - **iqargs): - if sid is None: - sid = uuid4().hex - if methods is None: - methods = list(self._methods.keys()) - if not isinstance(methods, (list, tuple, set)): - methods = [methods] - - si = self.xmpp.Iq() - si['to'] = jid - si['from'] = ifrom - si['type'] = 'set' - si['si']['id'] = sid - si['si']['mime_type'] = mime_type - si['si']['profile'] = profile - if not isinstance(payload, (list, tuple, set)): - payload = [payload] - for item in payload: - si['si'].append(item) - si['si']['feature_neg']['form'].add_field( - var='stream-method', - ftype='list-single', - options=methods) - return si.send(**iqargs) - - def accept(self, jid, sid, payload=None, ifrom=None, stream_handler=None): - stream = self.api['get_pending'](ifrom, sid, jid) - iq = self.xmpp.Iq() - iq['id'] = stream['response_id'] - iq['to'] = jid - iq['from'] = ifrom - iq['type'] = 'result' - if payload: - iq['si'].append(payload) - iq['si']['feature_neg']['form']['type'] = 'submit' - iq['si']['feature_neg']['form'].add_field( - var='stream-method', - ftype='list-single', - value=stream['method']) - - if ifrom is None: - ifrom = self.xmpp.boundjid - - method_plugin = self._methods[stream['method']][0] - self.xmpp[method_plugin].api['preauthorize_sid'](ifrom, sid, jid) - - self.api['del_pending'](ifrom, sid, jid) - - if stream_handler: - self.xmpp.add_event_handler('stream:%s:%s' % (sid, jid), - stream_handler, - threaded=True, - disposable=True) - return iq.send() - - def decline(self, jid, sid, ifrom=None): - stream = self.api['get_pending'](ifrom, sid, jid) - if not stream: - return - iq = self.xmpp.Iq() - iq['id'] = stream['response_id'] - iq['to'] = jid - iq['from'] = ifrom - iq['type'] = 'error' - iq['error']['condition'] = 'forbidden' - iq['error']['text'] = 'Offer declined' - self.api['del_pending'](ifrom, sid, jid) - return iq.send() - - def _add_pending(self, jid, node, ifrom, data): - with self._pending_lock: - self._pending[(jid, node, ifrom)] = data - - def _get_pending(self, jid, node, ifrom, data): - with self._pending_lock: - return self._pending.get((jid, node, ifrom), None) - - def _del_pending(self, jid, node, ifrom, data): - with self._pending_lock: - if (jid, node, ifrom) in self._pending: - del self._pending[(jid, node, ifrom)] |