From fb527b57609088287550e9529f1657f537bdb24a 2012-06-14 08:06:46 From: Jan Kaluza Date: 2012-06-14 08:06:46 Subject: [PATCH] Added NetworkPlugin::handleBuddyRemoved method to let backend remove buddy from XMPP user's roster --- diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 9f440152a6111e2e6ceb61ccd1d6a6508b0a1590..f54269a0a233cbffd57f77f35f3a053afad71a3e 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -75,6 +75,11 @@ class NetworkPlugin { bool blocked = false ); + /// Call this method when buddy is removed from legacy network contact list. + /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") + /// \param buddyName Name of legacy network buddy. (eg. "user2@gmail.com") + void handleBuddyRemoved(const std::string &user, const std::string &buddyName); + /// Call this function when participant in room changed. /// \param user XMPP JID of user for which this event occurs. You can get it from NetworkPlugin::handleLoginRequest(). (eg. "user%gmail.com@xmpp.domain.tld") /// \param nickname Nickname of participant. If participant renamed, this is old name of participant. (eg. "HanzZ") diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 5572780a90eda0687baf7d7087a3b0747c246aae..7e43ce33c4606ee984918bd022cbd1fd95085461 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -89,6 +89,7 @@ class NetworkPluginServer { void handleConnectedPayload(const std::string &payload); void handleDisconnectedPayload(const std::string &payload); void handleBuddyChangedPayload(const std::string &payload); + void handleBuddyRemovedPayload(const std::string &payload); void handleConvMessagePayload(const std::string &payload, bool subject = false); void handleParticipantChangedPayload(const std::string &payload); void handleRoomChangedPayload(const std::string &payload); diff --git a/include/transport/rostermanager.h b/include/transport/rostermanager.h index 64f05fa70f63d9a7b642547f617c952813fed9df..fd649b57df89e3466fc310edceb26d4ee1c9c5c4 100644 --- a/include/transport/rostermanager.h +++ b/include/transport/rostermanager.h @@ -69,6 +69,10 @@ class RosterManager { /// \param buddy Buddy. void unsetBuddy(Buddy *buddy); + /// Removes buddy from this roster, sends proper XML to XMPP side and deletes it. + /// \param name Buddy name. + void removeBuddy(const std::string &name); + Buddy *getBuddy(const std::string &name); void setStorageBackend(StorageBackend *storageBackend); @@ -107,7 +111,11 @@ class RosterManager { void sendBuddyRosterPush(Buddy *buddy); + void sendBuddyRosterRemove(Buddy *buddy); + void sendBuddySubscribePresence(Buddy *buddy); + + void sendBuddyUnsubscribePresence(Buddy *buddy); void sendCurrentPresences(const Swift::JID &to); diff --git a/plugin/cpp/networkplugin.cpp b/plugin/cpp/networkplugin.cpp index 43d82653731d0f0810c56af488c11fb75aaa3ee9..4455c37ed8629caf0a055920b492246dfd4ec49a 100644 --- a/plugin/cpp/networkplugin.cpp +++ b/plugin/cpp/networkplugin.cpp @@ -165,6 +165,19 @@ void NetworkPlugin::handleBuddyChanged(const std::string &user, const std::strin send(message); } +void NetworkPlugin::handleBuddyRemoved(const std::string &user, const std::string &buddyName) { + pbnetwork::Buddy buddy; + buddy.set_username(user); + buddy.set_buddyname(buddyName); + + std::string message; + buddy.SerializeToString(&message); + + WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_REMOVED); + + send(message); +} + void NetworkPlugin::handleBuddyTyping(const std::string &user, const std::string &buddyName) { pbnetwork::Buddy buddy; buddy.set_username(user); diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index fdd68e68430889248a9671c73f3d25e7388c0c69..c9b6f23cde107261d0ac9f7f9372d87723b1ee52 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -264,6 +264,7 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U LOG4CXX_INFO(logger, "Listening on host " << CONFIG_STRING(m_config, "service.backend_host") << " port " << CONFIG_STRING(m_config, "service.backend_port")); unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), m_config->getConfigFile().c_str()); + LOG4CXX_INFO(logger, "Tried to spawn first backend with pid " << pid); LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects"); #ifndef _WIN32 @@ -509,8 +510,6 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) { if (!user) return; - LOG4CXX_INFO(logger, "HANDLE BUDDY CHANGED " << payload.buddyname() << "-" << payload.alias()); - LocalBuddy *buddy = (LocalBuddy *) user->getRosterManager()->getBuddy(payload.buddyname()); if (buddy) { handleBuddyPayload(buddy, payload); @@ -524,6 +523,20 @@ void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) { } } +void NetworkPluginServer::handleBuddyRemovedPayload(const std::string &data) { + pbnetwork::Buddy payload; + if (payload.ParseFromString(data) == false) { + // TODO: ERROR + return; + } + + User *user = m_userManager->getUser(payload.username()); + if (!user) + return; + + user->getRosterManager()->removeBuddy(payload.buddyname()); +} + void NetworkPluginServer::handleParticipantChangedPayload(const std::string &data) { pbnetwork::Participant payload; if (payload.ParseFromString(data) == false) { @@ -828,6 +841,9 @@ void NetworkPluginServer::handleDataRead(Backend *c, boost::shared_ptrgetJID().toString() << ": Tried to remove unknown buddy " << name); + return; + } + + if (m_component->inServerMode() || m_remoteRosterRequest) { + sendBuddyRosterRemove(buddy); + } + else { + sendBuddyUnsubscribePresence(buddy); + } + + unsetBuddy(buddy); + delete buddy; +} + +void RosterManager::sendBuddyRosterRemove(Buddy *buddy) { + Swift::RosterPayload::ref p = Swift::RosterPayload::ref(new Swift::RosterPayload()); + Swift::RosterItemPayload item; + item.setJID(buddy->getJID().toBare()); + item.setSubscription(Swift::RosterItemPayload::Remove); + + p->addItem(item); + + // In server mode we have to send pushes to all resources, but in gateway-mode we send it only to bare JID + if (m_component->inServerMode()) { + std::vector presences = m_component->getPresenceOracle()->getAllPresence(m_user->getJID().toBare()); + BOOST_FOREACH(Swift::Presence::ref presence, presences) { + Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, presence->getFrom(), m_component->getIQRouter()); + request->send(); + } + } + else { + Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(p, m_user->getJID().toBare(), m_component->getIQRouter()); + request->send(); + } +} + void RosterManager::sendBuddyRosterPush(Buddy *buddy) { // user can't receive anything in server mode if he's not logged in. // He will ask for roster later (handled in rosterreponsder.cpp) @@ -142,6 +182,20 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) { } } +void RosterManager::sendBuddyUnsubscribePresence(Buddy *buddy) { + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo(m_user->getJID()); + response->setFrom(buddy->getJID()); + response->setType(Swift::Presence::Unsubscribe); + m_component->getStanzaChannel()->sendPresence(response); + + response = Swift::Presence::create(); + response->setTo(m_user->getJID()); + response->setFrom(buddy->getJID()); + response->setType(Swift::Presence::Unsubscribed); + m_component->getStanzaChannel()->sendPresence(response); +} + void RosterManager::sendBuddySubscribePresence(Buddy *buddy) { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(m_user->getJID());