Пример #1
0
    def _handle_open_request(self, iq):
        sid = iq['ibb_open']['sid']
        size = iq['ibb_open']['block_size'] or self.block_size

        log.debug('Received IBB stream request from %s', iq['from'])

        if not sid:
            raise XMPPError(etype='modify', condition='bad-request')

        if not self._accept_stream(iq):
            raise XMPPError(etype='modify', condition='not-acceptable')

        if size > self.max_block_size:
            raise XMPPError('resource-constraint')

        stream = IBBytestream(self.xmpp, sid, size, iq['to'], iq['from'],
                              self.window_size)
        stream.stream_started.set()
        self.api['set_stream'](stream.self_jid, stream.sid, stream.peer_jid,
                               stream)
        iq.reply()
        iq.send()

        self.xmpp.event('ibb_stream_start', stream)
        self.xmpp.event('stream:%s:%s' % (sid, stream.peer_jid), stream)
Пример #2
0
 def can_unsubscribe(self, iq, fjid, node, sjid, subid=None):
     if not self.node_exists(node):
         raise XMPPError(condition='item-not-found', etype='cancel')
     if subid is None or subid == '':
         subids = self.get_subids(node, sjid)
         if len(subids) == 0:
             raise XMPPError(
                 condition='unexpected-request',
                 etype='cancel',
                 extension='not-subscribed',
                 extension_ns='http://jabber.org/protocol/pubsub#errors')
         elif len(subids) > 1:
             raise XMPPError(
                 condition='bad-request',
                 etype='modify',
                 extension='subid-required',
                 extension_ns='http://jabber.org/protocol/pubsub#errors')
         else:
             subid = subids.pop()
     else:
         if not self.redis.sismember(
                 'xmpp.jid.subs.{%s}.{%s}' % (sjid, node), subid):
             raise XMPPError(
                 condition='unexpected-request',
                 etype='cancel',
                 extension='not-subscribed',
                 extension_ns='http://jabber.org/protocol/pubsub#errors')
     if self.is_admin(fjid) or self.is_affiliation(node, fjid, 'owner'):
         return True
     elif fjid.full != jid and fjid.bare != jid:
         raise XMPPError(condition='forbidden', etype='auth')
     return True
Пример #3
0
    def _default_get_last_activity(self, jid, node, ifrom, iq):
        if not isinstance(iq, Iq):
            reply = self.xmpp.Iq()
        else:
            iq.reply()
            reply = iq

        if jid not in self._last_activities:
            raise XMPPError('service-unavailable')

        bare = JID(jid).bare

        if bare != self.xmpp.boundjid.bare:
            if bare in self.xmpp.roster[jid]:
                sub = self.xmpp.roster[jid][bare]['subscription']
                if sub not in ('from', 'both'):
                    raise XMPPError('forbidden')

        td = datetime.now() - self._last_activities[jid]['seconds']
        seconds = td.seconds + td.days * 24 * 3600
        status = self._last_activities[jid]['status']

        reply['last_activity']['seconds'] = seconds
        reply['last_activity']['status'] = status

        return reply
Пример #4
0
    def _handle_streamhost(self, iq):
        """Handle incoming SOCKS5 session request."""
        sid = iq['socks']['sid']
        if not sid:
            raise XMPPError(etype='modify', condition='not-acceptable')

        streamhosts = iq['socks']['streamhosts']
        conn = None
        used_streamhost = None

        for streamhost in streamhosts:
            try:
                conn = self._connect_proxy(sid, iq['from'], self.xmpp.boundjid,
                                           streamhost['host'],
                                           streamhost['port'])
                used_streamhost = streamhost['jid']
                break
            except socket.error:
                continue
        else:
            raise XMPPError(etype='cancel', condition='item-not-found')

        iq.reply()
        with self._sessions_lock:
            self._sessions[sid] = conn
        iq['socks']['sid'] = sid
        iq['socks']['streamhost_used']['jid'] = used_streamhost
        iq.send()
Пример #5
0
        def handle_command(form, session):
            with self.lock:
                if self.max_tasks and len(self.tasks) + 1 > self.max_tasks:
                    raise XMPPError(
                        condition='resource-constraint',
                        text='Maximum number of tasks already running.',
                        etype='wait')

                self.tasks[session['id']] = True

                if len(self.tasks) == self.max_tasks:
                    self.xmpp.send_presence(ptype='dnd',
                                            pstatus='Executing tasks.')

            command = form['values']['command']
            command_started = self._execute(session['id'], command)
            if not command_started or session['id'] not in self.tasks:
                with self.lock:
                    if session['id'] in self.tasks:
                        del self.tasks[session['id']]
                raise XMPPError('internal-server-error', etype='cancel')

            form = self.xmpp['xep_0004'].makeForm(ftype='form')
            form.addField(var='cleanup', label='Cleanup', required=True)
            session['payload'] = form
            session['next'] = handle_cleanup
            session['has_next'] = False
            return session
Пример #6
0
 def handleCreateNode(self, iq):
     node = iq['pubsub']['create']['node'] or uuid.uuid4().hex
     config = iq['pubsub']['configure']['form'] or self.default_config
     if node in self.nodes:
         raise XMPPError('conflict', etype='cancel')
     if not self.createNode(node, config, iq['from'].full):
         raise XMPPError()
     iq.reply()
     iq['pubsub']['create']['node'] = node
     iq.send()
Пример #7
0
    def _get_items(self, jid, node, data, disco, pubsub):
        try:
            firstpart = node.split('/', 2)[1]
        except:
            raise XMPPError(condition='item-not-found')

        if firstpart == 'passtimes':
            pass

        elif firstpart in self.modalities.keys():
            return self.modalities[firstpart].get_items(
                jid, node, data, disco, pubsub)

        raise XMPPError(condition='item-not-found')
Пример #8
0
 def handlePublish(self, iq):
     fjid = iq['from'].bare
     node = iq['pubsub']['publish']['node']
     instant_node = False
     auto_create = False
     if not node:
         if 'instant-nodes' not in self.features:
             raise XMPPError(
                 etype='modify',
                 condition='not-acceptable',
                 extention='nodeid-required',
                 extention_ns='http://jabber.org/protocol/pubsub#errors')
         node = uuid.uuid4().hex
         instant_node = True
     if instant_node or not self.node_exists(node):
         if 'auto-create' in self.features:
             #create config from default config merged with publish-options
             config = self.xmpp.plugin['xep_0004'].make_form()
             config['values'] = self.default_config
             if 'publish_options' in iq['pubsub'].plugins:
                 config.merge(iq['pubsub']['publish_options'])
             config = self.xmppconfig2thoonkconfig(None, config['values'])
             self.thoonk.create_feed(node, config)
             self.set_affilation(node, fjid, 'owner')
             auto_create = True
         else:
             raise XMPPError(condition='item-not-found', etype='cancel')
     if not self.is_admin(fjid) and not self.is_affiliation(
             node, fjid, 'owner') and not self.is_affiliation(
                 node, fjid, 'publisher') and not self.is_affiliation(
                     node, fjid, 'publish-only'):
         raise XMPPError(etype='auth', condition='forbidden')
     #TODO: if too big, error payload-to-big 7.1.3.4
     #TODO: if wrong ns or more than one root element in <item /> error invalid-payload 7.1.3.5
     if not auto_create and 'publish_options' in iq['pubsub'].plugins:
         options = iq['pubsub']['publish_options']['values']
         existing_config = self.thoonkconfig2xmppconfig(node)
         for key in options:
             if options[key] != existing_config.get(key):
                 raise XMPPError(
                     condition='conflict',
                     etype='cancel',
                     extension='precondition-not-met',
                     extension_ns='http://jabber.org/protocol/pubsub#errors'
                 )
     item_id = iq['pubsub']['publish']['item']['id']
     if not item_id:
         item_id = uuid.uuid4().hex
     self.thoonk.publish(node, iq['pubsub']['publish']['item'], id=item_id)
Пример #9
0
def test_send_ping_with_monitor():
    v = a_vacbot(monitor=True)

    ping_mock = v.xmpp.send_ping = Mock()
    request_statuses_mock = v.request_all_statuses = Mock()

    # First ping should try to fetch statuses
    v.send_ping()
    assert_equals(1, request_statuses_mock.call_count)

    # Nothing blowing up is success

    # On four failed pings, vacuum state gets set to 'offline'
    ping_mock.side_effect = XMPPError()
    v.send_ping()
    v.send_ping()
    v.send_ping()
    assert_equals(None, v.vacuum_status)
    v.send_ping()
    assert_equals('offline', v.vacuum_status)

    # On a successful ping after the offline state, a request for initial statuses is made
    ping_mock.side_effect = None
    request_statuses_mock.reset_mock()
    v.send_ping()
    assert_equals(1, request_statuses_mock.call_count)
Пример #10
0
    def _handle_roster(self, iq):
        """Update the roster after receiving a roster stanza.

        :param iq: The roster stanza.
        """
        if iq['type'] == 'set':
            if iq['from'].bare and iq['from'].bare != self.boundjid.bare:
                raise XMPPError(condition='service-unavailable')

        roster = self.client_roster
        if iq['roster']['ver']:
            roster.version = iq['roster']['ver']
        items = iq['roster']['items']

        valid_subscriptions = ('to', 'from', 'both', 'none', 'remove')
        for jid, item in items.items():
            if item['subscription'] in valid_subscriptions:
                roster[jid]['name'] = item['name']
                roster[jid]['groups'] = item['groups']
                roster[jid]['from'] = item['subscription'] in ('from', 'both')
                roster[jid]['to'] = item['subscription'] in ('to', 'both')
                roster[jid]['pending_out'] = (item['ask'] == 'subscribe')

                roster[jid].save(remove=(item['subscription'] == 'remove'))

        self.event("roster_update", iq)
        if iq['type'] == 'set':
            resp = self.Iq(stype='result',
                           sto=iq['from'],
                           sid=iq['id'])
            resp.enable('roster')
            resp.send()
Пример #11
0
 def _handle_data(self, stanza):
     sid = stanza['ibb_data']['sid']
     stream = self.streams.get(sid, None)
     if stream is not None and stanza['from'] != stream.sender:
         stream._recv_data(stanza)
     else:
         raise XMPPError('item-not-found')
Пример #12
0
 def _handle_close(self, iq):
     sid = iq['ibb_close']['sid']
     stream = self.streams.get(sid, None)
     if stream is not None and iq['from'] != stream.sender:
         stream._closed(iq)
     else:
         raise XMPPError('item-not-found')
Пример #13
0
 def message(msg):
     raise XMPPError(condition='feature-not-implemented',
                     text="We don't do things that way here.",
                     etype='cancel',
                     extension='foo',
                     extension_ns='foo:error',
                     extension_args={'test': 'true'})
Пример #14
0
 def _handle_data(self, stanza):
     sid = stanza['ibb_data']['sid']
     stream = self.api['get_stream'](stanza['to'], sid, stanza['from'])
     if stream is not None and stanza['from'] == stream.peer_jid:
         stream._recv_data(stanza)
     else:
         raise XMPPError('item-not-found')
Пример #15
0
    def _handle_roster(self, iq, request=False):
        """Update the roster after receiving a roster stanza.

        :param iq: The roster stanza.
        :param request: Indicates if this stanza is a response
                        to a request for the roster, and not an
                        empty acknowledgement from the server.
        """
        if iq['from'].bare and iq['from'].bare != self.boundjid.bare:
            raise XMPPError(condition='service-unavailable')
        if iq['type'] == 'set' or (iq['type'] == 'result' and request):
            roster = self.client_roster
            if iq['roster']['ver']:
                roster.version = iq['roster']['ver']
            for jid in iq['roster']['items']:
                item = iq['roster']['items'][jid]
                roster[jid]['name'] = item['name']
                roster[jid]['groups'] = item['groups']
                roster[jid]['from'] = item['subscription'] in ['from', 'both']
                roster[jid]['to'] = item['subscription'] in ['to', 'both']
                roster[jid]['pending_out'] = (item['ask'] == 'subscribe')

                roster[jid].save(remove=(item['subscription'] == 'remove'))
                     
            self.event('roster_received', iq)

        self.event("roster_update", iq)
        if iq['type'] == 'set':
            iq.reply()
            iq.enable('roster')
            iq.send()
Пример #16
0
    def _recv_data(self, iq):
        with self._recv_seq_lock:
            new_seq = iq['ibb_data']['seq']
            if new_seq != (self.recv_seq + 1) % 65535:
                self.close()
                raise XMPPError('unexpected-request')
            self.recv_seq = new_seq

        data = iq['ibb_data']['data']
        if len(data) > self.block_size:
            self.close()
            raise XMPPError('not-acceptable')

        self.recv_queue.put(data)
        self.xmpp.event('ibb_stream_data', {'stream': self, 'data': data})
        iq.reply()
        iq.send()
Пример #17
0
    def _handle_open_request(self, iq):
        sid = iq['ibb_open']['sid']
        size = iq['ibb_open']['block_size']
        if not self._accept_stream(iq):
            raise XMPPError('not-acceptable')

        if size > self.max_block_size:
            raise XMPPError('resource-constraint')

        stream = IBBytestream(self.xmpp, sid, size, iq['from'], iq['to'],
                              self.window_size)
        stream.stream_started.set()
        self.streams[sid] = stream
        iq.reply()
        iq.send()

        self.xmpp.event('ibb_stream_start', stream)
Пример #18
0
 def _handle_close(self, iq):
     sid = iq['ibb_close']['sid']
     stream = self.api['get_stream'](iq['to'], sid, iq['from'])
     if stream is not None and iq['from'] == stream.peer_jid:
         stream._closed(iq)
         self.api['del_stream'](stream.self_jid, stream.sid,
                                stream.peer_jid)
     else:
         raise XMPPError('item-not-found')
Пример #19
0
    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)
Пример #20
0
 def connect_to_jabber(self, jabber_id, password):
     self.xmpp = ClientXMPP(jabber_id, password)
     self.xmpp.reconnect_max_attempts = 1
     connected = self.xmpp.connect()
     if not connected:
         raise XMPPError("Vyanse kwikonecta")
     self.xmpp.process()
     self.xmpp.send_presence()
     self.xmpp.get_roster()
     self.xmpp.add_event_handler('message', self.root.handle_xmpp_message)
Пример #21
0
    def _handle_task_command(self, iq, session):
        def handle_cleanup(form, session):
            cleanup = form['values'].get('cleanup', None)
            if cleanup:
                self._execute(session['id'], cleanup, cleanup=True)
            with self.lock:
                if session['id'] in self.tasks:
                    del self.tasks[session['id']]
            self.xmpp.send_presence(pstatus='Ready for Task')

        def handle_command(form, session):
            with self.lock:
                if self.max_tasks and len(self.tasks) + 1 > self.max_tasks:
                    raise XMPPError(
                        condition='resource-constraint',
                        text='Maximum number of tasks already running.',
                        etype='wait')

                self.tasks[session['id']] = True

                if len(self.tasks) == self.max_tasks:
                    self.xmpp.send_presence(ptype='dnd',
                                            pstatus='Executing tasks.')

            command = form['values']['command']
            command_started = self._execute(session['id'], command)
            if not command_started or session['id'] not in self.tasks:
                with self.lock:
                    if session['id'] in self.tasks:
                        del self.tasks[session['id']]
                raise XMPPError('internal-server-error', etype='cancel')

            form = self.xmpp['xep_0004'].makeForm(ftype='form')
            form.addField(var='cleanup', label='Cleanup', required=True)
            session['payload'] = form
            session['next'] = handle_cleanup
            session['has_next'] = False
            return session

        def handle_cancel(iq, session):
            self._cancel(session['id'])

        if self.whitelist:
            if iq['from'].bare not in self.whitelist:
                raise XMPPError('not-authorized', etype='cancel')

        form = self.xmpp['xep_0004'].makeForm(ftype='form')
        form.addField(var='command', label='Command', required=True)

        session['payload'] = form
        session['next'] = handle_command
        session['cancel'] = handle_cancel
        session['has_next'] = True

        return session
Пример #22
0
    def _default_handler(self, iq):
        """
        As a safe default, don't actually download files.

        Register a new handler using self.register_url_handler to
        screen requests and download files.

        Arguments:
            iq -- The Iq stanza containing the OOB transfer request.
        """
        raise XMPPError('service-unavailable')
Пример #23
0
    def get_info(self, jid, node, data):
        """
        Return the stored info data for the requested JID/node combination.

        The data parameter is not used.
        """
        if (jid, node) not in self.nodes:
            if not node:
                return DiscoInfo()
            else:
                raise XMPPError(condition='item-not-found')
        else:
            return self.nodes[(jid, node)]['info']
Пример #24
0
    def get_items(self, jid, node, ifrom, data):
        """
        Return the stored items data for the requested JID/node combination.

        The data parameter is not used.
        """
        with self.lock:
            if not self.node_exists(jid, node):
                if not node:
                    return DiscoItems()
                else:
                    raise XMPPError(condition='item-not-found')
            else:
                return self.get_node(jid, node)['items']
Пример #25
0
def patched_handle_get_vcard(self, iq):
    if iq['type'] == 'result':
        self.api['set_vcard'](jid=iq['from'], args=iq['vcard_temp'])
        return
    elif iq['type'] == 'get':
        vcard = self.api['get_vcard'](iq['to'].bare)
        if isinstance(vcard, Iq):
            vcard.send()
        else:
            iq = iq.reply()
            iq.append(vcard)
            iq.send()
    elif iq['type'] == 'set':
        raise XMPPError('service-unavailable')
Пример #26
0
    def _run_url_handler(self, iq):
        """
        Execute the appropriate handler for a transfer request.

        Arguments:
            iq -- The Iq stanza containing the OOB transfer request.
        """
        if iq['to'] in self.url_handlers['jid']:
            return self.url_handlers['jid'][jid](iq)
        else:
            if self.url_handlers['global']:
                self.url_handlers['global'](iq)
            else:
                raise XMPPError('service-unavailable')
Пример #27
0
 def handleSubscribe(self, stanza):
     node = stanza['pubsub']['subscribe']['node']
     jid = stanza['pubsub']['subscribe']['jid']
     subid = self.subscribeNode(node, jid, stanza['from'])
     if not subid:
         raise XMPPError('not-allowed')
         #self.xmpp.send(self.xmpp.makeIqError(stanza['id']))
         return
     stanza.reply()
     stanza.clear()
     stanza['pubsub']['subscription']['subid'] = subid
     stanza['pubsub']['subscription']['node'] = node
     stanza['pubsub']['subscription']['jid'] = str(jid)
     stanza['pubsub']['subscription']['subscription'] = 'subscribed'
     stanza.send()
Пример #28
0
 def handleSetState(self, iq):
     node = self.nodes.get(iq['psstate']['node'])
     payload = iq['psstate']['payload']
     if node is None:
         raise XMPPError('item-not-found')
     item = iq['psstate']['item']
     if item is not None:
         result = node.setItemState(item, payload, iq['from'])
         if result:
             iq.reply()
             iq['psstate']['payload'] = payload
             iq.send()
         else:
             iq.reply()
             iq['error']['condition'] = 'not-allowed'
             iq.send()
    def get_items(self, jid, node, data, disco=None, pubsub=None):
        latlon = self.validnode_latlon.match(node)
        print node
        if latlon is not None:
            lat = latlon.group(1)
            lon = latlon.group(2)
            what = latlon.group(3)
            
            x, y = wgs84_rd(lat, lon)
            x = int(x)
            y = int(y)
            if what == 'quays':
                if disco is not None:
                    return self.nearestuserstop_disco(disco, jid, node, x, y)
                elif pubsub is not None:
                    return self.nearestuserstop_get_items(pubsub, jid, node, x, y)
            elif what == 'stopplaces':
                if disco is not None:
                    return self.neareststopplace_disco(disco, jid, node, x, y)
                elif pubsub is not None:
                    return self.neareststopplace_get_items(pubsub, jid, node, x, y)

        else:
            if disco is not None:
                return disco.static.get_items(jid, node, data)
            
            elif pubsub is not None:
                print node
                match = self.validnode.match(node)
                if match is not None:
                    print 'match=>', match.group(0)
                    if match.group(9) is not None:
                        if match.group(10) is not None:
                            return self.passtimes(pubsub, match.group(3), match.group(6), match.group(9), match.group(12))
                        else:
                            return self.quay(pubsub, node, match.group(3), match.group(6), match.group(9))

                    elif match.group(6) is not None and match.group(6) != '':
                        if match.group(10) is not None:
                            return self.passtimes_stopplace(pubsub, match.group(3), match.group(6), match.group(12))
                        else:                            
                            return self.stopplace(pubsub, node, match.group(3), match.group(6))
                        

        raise XMPPError(condition='item-not-found') 
Пример #30
0
def test_send_ping_no_monitor():
    v = a_vacbot()

    mock = v.xmpp.send_ping = Mock()
    v.send_ping()

    # On four failed pings, vacuum state gets set to 'offline'
    mock.side_effect = XMPPError()
    v.send_ping()
    v.send_ping()
    v.send_ping()
    assert_equals(None, v.vacuum_status)
    v.send_ping()
    assert_equals('offline', v.vacuum_status)

    # On a successful ping after the offline state, state gets reset to None, indicating that it is unknown
    mock.side_effect = None
    v.send_ping()
    assert_equals(None, v.vacuum_status)