Files @ 50bcfbf84cb1
Branch filter:

Location: libtransport.git/src/transport.cpp - annotation

HanzZ
Don't store passwords to DB in server mode. Fixed disconnecting from legacy network
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
c5edfd19b1aa
c8006a0ebab6
c5edfd19b1aa
a6253712ccbc
07859ef3936a
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
c8006a0ebab6
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
e678a46286f4
e678a46286f4
c8006a0ebab6
e678a46286f4
bf4183c181eb
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
c5edfd19b1aa
e678a46286f4
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
e678a46286f4
e678a46286f4
79cc6dc63de8
79cc6dc63de8
5f017bd15dc7
e678a46286f4
79cc6dc63de8
c5edfd19b1aa
e678a46286f4
79cc6dc63de8
c5edfd19b1aa
a6253712ccbc
79cc6dc63de8
a6253712ccbc
07859ef3936a
07859ef3936a
07859ef3936a
07859ef3936a
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
c5edfd19b1aa
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
07859ef3936a
07859ef3936a
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
e678a46286f4
e678a46286f4
e678a46286f4
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
79cc6dc63de8
2ae880ff94b5
2ae880ff94b5
2ae880ff94b5
2ae880ff94b5
2ae880ff94b5
2ae880ff94b5
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
79cc6dc63de8
79cc6dc63de8
e678a46286f4
bf4183c181eb
e678a46286f4
e678a46286f4
e678a46286f4
c5edfd19b1aa
99aff9256622
e678a46286f4
e678a46286f4
e678a46286f4
c5edfd19b1aa
99aff9256622
e678a46286f4
c5edfd19b1aa
e678a46286f4
e678a46286f4
e678a46286f4
e678a46286f4
e5fcbf00b799
e5fcbf00b799
99aff9256622
99aff9256622
e5fcbf00b799
e5fcbf00b799
99aff9256622
99aff9256622
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
e5fcbf00b799
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
5f017bd15dc7
79cc6dc63de8
5f017bd15dc7
5f017bd15dc7
5f017bd15dc7
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
e5fcbf00b799
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
c5edfd19b1aa
5f017bd15dc7
5f017bd15dc7
5f017bd15dc7
c5edfd19b1aa
c5edfd19b1aa
e678a46286f4
/**
 * libtransport -- C++ library for easy XMPP Transports development
 *
 * Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 */

#include "transport/transport.h"
#include <boost/bind.hpp>
#include "transport/storagebackend.h"
#include "transport/factory.h"
#include "discoinforesponder.h"
#include "discoitemsresponder.h"
#include "rosterresponder.h"

using namespace Swift;
using namespace boost;

namespace Transport {


class MyUserRegistry : public Swift::UserRegistry {
	public:
		MyUserRegistry() {}
		~MyUserRegistry() {}
		bool isValidUserPassword(const JID& user, const std::string& password) const {
			users[user.toBare().toString()] = password;
			return true;
		}
		mutable std::map<std::string, std::string> users;
};

Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory) {
	m_component = NULL;
	m_userRegistry = NULL;
	m_server = NULL;
	m_reconnectCount = 0;
	m_config = config;
	m_factory = factory;

	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));

	m_factories = new BoostNetworkFactories(loop);

	m_reconnectTimer = m_factories->getTimerFactory()->createTimer(1000);
	m_reconnectTimer->onTick.connect(bind(&Component::connect, this)); 

	if (CONFIG_BOOL(m_config, "service.server_mode")) {
		m_userRegistry = new MyUserRegistry();
		m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_INT(m_config, "service.port"));
		m_server->start();
		m_stanzaChannel = m_server->getStanzaChannel();
		m_iqRouter = m_server->getIQRouter();
	}
	else {
		m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
		m_component->setSoftwareVersion("", "");
		m_component->onConnected.connect(bind(&Component::handleConnected, this));
		m_component->onError.connect(bind(&Component::handleConnectionError, this, _1));
		m_component->onDataRead.connect(bind(&Component::handleDataRead, this, _1));
		m_component->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1));
		m_component->onPresenceReceived.connect(bind(&Component::handlePresenceReceived, this, _1));
// 		m_component->onMessageReceived.connect(bind(&Component::handleMessageReceived, this, _1));
		m_stanzaChannel = m_component->getStanzaChannel();
		m_iqRouter = m_component->getIQRouter();
	}

	m_capsMemoryStorage = new CapsMemoryStorage();
	m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
	m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
 	m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
	
	m_presenceOracle = new PresenceOracle(m_stanzaChannel);
	m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));

	m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter);
	m_discoInfoResponder->start();

	m_discoItemsResponder = new DiscoItemsResponder(m_iqRouter);
	m_discoItemsResponder->start();

	m_rosterResponder = new RosterResponder(m_iqRouter);
	m_rosterResponder->start();
	
// 
// 	m_registerHandler = new SpectrumRegisterHandler(m_component);
// 	m_registerHandler->start();
}

Component::~Component() {
	delete m_presenceOracle;
	delete m_entityCapsManager;
	delete m_capsManager;
	delete m_capsMemoryStorage;
	delete m_rosterResponder;
	delete m_discoInfoResponder;
	if (m_component)
		delete m_component;
	if (m_server)
		delete m_server;
	if (m_userRegistry)
		delete m_userRegistry;
	delete m_factories;
}

const std::string &Component::getUserRegistryPassword(const std::string &barejid) {
	MyUserRegistry *registry = dynamic_cast<MyUserRegistry *>(m_userRegistry);
	return registry->users[barejid];
}

Swift::StanzaChannel *Component::getStanzaChannel() {
	return m_stanzaChannel;
}

Swift::PresenceOracle *Component::getPresenceOracle() {
	return m_presenceOracle;
}

void Component::setTransportFeatures(std::list<std::string> &features) {
	m_discoInfoResponder->setTransportFeatures(features);
}

void Component::setBuddyFeatures(std::list<std::string> &features) {
	// TODO: handle caps change
	m_discoInfoResponder->setBuddyFeatures(features);
}

void Component::connect() {
	if (!m_component)
		return;
	m_reconnectCount++;
	m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
	m_reconnectTimer->stop();
}

void Component::handleConnected() {
	onConnected();
	m_reconnectCount = 0;
}

void Component::handleConnectionError(const ComponentError &error) {
	onConnectionError(error);
// 	if (m_reconnectCount == 2)
// 		Component::instance()->userManager()->removeAllUsers();

	m_reconnectTimer->start();
}

void Component::handleDataRead(const std::string &data) {
	onXMLIn(data);
}

void Component::handleDataWritten(const std::string &data) {
	onXMLOut(data);
}

void Component::handlePresenceReceived(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;
		default:
			break;
	};
}

void Component::handlePresence(Swift::Presence::ref presence) {
	bool isMUC = presence->getPayload<MUCPayload>() != NULL;

	// filter out login/logout presence spam
	if (!presence->getTo().getNode().empty() && isMUC == false)
		return;

	// filter out bad presences
	if (!presence->getFrom().isValid()) {
		Swift::Presence::ref response = Swift::Presence::create();
		response->setTo(presence->getFrom());
		response->setFrom(presence->getTo());
		response->setType(Swift::Presence::Error);

		response->addPayload(boost::shared_ptr<Payload>(new ErrorPayload(ErrorPayload::JIDMalformed, ErrorPayload::Modify)));

		m_component->sendPresence(response);
		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();
			std::cout << "has capsInfo " << haveFeatures << "\n";
		}
// 		else {
// 			GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
// 			discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
// 			discoInfoRequest->send();
// 		}
	}

	onUserPresenceReceived(presence);
}

void Component::handleProbePresence(Swift::Presence::ref presence) {
	
}

void Component::handleSubscription(Swift::Presence::ref presence) {
	// answer to subscibe
	if (presence->getType() == Swift::Presence::Subscribe && presence->getTo().getNode().empty()) {
// 		Log(presence->getFrom().toString().getUTF8String(), "Subscribe presence received => sending subscribed");
		Swift::Presence::ref response = Swift::Presence::create();
		response->setFrom(presence->getTo());
		response->setTo(presence->getFrom());
		response->setType(Swift::Presence::Subscribed);
		m_component->sendPresence(response);
		return;
	}

	if (m_protocol == "irc") {
		return;
	}

// 	User *user;
// 	std::string barejid = presence->getTo().toBare().toString().getUTF8String();
// 	std::string userkey = presence->getFrom().toBare().toString().getUTF8String();
// 	if (Transport::instance()->protocol()->tempAccountsAllowed()) {
// 		std::string server = barejid.substr(barejid.find("%") + 1, barejid.length() - barejid.find("%"));
// 		userkey += server;
// 	}

// 	user = (User *) Transport::instance()->userManager()->getUserByJID(userkey);
// 	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->sendPresence(response);
// 	}
// 	else {
// // 		Log(presence->getFrom().toString().getUTF8String(), "Subscribe presence received, but this user is not logged in");
// 	}
}

void Component::handleCapsChanged(const Swift::JID& jid) {
	bool haveFeatures = m_entityCapsManager->getCaps(jid) != DiscoInfo::ref();
	std::cout << "has capsInfo " << haveFeatures << "\n";
}

}