コード例 #1
0
ファイル: userregistration.cpp プロジェクト: Kev/libtransport
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;
}
コード例 #2
0
ファイル: RosterManager.cpp プロジェクト: HazWard/spectrum2
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);
}
コード例 #3
0
ファイル: main.cpp プロジェクト: Ghabry/libtransport
		void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) {
			Swift::Presence::ref presence = Swift::Presence::create();
			presence->setTo(user);
			presence->setFrom(jid);
			presence->setType(Swift::Presence::Unsubscribe);
			handleSwiftPresenceChanged(user, presence);
		}
コード例 #4
0
void XMPPUserRegistration::handleRegisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref remoteRosterNotSupported, const UserInfo &row){
	if (remoteRosterNotSupported || !payload) {
		// Remote roster is not support, so send normal Subscribe presence to add transport.
		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->getFrontend()->sendPresence(response);
	}
	else {
		// Remote roster is support, so use remoteroster XEP to add transport.
		Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
		Swift::RosterItemPayload item;
		item.setJID(m_component->getJID());
		item.setSubscription(Swift::RosterItemPayload::Both);
		payload->addItem(item);
		Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, row.jid, static_cast<XMPPFrontend *>(m_component->getFrontend())->getIQRouter());
		request->send();
	}

	onUserRegistered(row);

	// If the JID for registration notification is configured, send the notification message.
	std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"registration.notify_jid");
	BOOST_FOREACH(const std::string &notify_jid, x) {
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
		msg->setBody(std::string("registered: ") + row.jid);
		msg->setTo(notify_jid);
		msg->setFrom(m_component->getJID());
		m_component->getFrontend()->sendMessage(msg);
	}
コード例 #5
0
ファイル: rostermanager.cpp プロジェクト: Ghabry/libtransport
	void unsubscribeExistingBuddy() {
		add2Buddies();
		received.clear();

		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("buddy1@localhost");
		response->setFrom("user@localhost/resource");
		response->setType(Swift::Presence::Unsubscribe);

		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::Unsubscribed, dynamic_cast<Swift::Presence *>(getStanza(received[1]))->getType());

		CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), m_buddy);
	}
コード例 #6
0
void ServerStanzaChannel::finishSession(const JID& to, SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ToplevelElement> element, bool last) {
#else
void ServerStanzaChannel::finishSession(const JID& to, SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<Element> element, bool last) {
#endif
	std::vector<SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ServerFromClientSession> > candidateSessions;
	for (std::list<SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
		candidateSessions.push_back(*i);
	}

	for (std::vector<SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
		removeSession(*i);
		if (element) {
			(*i)->sendElement(element);
		}

		if (last && (*i)->getRemoteJID().isValid()) {
			Swift::Presence::ref presence = Swift::Presence::create();
			presence->setFrom((*i)->getRemoteJID());
			presence->setType(Swift::Presence::Unavailable);
			onPresenceReceived(presence);
		}

		(*i)->finishSession();
// 		std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
		if (last) {
			break;
		}
	}
}
コード例 #7
0
ファイル: basictest.cpp プロジェクト: Ghabry/libtransport
void BasicTest::connectSecondResource() {
	serverFromClientSession2 = boost::shared_ptr<Swift::ServerFromClientSession>(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(),
			payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource2")));
	serverFromClientSession2->startSession();

	serverFromClientSession2->onDataWritten.connect(boost::bind(&BasicTest::handleDataReceived2, this, _1));

	dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->addSession(serverFromClientSession2);

	userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource2"), serverFromClientSession2.get(), Swift::createSafeByteArray("password"));
	userRegistry->onPasswordValid(Swift::JID("user@localhost/resource2"));

	loop->processEvents();

	Swift::Presence::ref response = Swift::Presence::create();
	response->setTo("localhost");
	response->setFrom("user@localhost/resource2");
	injectPresence(response);
	loop->processEvents();

	CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount());

	User *user = userManager->getUser("user@localhost");
	CPPUNIT_ASSERT(user);
	CPPUNIT_ASSERT_EQUAL(2, user->getResourceCount());

	CPPUNIT_ASSERT(getStanza(received2[1])->getPayload<Swift::DiscoInfo>());
}
コード例 #8
0
ファイル: Conversation.cpp プロジェクト: akatov/spectrum2
void Conversation::destroyRoom() {
	if (m_muc) {
		Swift::Presence::ref presence = Swift::Presence::create();
		std::string legacyName = m_legacyName;
		if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
		}
		legacyName = Swift::JID::getEscapedNode(legacyName);
		presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), m_nickname));
		presence->setType(Swift::Presence::Unavailable);

		Swift::MUCItem item;
		item.affiliation = Swift::MUCOccupant::NoAffiliation;
		item.role = Swift::MUCOccupant::NoRole;
		item.actor = "Transport";
		item.reason = "Spectrum 2 transport is being shut down.";
		Swift::MUCUserPayload *p = new Swift::MUCUserPayload ();
		p->addItem(item);

		Swift::MUCUserPayload::StatusCode c;
		c.code = 332;
		p->addStatusCode(c);
		Swift::MUCUserPayload::StatusCode c2;
		c2.code = 307;
		p->addStatusCode(c2);

		presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
		BOOST_FOREACH(const Swift::JID &jid, m_jids) {
			presence->setTo(jid);
			m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
		}
	}
コード例 #9
0
ファイル: main.cpp プロジェクト: jadestorm/libtransport
		void handleSwiftConnected(const std::string &user) {
			LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
			handleConnected(user);
			m_users[user]->requestRoster();
			Swift::Presence::ref response = Swift::Presence::create();
			response->setFrom(m_users[user]->getJID());
			m_users[user]->sendPresence(response);
		}
コード例 #10
0
void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ServerFromClientSession> &session) {
	if (safeByteArrayToString(data).find("</stream:stream>") != std::string::npos) {
		Swift::Presence::ref presence = Swift::Presence::create();
		presence->setFrom(session->getRemoteJID());
		presence->setType(Swift::Presence::Unavailable);
		onPresenceReceived(presence);
	}
}
コード例 #11
0
ファイル: component.cpp プロジェクト: Ghabry/libtransport
	void handlePresenceWithNode() {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("somebody@localhost");
		response->setFrom("user@localhost/resource");
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
		
		loop->processEvents();
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
	}
コード例 #12
0
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const SWIFTEN_SHRPTR_NAMESPACE::shared_ptr<ServerFromClientSession>& session) {
	removeSession(session);

// 	if (!session->initiatedFinish()) {
		Swift::Presence::ref presence = Swift::Presence::create();
		presence->setFrom(session->getRemoteJID());
		presence->setType(Swift::Presence::Unavailable);
		onPresenceReceived(presence);
// 	}
}
コード例 #13
0
ファイル: RosterManager.cpp プロジェクト: HazWard/spectrum2
void RosterManager::sendBuddySubscribePresence(Buddy *buddy) {
	Swift::Presence::ref response = Swift::Presence::create();
	response->setTo(m_user->getJID());
	response->setFrom(buddy->getJID().toBare());
	response->setType(Swift::Presence::Subscribe);
	if (!buddy->getAlias().empty()) {
		response->addPayload(boost::make_shared<Swift::Nickname>(buddy->getAlias()));
	}
	m_component->getFrontend()->sendPresence(response);
}
コード例 #14
0
ファイル: component.cpp プロジェクト: HazWard/spectrum2
	// 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<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->onPresenceReceived(response);
		
		loop->processEvents();
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
	}
コード例 #15
0
ファイル: component.cpp プロジェクト: Ghabry/libtransport
	void handlePresenceWithoutNode() {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("localhost");
		response->setFrom("user@localhost/resource");
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
		
		loop->processEvents();
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
		CPPUNIT_ASSERT(onUserPresenceReceived);
	}
コード例 #16
0
ファイル: user.cpp プロジェクト: leiflm/libtransport
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);
		}
	}
}
コード例 #17
0
ファイル: buddy.cpp プロジェクト: meyerd/libtransport
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;
}
コード例 #18
0
ファイル: rostermanager.cpp プロジェクト: Ghabry/libtransport
	void unsubscribeNewBuddy() {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("buddy1@localhost");
		response->setFrom("user@localhost/resource");
		response->setType(Swift::Presence::Unsubscribe);

		injectPresence(response);
		loop->processEvents();

		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());

		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unsubscribed, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());

		CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), m_buddy);
	}
コード例 #19
0
ファイル: user.cpp プロジェクト: mdonoughe/libtransport
	void handlePresence() {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("localhost");
		response->setFrom("user@localhost/resource");
		response->setShow(Swift::StatusShow::Away);

		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(changedPresence);
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, changedPresence->getShow());
	}
コード例 #20
0
ファイル: XMPPFrontend.cpp プロジェクト: mdabbagh88/spectrum2
void XMPPFrontend::reconnectUser(const std::string &user) {
	if (inServerMode()) {
		return;
	}

	LOG4CXX_INFO(logger, "Sending probe presence to " << user);
	Swift::Presence::ref response = Swift::Presence::create();
	try {
		response->setTo(user);
	}
	catch (...) { return; }
	
	response->setFrom(m_component->getJID());
	response->setType(Swift::Presence::Probe);

	m_stanzaChannel->sendPresence(response);
}
コード例 #21
0
ファイル: user.cpp プロジェクト: mdonoughe/libtransport
	void handlePresenceLeaveRoom() {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo("#room@localhost/hanzz");
		response->setFrom("user@localhost/resource");
		response->setType(Swift::Presence::Unavailable);

		Swift::MUCPayload *payload = new Swift::MUCPayload();
		payload->setPassword("password");
		response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
		injectPresence(response);
		loop->processEvents();

		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());

		CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
	}
コード例 #22
0
void UsersReconnecter::reconnectNextUser() {
	if (m_users.empty()) {
		LOG4CXX_INFO(logger, "All users reconnected, stopping UserReconnecter.");
		return;
	}

	std::string user = m_users.back();
	m_users.pop_back();

	LOG4CXX_INFO(logger, "Sending probe presence to " << user);
	Swift::Presence::ref response = Swift::Presence::create();
	response->setTo(user);
	response->setFrom(m_component->getJID());
	response->setType(Swift::Presence::Probe);

	m_component->getStanzaChannel()->sendPresence(response);
	m_nextUserTimer->start();
}
コード例 #23
0
ファイル: user.cpp プロジェクト: mdonoughe/libtransport
	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);
	}
コード例 #24
0
ファイル: userregistration.cpp プロジェクト: Kev/libtransport
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;
}
コード例 #25
0
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);
		}
	}
}
コード例 #26
0
ファイル: RosterManager.cpp プロジェクト: HazWard/spectrum2
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 &currentPresence, 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 {