Changeset - 3aff761db678
[Not reviewed]
0 4 0
Jan Kaluza - 13 years ago 2012-11-02 09:50:03
hanzz.k@gmail.com
Do not send subscribe presence just because, but send it as response to probe presence
4 files changed with 87 insertions and 4 deletions:
0 comments (0 inline, 0 general)
include/transport/usermanager.h
Show inline comments
 
@@ -86,68 +86,69 @@ class UserManager : public Swift::EntityCapsProvider {
 
		Swift::DiscoInfo::ref getCaps(const Swift::JID&) const;
 

	
 
		DiscoItemsResponder *getDiscoResponder() { return m_discoItemsResponder; }
 

	
 
		/// Called when new User class is created.
 
		/// \param user newly created User class
 
		boost::signal<void (User *user)> onUserCreated;
 

	
 
		/// Called when User class is going to be removed
 
		/// \param user removed User class
 
		boost::signal<void (User *user)> onUserDestroyed;
 

	
 
		/// Returns true if user is connected.
 
		/// \return True if user is connected.
 
		bool isUserConnected(const std::string &barejid) const {
 
			return m_users.find(barejid) != m_users.end();
 
		}
 

	
 
		/// Returns pointer to UserRegistry.
 
		/// \return Pointer to UserRegistry.
 
		UserRegistry *getUserRegistry() {
 
			return m_userRegistry;
 
		}
 

	
 
		Component *getComponent() {
 
			return m_component;
 
		}
 

	
 
		/// Connects user manually.
 
		/// \param user JID of user.
 
		void connectUser(const Swift::JID &user);
 

	
 
		/// Disconnects user manually.
 
		/// \param user JID of user.
 
		void disconnectUser(const Swift::JID &user);
 

	
 
		void messageToXMPPSent() { m_sentToXMPP++; }
 
		void messageToBackendSent() { m_sentToBackend++; }
 

	
 
		unsigned long getMessagesToXMPP() { return m_sentToXMPP; }
 
		unsigned long getMessagesToBackend() { return m_sentToBackend; }
 
		
 

	
 
	private:
 
		void handlePresence(Swift::Presence::ref presence);
 
		void handleMessageReceived(Swift::Message::ref message);
 
		void handleGeneralPresenceReceived(Swift::Presence::ref presence);
 
		void handleProbePresence(Swift::Presence::ref presence);
 
		void handleErrorPresence(Swift::Presence::ref presence);
 
		void handleSubscription(Swift::Presence::ref presence);
 
		void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
 
		void handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info);
 
		void addUser(User *user);
 

	
 
		long m_onlineBuddies;
 
		User *m_cachedUser;
 
		std::map<std::string, User *> m_users;
 
		Component *m_component;
 
		StorageBackend *m_storageBackend;
 
		StorageResponder *m_storageResponder;
 
		UserRegistry *m_userRegistry;
 
		Swift::Timer::ref m_removeTimer;
 
		unsigned long m_sentToXMPP;
 
		unsigned long m_sentToBackend;
 
		DiscoItemsResponder *m_discoItemsResponder;
 
		friend class RosterResponder;
 
};
 

	
 
}
src/tests/usermanager.cpp
Show inline comments
 
@@ -27,87 +27,128 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST(connectUserTransportDisabled);
 
	CPPUNIT_TEST(connectUserRegistrationNeeded);
 
	CPPUNIT_TEST(connectUserRegistrationNeededRegistered);
 
	CPPUNIT_TEST(handleProbePresence);
 
	CPPUNIT_TEST(disconnectUser);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		void setUp (void) {
 
			setMeUp();
 
		}
 

	
 
		void tearDown (void) {
 
			tearMeDown();
 
		}
 

	
 
	void connectUserTransportDisabled() {
 
		addUser();
 
		storage->updateUserSetting(1, "enable_transport", "0");
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
		loop->processEvents();
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 

	
 
		User *user = userManager->getUser("user@localhost");
 
		CPPUNIT_ASSERT(!user);
 
	}
 

	
 
	void connectUserRegistrationNeeded() {
 
		cfg->updateBackendConfig("[registration]\nneedRegistration=1\n");
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
		loop->processEvents();
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		CPPUNIT_ASSERT(streamEnded);
 
	}
 

	
 
	void connectUserRegistrationNeededRegistered() {
 
		addUser();
 
		cfg->updateBackendConfig("[registration]\nneedRegistration=1\n");
 
		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());
 
		CPPUNIT_ASSERT(!streamEnded);
 
	}
 

	
 
	void handleProbePresence() {
 
		UserInfo info;
 
		info.id = 1;
 
		info.jid = "user@localhost";
 
		storage->setUser(info);
 

	
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("localhost");
 
		response->setFrom("user@localhost/resource");
 
		response->setType(Swift::Presence::Probe);
 
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(3, (int) received.size());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
 

	
 
		Swift::Presence *presence = dynamic_cast<Swift::Presence *>(getStanza(received[1]));
 
		CPPUNIT_ASSERT(presence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType());
 

	
 
		presence = dynamic_cast<Swift::Presence *>(getStanza(received[2]));
 
		CPPUNIT_ASSERT(presence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Probe, presence->getType());
 

	
 
		received.clear();
 
		response = Swift::Presence::create();
 
		response->setTo("localhost");
 
		response->setFrom("user@localhost");
 
		response->setType(Swift::Presence::Unsubscribed);
 
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
		presence = dynamic_cast<Swift::Presence *>(getStanza(received[1]));
 
		CPPUNIT_ASSERT(presence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribe, presence->getType());
 

	
 
		received.clear();
 
		response = Swift::Presence::create();
 
		response->setTo("localhost");
 
		response->setFrom("user@localhost");
 
		response->setType(Swift::Presence::Error);
 
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		presence = dynamic_cast<Swift::Presence *>(getStanza(received[0]));
 
		CPPUNIT_ASSERT(presence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Subscribe, presence->getType());
 

	
 
		storage->removeUser(1);
 
		received.clear();
 
		response = Swift::Presence::create();
 
		response->setTo("localhost");
 
		response->setFrom("user@localhost");
 
		response->setType(Swift::Presence::Unsubscribed);
 
		dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->onPresenceReceived(response);
 
		loop->processEvents();
 

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

	
 
	void connectTwoResources() {
 
		connectUser();
 
		add2Buddies();
 
		connectSecondResource();
 

	
 
		// we should get presences
 
		CPPUNIT_ASSERT_EQUAL(4, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[2])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[2]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast<Swift::Presence *>(getStanza(received2[2]))->getStatus());
 

	
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[3])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[3]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast<Swift::Presence *>(getStanza(received2[3]))->getStatus());
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (UserManagerTest);
src/transport.cpp
Show inline comments
 
@@ -236,81 +236,88 @@ void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer
 
		if(*e == Swift::BoostConnectionServer::UnknownError)
 
			LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
 
		exit(1);
 
	}
 
}
 

	
 

	
 
void Component::handleConnectionError(const ComponentError &error) {
 
	onConnectionError(error);
 
// 	if (m_reconnectCount == 2)
 
// 		Component::instance()->userManager()->removeAllUsers();
 
	std::string str = "Unknown error";
 
	switch (error.getType()) {
 
		case ComponentError::UnknownError: str = "Unknown error"; break;
 
		case ComponentError::ConnectionError: str = "Connection error"; break;
 
		case ComponentError::ConnectionReadError: str = "Connection read error"; break;
 
		case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
 
		case ComponentError::XMLError: str = "XML Error"; break;
 
		case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
 
		case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
 
	}
 
	LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
 

	
 
	m_reconnectTimer->start();
 
}
 

	
 
void Component::handleDataRead(const Swift::SafeByteArray &data) {
 
	std::string d = safeByteArrayToString(data);
 
	if (!boost::starts_with(d, "<auth")) {
 
		LOG4CXX_INFO(logger_xml, "XML IN " << d);
 
	}
 
}
 

	
 
void Component::handleDataWritten(const Swift::SafeByteArray &data) {
 
	LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
 
}
 

	
 
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;
 
	}
 

	
 
	if (presence->getType() == Presence::Error) {
 
	switch (presence->getType()) {
 
		case Presence::Error:
 
		case Presence::Subscribe:
 
		case Presence::Subscribed:
 
		case Presence::Unsubscribe:
 
		case Presence::Unsubscribed:
 
			return;
 
	}
 
		default:
 
			break;
 
	};
 

	
 
	// 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 Component::handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid) {
 
#ifdef SUPPORT_LEGACY_CAPS
 
	onUserDiscoInfoReceived(jid, info);
 
#endif
 
}
 

	
 
void Component::handleCapsChanged(const Swift::JID& jid) {
 
	onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
 
}
 

	
 
}
src/usermanager.cpp
Show inline comments
 
@@ -150,103 +150,103 @@ void UserManager::handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift
 
	if (!user) {
 
		return;
 
	}
 

	
 
	user->handleDiscoInfo(jid, info);
 
}
 

	
 
void UserManager::handlePresence(Swift::Presence::ref presence) {
 
	std::string barejid = presence->getTo().toBare().toString();
 
	std::string userkey = presence->getFrom().toBare().toString();
 

	
 
	User *user = getUser(userkey);
 
	// Create user class if it's not there
 
	if (!user) {
 
		// Admin user is not legacy network user, so do not create User class instance for him
 
		if (m_component->inServerMode()) {
 
			std::vector<std::string> const &x = CONFIG_VECTOR(m_component->getConfig(),"service.admin_jid");
 
			if (std::find(x.begin(), x.end(), presence->getFrom().toBare().toString()) != x.end()) {
 
				// Send admin contact to the user.
 
				Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
 
				Swift::RosterItemPayload item;
 
				item.setJID(m_component->getJID());
 
				item.setName("Admin");
 
				item.setSubscription(Swift::RosterItemPayload::Both);
 
				payload->addItem(item);
 

	
 
				Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, presence->getFrom(), m_component->getIQRouter());
 
				request->send();
 

	
 
				Swift::Presence::ref response = Swift::Presence::create();
 
				response->setTo(presence->getFrom());
 
				response->setFrom(m_component->getJID());
 
				m_component->getStanzaChannel()->sendPresence(response);
 
				return;
 
		    }
 
		}
 

	
 
		UserInfo res;
 
		bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
 

	
 
		// No user and unavailable presence -> answer with unavailable
 
		if (presence->getType() == Swift::Presence::Unavailable || presence->getType() == Swift::Presence::Probe) {
 
			Swift::Presence::ref response = Swift::Presence::create();
 
			response->setTo(presence->getFrom());
 
			response->setFrom(presence->getTo());
 
			response->setType(Swift::Presence::Unavailable);
 
			m_component->getStanzaChannel()->sendPresence(response);
 

	
 
			// bother him with subscribe presence, just to be
 
			// bother him with probe presence, just to be
 
			// sure he is subscribed to us.
 
			if (/*registered && */presence->getType() == Swift::Presence::Probe) {
 
				Swift::Presence::ref response = Swift::Presence::create();
 
				response->setTo(presence->getFrom());
 
				response->setFrom(presence->getTo());
 
				response->setType(Swift::Presence::Subscribe);
 
				response->setType(Swift::Presence::Probe);
 
				m_component->getStanzaChannel()->sendPresence(response);
 
			}
 

	
 
			// Set user offline in database
 
			if (m_storageBackend) {
 
				UserInfo res;
 
				bool registered = m_storageBackend->getUser(userkey, res);
 
				if (registered) {
 
					m_storageBackend->setUserOnline(res.id, false);
 
				}
 
			}
 
			return;
 
		}
 

	
 
		// In server mode, we don't need registration normally, but for networks like IRC
 
		// or Twitter where there's no real authorization using password, we have to force
 
		// registration otherwise some data (like bookmarked rooms) could leak.
 
		if (m_component->inServerMode()) {
 
			if (!registered) {
 
				// If we need registration, stop login process because user is not registered
 
				if (CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", false)) {
 
					m_userRegistry->onPasswordInvalid(presence->getFrom());
 
					return;
 
				}
 
				res.password = "";
 
				res.uin = presence->getFrom().getNode();
 
				res.jid = userkey;
 
				if (res.uin.find_last_of("%") != std::string::npos) { // OK
 
					res.uin.replace(res.uin.find_last_of("%"), 1, "@"); // OK
 
				}
 
				if (m_storageBackend) {
 
					// store user and getUser again to get user ID.
 
					m_storageBackend->setUser(res);
 
					registered = m_storageBackend->getUser(userkey, res);
 
				}
 
				else {
 
					registered = true;
 
				}
 
			}
 
			res.password = m_userRegistry->getUserPassword(userkey);
 
		}
 

	
 
		// We allow auto_register feature in gateway-mode. This allows IRC user to register
 
		// the transport just by joining the room.
 
		if (!m_component->inServerMode()) {
 
			if (!registered && CONFIG_BOOL(m_component->getConfig(), "registration.auto_register")) {
 
				res.password = "";
 
				res.jid = userkey;
 
@@ -337,137 +337,171 @@ void UserManager::handleRemoveTimeout(const std::string jid, User *u, bool recon
 
	// Remove user
 
	if (user) {
 
		removeUser(user);
 
	}
 

	
 
	// Connect the user again when we're reconnecting.
 
	if (reconnect) {
 
		connectUser(jid);
 
	}
 
}
 

	
 
void UserManager::handleMessageReceived(Swift::Message::ref message) {
 
	if (message->getType() == Swift::Message::Error) {
 
		return;
 
	}
 

	
 
	// Do not count chatstate notification...
 
	boost::shared_ptr<Swift::ChatState> statePayload = message->getPayload<Swift::ChatState>();
 
	if (!statePayload) {
 
		messageToBackendSent();
 
	}
 

	
 
	if (message->getBody().empty() && !statePayload && message->getSubject().empty()) {
 
		return;
 
	}
 

	
 
	User *user = getUser(message->getFrom().toBare().toString());
 
	if (!user){
 
		return;
 
	}
 

	
 
	user->getConversationManager()->handleMessageReceived(message);
 
}
 

	
 
void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) {
 
	switch(presence->getType()) {
 
		case Swift::Presence::Subscribe:
 
		case Swift::Presence::Subscribed:
 
		case Swift::Presence::Unsubscribe:
 
		case Swift::Presence::Unsubscribed:
 
			handleSubscription(presence);
 
			break;
 
		case Swift::Presence::Available:
 
		case Swift::Presence::Unavailable:
 
			break;
 
		case Swift::Presence::Probe:
 
			handleProbePresence(presence);
 
			break;
 
		case Swift::Presence::Error:
 
			handleErrorPresence(presence);
 
			break;
 
		default:
 
			break;
 
	};
 
}
 

	
 
void UserManager::handleProbePresence(Swift::Presence::ref presence) {
 
	// Don't let RosterManager to handle presences for us
 
	if (presence->getTo().getNode().empty()) {
 
		return;
 
	}
 

	
 
	User *user = getUser(presence->getFrom().toBare().toString());
 

	
 
 	if (user) {
 
 		user->getRosterManager()->sendCurrentPresence(presence->getTo(), presence->getFrom());
 
 	}
 
 	else {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setFrom(presence->getTo());
 
		response->setTo(presence->getFrom());
 
		response->setType(Swift::Presence::Unavailable);
 
		m_component->getStanzaChannel()->sendPresence(response);
 
	}
 
}
 

	
 
void UserManager::handleErrorPresence(Swift::Presence::ref presence) {
 
	// Don't let RosterManager to handle presences for us
 
	if (!presence->getTo().getNode().empty()) {
 
		return;
 
	}
 
	std::string userkey = presence->getFrom().toBare().toString();
 
	UserInfo res;
 
	bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
 
	if (registered) {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setFrom(presence->getTo().toBare());
 
		response->setTo(presence->getFrom().toBare());
 
		response->setType(Swift::Presence::Subscribe);
 
		m_component->getStanzaChannel()->sendPresence(response);
 
	}
 
}
 

	
 
void UserManager::handleSubscription(Swift::Presence::ref presence) {
 
	
 
	// answer to subscibe for transport itself
 
	if (presence->getType() == Swift::Presence::Subscribe && presence->getTo().getNode().empty()) {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setFrom(presence->getTo().toBare());
 
		response->setTo(presence->getFrom().toBare());
 
		response->setType(Swift::Presence::Subscribed);
 
		m_component->getStanzaChannel()->sendPresence(response);
 

	
 
// 		response = Swift::Presence::create();
 
// 		response->setFrom(presence->getTo());
 
// 		response->setTo(presence->getFrom());
 
// 		response->setType(Swift::Presence::Subscribe);
 
// 		m_component->getStanzaChannel()->sendPresence(response);
 
		return;
 
	}
 
	else if (presence->getType() == Swift::Presence::Unsubscribed && presence->getTo().getNode().empty()) {
 
		std::string userkey = presence->getFrom().toBare().toString();
 
		UserInfo res;
 
		bool registered = m_storageBackend ? m_storageBackend->getUser(userkey, res) : false;
 
		if (registered) {
 
			Swift::Presence::ref response = Swift::Presence::create();
 
			response->setFrom(presence->getTo().toBare());
 
			response->setTo(presence->getFrom().toBare());
 
			response->setType(Swift::Presence::Subscribe);
 
			m_component->getStanzaChannel()->sendPresence(response);
 
		}
 
		return;
 
	}
 

	
 
	// Don't let RosterManager to handle presences for us
 
	if (presence->getTo().getNode().empty()) {
 
		return;
 
	}
 

	
 
	User *user = getUser(presence->getFrom().toBare().toString());
 

	
 
 	if (user) {
 
 		user->handleSubscription(presence);
 
 	}
 
 	else if (presence->getType() == Swift::Presence::Unsubscribe) {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setFrom(presence->getTo());
 
		response->setTo(presence->getFrom());
 
		response->setType(Swift::Presence::Unsubscribed);
 
		m_component->getStanzaChannel()->sendPresence(response);
 
	}
 
// 	else {
 
// // 		Log(presence->getFrom().toString().getUTF8String(), "Subscribe presence received, but this user is not logged in");
 
// 	}
 
}
 

	
 
void UserManager::connectUser(const Swift::JID &user) {
 
	// Called by UserRegistry in server mode when user connects the server and wants
 
	// to connect legacy network
 
	if (m_users.find(user.toBare().toString()) != m_users.end()) {
 
		if (!m_component->inServerMode()) {
 
			return;
 
		}
 

	
 
		User *u = m_users[user.toBare().toString()];
 
		if (u->isConnected()) {
 
			// User is already logged in, so his password is OK, but this new user has different password => bad password.
 
			// We can't call m_userRegistry->onPasswordInvalid() here, because this fuction is called from Swift::Parser
 
			// and onPasswordInvalid destroys whole session together with parser itself, which leads to crash.
 
			if (m_userRegistry->getUserPassword(user.toBare().toString()) != u->getUserInfo().password) {
 
				m_userRegistry->removeLater(user);
 
				return;
 
			}
 
			if (CONFIG_BOOL(m_component->getConfig(), "service.more_resources")) {
 
				m_userRegistry->onPasswordValid(user);
 
			}
 
			else {
 
				// Send message to currently logged in session
 
				boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
				msg->setBody("You have signed on from another location.");
 
				msg->setTo(user);
0 comments (0 inline, 0 general)