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)
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)
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)
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))
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)
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)
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""")
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
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
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()
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)
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")
def test_jid_ip(self): JID("[email protected]/res") JID("user@fe80::1/res")
def test_jid_compare(self): jid1 = JID("user1@host/res") jid2 = JID("user2@host/res") self.assertTrue(jid1 == jid1) self.assertFalse(jid1 == jid2)
def test_parse_domain_jid(self): jid = JID("host") self.assertEqual(jid.local, None) self.assertEqual(jid.domain, "host") self.assertEqual(jid.resource, None)
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")
def test_bad_jid(self): jid = JID('test') jid.domain = '' with self.assertRaises(ValueError): cont = Contact(jid)
def __init__(self, jid): self.jid = JID(jid)
def test_jid_true(self): jid = JID("user@host/res") self.assertTrue(jid.validate())
def test_bad_jid_inject(self): jid = JID('test') jid.domain = None with self.assertRaises(ValueError) as cm: jid.validate(True)
def test_bad_jids_false(self): for testjid in self.badjids: jid = JID(testjid, validate_on_init=False) self.assertFalse(jid.validate())
def test_init_required_attrs(self): with self.assertRaises(TypeError) as cm: cont = Contact() cont = Contact('test') cont = Contact(JID('test'))