Changeset - 1e48fe771986
[Not reviewed]
include/Swiften/Network/DummyNetworkFactories.cpp
Show inline comments
 
/*
 
 * Copyright (c) 2010 Remko Tronçon
 
 * Licensed under the GNU General Public License v3.
 
 * See Documentation/Licenses/GPLv3.txt for more information.
 
 */
 

	
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyTimerFactory.h>
 
#include <Swiften/Network/DummyConnectionFactory.h>
 
#include <Swiften/Network/PlatformDomainNameResolver.h>
 
#include <Swiften/Network/DummyConnectionServerFactory.h>
 
#if HAVE_SWIFTEN_3
 
#include <Swiften/Crypto/CryptoProvider.h>
 
#include <Swiften/Crypto/PlatformCryptoProvider.h>
 
#include <Swiften/Network/NetworkEnvironment.h>
 
#include <Swiften/Network/PlatformNetworkEnvironment.h>
 
#endif
 

	
 
namespace Swift {
 

	
 
DummyNetworkFactories::DummyNetworkFactories(EventLoop* eventLoop) {
 
	timerFactory = new DummyTimerFactory();
 
	connectionFactory = new DummyConnectionFactory(eventLoop);
 
#if HAVE_SWIFTEN_3
 
	idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());
 
	domainNameResolver = new PlatformDomainNameResolver(idnConverter.get(), eventLoop);
 
	cryptoProvider = PlatformCryptoProvider::create();
 
	networkEnvironment = new PlatformNetworkEnvironment();
 
#else
 
	domainNameResolver = new PlatformDomainNameResolver(eventLoop);
 
#endif
 
	connectionServerFactory = new DummyConnectionServerFactory(eventLoop);
 
	m_platformXMLParserFactory =  new PlatformXMLParserFactory();
 
	this->eventLoop = eventLoop;
 
}
 

	
 
DummyNetworkFactories::~DummyNetworkFactories() {
 
	delete connectionServerFactory;
 
	delete domainNameResolver;
 
	delete connectionFactory;
 
	delete timerFactory;
 
	delete m_platformXMLParserFactory;
 

	
 
#if HAVE_SWIFTEN_3
 
	delete cryptoProvider;
 
	delete networkEnvironment;
 
#endif
 
}
 

	
 
}
include/transport/HTTPRequest.h
Show inline comments
 

	
 
#pragma once
 

	
 
#include "curl/curl.h"
 
#include "transport/Logging.h"
 
#include "transport/ThreadPool.h"
 
#include <iostream>
 
#include <sstream>
 
#include <string.h>
 
#include "rapidjson/document.h"
 

	
 
#include <boost/signal.hpp>
 

	
 
namespace Transport {
 

	
 
class HTTPRequest : public Thread {
 
	public:
 
		typedef enum { Get } Type;
 
		typedef boost::function< void (HTTPRequest *, bool, rapidjson::Document &json, const std::string &data) > Callback;
 

	
 
		HTTPRequest(ThreadPool *tp, Type type, const std::string &url, Callback callback);
 
		HTTPRequest(Type type, const std::string &url);
 

	
 
		virtual ~HTTPRequest();
 

	
 
		void setProxy(std::string, std::string, std::string, std::string);
 
		bool execute();
 
		bool execute(rapidjson::Document &json);
 
		std::string getError() {return std::string(curl_errorbuffer);}
 
		const std::string &getRawData() {
 
			return m_data;
 
		}
 

	
 
		void run();
 
		void finalize();
 

	
 
		const std::string &getURL() {
 
			return m_url;
 
		}
 

	
 
		boost::signal<void ()> onRequestFinished;
 

	
 
		static void globalInit() {
 
			curl_global_init(CURL_GLOBAL_ALL);
 
		}
 

	
 
		static void globalCleanup() {
 
			curl_global_cleanup();
 
		}
 

	
 
	private:
 
		bool init();
 
		bool GET(std::string url, std::string &output);
 
		bool GET(std::string url, rapidjson::Document &json);
 

	
 

	
 
		CURL *curlhandle;
 
		char curl_errorbuffer[1024];
 
		std::string error;
 
		std::string callbackdata;
 
		ThreadPool *m_tp;
 
		std::string m_url;
 
		bool m_ok;
 
		rapidjson::Document m_json;
 
		std::string m_data;
 
		Callback m_callback;
 
		Type m_type;
 

	
 
		static int curlCallBack(char* data, size_t size, size_t nmemb, HTTPRequest *obj);
 

	
 
};
 

	
 
}
 

	
libtransport/NetworkPluginServer.cpp
Show inline comments
 
@@ -237,192 +237,193 @@ static void SigCatcher(int n) {
 
static void handleBuddyPayload(LocalBuddy *buddy, const pbnetwork::Buddy &payload) {
 
	// Set alias only if it's not empty. Backends are allowed to send empty alias if it has
 
	// not changed.
 
	if (!payload.alias().empty()) {
 
		buddy->setAlias(payload.alias());
 
	}
 

	
 
	// Change groups if it's not empty. The same as above...
 
	std::vector<std::string> groups;
 
	for (int i = 0; i < payload.group_size(); i++) {
 
		std::string group;
 
		utf8::replace_invalid(payload.group(i).begin(), payload.group(i).end(), std::back_inserter(group), '_');
 
		groups.push_back(group);
 
	}
 
	if (!groups.empty()) {
 
		buddy->setGroups(groups);
 
	}
 

	
 
	buddy->setStatus(Swift::StatusShow((Swift::StatusShow::Type) payload.status()), payload.statusmessage());
 
	buddy->setIconHash(payload.iconhash());
 
	buddy->setBlocked(payload.blocked());
 
}
 

	
 
NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager) {
 
	_server = this;
 
	m_ftManager = ftManager;
 
	m_userManager = userManager;
 
	m_config = config;
 
	m_component = component;
 
	m_isNextLongRun = false;
 
	m_adminInterface = NULL;
 
	m_startingBackend = false;
 
	m_lastLogin = 0;
 
	m_firstPong = true;
 
	m_xmppParser = new Swift::XMPPParser(this, &m_collection, component->getNetworkFactories()->getXMLParserFactory());
 
	m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
#if HAVE_SWIFTEN_3
 
	m_serializer = new Swift::XMPPSerializer(&m_collection2, Swift::ClientStreamType, false);
 
#else
 
	m_serializer = new Swift::XMPPSerializer(&m_collection2, Swift::ClientStreamType);
 
#endif
 
	m_component->m_factory = new NetworkFactory(this);
 
	m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1));
 
	m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1));
 

	
 
	m_component->onRawIQReceived.connect(boost::bind(&NetworkPluginServer::handleRawIQReceived, this, _1));
 

	
 
	m_pingTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(20000);
 
	m_pingTimer->onTick.connect(boost::bind(&NetworkPluginServer::pingTimeout, this));
 
	m_pingTimer->start();
 

	
 
	m_loginTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(config, "service.login_delay") * 1000);
 
	m_loginTimer->onTick.connect(boost::bind(&NetworkPluginServer::loginDelayFinished, this));
 
	m_loginTimer->start();
 

	
 
	if (CONFIG_INT(m_config, "service.memory_collector_time") != 0) {
 
		m_collectTimer = component->getNetworkFactories()->getTimerFactory()->createTimer(CONFIG_INT(m_config, "service.memory_collector_time"));
 
		m_collectTimer->onTick.connect(boost::bind(&NetworkPluginServer::collectBackend, this));
 
		m_collectTimer->start();
 
	}
 

	
 
	m_component->getFrontend()->onVCardRequired.connect(boost::bind(&NetworkPluginServer::handleVCardRequired, this, _1, _2, _3));
 
	m_component->getFrontend()->onVCardUpdated.connect(boost::bind(&NetworkPluginServer::handleVCardUpdated, this, _1, _2));
 

	
 
	m_component->getFrontend()->onBuddyAdded.connect(boost::bind(&NetworkPluginServer::handleBuddyAdded, this, _1, _2));
 
	m_component->getFrontend()->onBuddyRemoved.connect(boost::bind(&NetworkPluginServer::handleBuddyRemoved, this, _1));
 
	m_component->getFrontend()->onBuddyUpdated.connect(boost::bind(&NetworkPluginServer::handleBuddyUpdated, this, _1, _2));
 

	
 
// // 	m_blockResponder = new BlockResponder(component->getIQRouter(), userManager);
 
// // 	m_blockResponder->onBlockToggled.connect(boost::bind(&NetworkPluginServer::handleBlockToggled, this, _1));
 
// // 	m_blockResponder->start();
 

	
 
	m_server = component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(Swift::HostAddress(CONFIG_STRING(m_config, "service.backend_host")), boost::lexical_cast<int>(CONFIG_STRING(m_config, "service.backend_port")));
 
	m_server->onNewConnection.connect(boost::bind(&NetworkPluginServer::handleNewClientConnection, this, _1));
 
}
 

	
 
NetworkPluginServer::~NetworkPluginServer() {
 
#ifndef _WIN32
 
	signal(SIGCHLD, SIG_IGN);
 
#endif
 

	
 
	for (std::list<Backend *>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) {
 
		LOG4CXX_INFO(logger, "Stopping backend " << *it);
 
		std::string message;
 
		pbnetwork::WrapperMessage wrap;
 
		wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_EXIT);
 
		wrap.SerializeToString(&message);
 

	
 
		Backend *c = (Backend *) *it;
 
		send(c->connection, message);
 
	}
 

	
 
	m_pingTimer->stop();
 
	m_server->stop();
 
	m_server.reset();
 
	delete m_component->m_factory;
 
	delete m_xmppParser;
 
// 	delete m_vcardResponder;
 
// 	delete m_rosterResponder;
 
// 	delete m_blockResponder;
 
}
 

	
 
void NetworkPluginServer::start() {
 
	m_server->start();
 

	
 
	LOG4CXX_INFO(logger, "Listening on host " << CONFIG_STRING(m_config, "service.backend_host") << " port " << CONFIG_STRING(m_config, "service.backend_port"));
 

	
 
	while (true) {
 
		unsigned long pid = exec_(CONFIG_STRING(m_config, "service.backend"), CONFIG_STRING(m_config, "service.backend_host").c_str(), CONFIG_STRING(m_config, "service.backend_port").c_str(), "1", m_config->getCommandLineArgs().c_str());
 
		LOG4CXX_INFO(logger, "Tried to spawn first backend with pid " << pid);
 
		LOG4CXX_INFO(logger, "Backend should now connect to Spectrum2 instance. Spectrum2 won't accept any connection before backend connects");
 

	
 
#ifndef _WIN32
 
		// wait if the backend process will still be alive after 1 second
 
		sleep(1);
 
		pid_t result;
 
		int status;
 
		result = waitpid(-1, &status, WNOHANG);
 
		if (result != 0) {
 
			if (WIFEXITED(status)) {
 
				if (WEXITSTATUS(status) != 0) {
 
					if (status == 254) {
 
						LOG4CXX_ERROR(logger, "Backend can not be started, because it needs database to store data, but the database backend is not configured.");
 
					}
 
					else {
 
						LOG4CXX_ERROR(logger, "Backend can not be started, exit_code=" << WEXITSTATUS(status) << ", possible error: " << strerror(WEXITSTATUS(status)));
 
						if (WEXITSTATUS(status) == ENOENT) {
 
							LOG4CXX_ERROR(logger, "This usually means the path to backend executable defined in config file as '[service] backend=\"...\"' is wrong or the executable does not exists.");
 
						}
 
						
 
					}
 
					LOG4CXX_ERROR(logger, "Check backend log for more details");
 
					continue;
 
				}
 
			}
 
			else {
 
				LOG4CXX_ERROR(logger, "Backend can not be started");
 
				continue;
 
			}
 
		}
 

	
 
		m_pids.push_back(pid);
 

	
 
		signal(SIGCHLD, SigCatcher);
 
#endif
 
		// quit the while loop
 
		break;
 
	}
 
}
 

	
 
void NetworkPluginServer::loginDelayFinished() {
 
	m_loginTimer->stop();
 
	connectWaitingUsers();
 
}
 

	
 
void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr<Swift::Connection> c) {
 
	// Create new Backend instance
 
	Backend *client = new Backend;
 
	client->pongReceived = -1;
 
	client->connection = c;
 
	client->res = 0;
 
	client->init_res = 0;
 
	client->shared = 0;
 
	// Until we receive first PONG from backend, backend is in willDie state.
 
	client->willDie = true;
 
	// Backend does not accept new clients automatically if it's long-running
 
	client->acceptUsers = !m_isNextLongRun;
 
	client->longRun = m_isNextLongRun;
 

	
 
	m_startingBackend = false;
 

	
 
	LOG4CXX_INFO(logger, "New" + (client->longRun ? std::string(" long-running") : "") +  " backend " << client << " connected. Current backend count=" << (m_clients.size() + 1));
 

	
 
	m_clients.push_front(client);
 

	
 
	c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, client));
 
	c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, client, _1));
 
	sendPing(client);
 

	
 
	// sendPing sets pongReceived to 0, but we want to have it -1 to ignore this backend
 
	// in first ::pingTimeout call, because it can be called right after this function
 
	// and backend wouldn't have any time to response to ping.
 
	client->pongReceived = -1;
 
}
 

	
 
void NetworkPluginServer::handleSessionFinished(Backend *c) {
 
	LOG4CXX_INFO(logger, "Backend " << c << " (ID=" << c->id << ") disconnected. Current backend count=" << (m_clients.size() - 1));
 

	
 
	// This backend will do, so we can't reconnect users to it in User::handleDisconnected call
 
	c->willDie = true;
 

	
 
	// If there are users associated with this backend, it must have crashed, so print error output
 
	// and disconnect users
spectrum/src/frontends/slack/SlackFrontend.cpp
Show inline comments
 
 /**
 
 * Spectrum 2 Slack Frontend
 
 *
 
 * Copyright (C) 2015, 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 "SlackFrontend.h"
 
#include "SlackRosterManager.h"
 
#include "SlackUser.h"
 
#include "SlackUserManager.h"
 

	
 
#include "transport/StorageBackend.h"
 
#include "transport/Factory.h"
 
#include "transport/UserRegistry.h"
 
#include "transport/Logging.h"
 
#include "transport/Config.h"
 
#include "transport/Transport.h"
 
#include "transport/ThreadPool.h"
 
#include "transport/HTTPRequest.h"
 

	
 
#include <boost/bind.hpp>
 
#include <boost/smart_ptr/make_shared.hpp>
 
#include <boost/algorithm/string/predicate.hpp>
 

	
 
#if defined(_WIN32) && !defined(__cplusplus_winrt)
 
// Extra includes for Windows desktop.
 
#include <windows.h>
 
#include <Shellapi.h>
 
#endif
 

	
 
namespace Transport {
 

	
 

	
 
DEFINE_LOGGER(logger, "SlackFrontend");
 

	
 
SlackFrontend::SlackFrontend() {
 
	HTTPRequest::globalInit();
 
}
 

	
 
void SlackFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Transport::UserRegistry *userRegistry) {
 
	m_transport = transport;
 
	m_config = transport->getConfig();
 
	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
 
	m_tp = new ThreadPool(loop, 10);
 
}
 

	
 
SlackFrontend::~SlackFrontend() {
 
	HTTPRequest::globalCleanup();
 
}
 

	
 
void SlackFrontend::clearRoomList() {
 

	
 
}
 

	
 
void SlackFrontend::addRoomToRoomList(const std::string &handle, const std::string &name) {
 

	
 
}
 

	
 
void SlackFrontend::sendPresence(Swift::Presence::ref presence) {
 

	
 
}
 

	
 
void SlackFrontend::sendVCard(Swift::VCard::ref vcard, Swift::JID to) {
 
}
 

	
 
void SlackFrontend::sendRosterRequest(Swift::RosterPayload::ref payload, Swift::JID to) {
 
}
 

	
 
void SlackFrontend::sendMessage(boost::shared_ptr<Swift::Message> message) {
 
	return static_cast<SlackUserManager *>(m_userManager)->sendMessage(message);
 
}
 

	
 
void SlackFrontend::sendIQ(boost::shared_ptr<Swift::IQ> iq) {
 
}
 

	
 
boost::shared_ptr<Swift::DiscoInfo> SlackFrontend::sendCapabilitiesRequest(Swift::JID to) {
 

	
 
	return Swift::DiscoInfo::ref();
 
}
 

	
 
void SlackFrontend::reconnectUser(const std::string &user) {
 
	return static_cast<SlackUserManager *>(m_userManager)->reconnectUser(user);
 
}
 

	
 
RosterManager *SlackFrontend::createRosterManager(User *user, Component *component) {
 
	return new SlackRosterManager(user, component);
 
}
 

	
 
User *SlackFrontend::createUser(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) {
 
	SlackUser *user = new SlackUser(jid, userInfo, component, userManager);
 
	user->setReconnectLimit(-1);
 
	return user;
 
}
 

	
 
UserManager *SlackFrontend::createUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) {
 
	m_userManager = new SlackUserManager(component, userRegistry, storageBackend);
 
	return m_userManager;
 
}
 

	
 

	
 
void SlackFrontend::connectToServer() {
 
	LOG4CXX_INFO(logger, "Started.");
 
	m_transport->handleConnected();
 
}
 

	
 
std::string SlackFrontend::setOAuth2Code(const std::string &code, const std::string &state) {
 
	return static_cast<SlackUserManager *>(m_userManager)->handleOAuth2Code(code, state);
 
}
 

	
 
std::string SlackFrontend::getOAuth2URL(const std::vector<std::string> &args) {
 
	return static_cast<SlackUserManager *>(m_userManager)->getOAuth2URL(args);
 
}
 

	
 
std::string SlackFrontend::getRegistrationFields() {
 
	std::string fields = "Main Slack channel";
 
	if (CONFIG_BOOL(m_config, "registration.needRegistration")) {
 
		fields += "\n" + CONFIG_STRING(m_config, "registration.username_label") + "\n";
 
		fields += CONFIG_STRING(m_config, "registration.password_label");
 
	}
 
	return fields;
 
}
 

	
 
bool SlackFrontend::handleAdminMessage(Swift::Message::ref message) {
 
	return static_cast<SlackUserManager *>(m_userManager)->handleAdminMessage(message);
 
}
 

	
 
void SlackFrontend::disconnectFromServer() {
 

	
 
}
 

	
 
}
spectrum/src/frontends/xmpp/XMPPFrontend.cpp
Show inline comments
 
/**
 
 * 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 "XMPPFrontend.h"
 
#include "XMPPRosterManager.h"
 
#include "XMPPUser.h"
 
#include "XMPPUserManager.h"
 
#include <boost/bind.hpp>
 
#include <boost/smart_ptr/make_shared.hpp>
 
#include <boost/algorithm/string/predicate.hpp>
 
#include "transport/StorageBackend.h"
 
#include "transport/Factory.h"
 
#include "transport/UserRegistry.h"
 
#include "transport/Logging.h"
 
#include "transport/Config.h"
 
#include "transport/Transport.h"
 
#include "storageparser.h"
 
#ifdef _WIN32
 
#include <Swiften/TLS/CAPICertificate.h>
 
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
 
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
 
#elif defined(__APPLE__) && HAVE_SWIFTEN_3
 
#include <Swiften/TLS/SecureTransport/SecureTransportCertificate.h>
 
#include <Swiften/TLS/SecureTransport/SecureTransportServerContext.h>
 
#else
 
#include "Swiften/TLS/PKCS12Certificate.h"
 
#include "Swiften/TLS/CertificateWithKey.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
 
#endif
 
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
 
#include "BlockParser.h"
 
#include "BlockSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
 
#include "Swiften/Parser/GenericPayloadParserFactory.h"
 
#include "Swiften/Queries/IQRouter.h"
 
#include "Swiften/Elements/RosterPayload.h"
 
#include "discoitemsresponder.h"
 
#include "Swiften/Elements/InBandRegistrationPayload.h"
 

	
 
using namespace Swift;
 
using namespace boost;
 

	
 
namespace Transport {
 
	
 
DEFINE_LOGGER(logger, "XMPPFrontend");
 

	
 
XMPPFrontend::XMPPFrontend() {
 
}
 

	
 
void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Transport::UserRegistry *userRegistry) {
 
	m_transport = transport;
 
	m_component = NULL;
 
	m_server = NULL;
 
	m_rawXML = false;
 
	m_config = transport->getConfig();
 
	m_userManager = NULL;
 
	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
 

	
 
	m_config->onBackendConfigUpdated.connect(boost::bind(&XMPPFrontend::handleBackendConfigChanged, this));
 

	
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
	m_parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
	m_payloadSerializers.push_back(new Swift::AttentionSerializer());
 
	m_payloadSerializers.push_back(new Swift::XHTMLIMSerializer());
 
	m_payloadSerializers.push_back(new Transport::BlockSerializer());
 
	m_payloadSerializers.push_back(new Swift::InvisibleSerializer());
 
	m_payloadSerializers.push_back(new Swift::StatsSerializer());
 
	m_payloadSerializers.push_back(new Swift::SpectrumErrorSerializer());
 
	m_payloadSerializers.push_back(new Swift::GatewayPayloadSerializer());
 

	
 
	if (CONFIG_BOOL(m_config, "service.server_mode")) {
 
		LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server = new Swift::Server(loop, factories, userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
#ifndef _WIN32
 
#ifndef __APPLE__
 
//TODO: fix
 
			LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
 
			LOG4CXX_INFO(logger, "SSLv23_server_method used.");
 
			TLSServerContextFactory *f = new OpenSSLServerContextFactory();
 
			CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
 
			m_server->addTLSEncryption(f, certificate);
 
#endif
 
#endif
 
			
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
 
		}
 
// 		m_server->start();
 
		m_stanzaChannel = m_server->getStanzaChannel();
 
		m_iqRouter = m_server->getIQRouter();
 

	
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_server->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
		m_server->addPayloadSerializer(new Transport::BlockSerializer());
 
		m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_server->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 
		BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
 
			m_server->addPayloadParserFactory(factory);
 
		}
 

	
 
		BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
 
			m_server->addPayloadSerializer(serializer);
 
		}
 

	
 
		m_server->onDataRead.connect(boost::bind(&XMPPFrontend::handleDataRead, this, _1));
 
		m_server->onDataWritten.connect(boost::bind(&XMPPFrontend::handleDataWritten, this, _1));
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, "Creating component in gateway mode");
 
#if HAVE_SWIFTEN_3
 
		m_component = new Swift::Component(m_jid, CONFIG_STRING(m_config, "service.password"), factories);
 
#else
 
		m_component = new Swift::Component(loop, factories, m_jid, CONFIG_STRING(m_config, "service.password"));
 
#endif
 
		m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
 
		m_component->onConnected.connect(bind(&XMPPFrontend::handleConnected, this));
 
		m_component->onError.connect(boost::bind(&XMPPFrontend::handleConnectionError, this, _1));
 
		m_component->onDataRead.connect(boost::bind(&XMPPFrontend::handleDataRead, this, _1));
 
		m_component->onDataWritten.connect(boost::bind(&XMPPFrontend::handleDataWritten, this, _1));
 

	
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
		m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
		m_component->addPayloadSerializer(new Swift::AttentionSerializer());
 
		m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
 
		m_component->addPayloadSerializer(new Transport::BlockSerializer());
 
		m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
 
		m_component->addPayloadSerializer(new Swift::StatsSerializer());
 
		m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
 
		m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
 
		BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
 
			m_component->addPayloadParserFactory(factory);
 
		}
 

	
 
		BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
 
			m_component->addPayloadSerializer(serializer);
 
		}
 

	
 
		m_stanzaChannel = m_component->getStanzaChannel();
 
		m_iqRouter = m_component->getIQRouter();
 
	}
 

	
 
	m_capsMemoryStorage = new CapsMemoryStorage();
 
#if HAVE_SWIFTEN_3
 
	m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter, factories->getCryptoProvider());
 
#else
 
	m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
 
#endif
 
	m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
 
	m_entityCapsManager->onCapsChanged.connect(boost::bind(&XMPPFrontend::handleCapsChanged, this, _1));
 

	
 
	m_stanzaChannel->onPresenceReceived.connect(bind(&XMPPFrontend::handleGeneralPresence, this, _1));
 
	m_stanzaChannel->onMessageReceived.connect(bind(&XMPPFrontend::handleMessage, this, _1));
 
}
 

	
 
XMPPFrontend::~XMPPFrontend() {
 
	delete m_entityCapsManager;
 
	delete m_capsManager;
 
	delete m_capsMemoryStorage;
 
	if (m_component)
 
		delete m_component;
 
	if (m_server) {
 
		m_server->stop();
 
		delete m_server;
 
	}
 

	
 
	BOOST_FOREACH(Swift::PayloadParserFactory *factory, m_parserFactories) {
 
		delete factory;
 
	}
 
	m_parserFactories.clear();
 

	
 
	BOOST_FOREACH(Swift::PayloadSerializer *serializer, m_payloadSerializers) {
 
		delete serializer;
 
	}
 
	m_payloadSerializers.clear();
 
}
 

	
 
void XMPPFrontend::handleGeneralPresence(Swift::Presence::ref presence) {
 
	onPresenceReceived(presence);
 
}
 

	
 
void XMPPFrontend::handleMessage(boost::shared_ptr<Swift::Message> message) {
 
	onMessageReceived(message);
 
}
 

	
 

	
 
void XMPPFrontend::clearRoomList() {
 
	static_cast<XMPPUserManager *>(m_userManager)->getDiscoItemsResponder()->clearRooms();
 
}
 

	
 
void XMPPFrontend::addRoomToRoomList(const std::string &handle, const std::string &name) {
 
	static_cast<XMPPUserManager *>(m_userManager)->getDiscoItemsResponder()->addRoom(handle, name);
 
}
 

	
 
void XMPPFrontend::sendPresence(Swift::Presence::ref presence) {
 
	if (!presence->getFrom().getNode().empty()) {
 
		presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::CapsInfo(static_cast<XMPPUserManager *>(m_userManager)->getDiscoItemsResponder()->getBuddyCapsInfo())));
 
	}
 

	
 
	m_stanzaChannel->sendPresence(presence);
 
}
 

	
 
void XMPPFrontend::sendVCard(Swift::VCard::ref vcard, Swift::JID to) {
 
	boost::shared_ptr<Swift::GenericRequest<Swift::VCard> > request(new Swift::GenericRequest<Swift::VCard>(Swift::IQ::Result, to, vcard, m_iqRouter));
 
	request->send();
 
}
 

	
 
void XMPPFrontend::sendRosterRequest(Swift::RosterPayload::ref payload, Swift::JID to) {
 
	Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(payload, to, m_iqRouter);
 
	request->send();
 
}
 

	
 
void XMPPFrontend::sendMessage(boost::shared_ptr<Swift::Message> message) {
 
	m_stanzaChannel->sendMessage(message);
 
}
 

	
 
void XMPPFrontend::sendIQ(boost::shared_ptr<Swift::IQ> iq) {
 
	m_iqRouter->sendIQ(iq);
 
}
 

	
 
boost::shared_ptr<Swift::DiscoInfo> XMPPFrontend::sendCapabilitiesRequest(Swift::JID to) {
 
	Swift::DiscoInfo::ref caps = m_entityCapsManager->getCaps(to);
 
	if (caps != Swift::DiscoInfo::ref()) {
 
		onCapabilitiesReceived(to, caps);
 
		return caps;
 
	}
 
#ifdef SUPPORT_LEGACY_CAPS
 
	else {
 
		GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(to, m_iqRouter);
 
		discoInfoRequest->onResponse.connect(boost::bind(&XMPPFrontend::handleDiscoInfoResponse, this, _1, _2, to));
 
		discoInfoRequest->send();
 
	}
 
#endif
 

	
 
	return Swift::DiscoInfo::ref();
 
}
 

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

	
 
RosterManager *XMPPFrontend::createRosterManager(User *user, Component *component) {
 
	return new XMPPRosterManager(user, component);
 
}
 

	
 
User *XMPPFrontend::createUser(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager) {
 
	return new XMPPUser(jid, userInfo, component, userManager);
 
}
 

	
 
UserManager *XMPPFrontend::createUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) {
 
	if (m_userManager) {
 
		delete m_userManager;
 
	}
 
	m_userManager = new XMPPUserManager(component, userRegistry, storageBackend);
 
	return m_userManager;
 
}
 

	
 
bool XMPPFrontend::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
 
	if (!m_rawXML) {
 
		return false;
 
	}
 

	
 
	if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
 
	if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
 
	if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
 

	
 
	if (iq->getTo().getNode().empty()) {
 
		return false;
 
	}
 

	
 
	m_transport->onRawIQReceived(iq);
 
	return true;
 
}
 

	
 
void XMPPFrontend::handleBackendConfigChanged() {
 
	if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
 
		LOG4CXX_INFO(logger, "Enabled Raw XML mode");
 
		m_rawXML = true;
 
		m_iqRouter->addHandler(this);
 
	}
 
}
 

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

	
 
void XMPPFrontend::connectToServer() {
 
	if (m_component && !m_component->isAvailable()) {
 
		LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
 
		if (CONFIG_INT(m_config, "service.port") == 5222) {
 
			LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
 
		}
 
		m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
	}
 
	else if (m_server) {
 
		LOG4CXX_INFO(logger, "Starting XMPPFrontend in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server->start();
 

	
 
		//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
 
		//Ideally, onStopped must be defined in ConnectionServer
 
		if (boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())) {
 
			boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&XMPPFrontend::handleServerStopped, this, _1));
 
		}
 
		
 
		// We're connected right here, because we're in server mode...
 
		handleConnected();
 
	}
 
}
 

	
 
void XMPPFrontend::disconnectFromServer() {
 
	if (m_component) {
 
		// TODO: Call this once swiften will fix assert(!session_);
 
// 		m_component->disconnect();
 
	}
 
	else if (m_server) {
 
		LOG4CXX_INFO(logger, "Stopping component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server->stop();
 
	}
 
}
 

	
 
void XMPPFrontend::handleConnected() {
 
	m_transport->handleConnected();
 
}
 

	
 
void XMPPFrontend::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
 
	if(e) {
 
		if(*e == Swift::BoostConnectionServer::Conflict) {
 
			LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
 
			if (CONFIG_INT(m_config, "service.port") == 5347) {
 
				LOG4CXX_INFO(logger, "Port 5347 is usually used for components. You are using server_mode=1. Are you sure you don't want to use server_mode=0 and run spectrum as component?");
 
			}
 
		}
 
		if(*e == Swift::BoostConnectionServer::UnknownError)
 
			LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
 
		exit(1);
 
	}
 
}
 

	
 

	
 
void XMPPFrontend::handleConnectionError(const ComponentError &error) {
 
	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;
spectrum/src/frontends/xmpp/XMPPFrontend.h
Show inline comments
 
@@ -32,102 +32,104 @@
 
#include "Swiften/Disco/CapsMemoryStorage.h"
 
#include "Swiften/Network/BoostTimerFactory.h"
 
#include "Swiften/Network/BoostIOServiceThread.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include "Swiften/Base/SafeByteArray.h"
 
#include "Swiften/Queries/IQHandler.h"
 
#include "Swiften/Component/ComponentError.h"
 
#include "Swiften/Component/Component.h"
 
#include "Swiften/Queries/IQHandler.h"
 
#include "Swiften/Elements/Presence.h"
 

	
 
#include <boost/bind.hpp>
 
#include <Swiften/Network/BoostConnectionServer.h>
 

	
 
namespace Transport {
 
	class UserRegistry;
 
	class Frontend;
 
	class Config;
 
	class VCardResponder;
 

	
 
	class XMPPFrontend : public Frontend, Swift::IQHandler {
 
		public:
 
			XMPPFrontend();
 

	
 
			virtual ~XMPPFrontend();
 

	
 
			virtual void init(Component *component, Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, UserRegistry *userRegistry);
 

	
 
			virtual void connectToServer();
 

	
 
			virtual void disconnectFromServer();
 

	
 
			virtual void sendPresence(Swift::Presence::ref presence);
 

	
 
			virtual void sendVCard(Swift::VCard::ref vcard, Swift::JID to);
 

	
 
			virtual void sendRosterRequest(Swift::RosterPayload::ref, Swift::JID to);
 

	
 
			virtual void sendMessage(boost::shared_ptr<Swift::Message> message);
 

	
 
			virtual void sendIQ(boost::shared_ptr<Swift::IQ>);
 

	
 
			virtual void reconnectUser(const std::string &user);
 

	
 
			virtual RosterManager *createRosterManager(User *user, Component *component);
 
			virtual User *createUser(const Swift::JID &jid, UserInfo &userInfo, Component *component, UserManager *userManager);
 
			virtual UserManager *createUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend = NULL);
 
			virtual boost::shared_ptr<Swift::DiscoInfo> sendCapabilitiesRequest(Swift::JID to);
 
			virtual void clearRoomList();
 
			virtual void addRoomToRoomList(const std::string &handle, const std::string &name);
 
		
 
			void handleMessage(boost::shared_ptr<Swift::Message> message);
 

	
 

	
 
			Swift::StanzaChannel *getStanzaChannel();
 

	
 
			Swift::IQRouter *getIQRouter() { return m_iqRouter; }
 

	
 

	
 
			bool inServerMode() { return m_server != NULL; }
 

	
 
			bool isRawXMLEnabled() {
 
				return m_rawXML;
 
			}
 

	
 
			std::string getRegistrationFields();
 

	
 
		private:
 
			void handleConnected();
 
			void handleConnectionError(const Swift::ComponentError &error);
 
			void handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e);
 
			void handleGeneralPresence(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 handleCapsChanged(const Swift::JID& jid);
 

	
 
			void handleBackendConfigChanged();
 
			bool handleIQ(boost::shared_ptr<Swift::IQ>);
 

	
 
			Swift::NetworkFactories *m_factories;
 
			Swift::Component *m_component;
 
			Swift::Server *m_server;
 
			Swift::EntityCapsManager *m_entityCapsManager;
 
			Swift::CapsManager *m_capsManager;
 
			Swift::CapsMemoryStorage *m_capsMemoryStorage;
 
			Swift::StanzaChannel *m_stanzaChannel;
 
			Swift::IQRouter *m_iqRouter;
 
			VCardResponder *m_vcardResponder;
 
			
 
			Config* m_config;
 
			Swift::JID m_jid;
 
			bool m_rawXML;
 
			Component *m_transport;
 
			UserManager *m_userManager;
 
			std::vector<Swift::PayloadParserFactory *> m_parserFactories;
 
			std::vector<Swift::PayloadSerializer *> m_payloadSerializers;
 

	
 
		friend class XMPPUser;
 
		friend class UserRegistration;
 
		friend class NetworkPluginServer;
 
	};
 
}
spectrum/src/frontends/xmpp/XMPPUserManager.cpp
Show inline comments
 
/**
 
 * 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 "XMPPUserManager.h"
 
#include "XMPPUserRegistration.h"
 
#include "transport/User.h"
 
#include "transport/Transport.h"
 
#include "transport/StorageBackend.h"
 
#include "transport/Logging.h"
 
#include "transport/Frontend.h"
 
#include "storageresponder.h"
 
#include "vcardresponder.h"
 
#include "XMPPFrontend.h"
 
#include "gatewayresponder.h"
 
#include "adhocmanager.h"
 
#include "settingsadhoccommand.h"
 
#include "RosterResponder.h"
 
#include "discoitemsresponder.h"
 

	
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Elements/StreamError.h"
 
#include "Swiften/Elements/MUCPayload.h"
 
#include "Swiften/Elements/ChatState.h"
 
#ifndef __FreeBSD__ 
 
#ifndef __MACH__
 
#include "malloc.h"
 
#endif
 
#endif
 
// #include "valgrind/memcheck.h"
 

	
 
namespace Transport {
 

	
 
DEFINE_LOGGER(logger, "XMPPUserManager");
 

	
 
XMPPUserManager::XMPPUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend) : UserManager(component, userRegistry, storageBackend) {
 
	m_component = component;
 

	
 
	XMPPFrontend *frontend = static_cast<XMPPFrontend *>(component->getFrontend());
 
	if (storageBackend) {
 
		m_storageResponder = new StorageResponder(frontend->getIQRouter(), storageBackend, this);
 
		m_storageResponder->start();
 
	}
 
	else {
 
		m_storageResponder = NULL;
 
	}
 

	
 
	m_vcardResponder = new VCardResponder(frontend->getIQRouter(), component->getNetworkFactories(), this);
 
	m_vcardResponder->onVCardRequired.connect(boost::bind(&XMPPUserManager::handleVCardRequired, this, _1, _2, _3));
 
	m_vcardResponder->onVCardUpdated.connect(boost::bind(&XMPPUserManager::handleVCardUpdated, this, _1, _2));
 
	m_vcardResponder->start();
 

	
 
	if (storageBackend) {
 
		m_userRegistration = new XMPPUserRegistration(component, this, storageBackend);
 
		m_userRegistration->start();
 
	}
 
	else {
 
		m_userRegistration = NULL;
 
	}
 

	
 
// 	StatsResponder statsResponder(component, this, &plugin, storageBackend);
 
// 	statsResponder.start();
 

	
 
	m_gatewayResponder = new GatewayResponder(frontend->getIQRouter(), this);
 
	m_gatewayResponder->start();
 

	
 
	m_rosterResponder = new RosterResponder(frontend->getIQRouter(), this);
 
	m_rosterResponder->start();
 

	
 
	m_discoItemsResponder = new DiscoItemsResponder(component, this);
 
	m_discoItemsResponder->start();
 

	
 
	m_adHocManager = new AdHocManager(component, m_discoItemsResponder, this, storageBackend);
 
	m_adHocManager->start();
 

	
 
	SettingsAdHocCommandFactory *m_settings = new SettingsAdHocCommandFactory();
 
	m_settings = new SettingsAdHocCommandFactory();
 
	m_adHocManager->addAdHocCommand(m_settings);
 
}
 

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

	
 
	if (m_userRegistration) {
 
		m_userRegistration->stop();
 
		delete m_userRegistration;
 
	}
 

	
 
	m_gatewayResponder->stop();
 
	delete m_gatewayResponder;
 

	
 
	m_adHocManager->stop();
 
	delete m_adHocManager;
 

	
 
	m_vcardResponder->stop();
 
	delete m_vcardResponder;
 

	
 
	m_rosterResponder->stop();
 
	delete m_rosterResponder;
 

	
 
	m_discoItemsResponder->stop();
 
	delete m_discoItemsResponder;
 

	
 
	delete m_settings;
 
}
 

	
 
void XMPPUserManager::sendVCard(unsigned int id, Swift::VCard::ref vcard) {
 
	m_vcardResponder->sendVCard(id, vcard);
 
}
 

	
 
void XMPPUserManager::handleVCardRequired(User *user, const std::string &name, unsigned int id) {
 
	m_component->getFrontend()->onVCardRequired(user, name, id);
 
}
 

	
 
void XMPPUserManager::handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard) {
 
	m_component->getFrontend()->onVCardUpdated(user, vcard);
 
}
 

	
 
UserRegistration *XMPPUserManager::getUserRegistration() {
 
	return m_userRegistration;
 
}
 

	
 
}
tests/libtransport/SlackRTM.cpp
Show inline comments
 
#include "SlackRTM.h"
 
#include "SlackIdManager.h"
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include "BasicSlackTest.h"
 

	
 
using namespace Transport;
 

	
 
class SlackRTMTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(SlackRTMTest);
 
	CPPUNIT_TEST(handleRTMStart);
 
	CPPUNIT_TEST(handlePayloadReceivedChannelJoined);
 
	CPPUNIT_TEST(handlePayloadReceivedChannelCreated);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		SlackRTM *m_rtm;
 
		SlackIdManager *m_idManager;
 
		std::string rtmStartPayload;
 

	
 
		void setUp (void) {
 
			setMeUp();
 
			UserInfo uinfo;
 
			uinfo.id = 1;
 
			m_idManager = new SlackIdManager();
 
			m_rtm = new SlackRTM(component, storage, m_idManager, uinfo);
 

	
 
			rtmStartPayload = "{\"ok\":true,\"self\":{\"id\":\"U0KECRDJB\",\"name\":\"spectrum2\",\"prefs\":{\"highlight_words\":\"\",\"user_colors\":\"\",\"color_names_in_list\":true,\"growls_enabled\":true,\"tz\":null,\"push_dm_alert\":true,\"push_mention_alert\":true,\"msg_replies\":\"{ \\\"flexpane\\\":false }\",\"push_everything\":true,\"push_idle_wait\":2,\"push_sound\":\"b2.mp3\",\"push_loud_channels\":\"\",\"push_mention_channels\":\"\",\"push_loud_channels_set\":\"\",\"email_alerts\":\"instant\",\"email_alerts_sleep_until\":0,\"email_misc\":true,\"email_weekly\":true,\"welcome_message_hidden\":false,\"all_channels_loud\":true,\"loud_channels\":\"\",\"never_channels\":\"\",\"loud_channels_set\":\"\",\"show_member_presence\":true,\"search_sort\":\"timestamp\",\"expand_inline_imgs\":true,\"expand_internal_inline_imgs\":true,\"expand_snippets\":false,\"posts_formatting_guide\":true,\"seen_live_support_popup\":false,\"seen_welcome_2\":false,\"seen_ssb_prompt\":false,\"seen_spaces_new_xp_tooltip\":false,\"spaces_new_xp_banner_dismissed\":false,\"search_only_my_channels\":false,\"emoji_mode\":\"default\",\"emoji_use\":\"\",\"has_invited\":false,\"has_uploaded\":false,\"has_created_channel\":false,\"search_exclude_channels\":\"\",\"messages_theme\":\"default\",\"webapp_spellcheck\":true,\"no_joined_overlays\":false,\"no_created_overlays\":false,\"dropbox_enabled\":false,\"seen_domain_invite_reminder\":false,\"seen_member_invite_reminder\":false,\"mute_sounds\":false,\"arrow_history\":false,\"tab_ui_return_selects\":true,\"obey_inline_img_limit\":true,\"new_msg_snd\":\"knock_brush.mp3\",\"collapsible\":false,\"collapsible_by_click\":true,\"require_at\":false,\"ssb_space_window\":\"\",\"mac_ssb_bounce\":\"\",\"mac_ssb_bullet\":true,\"expand_non_media_attachments\":true,\"show_typing\":true,\"pagekeys_handled\":true,\"last_snippet_type\":\"\",\"display_real_names_override\":0,\"time24\":false,\"enter_is_special_in_tbt\":false,\"graphic_emoticons\":false,\"convert_emoticons\":true,\"autoplay_chat_sounds\":true,\"ss_emojis\":true,\"sidebar_behavior\":\"\",\"seen_onboarding_start\":false,\"onboarding_cancelled\":false,\"seen_onboarding_slackbot_conversation\":false,\"seen_onboarding_channels\":false,\"seen_onboarding_direct_messages\":false,\"seen_onboarding_invites\":false,\"seen_onboarding_search\":false,\"seen_onboarding_recent_mentions\":false,\"seen_onboarding_starred_items\":false,\"seen_onboarding_private_groups\":false,\"onboarding_slackbot_conversation_step\":0,\"dnd_enabled\":false,\"dnd_start_hour\":\"22:00\",\"dnd_end_hour\":\"08:00\",\"mark_msgs_read_immediately\":true,\"start_scroll_at_oldest\":true,\"snippet_editor_wrap_long_lines\":false,\"ls_disabled\":false,\"sidebar_theme\":\"default\",\"sidebar_theme_custom_values\":\"\",\"f_key_search\":false,\"k_key_omnibox\":true,\"speak_growls\":false,\"mac_speak_voice\":\"com.apple.speech.synthesis.voice.Alex\",\"mac_speak_speed\":250,\"comma_key_prefs\":false,\"at_channel_suppressed_channels\":\"\",\"push_at_channel_suppressed_channels\":\"\",\"prompted_for_email_disabling\":false,\"full_text_extracts\":false,\"no_text_in_notifications\":false,\"muted_channels\":\"\",\"no_macssb1_banner\":false,\"no_winssb1_banner\":false,\"no_omnibox_in_channels\":false,\"k_key_omnibox_auto_hide_count\":0,\"hide_user_group_info_pane\":false,\"mentions_exclude_at_user_groups\":false,\"privacy_policy_seen\":true,\"search_exclude_bots\":false,\"fuzzy_matching\":false,\"load_lato_2\":false,\"fuller_timestamps\":false,\"last_seen_at_channel_warning\":0,\"flex_resize_window\":false,\"msg_preview\":false,\"msg_preview_displaces\":true,\"msg_preview_persistent\":true,\"emoji_autocomplete_big\":false,\"winssb_run_from_tray\":true,\"winssb_window_flash_behavior\":\"idle\",\"two_factor_auth_enabled\":false,\"two_factor_type\":null,\"two_factor_backup_type\":null,\"mentions_exclude_at_channels\":true,\"confirm_clear_all_unreads\":true,\"confirm_user_marked_away\":true,\"box_enabled\":false,\"seen_single_emoji_msg\":false,\"confirm_sh_call_start\":true,\"preferred_skin_tone\":\"\",\"show_all_skin_tones\":false,\"separate_private_channels\":false,\"whats_new_read\":1453832311,\"hotness\":false,\"frecency_jumper\":\"\",\"jumbomoji\":false},\"created\":1453832311,\"manual_presence\":\"active\"},\"team\":{\"id\":\"T0H6F57L0\",\"name\":\"spectrum2test\",\"email_domain\":\"\",\"domain\":\"spectrum2tests\",\"msg_edit_window_mins\":-1,\"prefs\":{\"default_channels\":[\"C0H6BKHM1\",\"C0H6EJD2S\"],\"gateway_allow_xmpp_ssl\":1,\"gateway_allow_irc_ssl\":0,\"gateway_allow_irc_plain\":0,\"msg_edit_window_mins\":-1,\"allow_message_deletion\":true,\"hide_referers\":true,\"display_real_names\":false,\"disable_file_uploads\":\"allow_all\",\"who_can_at_everyone\":\"regular\",\"who_can_at_channel\":\"ra\",\"warn_before_at_channel\":\"always\",\"who_can_create_channels\":\"regular\",\"who_can_create_shared_channels\":\"admin\",\"who_can_archive_channels\":\"regular\",\"who_can_create_groups\":\"ra\",\"who_can_post_general\":\"ra\",\"who_can_kick_channels\":\"admin\",\"who_can_kick_groups\":\"regular\",\"dnd_enabled\":true,\"dnd_start_hour\":\"22:00\",\"dnd_end_hour\":\"08:00\",\"allow_shared_channels\":false,\"who_has_team_visibility\":\"ra\",\"who_can_create_delete_user_groups\":\"admin\",\"who_can_edit_user_groups\":\"admin\",\"who_can_change_team_profile\":\"admin\",\"retention_type\":0,\"retention_duration\":0,\"group_retention_type\":0,\"group_retention_duration\":0,\"dm_retention_type\":0,\"dm_retention_duration\":0,\"file_retention_type\":0,\"file_retention_duration\":0,\"allow_retention_override\":true,\"require_at_for_mention\":0,\"compliance_export_start\":0,\"invites_only_admins\":true,\"auth_mode\":\"normal\",\"who_can_manage_integrations\":{\"type\":[\"regular\"]}},\"icon\":{\"image_34\":\"https:\\/\\/slack.global.ssl.fastly.net\\/0180\\/img\\/avatars-teams\\/ava_0020-34.png\",\"image_44\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/avatars-teams\\/ava_0020-44.png\",\"image_68\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/avatars-teams\\/ava_0020-68.png\",\"image_88\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/avatars-teams\\/ava_0020-88.png\",\"image_102\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/avatars-teams\\/ava_0020-102.png\",\"image_132\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/avatars-teams\\/ava_0020-132.png\",\"image_default\":true},\"over_storage_limit\":false,\"plan\":\"\",\"over_integrations_limit\":true},\"latest_event_ts\":\"1454230362.000000\",\"channels\":[{\"id\":\"C0H6BKHM1\",\"name\":\"general\",\"is_channel\":true,\"created\":1450796647,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":true,\"has_pins\":false,\"is_member\":false},{\"id\":\"C0HEF8JCU\",\"name\":\"irc_channel\",\"is_channel\":true,\"created\":1451370608,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":false},{\"id\":\"C0KH09UQ2\",\"name\":\"my_new_channel\",\"is_channel\":true,\"created\":1453906652,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":true,\"last_read\":\"1453906652.000002\",\"latest\":{\"user\":\"U0H6EEWNN\",\"purpose\":\"Online users: Jan Kaluza, \",\"type\":\"message\",\"subtype\":\"channel_purpose\",\"text\":\"<@U0H6EEWNN|owner> set the channel purpose: Online users: Jan Kaluza, \",\"ts\":\"1454230914.000002\"},\"unread_count\":8,\"unread_count_display\":7,\"members\":[\"U0H6EEWNN\",\"U0KECRDJB\"],\"topic\":{\"value\":\"\",\"creator\":\"\",\"last_set\":0},\"purpose\":{\"value\":\"Online users: Jan Kaluza, \",\"creator\":\"U0H6EEWNN\",\"last_set\":1454230914}},{\"id\":\"C0H6EJD2S\",\"name\":\"random\",\"is_channel\":true,\"created\":1450796647,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":false},{\"id\":\"C0H6B0SQM\",\"name\":\"spectrum2_contactlist\",\"is_channel\":true,\"created\":1450797097,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":false},{\"id\":\"C0H6FMUSU\",\"name\":\"spectrum2_room\",\"is_channel\":true,\"created\":1450797111,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":false},{\"id\":\"C0KK70E92\",\"name\":\"spectrum_channel\",\"is_channel\":true,\"created\":1453969281,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"has_pins\":false,\"is_member\":false}],\"groups\":[],\"ims\":[{\"id\":\"D0KEDLA8Y\",\"is_im\":true,\"user\":\"USLACKBOT\",\"created\":1453832311,\"has_pins\":false,\"last_read\":\"0000000000.000000\",\"latest\":null,\"unread_count\":0,\"unread_count_display\":0,\"is_open\":true},{\"id\":\"D0KEC5UTT\",\"is_im\":true,\"user\":\"U0H6EEWNN\",\"created\":1453832311,\"has_pins\":false,\"last_read\":\"0000000000.000000\",\"latest\":{\"type\":\"message\",\"user\":\"U0KECRDJB\",\"text\":\"Unknown command. Use \\\".spectrum2 help\\\" for help.\",\"ts\":\"1454230892.000002\"},\"unread_count\":91,\"unread_count_display\":0,\"is_open\":true}],\"cache_ts\":1454230962,\"subteams\":{\"self\":[],\"all\":[]},\"dnd\":{\"dnd_enabled\":false,\"next_dnd_start_ts\":1,\"next_dnd_end_ts\":1,\"snooze_enabled\":false},\"users\":[{\"id\":\"U0HELRN5U\",\"team_id\":\"T0H6F57L0\",\"name\":\"anothertest\",\"deleted\":false,\"status\":null,\"color\":\"e7392d\",\"real_name\":\"\",\"tz\":null,\"tz_label\":\"Pacific Standard Time\",\"tz_offset\":-28800,\"profile\":{\"bot_id\":\"B0HEF7LJY\",\"api_app_id\":\"\",\"avatar_hash\":\"971145960e33\",\"image_24\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_24.png\",\"image_32\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_32.png\",\"image_48\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_48.png\",\"image_72\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_72.png\",\"image_192\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_192.png\",\"image_512\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_512.png\",\"image_1024\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_512.png\",\"image_original\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-29\\/17496560935_971145960e330b301ccd_original.png\",\"real_name\":\"\",\"real_name_normalized\":\"\",\"fields\":null},\"is_admin\":false,\"is_owner\":false,\"is_primary_owner\":false,\"is_restricted\":false,\"is_ultra_restricted\":false,\"is_bot\":true,\"presence\":\"away\"},{\"id\":\"U0H6EEWNN\",\"team_id\":\"T0H6F57L0\",\"name\":\"owner\",\"deleted\":false,\"status\":null,\"color\":\"9f69e7\",\"real_name\":\"\",\"tz\":\"Europe\\/Amsterdam\",\"tz_label\":\"Central European Time\",\"tz_offset\":3600,\"profile\":{\"avatar_hash\":\"g271b7615bd5\",\"real_name\":\"\",\"real_name_normalized\":\"\",\"email\":\"hanzz.k@gmail.com\",\"image_24\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=24&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0007-24.png\",\"image_32\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=32&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0007-32.png\",\"image_48\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=48&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0007-48.png\",\"image_72\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=72&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0007-72.png\",\"image_192\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=192&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F7fa9%2Fimg%2Favatars%2Fava_0007-192.png\",\"image_512\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/271b7615bd58df47d63e5204e04ee65d.jpg?s=512&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F7fa9%2Fimg%2Favatars%2Fava_0007-512.png\",\"fields\":null},\"is_admin\":true,\"is_owner\":true,\"is_primary_owner\":true,\"is_restricted\":false,\"is_ultra_restricted\":false,\"is_bot\":false,\"presence\":\"away\"},{\"id\":\"U0H69GY5S\",\"team_id\":\"T0H6F57L0\",\"name\":\"spectrum2\",\"deleted\":false,\"status\":null,\"color\":\"4bbe2e\",\"real_name\":\"\",\"tz\":null,\"tz_label\":\"Pacific Standard Time\",\"tz_offset\":-28800,\"profile\":{\"bot_id\":\"B0H6AU1HT\",\"api_app_id\":\"\",\"avatar_hash\":\"f8d23ca2bfcf\",\"image_24\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_24.png\",\"image_32\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_32.png\",\"image_48\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_48.png\",\"image_72\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_72.png\",\"image_192\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_192.png\",\"image_512\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_512.png\",\"image_1024\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_512.png\",\"image_original\":\"https:\\/\\/avatars.slack-edge.com\\/2015-12-22\\/17213576228_f8d23ca2bfcf67d184ad_original.png\",\"real_name\":\"\",\"real_name_normalized\":\"\",\"fields\":null},\"is_admin\":false,\"is_owner\":false,\"is_primary_owner\":false,\"is_restricted\":false,\"is_ultra_restricted\":false,\"is_bot\":true,\"presence\":\"away\"},{\"id\":\"U0KECRDJB\",\"team_id\":\"T0H6F57L0\",\"name\":\"spectrum22\",\"deleted\":false,\"status\":null,\"color\":\"3c989f\",\"real_name\":\"Spectrum 2\",\"tz\":null,\"tz_label\":\"Pacific Standard Time\",\"tz_offset\":-28800,\"profile\":{\"first_name\":\"Spectrum 2\",\"bot_id\":\"B0KE9SE83\",\"api_app_id\":\"A0ET5FEUT\",\"avatar_hash\":\"g54f5aa0341b\",\"real_name\":\"Spectrum 2\",\"real_name_normalized\":\"Spectrum 2\",\"image_24\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=24&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0001-24.png\",\"image_32\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=32&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F66f9%2Fimg%2Favatars%2Fava_0001-32.png\",\"image_48\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=48&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F0180%2Fimg%2Favatars%2Fava_0001-48.png\",\"image_72\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=72&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F3654%2Fimg%2Favatars%2Fava_0001-72.png\",\"image_192\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=192&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F7fa9%2Fimg%2Favatars%2Fava_0001-192.png\",\"image_512\":\"https:\\/\\/secure.gravatar.com\\/avatar\\/54f5aa0341b1d9b9bce259906cf8354d.jpg?s=512&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F7fa9%2Fimg%2Favatars%2Fava_0001-512.png\",\"fields\":null},\"is_admin\":false,\"is_owner\":false,\"is_primary_owner\":false,\"is_restricted\":false,\"is_ultra_restricted\":false,\"is_bot\":true,\"presence\":\"away\"},{\"id\":\"USLACKBOT\",\"team_id\":\"T0H6F57L0\",\"name\":\"slackbot\",\"deleted\":false,\"status\":null,\"color\":\"757575\",\"real_name\":\"slackbot\",\"tz\":null,\"tz_label\":\"Pacific Standard Time\",\"tz_offset\":-28800,\"profile\":{\"first_name\":\"slackbot\",\"last_name\":\"\",\"image_24\":\"https:\\/\\/slack.global.ssl.fastly.net\\/0180\\/img\\/slackbot_24.png\",\"image_32\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/slackbot_32.png\",\"image_48\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/slackbot_48.png\",\"image_72\":\"https:\\/\\/slack.global.ssl.fastly.net\\/0180\\/img\\/slackbot_72.png\",\"image_192\":\"https:\\/\\/slack.global.ssl.fastly.net\\/66f9\\/img\\/slackbot_192.png\",\"image_512\":\"https:\\/\\/slack.global.ssl.fastly.net\\/7fa9\\/img\\/slackbot_512.png\",\"avatar_hash\":\"sv1444671949\",\"real_name\":\"slackbot\",\"real_name_normalized\":\"slackbot\",\"email\":null,\"fields\":null},\"is_admin\":false,\"is_owner\":false,\"is_primary_owner\":false,\"is_restricted\":false,\"is_ultra_restricted\":false,\"is_bot\":false,\"presence\":\"active\"}],\"cache_version\":\"v12-rats\",\"cache_ts_version\":\"v1-cat\",\"bots\":[{\"id\":\"B0H6AU1HT\",\"deleted\":false,\"name\":\"bot\",\"icons\":{\"image_36\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_36.png\",\"image_48\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_48.png\",\"image_72\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_72.png\"}},{\"id\":\"B0H6F5BDE\",\"deleted\":false,\"name\":\"gdrive\"},{\"id\":\"B0HEF7LJY\",\"deleted\":false,\"name\":\"bot\",\"icons\":{\"image_36\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_36.png\",\"image_48\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_48.png\",\"image_72\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/bot\\/assets\\/service_72.png\"}},{\"id\":\"B0KE9SE83\",\"deleted\":false,\"name\":\"Spectrum 2\",\"icons\":{\"image_36\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/app\\/assets\\/service_36.png\",\"image_48\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/app\\/assets\\/service_48.png\",\"image_72\":\"https:\\/\\/slack.global.ssl.fastly.net\\/12b5a\\/plugins\\/app\\/assets\\/service_72.png\"}}],\"url\":\"wss:\\/\\/ms607.slack-msgs.com\\/websocket\\/qErn8B_c2XF7Xv7weT-YVYUeaxo0BGY5dzeyh_TjHPYrBivZfpaEXGITASOUtuT6856_MQoyLZybo-1R5-jY2cILbSskPs3uGJClpJqA_jTwHz00Sflcvp-Zoc8l5lCxnWQMJiGXtC7kKeLl4rme5g==\"}";
 
		}
 

	
 
		void tearDown (void) {
 
			delete m_rtm;
 
			delete m_idManager;
 
			tearMeDown();
 
		}
 

	
 
		void handleRTMStart() {
 
			rapidjson::Document json;
 
			json.Parse<0>(rtmStartPayload.c_str());
 
			m_rtm->handleRTMStart(NULL, true, json, rtmStartPayload);
 

	
 
			CPPUNIT_ASSERT_EQUAL(std::string("spectrum2"), m_idManager->getSelfName());
 
			CPPUNIT_ASSERT_EQUAL(std::string("U0KECRDJB"), m_idManager->getSelfId());
 
			CPPUNIT_ASSERT_EQUAL(std::string("owner"), m_idManager->getName("U0H6EEWNN"));
 
			CPPUNIT_ASSERT_EQUAL(std::string("C0H6B0SQM"), m_idManager->getId("spectrum2_contactlist"));
 
			CPPUNIT_ASSERT_EQUAL(true, m_idManager->hasMember("C0KH09UQ2", "U0KECRDJB"));
 
			CPPUNIT_ASSERT_EQUAL(false, m_idManager->hasMember("C0KH09UQ2", "U1KECRDJB"));
 
		}
 

	
 
		void handlePayloadReceivedChannelJoined() {
 
			CPPUNIT_ASSERT_EQUAL(false, m_idManager->hasMember("C0KSK7V7E", "U0KECRDJB"));
 

	
 
			std::string payload = "{\"type\":\"channel_joined\",\"channel\":{\"id\":\"C0KSK7V7E\",\"name\":\"new_slack_channel\",\"is_channel\":true,\"created\":1454231085,\"creator\":\"U0H6EEWNN\",\"is_archived\":false,\"is_general\":false,\"is_member\":true,\"last_read\":\"1454231085.000002\",\"latest\":{\"user\":\"U0H6EEWNN\",\"type\":\"message\",\"subtype\":\"channel_join\",\"text\":\"<@U0H6EEWNN|owner> has joined the channel\",\"ts\":\"1454231085.000002\"},\"unread_count\":0,\"unread_count_display\":0,\"members\":[\"U0H6EEWNN\",\"U0KECRDJB\"],\"topic\":{\"value\":\"\",\"creator\":\"\",\"last_set\":0},\"purpose\":{\"value\":\"\",\"creator\":\"\",\"last_set\":0}}}";
 
			m_rtm->handlePayloadReceived(payload);
 
			CPPUNIT_ASSERT_EQUAL(std::string("C0KSK7V7E"), m_idManager->getId("new_slack_channel"));
 
			CPPUNIT_ASSERT_EQUAL(true, m_idManager->hasMember("C0KSK7V7E", "U0KECRDJB"));
 
			CPPUNIT_ASSERT_EQUAL(false, m_idManager->hasMember("C0KSK7V7E", "U1KECRDJB"));
 
		}
 

	
 

	
 
		void handlePayloadReceivedChannelCreated() {
 
			std::string payload = "{\"type\":\"channel_created\",\"channel\":{\"id\":\"C0KH09UQ2\",\"is_channel\":true,\"name\":\"my_new_channel\",\"created\":1453906652,\"creator\":\"U0H6EEWNN\"},\"event_ts\":\"1453906652.085393\"}";
 
			m_rtm->handlePayloadReceived(payload);
 
			CPPUNIT_ASSERT_EQUAL(std::string("C0KH09UQ2"), m_idManager->getId("my_new_channel"));
 
		}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (SlackRTMTest);
tests/libtransport/basictest.cpp
Show inline comments
 
#include "basictest.h"
 
#include "XMPPFrontend.h"
 
#include "XMPPUserRegistration.h"
 
#include "XMPPUserManager.h"
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include <Swiften/Swiften.h>
 
#include <Swiften/EventLoop/DummyEventLoop.h>
 
#include <Swiften/Server/Server.h>
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyConnectionServer.h>
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 

	
 
#include "Swiften/Serializer/GenericPayloadSerializer.h"
 

	
 
#include "storageparser.h"
 
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
 
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
 
#include "BlockParser.h"
 
#include "BlockSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
 

	
 
using namespace Transport;
 

	
 
void BasicTest::setMeUp (void) {
 
	streamEnded = false;
 
	std::istringstream ifs("service.server_mode = 1\nservice.jid=localhost\nservice.more_resources=1\n");
 
	cfg = new Config();
 
	cfg->load(ifs);
 

	
 
	factory = new TestingFactory();
 

	
 
	storage = new TestingStorageBackend();
 

	
 
	loop = new Swift::DummyEventLoop();
 
	factories = new Swift::DummyNetworkFactories(loop);
 

	
 
	userRegistry = new UserRegistry(cfg, factories);
 

	
 
	frontend = new Transport::XMPPFrontend();
 

	
 
	component = new Component(frontend, loop, factories, cfg, factory, userRegistry);
 
	component->start();
 

	
 
	userManager = frontend->createUserManager(component, userRegistry, storage);
 

	
 
	itemsResponder = static_cast<XMPPUserManager *>(userManager)->getDiscoItemsResponder();
 

	
 
	payloadSerializers = new Swift::FullPayloadSerializerCollection();
 
	payloadParserFactories = new Swift::FullPayloadParserFactoryCollection();
 

	
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
	payloadParserFactories->addFactory(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
	payloadSerializers->addSerializer(new Swift::AttentionSerializer());
 
	payloadSerializers->addSerializer(new Swift::XHTMLIMSerializer());
 
	payloadSerializers->addSerializer(new Transport::BlockSerializer());
 
	payloadSerializers->addSerializer(new Swift::InvisibleSerializer());
 
	payloadSerializers->addSerializer(new Swift::StatsSerializer());
 
	payloadSerializers->addSerializer(new Swift::SpectrumErrorSerializer());
 
	payloadSerializers->addSerializer(new Swift::GatewayPayloadSerializer());
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
 
	parserFactories.push_back(new Swift::GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
 

	
 
	BOOST_FOREACH(Swift::PayloadParserFactory *factory, parserFactories) {
 
		payloadParserFactories->addFactory(factory);
 
	}
 

	
 
	_payloadSerializers.push_back(new Swift::AttentionSerializer());
 
	_payloadSerializers.push_back(new Swift::XHTMLIMSerializer());
 
	_payloadSerializers.push_back(new Transport::BlockSerializer());
 
	_payloadSerializers.push_back(new Swift::InvisibleSerializer());
 
	_payloadSerializers.push_back(new Swift::StatsSerializer());
 
	_payloadSerializers.push_back(new Swift::SpectrumErrorSerializer());
 
	_payloadSerializers.push_back(new Swift::GatewayPayloadSerializer());
 

	
 
	BOOST_FOREACH(Swift::PayloadSerializer *serializer, _payloadSerializers) {
 
		payloadSerializers->addSerializer(serializer);
 
	}
 

	
 
	parser = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
 
	parser2 = new Swift::XMPPParser(this, payloadParserFactories, factories->getXMLParserFactory());
 

	
 
	serverFromClientSession = boost::shared_ptr<Swift::ServerFromClientSession>(new Swift::ServerFromClientSession("id", factories->getConnectionFactory()->createConnection(),
 
			payloadParserFactories, payloadSerializers, userRegistry, factories->getXMLParserFactory(), Swift::JID("user@localhost/resource")));
 
	serverFromClientSession->startSession();
 

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

	
 
	dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->addSession(serverFromClientSession);
 
	parser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
	parser2->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
	received.clear();
 
	received2.clear();
 
	receivedData.clear();
 
	loop->processEvents();
 
}
 

	
 
void BasicTest::tearMeDown (void) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->removeSession(serverFromClientSession);
 
	if (serverFromClientSession2) {
 
		dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->removeSession(serverFromClientSession2);
 
		serverFromClientSession2.reset();
 
	}
 
	delete userManager;
 
	delete component;
 
	delete frontend;
 
	delete userRegistry;
 
	delete factories;
 
	delete factory;
 
	delete loop;
 
	delete cfg;
 
	delete parser;
 
	delete parser2;
 
	delete storage;
 
// 	delete userRegistration;
 
	received.clear();
 
	received2.clear();
 
	receivedData.clear();
 
	receivedData2.clear();
 

	
 
	delete payloadParserFactories;
 
	delete payloadSerializers;
 
	
 

	
 
	BOOST_FOREACH(Swift::PayloadParserFactory *factory, parserFactories) {
 
		delete factory;
 
	}
 
	parserFactories.clear();
 

	
 
	BOOST_FOREACH(Swift::PayloadSerializer *serializer, _payloadSerializers) {
 
		delete serializer;
 
	}
 
	_payloadSerializers.clear();
 
}
 

	
 
void BasicTest::handleDataReceived(const Swift::SafeByteArray &data) {
 
// 	std::cout << safeByteArrayToString(data) << "\n";
 
	stream1_active = true;
 
	receivedData += safeByteArrayToString(data) + "\n";
 
	parser->parse(safeByteArrayToString(data));
 
}
 

	
 
void BasicTest::handleDataReceived2(const Swift::SafeByteArray &data) {
 
// 	std::cout << safeByteArrayToString(data) << "\n";
 
	stream1_active = false;
 
	receivedData2 += safeByteArrayToString(data) + "\n";
 
	parser2->parse(safeByteArrayToString(data));
 
}
 

	
 
void BasicTest::handleStreamStart(const Swift::ProtocolHeader&) {
 

	
 
}
 

	
 
void BasicTest::dumpReceived() {
 
	std::cout << "\nStream1:\n";
 
	std::cout << receivedData << "\n";
 
	std::cout << "Stream2:\n";
 
	std::cout << receivedData2 << "\n";
 
}
 
#if HAVE_SWIFTEN_3
 
void BasicTest::handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
 
#else
 
void BasicTest::handleElement(boost::shared_ptr<Swift::Element> element) {
 
#endif
 
	if (stream1_active) {
 
		received.push_back(element);
 
	}
 
	else {
 
		received2.push_back(element);
 
	}
 
}
 

	
 
void BasicTest::handleStreamEnd() {
 
	streamEnded = true;
 
}
 

	
 
void BasicTest::injectPresence(boost::shared_ptr<Swift::Presence> &response) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->onPresenceReceived(response);
 
}
 

	
 
void BasicTest::injectIQ(boost::shared_ptr<Swift::IQ> iq) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->onIQReceived(iq);
 
}
 

	
 
void BasicTest::injectMessage(boost::shared_ptr<Swift::Message> msg) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->onMessageReceived(msg);
 
}
 

	
 
Swift::Stanza *BasicTest::getStanza(boost::shared_ptr<Swift::Element> element) {
 
	Swift::Stanza *stanza = dynamic_cast<Swift::Stanza *>(element.get());
 
	CPPUNIT_ASSERT(stanza);
 
	return stanza;
 
}
 

	
 
void BasicTest::connectUser() {
 
	CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
	userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
	userRegistry->onPasswordValid(Swift::JID("user@localhost/resource"));
 
	loop->processEvents();
 
	CPPUNIT_ASSERT_EQUAL(1, userManager->getUserCount());
 

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

	
 
	UserInfo userInfo = user->getUserInfo();
 
	CPPUNIT_ASSERT_EQUAL(std::string("password"), userInfo.password);
 
	CPPUNIT_ASSERT(user->isReadyToConnect() == true);
 
	CPPUNIT_ASSERT(user->isConnected() == false);
 

	
 
	user->setConnected(true);
 
	CPPUNIT_ASSERT(user->isConnected() == true);
 

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

	
 
	received.clear();
 
	receivedData.clear();
 
}
 

	
 
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 *>(static_cast<XMPPFrontend *>(component->getFrontend())->getStanzaChannel())->addSession(serverFromClientSession2);
 

	
 
	userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource2"), serverFromClientSession2.get(), Swift::createSafeByteArray("password"));
tests/libtransport/basictest.h
Show inline comments
 
@@ -189,98 +189,100 @@ class TestingStorageBackend : public StorageBackend {
 
		}
 

	
 
		virtual void getBuddySetting(long userId, long buddyId, const std::string &variable, int &type, std::string &value) {}
 
		virtual void updateBuddySetting(long userId, long buddyId, const std::string &variable, int type, const std::string &value) {}
 

	
 
		virtual void getUserSetting(long userId, const std::string &variable, int &type, std::string &value) {
 
			if (settings[userId].find(variable) == settings[userId].end()) {
 
				settings[userId][variable] = value;
 
				return;
 
			}
 
			value = settings[userId][variable];
 
		}
 

	
 
		virtual void updateUserSetting(long userId, const std::string &variable, const std::string &value) {
 
			settings[userId][variable] = value;
 
		}
 

	
 
		void dumpUserSettings() {
 
			std::cout << "\n\nUserSettings dump:\n";
 
			for (std::map<int, std::map<std::string, std::string> >::const_iterator it = settings.begin(); it != settings.end(); it++) {
 
				for (std::map<std::string, std::string>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); it2++) {
 
					std::cout << it->first << ":" << it2->first << "=" << it2->second << "\n";
 
				}
 
			}
 
		}
 

	
 
		virtual void beginTransaction() {}
 
		virtual void commitTransaction() {}
 
};
 

	
 
class BasicTest : public Swift::XMPPParserClient {
 

	
 
	public:
 
		void setMeUp (void);
 

	
 
		void tearMeDown (void);
 

	
 
	void handleDataReceived(const Swift::SafeByteArray &data);
 
	void handleDataReceived2(const Swift::SafeByteArray &data);
 

	
 
	void handleStreamStart(const Swift::ProtocolHeader&);
 
#if HAVE_SWIFTEN_3
 
	void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
 
#else
 
	void handleElement(boost::shared_ptr<Swift::Element> element);
 
#endif
 
	void handleStreamEnd();
 

	
 
	void injectPresence(boost::shared_ptr<Swift::Presence> &response);
 
	void injectIQ(boost::shared_ptr<Swift::IQ> iq);
 
	void injectMessage(boost::shared_ptr<Swift::Message> msg);
 

	
 
	void dumpReceived();
 

	
 
	void addUser() {
 
		UserInfo user;
 
		user.id = 1;
 
		user.jid = "user@localhost";
 
		user.uin = "legacyname";
 
		user.password = "password";
 
		user.vip = 0;
 
		storage->setUser(user);
 
	}
 

	
 
	void connectUser();
 
	void connectSecondResource();
 
	void disconnectUser();
 
	void add2Buddies();
 

	
 
	Swift::Stanza *getStanza(boost::shared_ptr<Swift::Element> element);
 

	
 
	protected:
 
		bool streamEnded;
 
		UserManager *userManager;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession2;
 
		Swift::FullPayloadSerializerCollection* payloadSerializers;
 
		Swift::FullPayloadParserFactoryCollection* payloadParserFactories;
 
		Swift::XMPPParser *parser;
 
		Swift::XMPPParser *parser2;
 
		UserRegistry *userRegistry;
 
		Config *cfg;
 
		Swift::Server *server;
 
		Swift::DummyNetworkFactories *factories;
 
		Swift::DummyEventLoop *loop;
 
		TestingFactory *factory;
 
		Component *component;
 
		std::vector<boost::shared_ptr<Swift::Element> > received;
 
		std::vector<boost::shared_ptr<Swift::Element> > received2;
 
		std::string receivedData;
 
		std::string receivedData2;
 
		StorageBackend *storage;
 
		XMPPUserRegistration *userRegistration;
 
		DiscoItemsResponder *itemsResponder;
 
		bool stream1_active;
 
		Transport::XMPPFrontend *frontend;
 
		std::vector<Swift::PayloadParserFactory *> parserFactories;
 
		std::vector<Swift::PayloadSerializer *> _payloadSerializers;
 
};
 

	
tests/libtransport/conversationmanager.cpp
Show inline comments
 
@@ -50,192 +50,193 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
			m_conv = NULL;
 
			m_msg.reset();
 
			setMeUp();
 
			connectUser();
 
			add2Buddies();
 
			factory->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
			received.clear();
 
		}
 

	
 
		void tearDown (void) {
 
			received.clear();
 
			disconnectUser();
 
			factory->onMessageToSend.disconnect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
			tearMeDown();
 
		}
 

	
 
	void conversationSize() {
 
		std::cout << " = " << sizeof(Conversation) << " B";
 
	}
 

	
 
	void handleMessageReceived(TestingConversation *_conv, boost::shared_ptr<Swift::Message> &_msg) {
 
		m_conv = _conv;
 
		m_msg = _msg;
 
	}
 

	
 
	void handleChatstateMessages() {
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "buddy1");
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->addPayload(boost::make_shared<Swift::ChatState>(Swift::ChatState::Composing));
 

	
 
		// Forward it
 
		conv->handleMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0]))->getPayload<Swift::ChatState>());
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("buddy1@localhost/bot");
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT(m_msg->getPayload<Swift::ChatState>());
 

	
 
		received.clear();
 
	}
 

	
 
	void handleSubjectMessages() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setSubject("subject");
 
		msg->setType(Swift::Message::Groupchat);
 

	
 
		conv->handleMessage(msg);
 
		loop->processEvents();
 

	
 
		// No response, because presence with code 110 has not been sent yet and we must not send
 
		// subject before this one.
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 

	
 
		// this user presence - status code 110
 
		conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[1])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getSubject());
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("#room@localhost");
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("subject"), m_msg->getSubject());
 

	
 
		received.clear();
 
		delete conv;
 
	}
 

	
 
	void handleNormalMessages() {
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "buddy1@test");
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setBody("hi there<>!");
 

	
 
		// Forward it
 
		conv->handleMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there<>!"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy1\\40test@localhost/bot"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getFrom().toString());
 
		
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("buddy1\\40test@localhost/bot");
 
		msg->setBody("response<>!");
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("response<>!"), m_msg->getBody().get_value_or(""));
 

	
 
		// send another message from legacy network, should be sent to user@localhost/resource now
 
		boost::shared_ptr<Swift::Message> msg2(new Swift::Message());
 
		msg2->setBody("hi there!");
 

	
 
		// Forward it
 
		conv->handleMessage(msg2);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy1\\40test@localhost/bot"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getFrom().toString());
 
		
 
		received.clear();
 

	
 
		// disable jid_escaping
 
		std::istringstream ifs("service.server_mode = 1\nservice.jid_escaping=0\nservice.jid=localhost\nservice.more_resources=1\n");
 
		cfg->load(ifs);
 

	
 
		// and now to bare JID again...
 
		user->getConversationManager()->resetResources();
 
		conv->handleMessage(msg2);
 
		loop->processEvents();
 

	
 
		// enable jid_escaping again
 
		std::istringstream ifs2("service.server_mode = 1\nservice.jid_escaping=1\nservice.jid=localhost\nservice.more_resources=1\n");
 
		cfg->load(ifs2);
 
		
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy1%test@localhost/bot"), dynamic_cast<Swift::Message *>(getStanza(received[0]))->getFrom().toString());
 
		
 
		received.clear();
 
	}
 

	
 
	void handleNormalMessagesInitiatedFromXMPP() {
 
		User *user = userManager->getUser("user@localhost");
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("buddy1@localhost/bot");
 
		msg->setBody("hi there<>!");
 
		injectMessage(msg);
 

	
 
		// Forward it
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there<>!"), m_msg->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("BuddY1"), m_conv->getLegacyName());
 
		
 
		TestingConversation *conv = (TestingConversation *) user->getConversationManager()->getConversation("BuddY1");
 
		CPPUNIT_ASSERT(conv);
 
		CPPUNIT_ASSERT_EQUAL(std::string("BuddY1"), conv->getLegacyName());
 
	}
 

	
 
	void handleNormalMessagesHeadline() {
 
@@ -518,304 +519,312 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 

	
 
	void handleGroupchatMessagesTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource2");
 

	
 
		// reset resources should not touch this resource
 
		user->getConversationManager()->resetResources();
 

	
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setBody("hi there!");
 

	
 
		// Forward it
 
		conv->handleMessage(msg, "anotheruser");
 

	
 
		loop->processEvents();
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received2[0])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getFrom().toString());
 

	
 
		received.clear();
 

	
 
		// send response
 
		msg->setFrom("user@localhost/resource2");
 
		msg->setTo("#room@localhost");
 
		msg->setBody("response!");
 
		msg->setType(Swift::Message::Groupchat);
 
		injectMessage(msg);
 
		loop->processEvents();
 
		
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody().get_value_or(""));
 
	}
 

	
 
	void handleParticipantChanged() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 

	
 
		received.clear();
 

	
 
		// this user presence - status code 110
 
		conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/nickname"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Admin, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Moderator, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
		CPPUNIT_ASSERT_EQUAL(110, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 

	
 
		received.clear();
 

	
 
		// renamed - status code 303
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message", "hanzz");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Admin, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Moderator, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
		CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].nick);
 
		CPPUNIT_ASSERT_EQUAL(303, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 
		delete conv;
 
	}
 

	
 
	void handleParticipantChangedEscaped() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "19:70027094a9c84c518535a610766bed65@thread.skype", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("19\\3a70027094a9c84c518535a610766bed65%thread.skype@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
		delete conv;
 
	}
 

	
 
	void handleParticipantChangedEscaped2() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "19:70027094a9c84c518535a610766bed65@thread.skype", true);
 
		conv->setMUCEscaping(true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("19\\3a70027094a9c84c518535a610766bed65\\40thread.skype@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
		delete conv;
 
	}
 

	
 
	void handleParticipantChangedIconHash() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "19:70027094a9c84c518535a610766bed65@thread.skype", true);
 
		conv->setMUCEscaping(true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message", "", "hash");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("19\\3a70027094a9c84c518535a610766bed65\\40thread.skype@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 

	
 
		Swift::VCardUpdate::ref payload = getStanza(received[0])->getPayload<Swift::VCardUpdate>();
 
		CPPUNIT_ASSERT(payload);
 
		delete conv;
 
	}
 

	
 
	void handleParticipantChangedTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		conv->addJID("user@localhost/resource2");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received2[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
		delete conv;
 
	}
 

	
 
	void handlePMFromXMPP() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		user->getConversationManager()->addConversation(conv);
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->setJID("user@localhost/resource");
 

	
 
		conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		received.clear();
 
		boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
		msg->setBody("hi there!");
 
		msg->setFrom("user@localhost/resource");
 
		msg->setTo("#room@localhost/anotheruser");
 
		msg->setBody("hi there!");
 
		injectMessage(msg);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
		CPPUNIT_ASSERT(m_msg);
 
		CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), m_msg->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room/anotheruser"), m_conv->getLegacyName());
 

	
 
		Conversation *pmconv = user->getConversationManager()->getConversation("#room/anotheruser");
 

	
 
		boost::shared_ptr<Swift::Message> msg2(new Swift::Message());
 
		msg2->setBody("response!");
 

	
 
		pmconv->handleMessage(msg2);
 
	}
 

	
 
	void handleGroupchatRemoved() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		received.clear();
 
		conv->destroyRoom();
 
		delete conv;
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::None, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getShow());
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/nickname"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT_EQUAL(332, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 
	}
 

	
 
	void handleNicknameConflict() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_CONFLICT, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::ErrorPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::Conflict, getStanza(received[0])->getPayload<Swift::ErrorPayload>()->getCondition());
 
		delete conv;
 
	}
 

	
 
	void handleNotAuthorized() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 

	
 
		// normal presence
 
		conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_NOT_AUTHORIZED, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::ErrorPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::NotAuthorized, getStanza(received[0])->getPayload<Swift::ErrorPayload>()->getCondition());
 
		delete conv;
 
	}
 

	
 
	void handleSetNickname() {
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
 
		conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
 
		conv->setNickname("nickname");
 
		conv->addJID("user@localhost/resource");
 
		loop->processEvents();
 

	
 
		conv->setNickname("nickname2");
 
		conv->handleParticipantChanged("nickname2", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
		CPPUNIT_ASSERT_EQUAL(110, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
 
		CPPUNIT_ASSERT_EQUAL(210, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[1].code);
 
		delete conv;
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (ConversationManagerTest);
tests/libtransport/main.cpp
Show inline comments
 
#include "main.h"
 
#include <cppunit/CompilerOutputter.h>
 
#include <cppunit/extensions/TestFactoryRegistry.h>
 
#include <cppunit/TestResult.h>
 
#include <cppunit/TestResultCollector.h>
 
#include <cppunit/TestRunner.h>
 
#include <cppunit/BriefTestProgressListener.h>
 
#ifdef WITH_LOG4CXX
 
#include "log4cxx/logger.h"
 
#include "log4cxx/fileappender.h"
 
#include "log4cxx/patternlayout.h"
 
#include "log4cxx/propertyconfigurator.h"
 

	
 
#include "transport/protocol.pb.h"
 

	
 
using namespace log4cxx;
 
#endif
 

	
 

	
 
int main (int argc, char* argv[])
 
{
 
#ifdef WITH_LOG4CXX
 
	LoggerPtr root = Logger::getRootLogger();
 
#ifndef _MSC_VER
 
	root->addAppender(new FileAppender(new PatternLayout("%d %-5p %c: %m%n"), "libtransport_test.log", false));
 
#else
 
	root->addAppender(new FileAppender(new PatternLayout(L"%d %-5p %c: %m%n"), L"libtransport_test.log", false));
 
#endif
 
#endif
 

	
 
	std::vector<std::string> testsToRun;
 
	for (int i = 1; i < argc; ++i) {
 
		std::string param(argv[i]);
 
		testsToRun.push_back(param);
 
	}
 

	
 
	if (testsToRun.empty()) {
 
		testsToRun.push_back("");
 
	}
 

	
 
	// informs test-listener about testresults
 
	CPPUNIT_NS :: TestResult testresult;
 

	
 
	// register listener for collecting the test-results
 
	CPPUNIT_NS :: TestResultCollector collectedresults;
 
	testresult.addListener (&collectedresults);
 

	
 
	// register listener for per-test progress output
 
	CPPUNIT_NS :: BriefTestProgressListener progress;
 
	testresult.addListener (&progress);
 

	
 
	// insert test-suite at test-runner by registry
 
	CPPUNIT_NS :: TestRunner testrunner;
 
	testrunner.addTest (CPPUNIT_NS :: TestFactoryRegistry :: getRegistry ().makeTest ());
 
	for (std::vector<std::string>::const_iterator i = testsToRun.begin(); i != testsToRun.end(); ++i) {
 
		try {
 
			testrunner.run(testresult, *i);
 
		}
 
		catch (const std::exception& e) {
 
			google::protobuf::ShutdownProtobufLibrary();
 
			std::cerr << "Error: " << e.what() << std::endl;
 
			return -1;
 
		}
 
	}
 

	
 
	// output results in compiler-format
 
	CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr);
 
	compileroutputter.write ();
 

	
 
	google::protobuf::ShutdownProtobufLibrary();
 

	
 
	// return 0 if tests were successful
 
	return collectedresults.wasSuccessful () ? 0 : 1;
 
}
tests/libtransport/usermanager.cpp
Show inline comments
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include <Swiften/Swiften.h>
 
#include <Swiften/EventLoop/DummyEventLoop.h>
 
#include <Swiften/Server/Server.h>
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyConnectionServer.h>
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 
#include "basictest.h"
 

	
 
using namespace Transport;
 

	
 
#if !HAVE_SWIFTEN_3
 
#define get_value_or(X) substr()
 
#endif
 

	
 
class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(UserManagerTest);
 
	CPPUNIT_TEST(connectUser);
 
// 	CPPUNIT_TEST(connectUser); // executed as part of other tests
 
	CPPUNIT_TEST(connectTwoResources);
 
	CPPUNIT_TEST(connectUserTransportDisabled);
 
	CPPUNIT_TEST(connectUserRegistrationNeeded);
 
	CPPUNIT_TEST(connectUserRegistrationNeededRegistered);
 
	CPPUNIT_TEST(connectUserVipOnlyNonVip);
 
	CPPUNIT_TEST(handleProbePresence);
 
	CPPUNIT_TEST(disconnectUser);
 
	CPPUNIT_TEST(disconnectUserBouncer);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		Swift::Presence::ref changedPresence;
 

	
 
		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 connectUserVipOnlyNonVip() {
 
		addUser();
 
		std::istringstream ifs("service.server_mode = 1\nservice.jid_escaping=0\nservice.jid=localhost\nservice.vip_only=1\nservice.vip_message=Ahoj\n");
 
		cfg->load(ifs);
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(3, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[1])));
 
		CPPUNIT_ASSERT_EQUAL(std::string("Ahoj"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getBody().get_value_or(""));
 
		CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getTo().toString());
 
		CPPUNIT_ASSERT_EQUAL(std::string("localhost"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getFrom().toString());
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		CPPUNIT_ASSERT(streamEnded);
 
		std::istringstream ifs2("service.server_mode = 1\nservice.jid_escaping=1\nservice.jid=localhost\nservice.more_resources=1\n");
 
		cfg->load(ifs2);
 
	}
 

	
 
	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 *>(static_cast<XMPPFrontend *>(component->getFrontend())->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());
 

	
tests/libtransport/userregistry.cpp
Show inline comments
 
#include <cppunit/TestFixture.h>
 
#include <cppunit/extensions/HelperMacros.h>
 
#include <Swiften/EventLoop/DummyEventLoop.h>
 
#include <Swiften/Server/Server.h>
 
#include <Swiften/Network/DummyNetworkFactories.h>
 
#include <Swiften/Network/DummyConnectionServer.h>
 
#include <Swiften/Network/ConnectionFactory.h>
 
#include <Swiften/Network/DummyTimerFactory.h>
 
#include "basictest.h"
 

	
 
using namespace Transport;
 

	
 
class UserRegistryTest : public CPPUNIT_NS :: TestFixture {
 
	CPPUNIT_TEST_SUITE(UserRegistryTest);
 
	CPPUNIT_TEST(login);
 
	CPPUNIT_TEST(loginInvalidPassword);
 
	CPPUNIT_TEST(loginTwoClientsValidPasswords);
 
	CPPUNIT_TEST(loginTwoClientsDifferentPasswords);
 
	CPPUNIT_TEST(loginDisconnect);
 
	CPPUNIT_TEST(removeLater);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		void setUp (void) {
 
			state1 = Init;
 
			state2 = Init;
 
			std::istringstream ifs;
 
			cfg = new Config();
 
			cfg->load(ifs);
 

	
 
			loop = new Swift::DummyEventLoop();
 
			factories = new Swift::DummyNetworkFactories(loop);
 

	
 
			userRegistry = new UserRegistry(cfg, factories);
 
			userRegistry->onConnectUser.connect(bind(&UserRegistryTest::handleConnectUser, this, _1));
 
			userRegistry->onDisconnectUser.connect(bind(&UserRegistryTest::handleDisconnectUser, this, _1));
 

	
 
			server = new Swift::Server(loop, factories, userRegistry, "localhost", "0.0.0.0", 5222);
 
			server->start();
 
			connectionServer = server->getConnectionServer();
 

	
 
			client1 = factories->getConnectionFactory()->createConnection();
 
			dynamic_cast<Swift::DummyConnectionServer *>(connectionServer.get())->acceptConnection(client1);
 

	
 
			dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.connect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client1));
 

	
 
			client2 = factories->getConnectionFactory()->createConnection();
 
			dynamic_cast<Swift::DummyConnectionServer *>(connectionServer.get())->acceptConnection(client2);
 

	
 
			dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.connect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client2));
 

	
 
			loop->processEvents();
 
		}
 

	
 
		void tearDown (void) {
 
			delete server;
 
			dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client1));
 
			dynamic_cast<Swift::DummyConnection *>(client1.get())->onDataSent.disconnect_all_slots();
 
			client1.reset();
 
			dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.disconnect(boost::bind(&UserRegistryTest::handleDataReceived, this, _1, client2));
 
			dynamic_cast<Swift::DummyConnection *>(client2.get())->onDataSent.disconnect_all_slots();
 
			client2.reset();
 
			connectionServer.reset();
 
			delete userRegistry;
 
			delete factories;
 
			delete loop;
 
			delete cfg;
 
			received1.clear();
 
			received2.clear();
 
		}
 

	
 
		void send(boost::shared_ptr<Swift::Connection> conn, const std::string &data) {
 
			dynamic_cast<Swift::DummyConnection *>(conn.get())->receive(Swift::createSafeByteArray(data));
 
			loop->processEvents();
 
		}
 

	
 
		void sendCredentials(boost::shared_ptr<Swift::Connection> conn, const std::string &username, const std::string &password, const std::string &b64) {
 
			std::vector<std::string> &received = conn == client1 ? received1 : received2;
 
			send(conn, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
			CPPUNIT_ASSERT(received[0].find("<?xml version=\"1.0\"?>") == 0);
 
			CPPUNIT_ASSERT(received[1].find("PLAIN") != std::string::npos);
 
			received.clear();
 

	
 
			// username:test
 
			send(conn, "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>" + b64 + "</auth>");
 
			if (conn == client1)
 
				CPPUNIT_ASSERT_EQUAL(Connecting, state1);
 
// 			else
 
// 				CPPUNIT_ASSERT_EQUAL(Connecting, state2);
 
			CPPUNIT_ASSERT_EQUAL(password, userRegistry->getUserPassword(username));
 
			CPPUNIT_ASSERT_EQUAL(std::string(""), userRegistry->getUserPassword("unknown@localhost"));
 
		}
 

	
 
		void bindSession(boost::shared_ptr<Swift::Connection> conn) {
 
			std::vector<std::string> &received = conn == client1 ? received1 : received2;
 

	
 
			send(conn, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
			CPPUNIT_ASSERT(received[0].find("<?xml version=\"1.0\"?>") == 0);
 
			CPPUNIT_ASSERT(received[1].find("urn:ietf:params:xml:ns:xmpp-bind") != std::string::npos);
 
			CPPUNIT_ASSERT(received[1].find("urn:ietf:params:xml:ns:xmpp-session") != std::string::npos);
 
			
 
		}
 

	
 
		void handleDataReceived(const Swift::SafeByteArray &data, boost::shared_ptr<Swift::Connection> conn) {
 
			if (conn == client1) {
 
				received1.push_back(safeByteArrayToString(data));
 
// 				std::cout << received1.back() << "\n";
 
			}
 
			else {
 
				received2.push_back(safeByteArrayToString(data));
 
// 				std::cout << received2.back() << "\n";
 
			}
 
		}
 

	
 
		void handleConnectUser(const Swift::JID &user) {
 
			state1 = Connecting;
 
		}
 

	
 
		void handleDisconnectUser(const Swift::JID &user) {
 
			state1 = Disconnected;
 
		}
 

	
 
		void login() {
 
			sendCredentials(client1, "username@localhost", "test", "AHVzZXJuYW1lAHRlc3Q=");
 

	
 
			userRegistry->onPasswordValid("username@localhost");
 
			loop->processEvents();
 
			CPPUNIT_ASSERT_EQUAL(std::string(""), userRegistry->getUserPassword("username@localhost"));
 
			CPPUNIT_ASSERT_EQUAL(1, (int) received1.size());
 
			CPPUNIT_ASSERT_EQUAL(std::string("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"></success>"), received1[0]);
 
			received1.clear();
 

	
 
			bindSession(client1);
 
			
 
		}
 

	
 
		void loginInvalidPassword() {
 
			sendCredentials(client1, "username@localhost", "test", "AHVzZXJuYW1lAHRlc3Q=");
 

	
 
			userRegistry->onPasswordInvalid("username@localhost");
 
			loop->processEvents();
 
			CPPUNIT_ASSERT_EQUAL(std::string(""), userRegistry->getUserPassword("username@localhost"));
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received1.size());
 
			CPPUNIT_ASSERT_EQUAL(std::string("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"/>"), received1[0]);
 
			CPPUNIT_ASSERT_EQUAL(std::string("</stream:stream>"), received1[1]);
 
		}
 

	
 
		void loginTwoClientsValidPasswords() {
 
			sendCredentials(client1, "username@localhost", "test", "AHVzZXJuYW1lAHRlc3Q=");
 
			sendCredentials(client2, "username@localhost", "test", "AHVzZXJuYW1lAHRlc3Q=");
 
			CPPUNIT_ASSERT_EQUAL(2, (int) received1.size());
 
			CPPUNIT_ASSERT_EQUAL(0, (int) received2.size());
 
			CPPUNIT_ASSERT_EQUAL(std::string("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"/>"), received1[0]);
 
			CPPUNIT_ASSERT_EQUAL(std::string("</stream:stream>"), received1[1]);
 

	
0 comments (0 inline, 0 general)