예제 #1
0
    async def _handle_disco_items(self, iq: Iq):
        """
        Process an incoming disco#items stanza. If it is a get
        request, find and return the appropriate items. If it
        is an items result, fire the disco_items event.

        :param iq: The incoming disco#items stanza.
        """
        if iq['type'] == 'get':
            log.debug("Received disco items query from "
                      "<%s> to <%s>.", iq['from'], iq['to'])
            items = await self.api['get_items'](iq['to'],
                                                iq['disco_items']['node'],
                                                iq['from'], iq)
            if isinstance(items, Iq):
                items.send()
            else:
                iq = iq.reply()
                if items:
                    iq.set_payload(items.xml)
                iq.send()
        elif iq['type'] == 'result':
            log.debug("Received disco items result from "
                      "%s to %s.", iq['from'], iq['to'])
            self.xmpp.event('disco_items', iq)
예제 #2
0
 async def _handle_get_vcard(self, iq: Iq):
     if iq['type'] == 'result':
         await self.api['set_vcard'](jid=iq['from'], args=iq['vcard_temp'])
         return
     elif iq['type'] == 'get' and self.xmpp.is_component:
         vcard = await self.api['get_vcard'](iq['to'].bare,
                                             ifrom=iq['from'])
         if isinstance(vcard, Iq):
             vcard.send()
         else:
             iq = iq.reply()
             iq.append(vcard)
             iq.send()
     elif iq['type'] == 'set':
         raise XMPPError('service-unavailable')
예제 #3
0
    async def _handle_registration(self, iq: Iq):
        if iq["type"] == "get":
            await self._send_form(iq)
        elif iq["type"] == "set":
            if iq["register"]["remove"]:
                try:
                    await self.api["user_remove"](None, None, iq["from"], iq)
                except KeyError:
                    _send_error(
                        iq,
                        "404",
                        "cancel",
                        "item-not-found",
                        "User not found",
                    )
                else:
                    reply = iq.reply()
                    reply.send()
                    self.xmpp.event("user_unregister", iq)
                return


            for field in self.form_fields:
                if not iq["register"][field]:
                    # Incomplete Registration
                    _send_error(
                        iq,
                        "406",
                        "modify",
                        "not-acceptable",
                        "Please fill in all fields.",
                    )
                    return

            try:
                await self.api["user_validate"](None, None, iq["from"], iq["register"])
            except ValueError as e:
                _send_error(
                    iq,
                    "406",
                    "modify",
                    "not-acceptable",
                    e.args,
                )
            else:
                reply = iq.reply()
                reply.send()
                self.xmpp.event("user_register", iq)
예제 #4
0
    def _handle_version(self, iq: Iq):
        """
        Respond to a software version query.

        :param iq: The Iq stanza containing the software version query.
        """
        iq = iq.reply()
        if self.software_name:
            iq['software_version']['name'] = self.software_name
            iq['software_version']['version'] = self.version
            iq['software_version']['os'] = self.os
        else:
            iq.error()
            iq['error']['type'] = 'cancel'
            iq['error']['condition'] = 'service-unavailable'
        iq.send()
예제 #5
0
    def _default_get_last_activity(self, jid: JID, node: str, ifrom: JID,
                                   iq: Iq) -> Iq:
        if not isinstance(iq, Iq):
            reply = self.xmpp.Iq()
        else:
            reply = iq.reply()

        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
예제 #6
0
    def Iq(self, *args, **kwargs):
        """
        Create an Iq stanza.

        Uses same arguments as StanzaBase.__init__

        Arguments:
            xml -- An XML object to use for the Iq's values.
        """
        return Iq(self.xmpp, *args, **kwargs)
예제 #7
0
 async def send_push(self, user, jid, values, checked=True):
     # called when a subscription is being changed
     iq = Iq(self.stream)
     iq['type'] = 'set'
     iq['roster'].set_items({jid.bare: values})
     if checked:
         type = 'roster.push'
     else:
         type = 'roster.push_unchecked'
     await self.stream.ipc_send(type, user, iq.xml)
예제 #8
0
파일: bob.py 프로젝트: yikuide/slixmpp
    async def _handle_bob_iq(self, iq: Iq):
        cid = iq['bob']['cid']

        if iq['type'] == 'result':
            await self.api['set_bob'](iq['from'],
                                      None,
                                      iq['to'],
                                      args=iq['bob'])
            self.xmpp.event('bob', iq)
        elif iq['type'] == 'get':
            data = await self.api['get_bob'](iq['to'],
                                             None,
                                             iq['from'],
                                             args=cid)
            if isinstance(data, Iq):
                data['id'] = iq['id']
                data.send()
                return

            iq = iq.reply()
            iq.append(data)
            iq.send()
예제 #9
0
    async def _handle_disco_info(self, iq: Iq):
        """
        Process an incoming disco#info stanza. If it is a get
        request, find and return the appropriate identities
        and features. If it is an info result, fire the
        disco_info event.

        :param iq: The incoming disco#items stanza.
        """
        if iq['type'] == 'get':
            log.debug("Received disco info query from "
                      "<%s> to <%s>.", iq['from'], iq['to'])
            info = await self.api['get_info'](iq['to'],
                                              iq['disco_info']['node'],
                                              iq['from'], iq)
            if isinstance(info, Iq):
                info['id'] = iq['id']
                info.send()
            else:
                node = iq['disco_info']['node']
                iq = iq.reply()
                if info:
                    info = self._fix_default_info(info)
                    info['node'] = node
                    iq.set_payload(info.xml)
                iq.send()
        elif iq['type'] == 'result':
            log.debug("Received disco info result from "
                      "<%s> to <%s>.", iq['from'], iq['to'])
            if self.use_cache:
                log.debug("Caching disco info result from "
                          "<%s> to <%s>.", iq['from'], iq['to'])
                if self.xmpp.is_component:
                    ito = iq['to'].full
                else:
                    ito = None
                await self.api['cache_info'](iq['from'],
                                             iq['disco_info']['node'], ito, iq)
            self.xmpp.event('disco_info', iq)
예제 #10
0
    async def _handle_open_request(self, iq: 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 await self._accept_stream(iq):
            raise XMPPError(etype='cancel', condition='not-acceptable')

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

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

        self.xmpp.event('ibb_stream_start', stream)
        self.xmpp.event('stream:%s:%s' % (sid, stream.peer_jid), stream)
예제 #11
0
 async def _relay_push(self, xml, checked):
     if checked:
         # Though the IPC push messages do give us notification that
         # the database has changed, messages are not guaranteed to
         # arrive in the same order that the database was updated.
         # So just in case, we should get up-to-date information from
         # the database before relaying any pushes to the user.
         iq = Iq(self.stream, xml)
         contacts = iq['roster'].get_items()
         for jid, values in contacts.items():
             values = await self.stream.roster_hook.get_contact(
                 self.stream.boundjid, jid)
             if values is None:
                 values = {'subscription': 'remove'}
             contacts[jid] = values
         iq['roster'].set_items(contacts)
         xml = iq.xml
     self.stream.send_element(xml)
예제 #12
0
    async def _make_registration_form(self, jid, node, ifrom, iq: Iq):
        reg = iq["register"]
        user = await self.api["user_get"](None, None, iq['from'], iq)

        if user is None:
            user = {}
        else:
            reg["registered"] = True

        reg["instructions"] = self.form_instructions

        for field in self.form_fields:
            data = user.get(field, "")
            if data:
                reg[field] = data
            else:
                # Add a blank field
                reg.add_field(field)

        reply = iq.reply()
        reply.set_payload(reg.xml)
        return reply
예제 #13
0
 def Iq(self, *args, **kwargs):
     """Create an Iq stanza associated with this stream."""
     return Iq(self, *args, **kwargs)