Changeset - e23f8e3c7f9d
[Not reviewed]
0 11 0
HanzZ - 14 years ago 2011-09-19 14:22:01
hanzz.k@gmail.com
Fixed password changing in gateway mode + working RIE
11 files changed with 87 insertions and 29 deletions:
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
@@ -22,48 +22,49 @@ set(event_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(event)
 

	
 
set(Swiften_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Swiften REQUIRED)
 

	
 
set(Boost_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Boost COMPONENTS date_time system filesystem regex thread signals REQUIRED)
 
message( STATUS "Found Boost: ${Boost_LIBRARIES}, ${Boost_INCLUDE_DIR}")
 

	
 
set(Protobuf_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(Protobuf REQUIRED)
 

	
 
set(IRCClientQt_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(IRCClientQt)
 

	
 
set(log4cxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
 
find_package(log4cxx)
 

	
 
find_package(Doxygen)
 

	
 
INCLUDE(FindQt4)
 
FIND_PACKAGE(Qt4 COMPONENTS QtCore)
 

	
 
# ADD_DEFINITIONS(${SWIFTEN_CFLAGS})
 
ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS)
 

	
 
message("  Supported features")
 
message("-----------------------")
 
if (SQLITE3_FOUND)
 
	ADD_DEFINITIONS(-DWITH_SQLITE)
 
	include_directories(${SQLITE3_INCLUDE_DIR})
 
	message("SQLite3           : yes")
 
else (SQLITE3_FOUND)
 
	set(SQLITE3_LIBRARIES "")
 
	message("SQLite3           : no")
 
endif (SQLITE3_FOUND)
 

	
 
if (MYSQL_FOUND)
 
	ADD_DEFINITIONS(-DWITH_MYSQL)
 
	include_directories(${MYSQL_INCLUDE_DIR})
 
	message("MySQL             : yes")
 
else (MYSQL_FOUND)
 
	set(MYSQL_LIBRARIES "")
 
	message("MySQL             : no (install mysql-devel)")
 
endif (MYSQL_FOUND)
 

	
 
if (PROTOBUF_FOUND)
 
	ADD_DEFINITIONS(-DWITH_PROTOBUF)
 
	include_directories(${PROTOBUF_INCLUDE_DIRS})
include/transport/transport.h
Show inline comments
 
@@ -136,58 +136,60 @@ namespace Transport {
 
			boost::signal<void (const Swift::ComponentError &error)> onConnectionError;
 

	
 
			/// This signal is emitted when transport successfully connects the server.
 
			boost::signal<void ()> onConnected;
 

	
 
			/// This signal is emitted when XML stanza is sent to server.
 

	
 
			/// \param xml xml stanza
 
			boost::signal<void (const std::string &xml)> onXMLOut;
 

	
 
			/// This signal is emitted when XML stanza is received from server.
 

	
 
			/// \param xml xml stanza
 
			boost::signal<void (const std::string &xml)> onXMLIn;
 

	
 
			Config *getConfig() { return m_config; }
 

	
 
			/// This signal is emitted when presence from XMPP user is received.
 

	
 
			/// It's emitted only for presences addressed to transport itself
 
			/// (for example to="j2j.domain.tld").
 
			/// \param presence presence data
 
			boost::signal<void (Swift::Presence::ref presence)> onUserPresenceReceived;
 

	
 
			boost::signal<void (const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info)> onUserDiscoInfoReceived;
 

	
 
// 			boost::signal<void (boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid)> onDiscoInfoResponse;
 

	
 
		private:
 
			void handleConnected();
 
			void handleConnectionError(const Swift::ComponentError &error);
 
			void handlePresence(Swift::Presence::ref presence);
 
			void handleDataRead(const Swift::SafeByteArray &data);
 
			void handleDataWritten(const Swift::SafeByteArray &data);
 

	
 
// 			void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
			void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
			void handleCapsChanged(const Swift::JID& jid);
 

	
 
			Swift::NetworkFactories *m_factories;
 
			Swift::Component *m_component;
 
			Swift::Server *m_server;
 
			Swift::Timer::ref m_reconnectTimer;
 
			Swift::EntityCapsManager *m_entityCapsManager;
 
			Swift::CapsManager *m_capsManager;
 
			Swift::CapsMemoryStorage *m_capsMemoryStorage;
 
			Swift::PresenceOracle *m_presenceOracle;
 
			Swift::StanzaChannel *m_stanzaChannel;
 
			Swift::IQRouter *m_iqRouter;
 
			Transport::UserRegistry *m_userRegistry;
 
			StorageBackend *m_storageBackend;
 
 			DiscoInfoResponder *m_discoInfoResponder;
 
			DiscoItemsResponder *m_discoItemsResponder;
 
			int m_reconnectCount;
 
			Config* m_config;
 
			std::string m_protocol;
 
			Swift::JID m_jid;
 
			Factory *m_factory;
 
			Swift::EventLoop *m_loop;
 

	
 
		friend class User;
include/transport/user.h
Show inline comments
 
@@ -54,48 +54,50 @@ class User {
 
		/// Returns full JID which supports particular feature or invalid JID.
 
		/// \param feature disco#info feature.
 
		/// \return full JID which supports particular feature or invalid JID.
 
		Swift::JID getJIDWithFeature(const std::string &feature);
 

	
 
		/// Returns UserInfo struct with informations needed to connect the legacy network.
 
		/// \return UserInfo struct
 
		UserInfo &getUserInfo() { return m_userInfo; }
 

	
 
		RosterManager *getRosterManager() { return m_rosterManager; }
 

	
 
		ConversationManager *getConversationManager() { return m_conversationManager; }
 

	
 
		Component *getComponent() { return m_component; }
 

	
 
		void setData(void *data) { m_data = data; }
 
		void *getData() { return m_data; }
 

	
 
		/// Handles presence from XMPP JID associated with this user.
 
		/// \param presence Swift::Presence.
 
		void handlePresence(Swift::Presence::ref presence);
 

	
 
		void handleSubscription(Swift::Presence::ref presence);
 

	
 
		void handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info);
 

	
 
		time_t &getLastActivity() {
 
			return m_lastActivity;
 
		}
 

	
 
		void updateLastActivity() {
 
			m_lastActivity = time(NULL);
 
		}
 

	
 
		/// Returns language.
 
		/// \return language
 
		const char *getLang() { return "en"; }
 

	
 
		void handleDisconnected(const std::string &error);
 

	
 
		bool isReadyToConnect() {
 
			return m_readyForConnect;
 
		}
 

	
 
		void setConnected(bool connected);
 

	
 
		void sendCurrentPresence();
 

	
 
		void setIgnoreDisconnect(bool ignoreDisconnect);
 

	
 
@@ -106,27 +108,28 @@ class User {
 
		boost::signal<void ()> onReadyToConnect;
 
		boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
 
		boost::signal<void (const std::string &room, const std::string &nickname, const std::string &password)> onRoomJoined;
 
		boost::signal<void (const std::string &room)> onRoomLeft;
 
		boost::signal<void ()> onDisconnected;
 

	
 
	private:
 
		void onConnectingTimeout();
 

	
 
		Swift::JID m_jid;
 
		Component *m_component;
 
		RosterManager *m_rosterManager;
 
		UserManager *m_userManager;
 
		ConversationManager *m_conversationManager;
 
		Swift::EntityCapsManager *m_entityCapsManager;
 
		Swift::PresenceOracle *m_presenceOracle;
 
		UserInfo m_userInfo;
 
		void *m_data;
 
		bool m_connected;
 
		bool m_readyForConnect;
 
		bool m_ignoreDisconnect;
 
		Swift::Timer::ref m_reconnectTimer;
 
		boost::shared_ptr<Swift::Connection> connection;
 
		time_t m_lastActivity;
 
		std::map<Swift::JID, Swift::DiscoInfo::ref> m_legacyCaps;
 
};
 

	
 
}
include/transport/usermanager.h
Show inline comments
 
@@ -96,39 +96,39 @@ class UserManager {
 
			return m_users.find(barejid) != m_users.end();
 
		}
 

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

	
 
		/// 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);
 

	
 
	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 handleSubscription(Swift::Presence::ref presence);
 
		void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
 
// 		void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
 
		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;
 
		friend class RosterResponder;
 
};
 

	
 
}
src/mysqlbackend.cpp
Show inline comments
 
@@ -275,49 +275,49 @@ MySQLBackend::~MySQLBackend(){
 
	delete m_setUserSetting;
 
	delete m_updateUserSetting;
 
	delete m_updateBuddySetting;
 
	delete m_setUserOnline;
 
	mysql_close(&m_conn);
 
}
 

	
 
bool MySQLBackend::connect() {
 
	LOG4CXX_INFO(logger, "Connecting MySQL server " << CONFIG_STRING(m_config, "database.server") << ", user " <<
 
		CONFIG_STRING(m_config, "database.user") << ", database " << CONFIG_STRING(m_config, "database.database") <<
 
		", port " << CONFIG_INT(m_config, "database.port")
 
	);
 
	
 
	if (!mysql_real_connect(&m_conn, CONFIG_STRING(m_config, "database.server").c_str(),
 
					   CONFIG_STRING(m_config, "database.user").c_str(),
 
					   CONFIG_STRING(m_config, "database.password").c_str(),
 
					   CONFIG_STRING(m_config, "database.database").c_str(),
 
					   CONFIG_INT(m_config, "database.port"), NULL, 0)) {
 
		LOG4CXX_ERROR(logger, "Can't connect database: " << mysql_error(&m_conn));
 
		return false;
 
	}
 

	
 
	createDatabase();
 

	
 
	m_setUser = new Statement(&m_conn, "sssssb", "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, NOW(), ?)");
 
	m_setUser = new Statement(&m_conn, "sssssbs", "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, NOW(), ?) ON DUPLICATE KEY UPDATE password=?");
 
	m_getUser = new Statement(&m_conn, "s|isssssb", "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?");
 

	
 
	m_removeUser = new Statement(&m_conn, "i", "DELETE FROM " + m_prefix + "users WHERE id=?");
 
	m_removeUserBuddies = new Statement(&m_conn, "i", "DELETE FROM " + m_prefix + "buddies WHERE user_id=?");
 
	m_removeUserSettings = new Statement(&m_conn, "i", "DELETE FROM " + m_prefix + "users_settings WHERE user_id=?");
 
	m_removeUserBuddiesSettings = new Statement(&m_conn, "i", "DELETE FROM " + m_prefix + "buddies_settings WHERE user_id=?");
 

	
 
	m_addBuddy = new Statement(&m_conn, "issssi", "INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)");
 
	m_updateBuddy = new Statement(&m_conn, "ssisis", "UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?");
 
	m_getBuddies = new Statement(&m_conn, "i|issssi", "SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC");
 
	m_getBuddiesSettings = new Statement(&m_conn, "i|iiss", "SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC");
 
	m_updateBuddySetting = new Statement(&m_conn, "iisiss", "INSERT INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE value=?");
 
	
 
	m_getUserSetting = new Statement(&m_conn, "is|is", "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?");
 
	m_setUserSetting = new Statement(&m_conn, "isis", "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)");
 
	m_updateUserSetting = new Statement(&m_conn, "sis", "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?");
 

	
 
	m_setUserOnline = new Statement(&m_conn, "bi", "UPDATE " + m_prefix + "users SET online=?, last_login=NOW()  WHERE id=?");
 

	
 
	return true;
 
}
 

	
 
bool MySQLBackend::createDatabase() {
 
	int not_exist = exec("CREATE TABLE IF NOT EXISTS `" + m_prefix + "buddies` ("
 
@@ -365,49 +365,49 @@ bool MySQLBackend::createDatabase() {
 
				"PRIMARY KEY (`user_id`,`var`),"
 
				"KEY `user_id` (`user_id`)"
 
			") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;");
 

	
 
		exec("CREATE TABLE IF NOT EXISTS `" + m_prefix + "db_version` ("
 
				"`ver` int(10) unsigned NOT NULL default '1',"
 
				"UNIQUE KEY `ver` (`ver`)"
 
			") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;");
 

	
 
		exec("INSERT INTO db_version (ver) VALUES ('2');");
 
	}
 

	
 
	return true;
 
}
 

	
 
bool MySQLBackend::exec(const std::string &query) {
 
	if (mysql_query(&m_conn, query.c_str())) {
 
		LOG4CXX_ERROR(logger, query << " " << mysql_error(&m_conn));
 
		return false;
 
	}
 
	return true;
 
}
 

	
 
void MySQLBackend::setUser(const UserInfo &user) {
 
	*m_setUser << user.jid << user.uin << user.password << user.language << user.encoding << user.vip;
 
	*m_setUser << user.jid << user.uin << user.password << user.language << user.encoding << user.vip << user.password;
 
	m_setUser->execute();
 
}
 

	
 
bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) {
 
	*m_getUser << barejid;
 
	if (!m_getUser->execute())
 
		return false;
 

	
 
	int ret = false;
 
	while (m_getUser->fetch() == 0) {
 
		ret = true;
 
		*m_getUser >> user.id >> user.jid >> user.uin >> user.password >> user.encoding >> user.language >> user.vip;
 
	}
 

	
 
	return ret;
 
}
 

	
 
void MySQLBackend::setUserOnline(long id, bool online) {
 
	*m_setUserOnline << online << id;
 
	m_setUserOnline->execute();
 
}
 

	
 
long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
 
// 	"INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)"
src/rostermanager.cpp
Show inline comments
 
@@ -177,49 +177,49 @@ void RosterManager::unsetBuddy(Buddy *buddy) {
 

	
 
void RosterManager::storeBuddy(Buddy *buddy) {
 
	if (m_rosterStorage) {
 
		m_rosterStorage->storeBuddy(buddy);
 
	}
 
}
 

	
 
void RosterManager::handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error, Swift::SetRosterRequest::ref request, const std::string &key) {
 
	if (m_buddies[key] != NULL) {
 
		m_buddies[key]->handleBuddyChanged();
 
	}
 

	
 
	m_requests.remove(request);
 
	request->onResponse.disconnect_all_slots();
 
}
 

	
 
void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error) {
 
	if (error) {
 
		m_supportRemoteRoster = false;
 
		LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server does not support remote roster protoXEP");
 
		return;
 
	}
 

	
 
	LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server supports remote roster protoXEP");
 
	m_supportRemoteRoster = true;
 
// 	m_supportRemoteRoster = true;
 
	return;
 

	
 
	BOOST_FOREACH(const Swift::RosterItemPayload &item, payload->getItems()) {
 
		std::string legacyName = Buddy::JIDToLegacyName(item.getJID());
 
		if (m_buddies.find(legacyName) != m_buddies.end()) {
 
			continue;
 
		}
 
		std::cout << "LEGACYNAME " << legacyName << "\n";
 

	
 
		BuddyInfo buddyInfo;
 
		buddyInfo.id = -1;
 
		buddyInfo.alias = item.getName();
 
		buddyInfo.legacyName = legacyName;
 
		buddyInfo.subscription = "both";
 
		buddyInfo.flags = Buddy::buddFlagsFromJID(item.getJID());
 

	
 
		Buddy *buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
 
		setBuddy(buddy);
 
	}
 
}
 

	
 
Buddy *RosterManager::getBuddy(const std::string &name) {
 
	return m_buddies[name];
 
}
src/sqlite3backend.cpp
Show inline comments
 
@@ -91,49 +91,49 @@ SQLite3Backend::~SQLite3Backend(){
 
		FINALIZE_STMT(m_removeUserBuddiesSettings);
 
		FINALIZE_STMT(m_addBuddy);
 
		FINALIZE_STMT(m_updateBuddy);
 
		FINALIZE_STMT(m_getBuddies);
 
		FINALIZE_STMT(m_getBuddiesSettings);
 
		FINALIZE_STMT(m_getUserSetting);
 
		FINALIZE_STMT(m_setUserSetting);
 
		FINALIZE_STMT(m_updateUserSetting);
 
		FINALIZE_STMT(m_updateBuddySetting);
 
		FINALIZE_STMT(m_setUserOnline);
 
		sqlite3_close(m_db);
 
	}
 
}
 

	
 
bool SQLite3Backend::connect() {
 
	LOG4CXX_INFO(logger, "Opening database " << CONFIG_STRING(m_config, "database.database"));
 
	if (sqlite3_open(CONFIG_STRING(m_config, "database.database").c_str(), &m_db)) {
 
		sqlite3_close(m_db);
 
		return false;
 
	}
 

	
 
	if (createDatabase() == false)
 
		return false;
 

	
 
	PREP_STMT(m_setUser, "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, DATETIME('NOW'), ?)");
 
	PREP_STMT(m_setUser, "INSERT OR REPLACE INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, DATETIME('NOW'), ?)");
 
	PREP_STMT(m_getUser, "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?");
 

	
 
	PREP_STMT(m_removeUser, "DELETE FROM " + m_prefix + "users WHERE id=?");
 
	PREP_STMT(m_removeUserBuddies, "DELETE FROM " + m_prefix + "buddies WHERE user_id=?");
 
	PREP_STMT(m_removeUserSettings, "DELETE FROM " + m_prefix + "users_settings WHERE user_id=?");
 
	PREP_STMT(m_removeUserBuddiesSettings, "DELETE FROM " + m_prefix + "buddies_settings WHERE user_id=?");
 

	
 
	PREP_STMT(m_addBuddy, "INSERT INTO " + m_prefix + "buddies (user_id, uin, subscription, groups, nickname, flags) VALUES (?, ?, ?, ?, ?, ?)");
 
	PREP_STMT(m_updateBuddy, "UPDATE " + m_prefix + "buddies SET groups=?, nickname=?, flags=?, subscription=? WHERE user_id=? AND uin=?");
 
	PREP_STMT(m_getBuddies, "SELECT id, uin, subscription, nickname, groups, flags FROM " + m_prefix + "buddies WHERE user_id=? ORDER BY id ASC");
 
	PREP_STMT(m_getBuddiesSettings, "SELECT buddy_id, type, var, value FROM " + m_prefix + "buddies_settings WHERE user_id=? ORDER BY buddy_id ASC");
 
	PREP_STMT(m_updateBuddySetting, "INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)");
 
	
 
	PREP_STMT(m_getUserSetting, "SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?");
 
	PREP_STMT(m_setUserSetting, "INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)");
 
	PREP_STMT(m_updateUserSetting, "UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?");
 

	
 
	PREP_STMT(m_setUserOnline, "UPDATE " + m_prefix + "users SET online=?, last_login=DATETIME('NOW') WHERE id=?");
 

	
 
	return true;
 
}
 

	
 
bool SQLite3Backend::createDatabase() {
 
	int not_exist = exec("CREATE TABLE " + m_prefix + "buddies ("
src/transport.cpp
Show inline comments
 
@@ -224,39 +224,47 @@ void Component::handleDataRead(const Swift::SafeByteArray &data) {
 
}
 

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

	
 
	// check if we have this client's capabilities and ask for them
 
// 	bool haveFeatures = false;
 
	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();
 
		}
 
// 		else {
 
// 			GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
 
// 			discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
 
// 			discoInfoRequest->send();
 
// 		}
 
#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) {
 
	m_entityCapsManager->getCaps(jid) != DiscoInfo::ref();
 
	onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
 
}
 

	
 
}
src/user.cpp
Show inline comments
 
@@ -67,58 +67,68 @@ User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, User
 
User::~User(){
 
	LOG4CXX_INFO(logger, m_jid.toString() << ": Destroying");
 
	if (m_component->inServerMode()) {
 
		dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr<Swift::Element>());
 
	}
 

	
 
	m_reconnectTimer->stop();
 
	delete m_rosterManager;
 
	delete m_conversationManager;
 
}
 

	
 
const Swift::JID &User::getJID() {
 
	return m_jid;
 
}
 

	
 
Swift::JID User::getJIDWithFeature(const std::string &feature) {
 
	Swift::JID jid;
 
	std::vector<Swift::Presence::ref> presences = m_presenceOracle->getAllPresence(m_jid);
 

	
 
	foreach(Swift::Presence::ref presence, presences) {
 
		if (presence->getType() == Swift::Presence::Unavailable)
 
			continue;
 

	
 
		Swift::DiscoInfo::ref discoInfo = m_entityCapsManager->getCaps(presence->getFrom());
 
		if (!discoInfo)
 
		if (!discoInfo) {
 
#ifdef SUPPORT_LEGACY_CAPS
 
			if (m_legacyCaps.find(presence->getFrom()) != m_legacyCaps.end()) {
 
				discoInfo = m_legacyCaps[presence->getFrom()];
 
			}
 
			else {
 
				continue;
 
			}
 
#else
 
			continue;
 
#endif
 
		}
 

	
 
		if (discoInfo->hasFeature(feature)) {
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Found JID with " << feature << " feature: " << presence->getFrom().toString());
 
			return presence->getFrom();
 
		}
 
	}
 

	
 
	LOG4CXX_INFO(logger, m_jid.toString() << ": No JID with " << feature << " feature");
 
	LOG4CXX_INFO(logger, m_jid.toString() << ": No JID with " << feature << " feature " << m_legacyCaps.size());
 
	return jid;
 
}
 

	
 
void User::sendCurrentPresence() {
 
	if (m_component->inServerMode()) {
 
		return;
 
	}
 

	
 
	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(m_jid);
 
			response->setFrom(m_component->getJID());
 
			m_component->getStanzaChannel()->sendPresence(response);
 
		}
 
		else {
 
			Swift::Presence::ref response = Swift::Presence::create();
 
			response->setTo(m_jid.toBare());
 
			response->setFrom(m_component->getJID());
 
			response->setType(Swift::Presence::Unavailable);
 
			m_component->getStanzaChannel()->sendPresence(response);
 
		}
 
	}
 
@@ -168,76 +178,100 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
			}
 
		}
 
	}
 
	bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
 
	if (isMUC) {
 
		if (presence->getType() == Swift::Presence::Unavailable) {
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << presence->getTo().getNode());
 
			onRoomLeft(presence->getTo().getNode());
 
		}
 
		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();
 
			}
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << presence->getTo().getNode() << " as " << presence->getTo().getResource());
 
			onRoomJoined(presence->getTo().getNode(), presence->getTo().getResource(), "");
 
		}
 
		return;
 
	}
 

	
 
	sendCurrentPresence();
 

	
 

	
 
	// Change legacy network presence
 
	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);
 
	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 User::handleSubscription(Swift::Presence::ref presence) {
 
	m_rosterManager->handleSubscription(presence);
 
}
 

	
 
void User::handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info) {
 
	LOG4CXX_INFO(logger, jid.toString() << ": got disco#info");
 
#ifdef SUPPORT_LEGACY_CAPS
 
	Swift::DiscoInfo::ref discoInfo = m_entityCapsManager->getCaps(jid);
 
	// This is old legacy cap which is not stored in entityCapsManager,
 
	// we have to store it in our user class.
 
	if (!discoInfo) {
 
		LOG4CXX_INFO(logger, jid.toString() << ": LEGACY");
 
		m_legacyCaps[jid] = info;
 
	}
 
#endif
 

	
 
	onConnectingTimeout();
 
}
 

	
 
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 User::setIgnoreDisconnect(bool ignoreDisconnect) {
 
	m_ignoreDisconnect = ignoreDisconnect;
 
	LOG4CXX_INFO(logger, m_jid.toString() << ": Setting ignoreDisconnect=" << m_ignoreDisconnect);
 
}
 

	
 
void User::handleDisconnected(const std::string &error) {
 
	if (m_ignoreDisconnect) {
 
		LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnecting from legacy network ignored (probably moving between backends)");
 
		return;
 
	}
 

	
 
	if (error.empty()) {
 
		LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnected from legacy network");
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, m_jid.toString() << ": Disconnected from legacy network with error " << error);
 
	}
 
	onDisconnected();
 

	
 
	boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
	msg->setBody(error);
 
	msg->setTo(m_jid.toBare());
src/usermanager.cpp
Show inline comments
 
@@ -32,54 +32,54 @@
 
#include "Swiften/Elements/StreamError.h"
 
#include "malloc.h"
 
// #include "valgrind/memcheck.h"
 

	
 
using namespace log4cxx;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("UserManager");
 

	
 
UserManager::UserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) {
 
	m_cachedUser = NULL;
 
	m_onlineBuddies = 0;
 
	m_component = component;
 
	m_storageBackend = storageBackend;
 
	m_storageResponder = NULL;
 
	m_userRegistry = userRegistry;
 

	
 
	if (m_storageBackend) {
 
		m_storageResponder = new StorageResponder(component->getIQRouter(), m_storageBackend, this);
 
		m_storageResponder->start();
 
	}
 

	
 
	component->onUserPresenceReceived.connect(bind(&UserManager::handlePresence, this, _1));
 
	component->onUserDiscoInfoReceived.connect(bind(&UserManager::handleDiscoInfo, this, _1, _2));
 
	m_component->getStanzaChannel()->onMessageReceived.connect(bind(&UserManager::handleMessageReceived, this, _1));
 
	m_component->getStanzaChannel()->onPresenceReceived.connect(bind(&UserManager::handleGeneralPresenceReceived, this, _1));
 

	
 
	m_userRegistry->onConnectUser.connect(bind(&UserManager::connectUser, this, _1));
 
	m_userRegistry->onDisconnectUser.connect(bind(&UserManager::disconnectUser, this, _1));
 
// 	component->onDiscoInfoResponse.connect(bind(&UserManager::handleDiscoInfoResponse, this, _1, _2, _3));
 

	
 
	m_removeTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1);
 
}
 

	
 
UserManager::~UserManager(){
 
	if (m_storageResponder) {
 
		m_storageResponder->stop();
 
		delete m_storageResponder;
 
	}
 
}
 

	
 
void UserManager::addUser(User *user) {
 
	m_users[user->getJID().toBare().toString()] = user;
 
	if (m_storageBackend) {
 
		m_storageBackend->setUserOnline(user->getUserInfo().id, true);
 
	}
 
	onUserCreated(user);
 
}
 

	
 
User *UserManager::getUser(const std::string &barejid){
 
	if (m_cachedUser && barejid == m_cachedUser->getJID().toBare().toString()) {
 
		return m_cachedUser;
 
	}
 

	
 
@@ -101,48 +101,57 @@ void UserManager::removeUser(User *user) {
 
	}
 

	
 
	if (m_storageBackend) {
 
		m_storageBackend->setUserOnline(user->getUserInfo().id, false);
 
	}
 

	
 
	onUserDestroyed(user);
 
	delete user;
 
#ifndef WIN32
 
	malloc_trim(0);
 
#endif
 
// 	VALGRIND_DO_LEAK_CHECK;
 
}
 

	
 
void UserManager::removeAllUsers() {
 
	while(m_users.begin() != m_users.end()) {
 
		removeUser((*m_users.begin()).second);
 
	}
 
}
 

	
 
int UserManager::getUserCount() {
 
	return m_users.size();
 
}
 

	
 
void UserManager::handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info) {
 
	User *user = getUser(jid.toBare().toString());
 
	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 (CONFIG_STRING(m_component->getConfig(), "service.admin_username") == presence->getFrom().getNode()) {
 
			return;
 
		}
 

	
 
		// No user and unavailable presence -> answer with unavailable
 
		if (presence->getType() == Swift::Presence::Unavailable) {
 
			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);
 

	
 
			// Set user offline in database
 
			if (m_storageBackend) {
 
				UserInfo res;
 
				bool registered = m_storageBackend->getUser(userkey, res);
src/userregistration.cpp
Show inline comments
 
@@ -367,36 +367,37 @@ bool UserRegistration::handleSetRequest(const Swift::JID& from, const Swift::JID
 
// 		sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
 
// 		return true;
 
// 	}
 

	
 
//TODO: Part of spectrum1 registration stuff, this should be potentially rewritten for S2 too
 
// #if GLIB_CHECK_VERSION(2,14,0)
 
// 	if (!CONFIG_STRING(m_config, "registration.reg_allowed_usernames").empty() &&
 
// 		!g_regex_match_simple(CONFIG_STRING(m_config, "registration.reg_allowed_usernames"), newUsername.c_str(),(GRegexCompileFlags) (G_REGEX_CASELESS | G_REGEX_EXTENDED), (GRegexMatchFlags) 0)) {
 
// 		Log("UserRegistration", "This is not valid username: "<< newUsername);
 
// 		sendError(from, id, ErrorPayload::NotAcceptable, ErrorPayload::Modify);
 
// 		return true;
 
// 	}
 
// #endif
 
	if (!registered) {
 
		res.jid = barejid;
 
		res.uin = username;
 
		res.password = *payload->getPassword();
 
		res.language = language;
 
		res.encoding = encoding;
 
		res.vip = 0;
 
		registerUser(res);
 
	}
 
	else {
 
		res.jid = barejid;
 
		res.uin = username;
 
		res.password = *payload->getPassword();
 
		res.language = language;
 
		res.encoding = encoding;
 
		m_storageBackend->setUser(res);
 
		onUserUpdated(res);
 
	}
 

	
 
	sendResponse(from, id, InBandRegistrationPayload::ref());
 
	return true;
 
}
 

	
 
}
0 comments (0 inline, 0 general)