diff --git a/include/transport/User.h b/include/transport/User.h index 3c245093..d0bd7f7b 100644 --- a/include/transport/User.h +++ b/include/transport/User.h @@ -138,6 +138,8 @@ class User { m_reconnectLimit = limit; } + void leaveRoom(const std::string &room); + boost::signal onReadyToConnect; boost::signal onPresenceChanged; boost::signal onRawPresenceReceived; diff --git a/libtransport/Conversation.cpp b/libtransport/Conversation.cpp index 24656509..24df3958 100644 --- a/libtransport/Conversation.cpp +++ b/libtransport/Conversation.cpp @@ -363,6 +363,13 @@ void Conversation::handleParticipantChanged(const std::string &nick, Conversatio m_conversationManager->getComponent()->getFrontend()->sendMessage(m_subject); m_subject.reset(); } + + // We send error presences only to inform user that he is disconnected + // from the room. This code must be extended in case we start sending error + // presences in other situations. + if (presence->getType() == Swift::Presence::Error) { + m_conversationManager->getUser()->leaveRoom(m_legacyName); + } } } diff --git a/libtransport/User.cpp b/libtransport/User.cpp index ce420755..b92981fc 100644 --- a/libtransport/User.cpp +++ b/libtransport/User.cpp @@ -151,6 +151,23 @@ void User::setCacheMessages(bool cacheMessages) { m_cacheMessages = cacheMessages; } +void User::leaveRoom(const std::string &room) { + onRoomLeft(room); + + BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) { + if (Buddy::JIDToLegacyName(p->getTo()) == room) { + m_joinedRooms.remove(p); + break; + } + } + + Conversation *conv = m_conversationManager->getConversation(room); + if (conv) { + m_conversationManager->removeConversation(conv); + delete conv; + } +} + void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString()); if (!m_connected) { @@ -196,19 +213,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { if (getUserSetting("stay_connected") != "1") { LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room); onRawPresenceReceived(presence); - onRoomLeft(room); - - BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) { - if (p->getTo() == presence->getTo()) { - m_joinedRooms.remove(p); - break; - } - } - - if (conv) { - m_conversationManager->removeConversation(conv); - delete conv; - } + leaveRoom(room); } return; diff --git a/tests/libtransport/user.cpp b/tests/libtransport/user.cpp index d6185d0c..8d40f277 100644 --- a/tests/libtransport/user.cpp +++ b/tests/libtransport/user.cpp @@ -29,6 +29,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST(handleDisconnected); CPPUNIT_TEST(handleDisconnectedReconnect); CPPUNIT_TEST(joinRoomHandleDisconnectedRejoin); + CPPUNIT_TEST(joinRoomAfterFlagNotAuthorized); CPPUNIT_TEST_SUITE_END(); public: @@ -138,6 +139,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // simulate that backend joined the room TestingConversation *conv = new TestingConversation(user->getConversationManager(), "room", true); conv->addJID("user@localhost/resource"); + conv->setNickname("hanzz"); user->getConversationManager()->addConversation(conv); received.clear(); @@ -452,6 +454,24 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); } + void joinRoomAfterFlagNotAuthorized() { + User *user = userManager->getUser("user@localhost"); + handlePresenceJoinRoom(); + + Conversation *conv = user->getConversationManager()->getConversation("room"); + conv->handleParticipantChanged("hanzz", Conversation::PARTICIPANT_FLAG_NOT_AUTHORIZED, Swift::StatusShow::Away, "my status message"); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast(getStanza(received[0]))->getType()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::NotAuthorized, getStanza(received[0])->getPayload()->getCondition()); + + received.clear(); + handlePresenceJoinRoom(); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION (UserTest);