示例#1
0
 def test_jid_operators(self):
     a = JID("user@host/res")
     b = JID("user@host/res")
     self.assertTrue(a == b)
     self.assertFalse(a != b)
     self.assertTrue(a is not b)
     self.assertFalse(a is b)
示例#2
0
 def test_bad_jids_raise(self):
     for testjid in self.badjids:
         try:
             with self.assertRaises(ValueError) as cm:
                 jid = JID(testjid)
         except AssertionError:
             raise AssertionError("ValueError not raised for JID '%s'" % testjid)
示例#3
0
    def test_str(self):
        jids = [
            "host",
            "user@host",
            "host/res",
            "user@host/res"
        ]

        for testjid in jids:
            jid = JID(testjid)
            self.assertEqual(str(jid), testjid)
示例#4
0
    def route_stanza(self, stanza, raw_bytes):
        """Takes care of routing stanzas supplied to their addressed destination"""

        # Stanzas without a sender MUST be ignored..
        if stanza.get('from') is None:
            log.info('ignoring stanza without from attribute for ' +
                     stanza.get('to'))
            log.debug(ET.tostring(stanza))
            return
        stanza_source = JID(stanza.get('from'))
        stanza_destination = stanza.get('to')
        log.debug("received stanza from %s to %s" %
                  (stanza_source, stanza_destination))
        if stanza_destination is None:
            destination = stanza_source.domain
            log.debug("setting to attribute to " + destination)
            stanza_destination = destination

        stanza_destination = JID(stanza_destination)
        try:
            for peer in self.peers[stanza_destination.bare]:
                # Send to peer if the stanza has a bare jid as recipient
                # or if the full jid matches
                if (stanza_destination.resource is None \
                            and stanza_source != peer[0]) \
                            or stanza_destination == peer[0]:
                    log.debug("routing stanza from %s to %s" %
                              (stanza_source, peer[0]))
                    peer[1].send(raw_bytes)
        except KeyError:
            log.debug("Unknown message destination..")
            # Do not send errors if we cant deliver error messages
            if stanza.find('error') is None:
                # import error here on demand to prevent import loop
                from pyfire.stream.stanzas.errors import ServiceUnavailableError
                error_message = ServiceUnavailableError(stanza)
                self.route_stanza(error_message.element,
                                  cPickle.dumps(error_message.element))
示例#5
0
    def streamhandler(self, attrs):
        """Handles a stream start"""

        if attrs == {}:
            # </stream:stream> received
            self.connection.stop_connection()
        else:
            # check if we are responsible for this stream
            self.hostname = attrs.getValue("to")
            if self.hostname not in config.getlist("listeners", "domains"):
                raise HostUnknownError

            # Stream restart
            stream = ET.Element("stream:stream")
            stream.set("xmlns", attrs.getValue("xmlns"))
            stream.set("from", self.hostname)
            stream.set("id", uuid.uuid4().hex)
            stream.set("xml:lang", "en")
            stream.set("xmlns:stream", "http://etherx.jabber.org/streams")

            # only include version in response if client sent its max supported
            # version (RFC6120 Section 4.7.5)
            try:
                if attrs.getValue("version") != "1.0":
                    raise UnsupportedVersionError
                stream.set("version", "1.0")
            except KeyError:
                pass

            try:
                from_jid = JID(attrs.getValue("from"))
                stream.set("to", unicode(from_jid))
            except ValueError:
                raise InvalidFromError
            except KeyError:
                pass

            start_stream = """<?xml version="1.0"?>""" + ET.tostring(stream)
            # Element has subitems but are added later to the stream,
            # so don't mark it a single element
            self.send_string(start_stream.replace("/>", ">"))

            # Make a list of supported features
            features = ET.Element("stream:features")
            if not self.authenticated:
                self.add_auth_options(features)
            else:
                self.add_server_features(features)

            self.send_element(features)
示例#6
0
    def authenticate(self, tree):
        """Authenticates user for session"""

        # Currently RFC specifies only SASL as supported way of auth'ing
        handler = SASLAuthHandler()
        if tree.get('xmlns') != handler.namespace:
            raise MalformedRequestError
        handler.process(tree)
        self.connection.parser.reset()
        self.jid = JID("@".join([handler.authenticated_user, self.hostname]))
        self.authenticated = True
        response_element = ET.Element("success")
        response_element.set("xmlns", handler.namespace)
        self.send_element(response_element)
示例#7
0
    def roster(self):
        """RFC6121 Section 2"""

        session = Session()
        senderjid = JID(self.sender)
        roster = session.query(Roster).filter_by(jid=senderjid.bare).first()
        if roster is None:
            roster = Roster(jid=senderjid.bare)
            session.add(roster)
            session.commit()

        for contact in roster.contacts:
            self.response.append(contact.to_element())
        self.response.set("xmlns", """jabber:iq:roster""")
示例#8
0
    def handle(self, tree):
        """handler for resence requests,
           returns a response that should be sent back"""
        log.debug('loading roster to broadcast presence to subscribers..')
        session = Session()
        response = list()
        senderjid = JID(tree.get("from"))
        roster = session.query(Roster).filter_by(jid=senderjid.bare).first()
        if roster is not None:
            for contact in roster.contacts:
                # only broadcast to contacts having from or both subscription to brodcasting contact..
                if contact.subscription not in ['from', 'both']:
                    continue
                log.debug('broadcasting presence to ' + contact.jid.bare)
                brd_element = copy.deepcopy(tree)
                brd_element.set('to', contact.jid.bare)
                response.append(brd_element)

        # also broadcast presence to bare JID so all resources gets it
        brd_element = copy.deepcopy(tree)
        brd_element.set('to', JID(tree.get('from')).bare)
        response.append(brd_element)

        return response
示例#9
0
    def handle(self, tree):
        """<iq> handler, returns one or more <iq> tags with results and new ones if required"""

        self.from_jid = JID(tree.get("from"))
        self.tree = tree

        responses = []
        # dispatch to the handler for the given request query
        for req in list(tree):
            if tree.get("type") == "get":
                try:
                    data = self.get_handler[req.tag](self, req)
                    if data != None:
                        responses.append(self.create_response(data))
                except KeyError as e:
                    for elem in self.failure(req):
                        iq.append(elem)
                    iq.set("type", "error")
        # return the result
        return responses
示例#10
0
    def handle_forwarder_message(self, msg):
        """Handles incoming command requests from peer"""

        if msg.command == 'REGISTER':
            (password, push_url, jids) = msg.attributes
            log.info('peer is trying to register')
            if password != config.get('ipc', 'password'):
                log.info('Authorization failed')
                return
            log.info('registering new peer at ' + push_url)
            peer = self.ctx.socket(zmq.PUSH)
            peer.connect(push_url)
            if isinstance(jids, JID):
                jids = [
                    jids,
                ]
            for jid in jids:
                log.info('adding routing entry for ' + unicode(jid))
                jid = JID(jid)
                try:
                    # append to bare jids list of existing connections
                    self.peers[jid.bare].append((jid, peer))
                except KeyError:
                    # create new entry
                    self.peers[jid.bare] = [
                        (jid, peer),
                    ]
        elif msg.command == 'UNREGISTER':
            push_url = msg.attributes
            log.info('unregistering peer at ' + push_url)
            for bare_jid in self.peers.keys():
                for peer in self.peers[bare_jid]:
                    if peer[1] == push_url:
                        self.peers.remove(peer)
                        if len(self.peers) == 0:
                            del self.peers[bare_jid]

        else:
            raise InternalServerError()
示例#11
0
    def __init__(self, jid, **kwds):
        super(Contact, self).__init__()

        # required
        if isinstance(jid, basestring):
            self.jid = JID(jid)
        elif isinstance(jid, JID):
            self.jid = jid
            self.jid.validate(raise_error=True)
        else:
            raise AttributeError(
                "Needs valid jid either as string or JID instance")

        # optional
        self.approved = False
        self.ask = None
        self.name = None
        self.subscription = "none"
        self.groups = []

        for k, v in kwds.iteritems():
            setattr(self, k, v)
示例#12
0
 def test_bare_jid(self):
     jid = JID("user@host/res")
     self.assertEqual(jid.bare, "user@host")
     jid = JID("host/res")
     self.assertEqual(jid.bare, "host")
示例#13
0
 def test_jid_ip(self):
     JID("[email protected]/res")
     JID("user@fe80::1/res")
示例#14
0
 def test_jid_compare(self):
     jid1 = JID("user1@host/res")
     jid2 = JID("user2@host/res")
     self.assertTrue(jid1 == jid1)
     self.assertFalse(jid1 == jid2)
示例#15
0
 def test_parse_domain_jid(self):
     jid = JID("host")
     self.assertEqual(jid.local, None)
     self.assertEqual(jid.domain, "host")
     self.assertEqual(jid.resource, None)
示例#16
0
 def test_parse_full_jid(self):
     jid = JID("user@host/res")
     self.assertEqual(jid.local, "user")
     self.assertEqual(jid.domain, "host")
     self.assertEqual(jid.resource, "res")
示例#17
0
 def test_bad_jid(self):
     jid = JID('test')
     jid.domain = ''
     with self.assertRaises(ValueError):
         cont = Contact(jid)
示例#18
0
 def __init__(self, jid):
     self.jid = JID(jid)
示例#19
0
 def test_jid_true(self):
     jid = JID("user@host/res")
     self.assertTrue(jid.validate())
示例#20
0
 def test_bad_jid_inject(self):
     jid = JID('test')
     jid.domain = None
     with self.assertRaises(ValueError) as cm:
         jid.validate(True)
示例#21
0
 def test_bad_jids_false(self):
     for testjid in self.badjids:
         jid = JID(testjid, validate_on_init=False)
         self.assertFalse(jid.validate())
示例#22
0
 def test_init_required_attrs(self):
     with self.assertRaises(TypeError) as cm:
         cont = Contact()
     cont = Contact('test')
     cont = Contact(JID('test'))