diff --git a/include/transport/buddy.h b/include/transport/buddy.h index ec77c883..35205822 100644 --- a/include/transport/buddy.h +++ b/include/transport/buddy.h @@ -165,7 +165,7 @@ class Buddy { /// \param jid Jabber ID. /// \return legacy name of buddy from JID. static std::string JIDToLegacyName(const Swift::JID &jid); - static BuddyFlag buddFlagsFromJID(const Swift::JID &jid); + static BuddyFlag buddyFlagsFromJID(const Swift::JID &jid); protected: void generateJID(); diff --git a/include/transport/localbuddy.h b/include/transport/localbuddy.h index cccb8592..7a0ff92d 100644 --- a/include/transport/localbuddy.h +++ b/include/transport/localbuddy.h @@ -62,7 +62,8 @@ class LocalBuddy : public Buddy { void setGroups(const std::vector &groups); bool isValid() { - return m_jid.isValid(); + std::string safeName = getSafeName(); + return m_jid.isValid() && safeName.find("/") == std::string::npos; } private: diff --git a/src/buddy.cpp b/src/buddy.cpp index 01eb28f2..3a32c558 100644 --- a/src/buddy.cpp +++ b/src/buddy.cpp @@ -178,7 +178,7 @@ std::string Buddy::JIDToLegacyName(const Swift::JID &jid) { return name; } -BuddyFlag Buddy::buddFlagsFromJID(const Swift::JID &jid) { +BuddyFlag Buddy::buddyFlagsFromJID(const Swift::JID &jid) { if (jid.getUnescapedNode() == jid.getNode()) { return BUDDY_NO_FLAG; } diff --git a/src/rostermanager.cpp b/src/rostermanager.cpp index ea40db79..dab6da91 100644 --- a/src/rostermanager.cpp +++ b/src/rostermanager.cpp @@ -299,7 +299,7 @@ void RosterManager::handleRemoteRosterResponse(boost::shared_ptrgetFactory()->createBuddy(this, buddyInfo); @@ -394,7 +394,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { buddyInfo.alias = ""; buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo()); buddyInfo.subscription = "both"; - buddyInfo.flags = Buddy::buddFlagsFromJID(presence->getTo()); + buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo()); LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received for new buddy " << buddyInfo.legacyName << " => adding to legacy network"); buddy = m_component->getFactory()->createBuddy(this, buddyInfo); @@ -473,7 +473,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) { buddyInfo.alias = ""; buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo()); buddyInfo.subscription = "both"; - buddyInfo.flags = Buddy::buddFlagsFromJID(presence->getTo()); + buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo()); buddy = m_component->getFactory()->createBuddy(this, buddyInfo); setBuddy(buddy); diff --git a/src/rosterresponder.cpp b/src/rosterresponder.cpp index 3b0c4612..9c0be47d 100644 --- a/src/rosterresponder.cpp +++ b/src/rosterresponder.cpp @@ -96,7 +96,7 @@ bool RosterResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& buddyInfo.alias = item.getName(); buddyInfo.legacyName = Buddy::JIDToLegacyName(item.getJID()); buddyInfo.subscription = "both"; - buddyInfo.flags = Buddy::buddFlagsFromJID(item.getJID()); + buddyInfo.flags = Buddy::buddyFlagsFromJID(item.getJID()); LOG4CXX_INFO(logger, from.toBare().toString() << ": Adding buddy " << buddyInfo.legacyName); buddy = user->getComponent()->getFactory()->createBuddy(user->getRosterManager(), buddyInfo); diff --git a/src/tests/component.cpp b/src/tests/component.cpp index a3f709b5..1ca010ea 100644 --- a/src/tests/component.cpp +++ b/src/tests/component.cpp @@ -22,6 +22,7 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST_SUITE(ComponentTest); CPPUNIT_TEST(handlePresenceWithNode); CPPUNIT_TEST(handlePresenceWithoutNode); + CPPUNIT_TEST(handleErrorPresence); CPPUNIT_TEST_SUITE_END(); public: @@ -56,6 +57,18 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); } + // Error presence should be ignored + void handleErrorPresence() { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("localhost"); + response->setFrom("user@localhost/resource"); + response->setType(Swift::Presence::Error); + dynamic_cast(component->getStanzaChannel())->onPresenceReceived(response); + + loop->processEvents(); + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); + } + void handlePresenceWithoutNode() { Swift::Presence::ref response = Swift::Presence::create(); response->setTo("localhost"); diff --git a/src/tests/localbuddy.cpp b/src/tests/localbuddy.cpp new file mode 100644 index 00000000..3115aea0 --- /dev/null +++ b/src/tests/localbuddy.cpp @@ -0,0 +1,129 @@ +#include "transport/userregistry.h" +#include "transport/config.h" +#include "transport/storagebackend.h" +#include "transport/user.h" +#include "transport/transport.h" +#include "transport/conversation.h" +#include "transport/usermanager.h" +#include "transport/localbuddy.h" +#include +#include +#include +#include +#include +#include +#include +#include "Swiften/Server/ServerStanzaChannel.h" +#include "Swiften/Server/ServerFromClientSession.h" +#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" +#include "basictest.h" + +using namespace Transport; + +class LocalBuddyTest : public CPPUNIT_NS :: TestFixture, public BasicTest { + CPPUNIT_TEST_SUITE(LocalBuddyTest); + CPPUNIT_TEST(createWithInvalidName); + CPPUNIT_TEST(buddyFlagsFromJID); + CPPUNIT_TEST(JIDToLegacyName); + CPPUNIT_TEST(handleBuddyChanged); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp (void) { + setMeUp(); + connectUser(); + received.clear(); + } + + void tearDown (void) { + received.clear(); + disconnectUser(); + tearMeDown(); + } + + void connectUser() { + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password")); + loop->processEvents(); + CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount()); + + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + UserInfo userInfo = user->getUserInfo(); + CPPUNIT_ASSERT_EQUAL(std::string("password"), userInfo.password); + CPPUNIT_ASSERT(user->isReadyToConnect() == true); + CPPUNIT_ASSERT(user->isConnected() == false); + + user->setConnected(true); + CPPUNIT_ASSERT(user->isConnected() == true); + + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + received.clear(); + } + + void createWithInvalidName() { + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + std::vector grp; + grp.push_back("group"); + + // with BUDDY_JID_ESCAPING it escapes / + LocalBuddy *buddy = new LocalBuddy(user->getRosterManager(), -1, "msn/something", "Buddy 1", grp, BUDDY_JID_ESCAPING); + CPPUNIT_ASSERT(buddy->isValid()); + CPPUNIT_ASSERT_EQUAL(std::string("msn\\2fsomething@localhost/bot"), buddy->getJID().toString()); + delete buddy; + + // without BUDDY_JID_ESCAPING it shoudl fail + buddy = new LocalBuddy(user->getRosterManager(), -1, "msn/something", "Buddy 1", grp); + CPPUNIT_ASSERT(!buddy->isValid()); + delete buddy; + + buddy = new LocalBuddy(user->getRosterManager(), -1, "\xd7\x92\xd7\x9c\xd7\x99\xd7\x9d@nimbuzz.com", "Buddy 1", grp); + CPPUNIT_ASSERT(!buddy->isValid()); + delete buddy; + } + + void JIDToLegacyName() { + CPPUNIT_ASSERT_EQUAL(std::string("hanzz@test"), Buddy::JIDToLegacyName("hanzz\\40test@localhost/bot")); + CPPUNIT_ASSERT_EQUAL(std::string("hanzz@test"), Buddy::JIDToLegacyName("hanzz%test@localhost/bot")); + } + + void buddyFlagsFromJID() { + CPPUNIT_ASSERT_EQUAL(BUDDY_JID_ESCAPING, Buddy::buddyFlagsFromJID("hanzz\\40test@localhost/bot")); + CPPUNIT_ASSERT_EQUAL(BUDDY_NO_FLAG, Buddy::buddyFlagsFromJID("hanzz%test@localhost/bot")); + } + + void handleBuddyChanged() { + User *user = userManager->getUser("user@localhost"); + CPPUNIT_ASSERT(user); + + std::vector grp; + grp.push_back("group1"); + LocalBuddy *buddy = new LocalBuddy(user->getRosterManager(), -1, "buddy1", "Buddy 1", grp, BUDDY_JID_ESCAPING); + buddy->setStatus(Swift::StatusShow(Swift::StatusShow::Away), "status1"); + user->getRosterManager()->setBuddy(buddy); + received.clear(); + + buddy->handleBuddyChanged(); + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast(getStanza(received[0]))->getShow()); + CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast(getStanza(received[0]))->getStatus()); + } + + void disconnectUser() { + userManager->disconnectUser("user@localhost"); + dynamic_cast(factories->getTimerFactory())->setTime(10); + loop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount()); + CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); + CPPUNIT_ASSERT(dynamic_cast(getStanza(received[0]))); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION (LocalBuddyTest);