diff --git a/src/jcl/jabber/component.py b/src/jcl/jabber/component.py index 71e5a62..baf7b7e 100644 --- a/src/jcl/jabber/component.py +++ b/src/jcl/jabber/component.py @@ -302,7 +302,7 @@ class JCLComponent(Component, object): name = to_jid.node info_query = info_query.make_result_response() query = info_query.new_query("jabber:iq:register") - if to_jid and to_jid != self.jid: + if name is not None: self.db_connect() for _account in self.account_class.select(\ AND(self.account_class.q.name == name, \ @@ -439,14 +439,15 @@ class JCLComponent(Component, object): for _account in accounts: accounts_length += 1 self._send_presence_available(_account, show, lang_class) - presence = Presence(from_jid = self.jid, \ - to_jid = from_jid, \ - status = \ - str(accounts_length) \ - + lang_class.message_status, \ - show = show, \ - stanza_type = "available") - self.stream.send(presence) + if (accounts_length > 0): + presence = Presence(from_jid = self.jid, \ + to_jid = from_jid, \ + status = \ + str(accounts_length) \ + + lang_class.message_status, \ + show = show, \ + stanza_type = "available") + self.stream.send(presence) else: accounts = self.account_class.select(\ AND(self.account_class.q.name == name, \ @@ -462,28 +463,55 @@ class JCLComponent(Component, object): self.__logger.debug("PRESENCE_UNAVAILABLE") from_jid = stanza.get_from() base_from_jid = unicode(from_jid.bare()) - if stanza.get_to() == unicode(self.jid): - self.db_connect() - for _account in self.account_class.select(\ - self.account_class.q.user_jid == base_from_jid): + name = stanza.get_to().node + self.db_connect() + if not name: + accounts = self.account_class.select(\ + self.account_class.q.user_jid == base_from_jid) + for _account in accounts: _account.status = jcl.model.account.OFFLINE presence = Presence(from_jid = _account.jid, \ to_jid = from_jid, \ stanza_type = "unavailable") self.stream.send(presence) - self.db_disconnect() - presence = Presence(from_jid = stanza.get_to(), \ - to_jid = from_jid, \ - stanza_type = "unavailable") - self.stream.send(presence) + if accounts.count() > 0: + presence = Presence(from_jid = stanza.get_to(), \ + to_jid = from_jid, \ + stanza_type = "unavailable") + self.stream.send(presence) + else: + accounts = self.account_class.select(\ + AND(self.account_class.q.name == name, \ + self.account_class.q.user_jid == base_from_jid)) + if accounts.count() > 0: + presence = Presence(from_jid = stanza.get_to(), \ + to_jid = from_jid, \ + stanza_type = "unavailable") + self.stream.send(presence) + self.db_disconnect() return 1 def handle_presence_subscribe(self, stanza): """Handle subscribe presence from user """ self.__logger.debug("PRESENCE_SUBSCRIBE") - presence = stanza.make_accept_response() - self.stream.send(presence) + from_jid = stanza.get_from() + base_from_jid = unicode(from_jid.bare()) + name = stanza.get_to().node + accounts = None + self.db_connect() + if not name: + accounts = self.account_class.select(\ + self.account_class.q.user_jid == base_from_jid) + else: + accounts = self.account_class.select(\ + AND(self.account_class.q.name == name, \ + self.account_class.q.user_jid == base_from_jid)) + if (accounts is not None \ + and accounts.count() > 0): + presence = stanza.make_accept_response() + self.stream.send(presence) + self.db_disconnect() return 1 def handle_presence_subscribed(self, stanza): @@ -510,17 +538,21 @@ class JCLComponent(Component, object): name = stanza.get_to().node from_jid = stanza.get_from() base_from_jid = unicode(from_jid.bare()) - presence = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \ - stanza_type = "unsubscribe") - self.stream.send(presence) self.db_connect() - for _account in self.account_class.select(\ - self.account_class.q.user_jid == base_from_jid \ - and self.account_class.q.name == name): + accounts = self.account_class.select(\ + AND(self.account_class.q.name == name, \ + self.account_class.q.user_jid == base_from_jid)) + for _account in accounts: + presence = Presence(from_jid = _account.jid, \ + to_jid = from_jid, \ + stanza_type = "unsubscribe") + self.stream.send(presence) _account.destroySelf() + presence = Presence(from_jid = _account.jid, \ + to_jid = from_jid, \ + stanza_type = "unsubscribed") + self.stream.send(presence) self.db_disconnect() - presence = stanza.make_accept_response() - self.stream.send(presence) return 1 def handle_presence_unsubscribed(self, stanza): diff --git a/tests/jcl/jabber/test_component.py b/tests/jcl/jabber/test_component.py index 42839ff..e426901 100644 --- a/tests/jcl/jabber/test_component.py +++ b/tests/jcl/jabber/test_component.py @@ -445,13 +445,19 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp.stream = MockStream() self.comp.stream_class = MockStream account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account1 = Account(user_jid = "user1@test.com", \ - name = "account1", \ - jid = "account1@jcl.test.com") + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account21 = Account(user_jid = "user1@test.com", \ + name = "account21", \ + jid = "account21@jcl.test.com") del account.hub.threadConnection self.comp.handle_get_register(Iq(stanza_type = "get", \ from_jid = "user1@test.com", \ - to_jid = "account1@jcl.test.com")) + to_jid = "account11@jcl.test.com")) self.assertEquals(len(self.comp.stream.sent), 1) iq_sent = self.comp.stream.sent[0] self.assertEquals(iq_sent.get_to(), "user1@test.com") @@ -479,7 +485,7 @@ class JCLComponent_TestCase(unittest.TestCase): {"jir" : "jabber:iq:register", \ "jxd" : "jabber:x:data"}) self.assertEquals(len(value), 1) - self.assertEquals(value[0].content, "account1") + self.assertEquals(value[0].content, "account11") def test_handle_get_register_exist_complex(self): self.comp.account_class = AccountExample @@ -494,6 +500,22 @@ class JCLComponent_TestCase(unittest.TestCase): store_password = False, \ test_enum = "choice3", \ test_int = 21) + account11 = AccountExample(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com", \ + login = "mylogin", \ + password = "mypassword", \ + store_password = False, \ + test_enum = "choice3", \ + test_int = 21) + account21 = AccountExample(user_jid = "user2@test.com", \ + name = "account21", \ + jid = "account21@jcl.test.com", \ + login = "mylogin", \ + password = "mypassword", \ + store_password = False, \ + test_enum = "choice3", \ + test_int = 21) del account.hub.threadConnection self.comp.handle_get_register(Iq(stanza_type = "get", \ from_jid = "user1@test.com", \ @@ -981,6 +1003,27 @@ class JCLComponent_TestCase(unittest.TestCase): and isinstance(presence, Presence)]), \ 1) + def test_handle_presence_available_to_component_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_available(Presence(\ + stanza_type = "available", \ + from_jid = "unknown@test.com",\ + to_jid = "jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + def test_handle_presence_available_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream @@ -1005,6 +1048,48 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEqual(presence_sent[0].get_from(), "account11@jcl.test.com") self.assertTrue(isinstance(presence_sent[0], Presence)) + def test_handle_presence_available_to_account_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_available(Presence(\ + stanza_type = "available", \ + from_jid = "unknown@test.com",\ + to_jid = "account11@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + + def test_handle_presence_available_to_unknown_account(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_available(Presence(\ + stanza_type = "available", \ + from_jid = "user1@test.com",\ + to_jid = "unknown@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + def test_handle_presence_available_to_account_live_password(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream @@ -1125,6 +1210,26 @@ class JCLComponent_TestCase(unittest.TestCase): == "unavailable"]), \ 1) + def test_handle_presence_unavailable_to_component_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_unavailable(Presence(\ + stanza_type = "unavailable", \ + from_jid = "unknown@test.com",\ + to_jid = "jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) def test_handle_presence_unavailable_to_account(self): self.comp.stream = MockStream() @@ -1152,9 +1257,62 @@ class JCLComponent_TestCase(unittest.TestCase): presence_sent[0].xpath_eval("@type")[0].get_content(), \ "unavailable") + def test_handle_presence_unavailable_to_account_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_unavailable(Presence(\ + stanza_type = "unavailable", \ + from_jid = "unknown@test.com",\ + to_jid = "account11@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + + def test_handle_presence_unavailable_to_unknown_account(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_unavailable(Presence(\ + stanza_type = "unavailable", \ + from_jid = "user1@test.com",\ + to_jid = "unknown@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + def test_handle_presence_subscribe_to_component(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -1167,9 +1325,41 @@ class JCLComponent_TestCase(unittest.TestCase): presence_sent[0].xpath_eval("@type")[0].get_content(), \ "subscribed") + def test_handle_presence_subscribe_to_component_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_subscribe(Presence(\ + stanza_type = "subscribe", \ + from_jid = "unknown@test.com",\ + to_jid = "jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + def test_handle_presence_subscribe_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -1182,9 +1372,47 @@ class JCLComponent_TestCase(unittest.TestCase): presence_sent[0].xpath_eval("@type")[0].get_content(), \ "subscribed") - def test_handle_presence_subscribed(self): - # TODO - pass + def test_handle_presence_subscribe_to_account_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_subscribe(Presence(\ + stanza_type = "subscribe", \ + from_jid = "unknown@test.com",\ + to_jid = "account11@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + + def test_handle_presence_subscribe_to_unknown_account(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_subscribe(Presence(\ + stanza_type = "subscribe", \ + from_jid = "user1@test.com",\ + to_jid = "unknown@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) def test_handle_presence_unsubscribe(self): self.comp.stream = MockStream() @@ -1206,31 +1434,77 @@ class JCLComponent_TestCase(unittest.TestCase): to_jid = "account11@jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 2) - self.assertEqual(len([presence \ - for presence in presence_sent \ - if presence.get_to_jid() == "user1@test.com"]), \ - 2) - self.assertEqual(\ - len([presence \ - for presence in presence_sent \ - if presence.get_from_jid() == \ - "account11@jcl.test.com" \ - and presence.xpath_eval("@type")[0].get_content() \ - == "unsubscribe"]), \ - 1) - self.assertEqual(\ - len([presence \ - for presence in presence_sent \ - if presence.get_from_jid() == \ - "account11@jcl.test.com" \ - and presence.xpath_eval("@type")[0].get_content() \ - == "unsubscribed"]), \ - 1) + presence = presence_sent[0] + self.assertEqual(presence.get_from(), "account11@jcl.test.com") + self.assertEqual(presence.get_to(), "user1@test.com") + self.assertEqual(presence.xpath_eval("@type")[0].get_content(), \ + "unsubscribe") + presence = presence_sent[1] + self.assertEqual(presence.get_from(), "account11@jcl.test.com") + self.assertEqual(presence.get_to(), "user1@test.com") + self.assertEqual(presence.xpath_eval("@type")[0].get_content(), \ + "unsubscribed") account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) self.assertEquals(self.comp.account_class.select(\ self.comp.account_class.q.user_jid == "user1@test.com" \ and self.comp.account_class.q.name == "account11").count(), \ 0) + self.assertEquals(self.comp.account_class.select(\ + self.comp.account_class.q.user_jid == "user1@test.com").count(), \ + 1) + self.assertEquals(self.comp.account_class.select().count(), \ + 2) + del account.hub.threadConnection + + def test_handle_presence_unsubscribe_to_account_unknown_user(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_unsubscribe(Presence(\ + stanza_type = "unsubscribe", \ + from_jid = "unknown@test.com",\ + to_jid = "account11@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.assertEquals(self.comp.account_class.select().count(), \ + 3) + del account.hub.threadConnection + + + def test_handle_presence_unsubscribe_to_unknown_account(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + account11 = Account(user_jid = "user1@test.com", \ + name = "account11", \ + jid = "account11@jcl.test.com") + account12 = Account(user_jid = "user1@test.com", \ + name = "account12", \ + jid = "account12@jcl.test.com") + account2 = Account(user_jid = "user2@test.com", \ + name = "account2", \ + jid = "account2@jcl.test.com") + del account.hub.threadConnection + self.comp.handle_presence_unsubscribe(Presence(\ + stanza_type = "unsubscribe", \ + from_jid = "user1@test.com",\ + to_jid = "unknown@jcl.test.com")) + presence_sent = self.comp.stream.sent + self.assertEqual(len(presence_sent), 0) + account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.assertEquals(self.comp.account_class.select().count(), \ + 3) del account.hub.threadConnection def test_handle_presence_unsubscribed(self):