void handlePresenceJoinRoom() { Swift::Presence::ref response = Swift::Presence::create(); response->setTo("#room@localhost/hanzz"); response->setFrom("user@localhost/resource"); Swift::MUCPayload *payload = new Swift::MUCPayload(); payload->setPassword("password"); response->addPayload(boost::shared_ptr<Swift::Payload>(payload)); injectPresence(response); loop->processEvents(); // no presence received in server mode, just disco#info CPPUNIT_ASSERT_EQUAL(1, (int) received.size()); CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>()); CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); }
bool UserRegistration::registerUser(const UserInfo &row) { // TODO: move this check to sql()->addUser(...) and let it return bool UserInfo user; bool registered = m_storageBackend->getUser(row.jid, user); // This user is already registered if (registered) return false; m_storageBackend->setUser(row); Swift::Presence::ref response = Swift::Presence::create(); response->setFrom(m_component->getJID()); response->setTo(Swift::JID(row.jid)); response->setType(Swift::Presence::Subscribe); m_component->m_component->sendPresence(response); onUserRegistered(row); return true; }
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) { LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed"); std::string message = presence->getStatus(); std::string photo = ""; boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>(); if (update) { photo = update->getPhotoHash(); } boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom()); if (item) { handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo); } else { std::vector<std::string> groups; handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo); } }
void subscribeNewBuddy() { Swift::Presence::ref response = Swift::Presence::create(); response->setTo("buddy1@localhost"); response->setFrom("user@localhost/resource"); response->setType(Swift::Presence::Subscribe); injectPresence(response); loop->processEvents(); CPPUNIT_ASSERT_EQUAL(2, (int) received.size()); Swift::RosterPayload::ref payload1 = getStanza(received[0])->getPayload<Swift::RosterPayload>(); CPPUNIT_ASSERT_EQUAL(1, (int) payload1->getItems().size()); Swift::RosterItemPayload item = payload1->getItems()[0]; CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), Buddy::JIDToLegacyName(item.getJID())); CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[1]))); CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribed, dynamic_cast<Swift::Presence *>(getStanza(received[1]))->getType()); CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), m_buddy); }
void Component::handlePresence(Swift::Presence::ref presence) { bool isMUC = presence->getPayload<MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#'; // filter out login/logout presence spam if (!presence->getTo().getNode().empty() && isMUC == false) return; // filter out bad presences if (!presence->getFrom().isValid()) { return; } // check if we have this client's capabilities and ask for them if (presence->getType() != Swift::Presence::Unavailable) { boost::shared_ptr<CapsInfo> capsInfo = presence->getPayload<CapsInfo>(); if (capsInfo && capsInfo->getHash() == "sha-1") { /*haveFeatures = */m_entityCapsManager->getCaps(presence->getFrom()) != DiscoInfo::ref(); } #ifdef SUPPORT_LEGACY_CAPS else { GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter); discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom())); discoInfoRequest->send(); } #endif } onUserPresenceReceived(presence); }
void User::onConnectingTimeout() { if (m_connected || m_readyForConnect) return; m_reconnectTimer->stop(); m_readyForConnect = true; onReadyToConnect(); Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare()); if (highest) { LOG4CXX_INFO(logger, m_jid.toString() << ": Changing legacy network presence to " << highest->getType()); onPresenceChanged(highest); } }
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->getFrontend()->sendPresence(response); response = Swift::Presence::create(); response->setTo(m_user->getJID()); response->setFrom(buddy->getJID()); response->setType(Swift::Presence::Unsubscribed); m_component->getFrontend()->sendPresence(response); }
void User::sendCurrentPresence() { if (m_component->inServerMode()) { return; } std::vector<Swift::Presence::ref> presences = m_presenceOracle->getAllPresence(m_jid); foreach(Swift::Presence::ref presence, presences) { if (presence->getType() == Swift::Presence::Unavailable) { continue; } if (m_connected) { Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare()); if (highest) { Swift::Presence::ref response = Swift::Presence::create(highest); response->setTo(presence->getFrom()); response->setFrom(m_component->getJID()); m_component->getStanzaChannel()->sendPresence(response); } else { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom()); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unavailable); m_component->getStanzaChannel()->sendPresence(response); } } else { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom()); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unavailable); response->setStatus("Connecting"); m_component->getStanzaChannel()->sendPresence(response); } } }
void User::handlePresence(Swift::Presence::ref presence) { int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size(); m_conversationManager->resetResources(); if (!m_connected) { // we are not connected to legacy network, so we should do it when disco#info arrive :) if (m_readyForConnect == false) { // Forward status message to legacy network, but only if it's sent from active resource // if (m_activeResource == presence->getFrom().getResource().getUTF8String()) { // forwardStatus(presenceShow, stanzaStatus); // } boost::shared_ptr<Swift::CapsInfo> capsInfo = presence->getPayload<Swift::CapsInfo>(); if (capsInfo && capsInfo->getHash() == "sha-1") { if (m_entityCapsManager->getCaps(presence->getFrom()) != Swift::DiscoInfo::ref()) { LOG4CXX_INFO(logger, m_jid.toString() << ": Ready to be connected to legacy network"); m_readyForConnect = true; onReadyToConnect(); } else { m_reconnectTimer->start(); } } else if (m_component->inServerMode()) { LOG4CXX_INFO(logger, m_jid.toString() << ": Ready to be connected to legacy network"); m_readyForConnect = true; onReadyToConnect(); } else { m_reconnectTimer->start(); } } } bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#'; if (isMUC) { if (presence->getType() == Swift::Presence::Unavailable) { std::string room = Buddy::JIDToLegacyName(presence->getTo()); LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room); onRoomLeft(room); Conversation *conv = m_conversationManager->getConversation(room); if (conv) { m_conversationManager->removeConversation(conv); delete conv; } } else { // force connection to legacy network to let backend to handle auto-join on connect. if (!m_readyForConnect) { LOG4CXX_INFO(logger, m_jid.toString() << ": Ready to be connected to legacy network"); m_readyForConnect = true; onReadyToConnect(); } std::string room = Buddy::JIDToLegacyName(presence->getTo()); if (m_conversationManager->getConversation(room) != NULL) { LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource()); return; } LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << room << " as " << presence->getTo().getResource()); std::string password = ""; if (presence->getPayload<Swift::MUCPayload>() != NULL) { password = presence->getPayload<Swift::MUCPayload>()->getPassword() ? *presence->getPayload<Swift::MUCPayload>()->getPassword() : ""; } onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password); } return; } // User wants to disconnect this resource if (!m_component->inServerMode()) { if (presence->getType() == Swift::Presence::Unavailable) { // Send unavailable presences for online contacts m_rosterManager->sendUnavailablePresences(presence->getFrom()); // Send unavailable presence for transport contact itself Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom()); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unavailable); m_component->getStanzaChannel()->sendPresence(response); } else { sendCurrentPresence(); // This resource is new, so we have to send buddies presences if (currentResourcesCount != m_resources) { m_rosterManager->sendCurrentPresences(presence->getFrom()); } } } m_resources = currentResourcesCount; // Change legacy network presence if (m_readyForConnect) { Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare()); if (highest) { Swift::Presence::ref response = Swift::Presence::create(highest); response->setTo(m_jid); response->setFrom(m_component->getJID()); LOG4CXX_INFO(logger, m_jid.toString() << ": Changing legacy network presence to " << response->getType()); onPresenceChanged(highest); } else { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(m_jid.toBare()); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unavailable); onPresenceChanged(response); } } }
void RosterManager::handleSubscription(Swift::Presence::ref presence) { std::string legacyName = Buddy::JIDToLegacyName(presence->getTo(), m_user); if (legacyName.empty()) { return; } // For server mode the subscription changes are handler in rosterresponder.cpp // using roster pushes. if (m_component->inServerMode()) { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom().toBare()); response->setFrom(presence->getTo().toBare()); Buddy *buddy = getBuddy(legacyName); if (buddy) { LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received and buddy " << legacyName << " is already there => answering"); switch (presence->getType()) { case Swift::Presence::Subscribe: onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); break; case Swift::Presence::Unsubscribe: onBuddyRemoved(buddy); removeBuddy(buddy->getName()); buddy = NULL; response->setType(Swift::Presence::Unsubscribed); break; case Swift::Presence::Subscribed: onBuddyAdded(buddy); break; default: return; } m_component->getFrontend()->sendPresence(response); } else { BuddyInfo buddyInfo; switch (presence->getType()) { // buddy is not in roster, so add him case Swift::Presence::Subscribe: buddyInfo.id = -1; buddyInfo.alias = ""; buddyInfo.legacyName = legacyName; buddyInfo.subscription = "both"; 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); setBuddy(buddy); onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); break; case Swift::Presence::Subscribed: // onBuddyAdded(buddy); return; // buddy is not there, so nothing to do, just answer case Swift::Presence::Unsubscribe: buddyInfo.id = -1; buddyInfo.alias = ""; buddyInfo.legacyName = legacyName; buddyInfo.subscription = "both"; buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo()); buddy = m_component->getFactory()->createBuddy(this, buddyInfo); onBuddyRemoved(buddy); delete buddy; response->setType(Swift::Presence::Unsubscribed); break; default: return; } m_component->getFrontend()->sendPresence(response); } } else { Swift::Presence::ref response = Swift::Presence::create(); Swift::Presence::ref currentPresence; response->setTo(presence->getFrom().toBare()); response->setFrom(presence->getTo().toBare()); Buddy *buddy = getBuddy(legacyName); if (buddy) { std::vector<Swift::Presence::ref> &presences = buddy->generatePresenceStanzas(255); switch (presence->getType()) { // buddy is already there, so nothing to do, just answer case Swift::Presence::Subscribe: onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); BOOST_FOREACH(Swift::Presence::ref ¤tPresence, presences) { currentPresence->setTo(presence->getFrom()); m_component->getFrontend()->sendPresence(currentPresence); } if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } break; // remove buddy case Swift::Presence::Unsubscribe: response->setType(Swift::Presence::Unsubscribed); onBuddyRemoved(buddy); removeBuddy(buddy->getName()); buddy = NULL; break; // just send response case Swift::Presence::Unsubscribed: response->setType(Swift::Presence::Unsubscribe); // We set both here, because this Unsubscribed can be response to // subscribe presence and we don't want that unsubscribe presence // to be send later again if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } break; case Swift::Presence::Subscribed: if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } return; default: return; } } else {
bool UserRegistration::unregisterUser(const std::string &barejid) { UserInfo userInfo; bool registered = m_storageBackend->getUser(barejid, userInfo); // This user is not registered if (!registered) return false; onUserUnregistered(userInfo); Swift::Presence::ref response; User *user = m_userManager->getUser(barejid); // roster contains already escaped jids std::list <std::string> roster; m_storageBackend->getBuddies(userInfo.id, roster); for(std::list<std::string>::iterator u = roster.begin(); u != roster.end() ; u++){ std::string name = *u; response = Swift::Presence::create(); response->setTo(Swift::JID(barejid)); response->setFrom(Swift::JID(name + "@" + m_component->getJID().toString())); response->setType(Swift::Presence::Unsubscribe); m_component->m_component->sendPresence(response); response = Swift::Presence::create(); response->setTo(Swift::JID(barejid)); response->setFrom(Swift::JID(name + "@" + m_component->getJID().toString())); response->setType(Swift::Presence::Unsubscribed); m_component->m_component->sendPresence(response); } // Remove user from database m_storageBackend->removeUser(userInfo.id); // Disconnect the user if (user) { m_userManager->removeUser(user); } response = Swift::Presence::create(); response->setTo(Swift::JID(barejid)); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unsubscribe); m_component->m_component->sendPresence(response); response = Swift::Presence::create(); response->setTo(Swift::JID(barejid)); response->setFrom(m_component->getJID()); response->setType(Swift::Presence::Unsubscribed); m_component->m_component->sendPresence(response); return true; }
Swift::Presence::ref Buddy::generatePresenceStanza(int features, bool only_new) { std::string alias = getAlias(); std::string name = getSafeName(); Swift::StatusShow s; std::string statusMessage; if (!getStatus(s, statusMessage)) return Swift::Presence::ref(); if (m_jid.getNode().empty()) { generateJID(); } Swift::Presence::ref presence = Swift::Presence::create(); presence->setFrom(m_jid); presence->setTo(m_rosterManager->getUser()->getJID().toBare()); presence->setType(Swift::Presence::Available); if (!statusMessage.empty()) presence->setStatus(statusMessage); if (s.getType() == Swift::StatusShow::None) presence->setType(Swift::Presence::Unavailable); presence->setShow(s.getType()); if (presence->getType() != Swift::Presence::Unavailable) { // caps presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::CapsInfo(m_rosterManager->getUser()->getComponent()->getBuddyCapsInfo()))); // if (features & 0/*TRANSPORT_FEATURE_AVATARS*/) { presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::VCardUpdate (getIconHash()))); // } if (isBlocked()) { presence->addPayload(boost::shared_ptr<Swift::Payload>(new Transport::BlockPayload ())); } } // if (only_new) { // if (m_lastPresence) // m_lastPresence->setTo(Swift::JID("")); // if (m_lastPresence == presence) { // return Swift::Presence::ref(); // } // m_lastPresence = presence; // } return presence; }