Changeset - bfb1488c950d
CMakeLists.txt
Show inline comments
 
@@ -54,7 +54,7 @@ find_package(event)
 
find_package(Doxygen)
 

	
 
INCLUDE(FindQt4)
 
FIND_PACKAGE(Qt4 COMPONENTS QtCore)
 
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtNetwork REQUIRED)
 

	
 
# ADD_DEFINITIONS(${SWIFTEN_CFLAGS})
 
ADD_DEFINITIONS(-DSUPPORT_LEGACY_CAPS)
 
@@ -104,6 +104,7 @@ if (PROTOBUF_FOUND)
 
	if(IRC_FOUND)
 
		ADD_DEFINITIONS(-DIRC_SHARED)
 
		message("IRC plugin        : yes")
 
		include_directories(${QT_QTNETWORK_INCLUDE_DIR})
 
		include_directories(${IRC_INCLUDE_DIR})
 
		include(${QT_USE_FILE})
 
	else()
backends/libircclient-qt/ircnetworkplugin.cpp
Show inline comments
 
new file 100644
 
#include "ircnetworkplugin.h"
 

	
 
IRCNetworkPlugin::IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) {
 
	this->config = config;
 
	m_socket = new QTcpSocket();
 
	m_socket->connectToHost(QString::fromStdString(host), port);
 
	connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData()));
 
}
 

	
 
void IRCNetworkPlugin::readData() {
 
	size_t availableBytes = m_socket->bytesAvailable();
 
	if (availableBytes == 0)
 
		return;
 

	
 
	std::cout << "READ\n";
 
	std::string d = std::string(m_socket->readAll().data(), availableBytes);
 
	handleDataRead(d);
 
}
 

	
 
void IRCNetworkPlugin::sendData(const std::string &string) {
 
	m_socket->write(string.c_str(), string.size());
 
}
 

	
 
void IRCNetworkPlugin::handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
	// Server is in server-mode, so user is JID of server when we want to connect
 
	if (CONFIG_BOOL(config, "service.server_mode")) {
 
		MyIrcSession *session = new MyIrcSession(user, this);
 
		std::string h = user.substr(0, user.find("@"));
 
		session->setNick(QString::fromStdString(h.substr(0, h.find("%"))));
 
		session->connectToServer(QString::fromStdString(h.substr(h.find("%") + 1)), 6667);
 
		std::cout << "CONNECTING IRC NETWORK " << h.substr(h.find("%") + 1) << "\n";
 
		m_sessions[user] = session;
 
	}
 
	else {
 
		handleConnected(user);
 
	}
 
}
 

	
 
void IRCNetworkPlugin::handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
	if (m_sessions[user] == NULL)
 
		return;
 
	m_sessions[user]->disconnectFromServer();
 
	m_sessions[user]->deleteLater();
 
	m_sessions.erase(user);
 
}
 

	
 
void IRCNetworkPlugin::handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
 
	std::string u = user;
 
	std::cout << "AAAAA " << legacyName << "\n";
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		u = user + legacyName.substr(legacyName.find("@") + 1);
 
		if (u.find("/") != std::string::npos) {
 
			u = u.substr(0, u.find("/"));
 
		}
 
	}
 
	if (m_sessions[u] == NULL) {
 
		std::cout << "No session for " << u << "\n";
 
		return;
 
	}
 

	
 
	std::string r = legacyName;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		if (legacyName.find("/") == std::string::npos) {
 
			r = legacyName.substr(0, r.find("@"));
 
		}
 
		else {
 
			r = legacyName.substr(legacyName.find("/") + 1);
 
		}
 
	}
 
	std::cout << "MESSAGE " << u << " " << r << "\n";
 
	m_sessions[u]->message(QString::fromStdString(r), QString::fromStdString(message));
 
	std::cout << "SENT\n";
 
}
 

	
 
void IRCNetworkPlugin::handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
	std::cout << "JOIN\n";
 
	std::string r = room;
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		u = user + room.substr(room.find("@") + 1);
 
		r = room.substr(0, room.find("@"));
 
	}
 
	if (m_sessions[u] == NULL) {
 
		// in gateway mode we want to login this user to network according to legacyName
 
		if (room.find("@") != std::string::npos) {
 
			// suffix is %irc.freenode.net to let MyIrcSession return #room%irc.freenode.net
 
			MyIrcSession *session = new MyIrcSession(user, this, room.substr(room.find("@")));
 
			session->setNick(QString::fromStdString(nickname));
 
			session->connectToServer(QString::fromStdString(room.substr(room.find("@") + 1)), 6667);
 
			std::cout << "CONNECTING IRC NETWORK " << room.substr(room.find("@") + 1) << "\n";
 
			std::cout << "SUFFIX " << room.substr(room.find("@")) << "\n";
 
			m_sessions[u] = session;
 
		}
 
		else {
 
			return;
 
		}
 
	}
 
	std::cout << "JOINING " << r << "\n";
 
	m_sessions[u]->addAutoJoinChannel(QString::fromStdString(r));
 
	m_sessions[u]->join(QString::fromStdString(r), QString::fromStdString(password));
 
	m_sessions[u]->rooms += 1;
 
	// update nickname, because we have nickname per session, no nickname per room.
 
	handleRoomNicknameChanged(user, r, m_sessions[u]->nick().toStdString());
 
}
 

	
 
void IRCNetworkPlugin::handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
	std::string r = room;
 
	std::string u = user;
 
	if (!CONFIG_BOOL(config, "service.server_mode")) {
 
		r = room.substr(0, room.find("@"));
 
		u = user + room.substr(room.find("@") + 1);
 
	}
 

	
 
	if (m_sessions[u] == NULL)
 
		return;
 

	
 
	m_sessions[u]->part(QString::fromStdString(r));
 
	m_sessions[u]->removeAutoJoinChannel(QString::fromStdString(r));
 
	m_sessions[u]->rooms -= 1;
 

	
 
	if (m_sessions[u]->rooms <= 0) {
 
		m_sessions[u]->disconnectFromServer();
 
		m_sessions[u]->deleteLater();
 
		m_sessions.erase(u);
 
	}
 
}
backends/libircclient-qt/ircnetworkplugin.h
Show inline comments
 
new file 100644
 

	
 
#pragma once
 

	
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "session.h"
 
#include <QtCore>
 
#include <QtNetwork>
 
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
 
#include "ircnetworkplugin.h"
 

	
 

	
 
class IRCNetworkPlugin : public QObject, public NetworkPlugin {
 
	Q_OBJECT
 

	
 
	public:
 
		IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port);
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName);
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/);
 

	
 
		void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password);
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room);
 

	
 
		std::map<std::string, MyIrcSession *> m_sessions;
 

	
 
	public slots:
 
		void readData();
 
		void sendData(const std::string &string);
 

	
 
	private:
 
		Config *config;
 
		QTcpSocket *m_socket;
 
};
 
\ No newline at end of file
backends/libircclient-qt/main.cpp
Show inline comments
 
@@ -12,67 +12,15 @@
 
#include "transport/networkplugin.h"
 
#include "session.h"
 
#include <QtCore>
 
#include <QtNetwork>
 
#include "Swiften/EventLoop/Qt/QtEventLoop.h"
 
#include "ircnetworkplugin.h"
 

	
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
class IRCNetworkPlugin;
 
IRCNetworkPlugin * np = NULL;
 

	
 
class IRCNetworkPlugin : public NetworkPlugin {
 
	public:
 
		IRCNetworkPlugin(Config *config, Swift::QtEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
 
			this->config = config;
 
		}
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			MyIrcSession *session = new MyIrcSession(user, this);
 
			session->setNick(QString::fromStdString(user.substr(0, user.find("@"))));
 
			session->connectToServer(QString::fromStdString(user.substr(user.find("@") + 1)), 6667);
 
// 			std::cout << "CONNECTING IRC NETWORK " << jid.getNode() << " " << jid.getDomain() << "\n";
 
			m_sessions[user] = session;
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			if (m_sessions[user] == NULL)
 
				return;
 
			m_sessions[user]->disconnectFromServer();
 
			m_sessions[user]->deleteLater();
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
 
			std::cout << "MESSAGE " << user << " " << legacyName << "\n";
 
			if (m_sessions[user] == NULL)
 
				return;
 
			m_sessions[user]->message(QString::fromStdString(legacyName), QString::fromStdString(message));
 
			std::cout << "SENT\n";
 
		}
 

	
 
		void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
			std::cout << "JOIN\n";
 
			if (m_sessions[user] == NULL)
 
				return;
 
			m_sessions[user]->addAutoJoinChannel(QString::fromStdString(room));
 
			m_sessions[user]->join(QString::fromStdString(room), QString::fromStdString(password));
 
			// update nickname, because we have nickname per session, no nickname per room.
 
			handleRoomNicknameChanged(user, room, m_sessions[user]->nick().toStdString());
 
		}
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
			std::cout << "PART\n";
 
			if (m_sessions[user] == NULL)
 
				return;
 
			m_sessions[user]->part(QString::fromStdString(room));
 
			m_sessions[user]->removeAutoJoinChannel(QString::fromStdString(room));
 
		}
 

	
 
		std::map<std::string, MyIrcSession *> m_sessions;
 

	
 
	private:
 
		Config *config;
 
};
 

	
 
int main (int argc, char* argv[]) {
 
	std::string host;
 
	int port;
backends/libircclient-qt/session.cpp
Show inline comments
 
@@ -13,10 +13,12 @@
 
#include <iostream>
 
#include "Swiften/Elements/StatusShow.h"
 

	
 
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, QObject* parent) : Irc::Session(parent)
 
MyIrcSession::MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix, QObject* parent) : Irc::Session(parent)
 
{
 
	this->np = np;
 
	this->user = user;
 
	this->suffix = suffix;
 
	rooms = 0;
 
	connect(this, SIGNAL(disconnected()), SLOT(on_disconnected()));
 
}
 

	
 
@@ -26,8 +28,9 @@ void MyIrcSession::on_connected(){
 

	
 
void MyIrcSession::on_disconnected()
 
{
 
    std::cout << "disconnected:\n";
 
    np->handleDisconnected(user, 0, "");
 
	std::cout << "disconnected:\n";
 
	if (suffix.empty())
 
		np->handleDisconnected(user, 0, "");
 
}
 

	
 
void MyIrcSession::on_bufferAdded(Irc::Buffer* buffer)
 
@@ -42,14 +45,15 @@ void MyIrcSession::on_bufferRemoved(Irc::Buffer* buffer)
 

	
 
Irc::Buffer* MyIrcSession::createBuffer(const QString& receiver)
 
{
 
    return new MyIrcBuffer(receiver, user, np, this);
 
	return new MyIrcBuffer(receiver, user, np, suffix, this);
 
}
 

	
 
MyIrcBuffer::MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, Irc::Session* parent)
 
MyIrcBuffer::MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent)
 
    : Irc::Buffer(receiver, parent)
 
{
 
	this->np = np;
 
	this->user = user;
 
		this->suffix = suffix;
 
	p = (MyIrcSession *) parent;
 
    connect(this, SIGNAL(receiverChanged(QString)), SLOT(on_receiverChanged(QString)));
 
    connect(this, SIGNAL(joined(QString)), SLOT(on_joined(QString)));
 
@@ -94,7 +98,7 @@ void MyIrcBuffer::on_joined(const QString& origin) {
 
	bool flags = 0;
 
	std::string nickname = origin.toStdString();
 
	flags = correctNickname(nickname);
 
	np->handleParticipantChanged(user, origin.toStdString(), receiver().toStdString(), (int) flags, pbnetwork::STATUS_ONLINE);
 
	np->handleParticipantChanged(user, origin.toStdString(), receiver().toStdString() + suffix, (int) flags, pbnetwork::STATUS_ONLINE);
 
}
 

	
 
void MyIrcBuffer::on_parted(const QString& origin, const QString& message) {
 
@@ -102,7 +106,7 @@ void MyIrcBuffer::on_parted(const QString& origin, const QString& message) {
 
	bool flags = 0;
 
	std::string nickname = origin.toStdString();
 
	flags = correctNickname(nickname);
 
	np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_NONE, message.toStdString());
 
		np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_NONE, message.toStdString());
 
}
 

	
 
void MyIrcBuffer::on_quit(const QString& origin, const QString& message)
 
@@ -116,7 +120,7 @@ void MyIrcBuffer::on_nickChanged(const QString& origin, const QString& nick) {
 
	std::string nickname = origin.toStdString();
 
	bool flags = p->m_modes[receiver().toStdString() + nickname];
 
// 	std::cout << receiver().toStdString() + nickname << " " << flags <<  "\n";
 
	np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_ONLINE, "", nick.toStdString());
 
		np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "", nick.toStdString());
 
}
 

	
 
void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, const QString& args) {
 
@@ -132,13 +136,13 @@ void MyIrcBuffer::on_modeChanged(const QString& origin, const QString& mode, con
 
		p->m_modes[receiver().toStdString() + nickname] = 0;
 
	}
 
	bool flags = p->m_modes[receiver().toStdString() + nickname];
 
	np->handleParticipantChanged(user, nickname, receiver().toStdString(),(int) flags, pbnetwork::STATUS_ONLINE, "");
 
		np->handleParticipantChanged(user, nickname, receiver().toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE, "");
 
}
 

	
 
void MyIrcBuffer::on_topicChanged(const QString& origin, const QString& topic) {
 
	//topic changed: "#testik" "HanzZ" "test"
 
	qDebug() << "topic changed:" << receiver() << origin << topic;
 
	np->handleSubject(user, receiver().toStdString(), topic.toStdString(), origin.toStdString());
 
		np->handleSubject(user, receiver().toStdString() + suffix, topic.toStdString(), origin.toStdString());
 
}
 

	
 
void MyIrcBuffer::on_invited(const QString& origin, const QString& receiver, const QString& channel)
 
@@ -155,7 +159,17 @@ void MyIrcBuffer::on_messageReceived(const QString& origin, const QString& messa
 
	qDebug() << "message received:" << receiver() << origin << message << (flags & Irc::Buffer::IdentifiedFlag ? "(identified!)" : "(not identified)");
 
	if (!receiver().startsWith("#") && (flags & Irc::Buffer::EchoFlag))
 
		return;
 
	np->handleMessage(user, receiver().toStdString(), message.toStdString(), origin.toStdString());
 
	std::string r = receiver().toStdString();
 
//	if (!suffix.empty()) {
 
//		r = receiver().replace('@', '%').toStdString();
 
//	}
 

	
 
	if (r.find("#") == 0) {
 
		np->handleMessage(user, r + suffix, message.toStdString(), origin.toStdString());
 
	}
 
	else {
 
		np->handleMessage(user, r + suffix, message.toStdString());
 
	}
 
}
 

	
 
void MyIrcBuffer::on_noticeReceived(const QString& origin, const QString& notice, Irc::Buffer::MessageFlags flags)
 
@@ -186,13 +200,14 @@ void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, co
 
{
 
	switch (code) {
 
		case 251:
 
			np->handleConnected(user);
 
			if (suffix.empty())
 
				np->handleConnected(user);
 
			break;
 
		case 332:
 
			m_topicData = params.value(2).toStdString();
 
			break;
 
		case 333:
 
			np->handleSubject(user, params.value(1).toStdString(), m_topicData, params.value(2).toStdString());
 
			 np->handleSubject(user, params.value(1).toStdString() + suffix, m_topicData, params.value(2).toStdString());
 
			break;
 
		case 353:
 
			QString channel = params.value(2);
 
@@ -203,12 +218,12 @@ void MyIrcBuffer::on_numericMessageReceived(const QString& origin, uint code, co
 
				std::string nickname = members.at(i).toStdString();
 
				flags = correctNickname(nickname);
 
				p->m_modes[channel.toStdString() + nickname] = flags;
 
// 				std::cout << channel.toStdString() + nickname << " " << flags << "\n";
 
				np->handleParticipantChanged(user, nickname, channel.toStdString(),(int) flags, pbnetwork::STATUS_ONLINE);
 
				std::cout << channel.toStdString() + suffix << " " << flags << "\n";
 
				np->handleParticipantChanged(user, nickname, channel.toStdString() + suffix,(int) flags, pbnetwork::STATUS_ONLINE);
 
			}
 
			break;
 
	}
 
    qDebug() << "numeric message received:" << receiver() << origin << code << params;
 
	qDebug() << "numeric message received:" << receiver() << origin << code << params;
 
}
 

	
 
void MyIrcBuffer::on_unknownMessageReceived(const QString& origin, const QStringList& params)
backends/libircclient-qt/session.h
Show inline comments
 
@@ -22,8 +22,10 @@ class MyIrcSession : public Irc::Session
 
    Q_OBJECT
 

	
 
public:
 
    MyIrcSession(const std::string &user, NetworkPlugin *np, QObject* parent = 0);
 
	MyIrcSession(const std::string &user, NetworkPlugin *np, const std::string &suffix = "", QObject* parent = 0);
 
	std::map<std::string, bool> m_modes;
 
	std::string suffix;
 
	int rooms;
 

	
 
protected Q_SLOTS:
 
    void on_connected();
 
@@ -35,6 +37,7 @@ protected Q_SLOTS:
 
protected:
 
	NetworkPlugin *np;
 
	std::string user;
 

	
 
    virtual Irc::Buffer* createBuffer(const QString& receiver);
 
};
 

	
 
@@ -43,11 +46,12 @@ class MyIrcBuffer : public Irc::Buffer
 
    Q_OBJECT
 

	
 
public:
 
    MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, Irc::Session* parent);
 
	MyIrcBuffer(const QString& receiver, const std::string &user, NetworkPlugin *np, const std::string &suffix, Irc::Session* parent);
 
	NetworkPlugin *np;
 
	std::string user;
 
	MyIrcSession *p;
 
	std::string m_topicData;
 
		std::string suffix;
 

	
 
protected Q_SLOTS:
 
    void on_receiverChanged(const QString& receiver);
backends/libpurple/main.cpp
Show inline comments
 
@@ -45,6 +45,7 @@ using namespace log4cxx;
 
static LoggerPtr logger_libpurple = log4cxx::Logger::getLogger("libpurple");
 
static LoggerPtr logger = log4cxx::Logger::getLogger("backend");
 
int m_sock;
 
static int writeInput;
 

	
 
using namespace Transport;
 

	
 
@@ -61,6 +62,8 @@ template <class T> std::string stringOf(T object) {
 
	return (os.str());
 
}
 

	
 
static void transportDataReceived(gpointer data, gint source, PurpleInputCondition cond);
 

	
 
class SpectrumNetworkPlugin;
 

	
 
GKeyFile *keyfile;
 
@@ -73,6 +76,13 @@ static std::string KEYFILE_STRING(const std::string &cat, const std::string &key
 
	}
 
	std::string ret(str);
 
	free(str);
 

	
 
	if (ret.find("#") != std::string::npos) {
 
		ret = ret.substr(0, ret.find("#"));
 
		while(*(ret.end() - 1) == ' ') {
 
			ret.erase(ret.end() - 1);
 
		}
 
	}
 
	return ret;
 
}
 

	
 
@@ -907,6 +917,8 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 

	
 
		void sendData(const std::string &string) {
 
			write(m_sock, string.c_str(), string.size());
 
			if (writeInput == 0)
 
				writeInput = purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
 
		}
 

	
 
		void readyForData() {
 
@@ -1750,6 +1762,10 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
 
		np->handleDataRead(d);
 
	}
 
	else {
 
		if (writeInput != 0) {
 
			purple_input_remove(writeInput);
 
			writeInput = 0;
 
		}
 
		np->readyForData();
 
	}
 
}
 
@@ -1852,7 +1868,6 @@ int main(int argc, char **argv) {
 
		m_sock = create_socket(host, port);
 

	
 
		purple_input_add(m_sock, PURPLE_INPUT_READ, &transportDataReceived, NULL);
 
// 		purple_input_add(m_sock, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
 

	
 
		np = new SpectrumNetworkPlugin(host, port);
 
		bool libev = KEYFILE_STRING("service", "eventloop") == "libev";
cmake_modules/FindPackageHandleStandardArgs.cmake
Show inline comments
 
deleted file
cmake_modules/opensslConfig.cmake
Show inline comments
 
@@ -229,7 +229,7 @@
 
      set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_PATCH}")
 
    endif (OPENSSL_INCLUDE_DIR)
 
     
 
    include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 
    include(FindPackageHandleStandardArgs)
 
     
 
    if (OPENSSL_VERSION)
 
      find_package_handle_standard_args(OpenSSL
include/Swiften/Server/ServerStanzaChannel.cpp
Show inline comments
 
@@ -73,7 +73,7 @@ void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element
 
		}
 

	
 
		(*i)->finishSession();
 
		std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
 
// 		std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
 
		if (last) {
 
			break;
 
		}
include/transport/conversation.h
Show inline comments
 
@@ -97,9 +97,7 @@ class Conversation {
 

	
 
		/// This is used to detect Private messages associated with particular room.
 
		/// \param room room name associated with this Conversation.
 
		void setRoom(const std::string &room) {
 
			m_room = room;
 
		}
 
		void setRoom(const std::string &room);
 

	
 
		/// Returns room name associated with this Conversation.
 

	
include/transport/localbuddy.h
Show inline comments
 
@@ -63,6 +63,7 @@ class LocalBuddy : public Buddy {
 
		std::string m_statusMessage;
 
		std::string m_iconHash;
 
		Swift::StatusShow m_status;
 
		bool m_firstSet;
 
};
 

	
 
}
include/transport/mysqlbackend.h
Show inline comments
 
@@ -48,6 +48,7 @@ class MySQLBackend : public StorageBackend
 
		/// automatically.
 
		/// \return true if database is opened successfully.
 
		bool connect();
 
		void disconnect();
 

	
 
		/// Creates database structure.
 
		/// \see connect()
 
@@ -100,7 +101,7 @@ class MySQLBackend : public StorageBackend
 
				Statement(MYSQL *conn, const std::string &format, const std::string &statement);
 
				~Statement();
 

	
 
				bool execute();
 
				int execute();
 

	
 
				int fetch();
 

	
include/transport/networkplugin.h
Show inline comments
 
@@ -217,7 +217,6 @@ class NetworkPlugin {
 
		
 

	
 
	private:
 
		void connect();
 
		void handleLoginPayload(const std::string &payload);
 
		void handleLogoutPayload(const std::string &payload);
 
		void handleStatusChangedPayload(const std::string &payload);
plugin/src/CMakeLists.txt
Show inline comments
 
@@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC *.cpp *.h)
 
FILE(GLOB HEADERS ../include/transport/*.h)
 
 
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc)
 
if (NOT WIN32)
 
	ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc)
 
else()
 
	ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ../../src/memoryusage.cpp ${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc)
 
endif()
 
ADD_DEPENDENCIES(transport-plugin pb)
 
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
 
spectrum/src/sample.cfg
Show inline comments
 
@@ -4,7 +4,8 @@ password = secret
 
server = 127.0.0.1
 
port = 5222
 
server_mode = 1
 
backend_host=localhost # < this option doesn't work yet
 
backend_host=localhost
 
# < this option doesn't work yet
 
backend_port=10001
 
admin_username=admin
 
admin_password=test
 
@@ -14,7 +15,7 @@ users_per_backend=10
 
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum2_libpurple_backend
 
#backend=/usr/bin/mono /home/hanzz/code/networkplugin-csharp/msnp-sharp-backend/bin/Debug/msnp-sharp-backend.exe
 
#backend=/home/hanzz/code/libtransport/backends/frotz/spectrum2_frotz_backend
 
#backend=../../backends/libircclient-qt/spectrum2_libircclient-qt_backend
 
#backend=/home/hanzz/code/libtransport/backends/libircclient-qt/spectrum2_libircclient-qt_backend
 
#protocol=prpl-msn
 
protocol=any
 
#protocol=prpl-icq
 
@@ -25,7 +26,7 @@ protocol=any
 

	
 
[logging]
 
#config=logging.cfg # log4cxx/log4j logging configuration file
 
#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 
#backend_config=/home/hanzz/code/libtransport/spectrum/src/backend-logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
type = none # or "none" without database backend
spectrum/src/sample2.cfg
Show inline comments
 
@@ -65,7 +65,7 @@ type=xmpp
 
config = /etc/spectrum2/logging.cfg 
 

	
 
# log4cxx/log4j logging configuration file in ini format used for backends.
 
backend_config = /etc/spectrum2/backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 
backend_config = /etc/spectrum2/backend-logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
# Database backend type
spectrum_manager/src/main.cpp
Show inline comments
 
@@ -26,26 +26,26 @@ using namespace boost;
 
static int finished;
 
static std::string *m;
 
 
static void handleDisconnected(Swift::Client *client, const boost::optional<Swift::ClientError> &) {
 
	std::cout << "[ DISCONNECTED ] " << client->getJID().getDomain() << "\n";
 
static void handleDisconnected(Swift::Client *client, const boost::optional<Swift::ClientError> &, const std::string &server) {
 
	std::cout << "[ DISCONNECTED ] " << server << "\n";
 
	if (--finished == 0) {
 
		exit(0);
 
	}
 
}
 
 
static void handleConnected(Swift::Client *client) {
 
static void handleConnected(Swift::Client *client, const std::string &server) {
 
	boost::shared_ptr<Swift::Message> message(new Swift::Message());
 
	message->setTo(client->getJID().getDomain());
 
	message->setTo(server);
 
	message->setFrom(client->getJID());
 
	message->setBody(*m);
 
 
	client->sendMessage(message);
 
}
 
 
static void handleMessageReceived(Swift::Client *client, Swift::Message::ref message) {
 
static void handleMessageReceived(Swift::Client *client, Swift::Message::ref message, const std::string &server) {
 
	std::string body = message->getBody();
 
	boost::replace_all(body, "\n", "\n[      OK      ] " + client->getJID().getDomain() + ": ");
 
	std::cout << "[      OK      ] " << client->getJID().getDomain() << ": " << body <<  "\n";
 
	boost::replace_all(body, "\n", "\n[      OK      ] " + server + ": ");
 
	std::cout << "[      OK      ] " << server << ": " << body <<  "\n";
 
	if (--finished == 0) {
 
		exit(0);
 
	}
 
@@ -205,6 +205,47 @@ static void stop_all_instances(ManagerConfig *config) {
 
	}
 
}
 
 
void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) {
 
	path p(CONFIG_STRING(config, "service.config_directory"));
 
 
	try {
 
		if (!exists(p)) {
 
			std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
 
			exit(6);
 
		}
 
 
		if (!is_directory(p)) {
 
			std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
 
			exit(7);
 
		}
 
 
		directory_iterator end_itr;
 
		for (directory_iterator itr(p); itr != end_itr; ++itr) {
 
			if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
 
				Config cfg;
 
				if (cfg.load(itr->path().string()) == false) {
 
					std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
 
				}
 
 
				finished++;
 
				Swift::Client *client = new Swift::Client(CONFIG_STRING(&cfg, "service.admin_username"), CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
 
				client->setAlwaysTrustCertificates();
 
				client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
 
				client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
 
				client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid")));
 
				Swift::ClientOptions opt;
 
				opt.allowPLAINWithoutTLS = true;
 
				client->connect(opt);
 
			}
 
		}
 
	}
 
	catch (const filesystem_error& ex) {
 
		std::cerr << "boost filesystem error\n";
 
		exit(5);
 
	}
 
}
 
 
 
int main(int argc, char **argv)
 
{
 
	ManagerConfig config;
 
@@ -215,7 +256,7 @@ int main(int argc, char **argv)
 
	boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\nAllowed options");
 
	desc.add_options()
 
		("help,h", "Show help output")
 
		("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum-manager.cfg"), "Spectrum manager config file")
 
		("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file")
 
		("command", boost::program_options::value<std::string>(&command)->default_value(""), "Command")
 
		;
 
	try
 
@@ -243,12 +284,16 @@ int main(int argc, char **argv)
 
		return 3;
 
	}
 
 
 
	if (!config.load(config_file)) {
 
		std::cerr << "Can't load configuration file.\n";
 
		return 4;
 
	}
 
 
	if (command.empty()) {
 
		std::cout << desc << "\n";
 
		return 1;
 
	}
 
 
	if (command == "start") {
 
		start_all_instances(&config);
 
	}
 
@@ -259,17 +304,19 @@ int main(int argc, char **argv)
 
		Swift::SimpleEventLoop eventLoop;
 
		Swift::BoostNetworkFactories networkFactories(&eventLoop);
 
 
		std::string message = argv[1];
 
		std::string message = command;
 
		m = &message;
 
 
		ask_local_servers(&config, networkFactories, message);
 
 
		std::vector<std::string> servers = CONFIG_VECTOR(&config, "servers.server");
 
		for (std::vector<std::string>::const_iterator it = servers.begin(); it != servers.end(); it++) {
 
			finished++;
 
			Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + (*it), CONFIG_STRING(&config, "service.admin_password"), &networkFactories);
 
			Swift::Client *client = new Swift::Client(CONFIG_STRING(&config, "service.admin_username") + "@" + *it, CONFIG_STRING(&config, "service.admin_password"), &networkFactories);
 
			client->setAlwaysTrustCertificates();
 
			client->onConnected.connect(boost::bind(&handleConnected, client));
 
			client->onDisconnected.connect(bind(&handleDisconnected, client, _1));
 
			client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1));
 
			client->onConnected.connect(boost::bind(&handleConnected, client, *it));
 
			client->onDisconnected.connect(bind(&handleDisconnected, client, _1, *it));
 
			client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, *it));
 
			Swift::ClientOptions opt;
 
			opt.allowPLAINWithoutTLS = true;
 
			client->connect(opt);
src/admininterface.cpp
Show inline comments
 
@@ -61,8 +61,8 @@ void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
 
	if (!message->getTo().getNode().empty())
 
		return;
 

	
 
	if (message->getFrom().getNode() != CONFIG_STRING(m_component->getConfig(), "service.admin_username")) {
 
		LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().getNode());
 
	if (message->getFrom().toBare().toString() != CONFIG_STRING(m_component->getConfig(), "service.admin_jid")) {
 
		LOG4CXX_WARN(logger, "Message not from admin user, but from " << message->getFrom().toBare().toString());
 
		return;
 
	}
 

	
src/config.cpp
Show inline comments
 
@@ -69,7 +69,7 @@ bool Config::load(std::istream &ifs, boost::program_options::options_description
 
		("service.backend_port", value<std::string>()->default_value("10000"), "Port to bind backend server to")
 
		("service.cert", value<std::string>()->default_value(""), "PKCS#12 Certificate.")
 
		("service.cert_password", value<std::string>()->default_value(""), "PKCS#12 Certificate password.")
 
		("service.admin_username", value<std::string>()->default_value(""), "Administrator username.")
 
		("service.admin_jid", value<std::string>()->default_value(""), "Administrator jid.")
 
		("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
 
		("service.reuse_old_backends", value<bool>()->default_value(true), "True if Spectrum should use old backends which were full in the past.")
 
		("service.idle_reconnect_time", value<int>()->default_value(0), "Time in seconds after which idle users are reconnected to let their backend die.")
src/conversation.cpp
Show inline comments
 
@@ -42,6 +42,11 @@ Conversation::Conversation(ConversationManager *conversationManager, const std::
 
Conversation::~Conversation() {
 
}
 

	
 
void Conversation::setRoom(const std::string &room) {
 
	m_room = room;
 
	m_legacyName = m_room + "/" + m_legacyName;
 
}
 

	
 
void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, const std::string &nickname) {
 
	if (m_muc) {
 
		message->setType(Swift::Message::Groupchat);
 
@@ -74,8 +79,12 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
	}
 
	else {
 
		std::string legacyName = m_legacyName;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
		message->setTo(m_conversationManager->getUser()->getJID().toString());
 
		message->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
		message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
		m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
 
	}
 
}
 
@@ -83,7 +92,13 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
	std::string nickname = nick;
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
 	presence->setFrom(Swift::JID(m_legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
	std::string legacyName = m_legacyName;
 
	if (m_muc) {
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
	}
 
	presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
	presence->setTo(m_conversationManager->getUser()->getJID().toString());
 
	presence->setType(Swift::Presence::Available);
 

	
src/localbuddy.cpp
Show inline comments
 
@@ -25,12 +25,18 @@ namespace Transport {
 

	
 
LocalBuddy::LocalBuddy(RosterManager *rosterManager, long id) : Buddy(rosterManager, id) {
 
	m_status = Swift::StatusShow::None;
 
	m_firstSet = true;
 
}
 

	
 
LocalBuddy::~LocalBuddy() {
 
}
 

	
 
void LocalBuddy::setAlias(const std::string &alias) {
 
	if (m_firstSet) {
 
		m_firstSet = false;
 
		m_alias = alias;
 
		return;
 
	}
 
	bool changed = m_alias != alias;
 
	m_alias = alias;
 

	
src/mysqlbackend.cpp
Show inline comments
 
@@ -29,7 +29,7 @@ using namespace log4cxx;
 
#define MYSQL_DB_VERSION 2
 
#define CHECK_DB_RESPONSE(stmt) \
 
	if(stmt) { \
 
		sqlite3_exec(m_db, "ROLLBACK;", NULL, NULL, NULL); \
 
		sqlite3_EXEC(m_db, "ROLLBACK;", NULL, NULL, NULL); \
 
		return 0; \
 
	}
 

	
 
@@ -72,11 +72,27 @@ using namespace log4cxx;
 
		LOG4CXX_ERROR(logger, NAME << " " << mysql_error(&m_conn)); \
 
	}
 

	
 
#define EXEC(STMT, METHOD) \
 
	{\
 
	int ret = STMT->execute(); \
 
	if (ret == 0) \
 
		exec_ok = true; \
 
	else if (ret == 2013) { \
 
		LOG4CXX_INFO(logger, "MySQL connection lost. Reconnecting...");\
 
		disconnect(); \
 
		connect(); \
 
		return METHOD; \
 
	} \
 
	else \
 
		exec_ok = false; \
 
	}
 

	
 
using namespace boost;
 

	
 
namespace Transport {
 

	
 
static LoggerPtr logger = Logger::getLogger("MySQLBackend");
 
static bool exec_ok;
 

	
 
MySQLBackend::Statement::Statement(MYSQL *conn, const std::string &format, const std::string &statement) {
 
	m_resultOffset = -1;
 
@@ -184,7 +200,7 @@ MySQLBackend::Statement::~Statement() {
 
	FINALIZE_STMT(m_stmt);
 
}
 

	
 
bool MySQLBackend::Statement::execute() {
 
int MySQLBackend::Statement::execute() {
 
	// If statement has some input and doesn't have any output, we have
 
	// to clear the offset now, because operator>> will not be called.
 
	m_offset = 0;
 
@@ -193,9 +209,9 @@ bool MySQLBackend::Statement::execute() {
 

	
 
	if ((ret = mysql_stmt_execute(m_stmt)) != 0) {
 
		LOG4CXX_ERROR(logger, m_string << " " << mysql_stmt_error(m_stmt) << "; " << mysql_error(m_conn));
 
		return false;
 
		return mysql_stmt_errno(m_stmt);
 
	}
 
	return true;
 
	return 0;
 
}
 

	
 
int MySQLBackend::Statement::fetch() {
 
@@ -256,13 +272,18 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator >> (std::string& t) {
 

	
 
MySQLBackend::MySQLBackend(Config *config) {
 
	m_config = config;
 
	m_prefix = CONFIG_STRING(m_config, "database.prefix");
 
	mysql_init(&m_conn);
 
	my_bool my_true = 1;
 
	mysql_options(&m_conn, MYSQL_OPT_RECONNECT, &my_true);
 
	m_prefix = CONFIG_STRING(m_config, "database.prefix");
 
}
 

	
 
MySQLBackend::~MySQLBackend(){
 
	disconnect();
 
}
 

	
 
void MySQLBackend::disconnect() {
 
	LOG4CXX_INFO(logger, "Disconnecting");
 
	delete m_setUser;
 
	delete m_getUser;
 
	delete m_removeUser;
 
@@ -286,7 +307,7 @@ bool MySQLBackend::connect() {
 
		CONFIG_STRING(m_config, "database.user") << ", database " << CONFIG_STRING(m_config, "database.database") <<
 
		", port " << CONFIG_INT(m_config, "database.port")
 
	);
 
	
 

	
 
	if (!mysql_real_connect(&m_conn, CONFIG_STRING(m_config, "database.server").c_str(),
 
					   CONFIG_STRING(m_config, "database.user").c_str(),
 
					   CONFIG_STRING(m_config, "database.password").c_str(),
 
@@ -389,12 +410,13 @@ bool MySQLBackend::exec(const std::string &query) {
 

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

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

	
 
	int ret = false;
 
@@ -408,7 +430,7 @@ bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) {
 

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

	
 
long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
 
@@ -417,14 +439,14 @@ long MySQLBackend::addBuddy(long userId, const BuddyInfo &buddyInfo) {
 
	*m_addBuddy << (buddyInfo.groups.size() == 0 ? "" : buddyInfo.groups[0]);
 
	*m_addBuddy << buddyInfo.alias << buddyInfo.flags;
 

	
 
	m_addBuddy->execute();
 
	EXEC(m_addBuddy, addBuddy(userId, buddyInfo));
 

	
 
	long id = (long) mysql_insert_id(&m_conn);
 

	
 
// 	INSERT OR REPLACE INTO " + m_prefix + "buddies_settings (user_id, buddy_id, var, type, value) VALUES (?, ?, ?, ?, ?)
 
	if (!buddyInfo.settings.find("icon_hash")->second.s.empty()) {
 
		*m_updateBuddySetting << userId << id << buddyInfo.settings.find("icon_hash")->first << (int) TYPE_STRING << buddyInfo.settings.find("icon_hash")->second.s << buddyInfo.settings.find("icon_hash")->second.s;
 
		m_updateBuddySetting->execute();
 
		EXEC(m_updateBuddySetting, addBuddy(userId, buddyInfo));
 
	}
 

	
 
	return id;
 
@@ -436,7 +458,7 @@ void MySQLBackend::updateBuddy(long userId, const BuddyInfo &buddyInfo) {
 
	*m_updateBuddy << buddyInfo.alias << buddyInfo.flags << buddyInfo.subscription;
 
	*m_updateBuddy << userId << buddyInfo.legacyName;
 

	
 
	m_updateBuddy->execute();
 
	EXEC(m_updateBuddy, updateBuddy(userId, buddyInfo));
 
}
 

	
 
bool MySQLBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
@@ -450,7 +472,8 @@ bool MySQLBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
	long buddy_id = -1;
 
	std::string key;
 

	
 
	if (!m_getBuddies->execute())
 
	EXEC(m_getBuddies, getBuddies(id, roster));
 
	if (!exec_ok)
 
		return false;
 

	
 
	while (m_getBuddies->fetch() == 0) {
 
@@ -465,7 +488,8 @@ bool MySQLBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 
		roster.push_back(b);
 
	}
 

	
 
	if (!m_getBuddiesSettings->execute())
 
	EXEC(m_getBuddiesSettings, getBuddies(id, roster));
 
	if (!exec_ok)
 
		return false;
 

	
 
	BOOST_FOREACH(BuddyInfo &b, roster) {
 
@@ -511,19 +535,23 @@ bool MySQLBackend::getBuddies(long id, std::list<BuddyInfo> &roster) {
 

	
 
bool MySQLBackend::removeUser(long id) {
 
	*m_removeUser << (int) id;
 
	if (!m_removeUser->execute())
 
	EXEC(m_removeUser, removeUser(id));
 
	if (!exec_ok)
 
		return false;
 

	
 
	*m_removeUserSettings << (int) id;
 
	if (!m_removeUserSettings->execute())
 
	EXEC(m_removeUserSettings, removeUser(id));
 
	if (!exec_ok)
 
		return false;
 

	
 
	*m_removeUserBuddies << (int) id;
 
	if (!m_removeUserBuddies->execute())
 
	EXEC(m_removeUserBuddies, removeUser(id));
 
	if (!exec_ok)
 
		return false;
 

	
 
	*m_removeUserBuddiesSettings << (int) id;
 
	if (!m_removeUserBuddiesSettings->execute())
 
	EXEC(m_removeUserBuddiesSettings, removeUser(id));
 
	if (!exec_ok)
 
		return false;
 

	
 
	return true;
 
@@ -532,11 +560,11 @@ bool MySQLBackend::removeUser(long id) {
 
void MySQLBackend::getUserSetting(long id, const std::string &variable, int &type, std::string &value) {
 
// 	"SELECT type, value FROM " + m_prefix + "users_settings WHERE user_id=? AND var=?"
 
	*m_getUserSetting << id << variable;
 
	m_getUserSetting->execute();
 
	EXEC(m_getUserSetting, getUserSetting(id, variable, type, value));
 
	if (m_getUserSetting->fetch() != 0) {
 
// 		"INSERT INTO " + m_prefix + "users_settings (user_id, var, type, value) VALUES (?,?,?,?)"
 
		*m_setUserSetting << id << variable << type << value;
 
		m_setUserSetting->execute();
 
		EXEC(m_setUserSetting, getUserSetting(id, variable, type, value));
 
	}
 
	else {
 
		*m_getUserSetting >> type >> value;
 
@@ -546,7 +574,7 @@ void MySQLBackend::getUserSetting(long id, const std::string &variable, int &typ
 
void MySQLBackend::updateUserSetting(long id, const std::string &variable, const std::string &value) {
 
// 	"UPDATE " + m_prefix + "users_settings SET value=? WHERE user_id=? AND var=?"
 
	*m_updateUserSetting << value << id << variable;
 
	m_updateUserSetting->execute();
 
	EXEC(m_updateUserSetting, updateUserSetting(id, variable, value));
 
}
 

	
 
void MySQLBackend::beginTransaction() {
src/networkpluginserver.cpp
Show inline comments
 
@@ -355,6 +355,7 @@ void NetworkPluginServer::handleConnectedPayload(const std::string &data) {
 

	
 
	User *user = m_userManager->getUser(payload.user());
 
	if (!user) {
 
		LOG4CXX_ERROR(logger, "Connected payload received for unknown user " << payload.user());
 
		return;
 
	}
 

	
 
@@ -1300,7 +1301,8 @@ void NetworkPluginServer::handleFTRejected(User *user, const std::string &buddyN
 
void NetworkPluginServer::handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id) {
 
	User *user = m_userManager->getUser(userName);
 
	if (!user) {
 
		// TODO: reject and remove filetransfer
 
		// TODO: FIXME We have to remove filetransfer when use disconnects
 
		return;
 
	}
 
	if (state.state == Swift::FileTransfer::State::Transferring) {
 
		handleFTAccepted(user, buddyName, fileName, size, id);
src/tests/basictest.cpp
Show inline comments
 
new file 100644
 
#include "basictest.h"
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include "transport/storagebackend.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/conversation.h"
 
#include "transport/usermanager.h"
 
#include "transport/localbuddy.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"
 

	
 
using namespace Transport;
 

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

	
 
	factory = new TestingFactory();
 

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

	
 
	userRegistry = new UserRegistry(cfg, factories);
 

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

	
 
	userManager = new UserManager(component, userRegistry);
 

	
 
	payloadSerializers = new Swift::FullPayloadSerializerCollection();
 
	payloadParserFactories = new Swift::FullPayloadParserFactoryCollection();
 
	parser = 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 *>(component->getStanzaChannel())->addSession(serverFromClientSession);
 
	parser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
 
	received.clear();
 
	loop->processEvents();
 
}
 

	
 
void BasicTest::tearMeDown (void) {
 
	dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->removeSession(serverFromClientSession);
 
	delete component;
 
	delete userRegistry;
 
	delete factories;
 
	delete factory;
 
	delete loop;
 
	delete cfg;
 
	delete parser;
 
	received.clear();
 
}
 

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

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

	
 
}
 

	
 
void BasicTest::handleElement(boost::shared_ptr<Swift::Element> element) {
 
received.push_back(element);
 
}
 

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

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

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

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

	
src/tests/basictest.h
Show inline comments
 
new file 100644
 
/**
 
 * 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
 
 */
 

	
 
#pragma once
 

	
 
#include <vector>
 
#include "Swiften/Swiften.h"
 
#include "Swiften/Queries/SetResponder.h"
 
#include "transport/conversation.h"
 
#include "transport/conversationmanager.h"
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include "transport/storagebackend.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/conversation.h"
 
#include "transport/usermanager.h"
 
#include "transport/localbuddy.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"
 

	
 
using namespace Transport;
 

	
 
class TestingConversation : public Conversation {
 
	public:
 
		TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
 
		}
 

	
 
		// Called when there's new message to legacy network from XMPP network
 
		void sendMessage(boost::shared_ptr<Swift::Message> &message) {
 

	
 
		}
 
};
 

	
 
class TestingFactory : public Factory {
 
	public:
 
		TestingFactory() {
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			Conversation *nc = new TestingConversation(conversationManager, legacyName);
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
				buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s);
 
			return buddy;
 
		}
 
};
 

	
 
class BasicTest : public Swift::XMPPParserClient {
 

	
 
	public:
 
		void setMeUp (void);
 

	
 
		void tearMeDown (void);
 

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

	
 
	void handleStreamStart(const Swift::ProtocolHeader&);
 

	
 
	void handleElement(boost::shared_ptr<Swift::Element> element);
 

	
 
	void handleStreamEnd();
 

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

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

	
 
	protected:
 
		bool streamEnded;
 
		UserManager *userManager;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession;
 
		Swift::FullPayloadSerializerCollection* payloadSerializers;
 
		Swift::FullPayloadParserFactoryCollection* payloadParserFactories;
 
		Swift::XMPPParser *parser;
 
		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;
 
};
 

	
src/tests/component.cpp
Show inline comments
 
@@ -14,45 +14,11 @@
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 

	
 
using namespace Transport;
 
#include "basictest.h"
 

	
 
class TestingConversation : public Conversation {
 
	public:
 
		TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
 
		}
 

	
 
		// Called when there's new message to legacy network from XMPP network
 
		void sendMessage(boost::shared_ptr<Swift::Message> &message) {
 
			
 
		}
 
};
 

	
 
class TestingFactory : public Factory {
 
	public:
 
		TestingFactory() {
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			Conversation *nc = new TestingConversation(conversationManager, legacyName);
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
				buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s);
 
			return buddy;
 
		}
 
};
 
using namespace Transport;
 

	
 
class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParserClient {
 
class ComponentTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(ComponentTest);
 
	CPPUNIT_TEST(handlePresenceWithNode);
 
	CPPUNIT_TEST(handlePresenceWithoutNode);
 
@@ -62,48 +28,14 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser
 
		void setUp (void) {
 
			onUserPresenceReceived = false;
 
			onUserDiscoInfoReceived = false;
 
			std::istringstream ifs("service.server_mode = 1\n");
 
			cfg = new Config();
 
			cfg->load(ifs);
 

	
 
			factory = new TestingFactory();
 

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

	
 
			userRegistry = new UserRegistry(cfg, factories);
 

	
 
			component = new Component(loop, factories, cfg, factory, userRegistry);
 
			setMeUp();
 
			component->onUserPresenceReceived.connect(boost::bind(&ComponentTest::handleUserPresenceReceived, this, _1));
 
			component->onUserDiscoInfoReceived.connect(boost::bind(&ComponentTest::handleUserDiscoInfoReceived, this, _1, _2));
 
			component->start();
 

	
 
			payloadSerializers = new Swift::FullPayloadSerializerCollection();
 
			payloadParserFactories = new Swift::FullPayloadParserFactoryCollection();
 
			parser = 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(&ComponentTest::handleDataReceived, this, _1));
 

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

	
 
		void tearDown (void) {
 
			dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->removeSession(serverFromClientSession);
 
			delete component;
 
			delete userRegistry;
 
			delete factories;
 
			delete factory;
 
			delete loop;
 
			delete cfg;
 
			delete parser;
 
			received.clear();
 
			tearMeDown();
 
		}
 

	
 
	void handleUserDiscoInfoReceived(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info) {
 
@@ -114,22 +46,6 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser
 
		onUserPresenceReceived = true;
 
	}
 

	
 
	void handleDataReceived(const Swift::SafeByteArray &data) {
 
		parser->parse(safeByteArrayToString(data));
 
	}
 

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

	
 
	void handleElement(boost::shared_ptr<Swift::Element> element) {
 
		received.push_back(element);
 
	}
 

	
 
	void handleStreamEnd() {
 
		
 
	}
 

	
 
	void handlePresenceWithNode() {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("somebody@localhost");
 
@@ -151,27 +67,9 @@ class ComponentTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParser
 
		CPPUNIT_ASSERT(onUserPresenceReceived);
 
	}
 

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

	
 
	private:
 
		bool onUserPresenceReceived;
 
		bool onUserDiscoInfoReceived;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession;
 
		Swift::FullPayloadSerializerCollection* payloadSerializers;
 
		Swift::FullPayloadParserFactoryCollection* payloadParserFactories;
 
		Swift::XMPPParser *parser;
 
		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;
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (ComponentTest);
src/tests/rostermanager.cpp
Show inline comments
 
new file 100644
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include "transport/storagebackend.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/conversation.h"
 
#include "transport/usermanager.h"
 
#include "transport/localbuddy.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 "basictest.h"
 

	
 
using namespace Transport;
 

	
 
class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(RosterManagerTest);
 
	CPPUNIT_TEST(setBuddy);
 
	CPPUNIT_TEST(sendCurrentPresences);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		void setUp (void) {
 
			setMeUp();
 
			userManager->onUserCreated.connect(boost::bind(&RosterManagerTest::handleUserCreated, this, _1));
 
			connectUser();
 
			received.clear();
 
		}
 

	
 
		void tearDown (void) {
 
			received.clear();
 
			disconnectUser();
 
			tearMeDown();
 
		}
 

	
 
	void handleUserCreated(User *user) {
 
		
 
	}
 

	
 
	void connectUser() {
 
		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());
 

	
 
		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(1, (int) received.size());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
 
		received.clear();
 
	}
 

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

	
 
		LocalBuddy *buddy = new LocalBuddy(user->getRosterManager(), -1);
 
		buddy->setFlags(BUDDY_JID_ESCAPING);
 
		buddy->setName("buddy1");
 
		buddy->setAlias("Buddy 1");
 
		std::vector<std::string> grp;
 
		grp.push_back("group1");
 
		buddy->setGroups(grp);
 
		buddy->setStatus(Swift::StatusShow(Swift::StatusShow::Away), "status1");
 
		user->getRosterManager()->setBuddy(buddy);
 

	
 
		buddy = new LocalBuddy(user->getRosterManager(), -1);
 
		buddy->setFlags(BUDDY_JID_ESCAPING);
 
		buddy->setName("buddy2");
 
		buddy->setAlias("Buddy 2");
 
		std::vector<std::string> grp2;
 
		grp2.push_back("group2");
 
		buddy->setGroups(grp2);
 
		buddy->setStatus(Swift::StatusShow(Swift::StatusShow::Away), "status2");
 
		user->getRosterManager()->setBuddy(buddy);
 
	}
 

	
 
	void setBuddy() {
 
		add2Buddies();
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 

	
 
		Swift::RosterPayload::ref payload1 = getStanza(received[0])->getPayload<Swift::RosterPayload>();
 
		CPPUNIT_ASSERT(payload1);
 
		CPPUNIT_ASSERT_EQUAL(1, (int) payload1->getItems().size());
 
		Swift::RosterItemPayload item = payload1->getItems()[0];
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy1"), Buddy::JIDToLegacyName(item.getJID()));
 
		CPPUNIT_ASSERT_EQUAL(std::string("Buddy 1"), item.getName());
 

	
 
		Swift::RosterPayload::ref payload2 = getStanza(received[1])->getPayload<Swift::RosterPayload>();
 
		CPPUNIT_ASSERT(payload2);
 
		CPPUNIT_ASSERT_EQUAL(1, (int) payload2->getItems().size());
 
		item = payload2->getItems()[0];
 
		CPPUNIT_ASSERT_EQUAL(std::string("buddy2"), Buddy::JIDToLegacyName(item.getJID()));
 
		CPPUNIT_ASSERT_EQUAL(std::string("Buddy 2"), item.getName());
 

	
 
		// send responses back
 
		injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID()));
 
		injectIQ(Swift::IQ::createResult(getStanza(received[1])->getFrom(), getStanza(received[1])->getTo(), getStanza(received[1])->getID()));
 

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

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

	
 
	void sendCurrentPresences() {
 
		setBuddy();
 
		received.clear();
 

	
 
		User *user = userManager->getUser("user@localhost");
 
		user->getRosterManager()->sendCurrentPresences("user@localhost/resource");
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
// 		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[2])));
 
// 		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getShow());
 
// 		CPPUNIT_ASSERT_EQUAL(std::string("status1"), dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getStatus());
 
// 
 
// 		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[3])));
 
// 		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received[3]))->getShow());
 
// 		CPPUNIT_ASSERT_EQUAL(std::string("status2"), dynamic_cast<Swift::Presence *>(getStanza(received[3]))->getStatus());
 
	}
 

	
 
	void disconnectUser() {
 
		userManager->disconnectUser("user@localhost");
 
		dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(10);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (RosterManagerTest);
src/tests/user.cpp
Show inline comments
 
new file 100644
 
#include "transport/userregistry.h"
 
#include "transport/config.h"
 
#include "transport/storagebackend.h"
 
#include "transport/user.h"
 
#include "transport/transport.h"
 
#include "transport/conversation.h"
 
#include "transport/usermanager.h"
 
#include "transport/localbuddy.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 "basictest.h"
 

	
 
using namespace Transport;
 

	
 
class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(UserTest);
 
	CPPUNIT_TEST(sendCurrentPresence);
 
    CPPUNIT_TEST(handlePresence);
 
	CPPUNIT_TEST(handlePresenceJoinRoom);
 
	CPPUNIT_TEST(handlePresenceLeaveRoom);
 
	CPPUNIT_TEST(handleDisconnected);
 
	CPPUNIT_TEST_SUITE_END();
 

	
 
	public:
 
		std::string room;
 
		std::string roomNickname;
 
		std::string roomPassword;
 
		bool readyToConnect;
 
		bool disconnected;
 
		Swift::Presence::ref changedPresence;
 

	
 
		void setUp (void) {
 
			disconnected = false;
 
			readyToConnect = false;
 
			changedPresence = Swift::Presence::ref();
 
			room = "";
 
			roomNickname = "";
 
			roomPassword = "";
 

	
 
			setMeUp();
 
			userManager->onUserCreated.connect(boost::bind(&UserTest::handleUserCreated, this, _1));
 
			connectUser();
 
			received.clear();
 
		}
 

	
 
		void tearDown (void) {
 
			received.clear();
 
			disconnectUser();
 
			tearMeDown();
 
		}
 

	
 
	void handleUserCreated(User *user) {
 
		user->onReadyToConnect.connect(boost::bind(&UserTest::handleUserReadyToConnect, this, user));
 
		user->onPresenceChanged.connect(boost::bind(&UserTest::handleUserPresenceChanged, this, user, _1));
 
		user->onRoomJoined.connect(boost::bind(&UserTest::handleRoomJoined, this, user, _1, _2, _3));
 
		user->onRoomLeft.connect(boost::bind(&UserTest::handleRoomLeft, this, user, _1));
 
	}
 

	
 
	void handleUserReadyToConnect(User *user) {
 
		readyToConnect = true;
 
	}
 

	
 
	void handleUserPresenceChanged(User *user, Swift::Presence::ref presence) {
 
		changedPresence = presence;
 
	}
 

	
 
	void handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) {
 
		room = r;
 
		roomNickname = nickname;
 
		roomPassword = password;
 
	}
 

	
 
	void handleRoomLeft(User *user, const std::string &r) {
 
		room = r;
 
	}
 

	
 
	void connectUser() {
 
		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());
 

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

	
 
		CPPUNIT_ASSERT_EQUAL(true, readyToConnect);
 

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

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

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

	
 
		// We're not forwarding current presence in server-mode
 
		CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
 
	}
 

	
 
	void handlePresence() {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("localhost");
 
		response->setFrom("user@localhost/resource");
 
		response->setShow(Swift::StatusShow::Away);
 

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

	
 
		// no presence received in server mode, just disco#info
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
 

	
 
		CPPUNIT_ASSERT(changedPresence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, changedPresence->getShow());
 
	}
 

	
 
	void handlePresenceJoinRoom() {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource");
 

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

	
 
		// no presence received in server mode, just disco#info
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::DiscoInfo>());
 

	
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword);
 
	}
 

	
 
	void handlePresenceLeaveRoom() {
 
		Swift::Presence::ref response = Swift::Presence::create();
 
		response->setTo("#room@localhost/hanzz");
 
		response->setFrom("user@localhost/resource");
 
		response->setType(Swift::Presence::Unavailable);
 

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

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

	
 
		CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
 
		CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
 
	}
 

	
 
	void handleDisconnected() {
 
		User *user = userManager->getUser("user@localhost");
 
		user->handleDisconnected("Connection error");
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT(streamEnded);
 
		user = userManager->getUser("user@localhost");
 
		CPPUNIT_ASSERT(!user);
 

	
 
		CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
 
		Swift::Message *m = dynamic_cast<Swift::Message *>(getStanza(received[0]));
 
		CPPUNIT_ASSERT_EQUAL(std::string("Connection error"), m->getBody());
 

	
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::StreamError *>(received[1].get()));
 
		CPPUNIT_ASSERT_EQUAL(std::string("Connection error"), dynamic_cast<Swift::StreamError *>(received[1].get())->getText());
 

	
 
		disconnected = true;
 
	}
 

	
 
	void disconnectUser() {
 
		if (disconnected)
 
			return;
 
		userManager->disconnectUser("user@localhost");
 
		dynamic_cast<Swift::DummyTimerFactory *>(factories->getTimerFactory())->setTime(10);
 
		loop->processEvents();
 

	
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
 
		CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
 
	}
 

	
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (UserTest);
src/tests/usermanager.cpp
Show inline comments
 
@@ -16,46 +16,11 @@
 
#include "Swiften/Server/ServerStanzaChannel.h"
 
#include "Swiften/Server/ServerFromClientSession.h"
 
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
 
#include "basictest.h"
 

	
 
using namespace Transport;
 

	
 
class TestingConversation : public Conversation {
 
	public:
 
		TestingConversation(ConversationManager *conversationManager, const std::string &legacyName, bool muc = false) : Conversation(conversationManager, legacyName, muc) {
 
		}
 

	
 
		// Called when there's new message to legacy network from XMPP network
 
		void sendMessage(boost::shared_ptr<Swift::Message> &message) {
 
			
 
		}
 
};
 

	
 
class TestingFactory : public Factory {
 
	public:
 
		TestingFactory() {
 
		}
 

	
 
		// Creates new conversation (NetworkConversation in this case)
 
		Conversation *createConversation(ConversationManager *conversationManager, const std::string &legacyName) {
 
			Conversation *nc = new TestingConversation(conversationManager, legacyName);
 
			return nc;
 
		}
 

	
 
		// Creates new LocalBuddy
 
		Buddy *createBuddy(RosterManager *rosterManager, const BuddyInfo &buddyInfo) {
 
			LocalBuddy *buddy = new LocalBuddy(rosterManager, buddyInfo.id);
 
			buddy->setAlias(buddyInfo.alias);
 
			buddy->setName(buddyInfo.legacyName);
 
			buddy->setSubscription(buddyInfo.subscription);
 
			buddy->setGroups(buddyInfo.groups);
 
			buddy->setFlags((BuddyFlag) buddyInfo.flags);
 
			if (buddyInfo.settings.find("icon_hash") != buddyInfo.settings.end())
 
				buddy->setIconHash(buddyInfo.settings.find("icon_hash")->second.s);
 
			return buddy;
 
		}
 
};
 

	
 
class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPParserClient {
 
class UserManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
 
	CPPUNIT_TEST_SUITE(UserManagerTest);
 
	CPPUNIT_TEST(connectUser);
 
	CPPUNIT_TEST(handleProbePresence);
 
@@ -64,67 +29,13 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPPars
 

	
 
	public:
 
		void setUp (void) {
 
			streamEnded = false;
 
			std::istringstream ifs("service.server_mode = 1\n");
 
			cfg = new Config();
 
			cfg->load(ifs);
 

	
 
			factory = new TestingFactory();
 

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

	
 
			userRegistry = new UserRegistry(cfg, factories);
 

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

	
 
			userManager = new UserManager(component, userRegistry);
 

	
 
			payloadSerializers = new Swift::FullPayloadSerializerCollection();
 
			payloadParserFactories = new Swift::FullPayloadParserFactoryCollection();
 
			parser = 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(&UserManagerTest::handleDataReceived, this, _1));
 

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

	
 
		void tearDown (void) {
 
			dynamic_cast<Swift::ServerStanzaChannel *>(component->getStanzaChannel())->removeSession(serverFromClientSession);
 
			delete component;
 
			delete userRegistry;
 
			delete factories;
 
			delete factory;
 
			delete loop;
 
			delete cfg;
 
			delete parser;
 
			received.clear();
 
			tearMeDown();
 
		}
 

	
 
	void handleDataReceived(const Swift::SafeByteArray &data) {
 
		parser->parse(safeByteArrayToString(data));
 
	}
 

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

	
 
	void handleElement(boost::shared_ptr<Swift::Element> element) {
 
		received.push_back(element);
 
	}
 

	
 
	void handleStreamEnd() {
 
		streamEnded = true;
 
	}
 

	
 
	void connectUser() {
 
		CPPUNIT_ASSERT_EQUAL(0, userManager->getUserCount());
 
		userRegistry->isValidUserPassword(Swift::JID("user@localhost/resource"), serverFromClientSession.get(), Swift::createSafeByteArray("password"));
 
@@ -169,30 +80,12 @@ class UserManagerTest : public CPPUNIT_NS :: TestFixture, public Swift::XMPPPars
 

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

	
 
	Swift::Stanza *getStanza(boost::shared_ptr<Swift::Element> element) {
 
		Swift::Stanza *stanza = dynamic_cast<Swift::Stanza *>(element.get());
 
		CPPUNIT_ASSERT(stanza);
 
		return stanza;
 
		Swift::Presence *presence = dynamic_cast<Swift::Presence *>(getStanza(received[1]));
 
		CPPUNIT_ASSERT(presence);
 
		CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, presence->getType());
 
	}
 

	
 
	private:
 
		bool streamEnded;
 
		UserManager *userManager;
 
		boost::shared_ptr<Swift::ServerFromClientSession> serverFromClientSession;
 
		Swift::FullPayloadSerializerCollection* payloadSerializers;
 
		Swift::FullPayloadParserFactoryCollection* payloadParserFactories;
 
		Swift::XMPPParser *parser;
 
		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;
 
};
 

	
 
CPPUNIT_TEST_SUITE_REGISTRATION (UserManagerTest);
src/user.cpp
Show inline comments
 
@@ -194,7 +194,8 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
	if (isMUC) {
 
		if (presence->getType() == Swift::Presence::Unavailable) {
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << presence->getTo().getNode());
 
			onRoomLeft(presence->getTo().getNode());
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			onRoomLeft(room);
 
		}
 
		else {
 
			// force connection to legacy network to let backend to handle auto-join on connect.
 
@@ -204,7 +205,12 @@ void User::handlePresence(Swift::Presence::ref presence) {
 
				onReadyToConnect();
 
			}
 
			LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << presence->getTo().getNode() << " as " << presence->getTo().getResource());
 
			onRoomJoined(presence->getTo().getNode(), presence->getTo().getResource(), "");
 
			std::string room = Buddy::JIDToLegacyName(presence->getTo());
 
			std::string password = "";
 
			if (presence->getPayload<Swift::MUCPayload>() != NULL) {
 
				password = presence->getPayload<Swift::MUCPayload>()->getPassword() ? *presence->getPayload<Swift::MUCPayload>()->getPassword() : "";
 
			}
 
			onRoomJoined(room, presence->getTo().getResource(), password);
 
		}
 
		return;
 
	}
 
@@ -298,7 +304,7 @@ void User::handleDisconnected(const std::string &error) {
 
		// We can't be sure finishSession sends unavailable presence everytime, so check if user gets removed
 
		// in finishSession(...) call and if not, remove it here.
 
		std::string jid = m_jid.toBare().toString();		
 
		dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr<Swift::Element>(new Swift::StreamError(Swift::StreamError::UndefinedCondition, "test")));
 
		dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr<Swift::Element>(new Swift::StreamError(Swift::StreamError::UndefinedCondition, error)));
 
		if (m_userManager->getUser(jid) != NULL) {
 
			m_userManager->removeUser(this);
 
		}
src/userregistry.cpp
Show inline comments
 
@@ -40,7 +40,7 @@ UserRegistry::UserRegistry(Config *cfg, Swift::NetworkFactories *factories) {
 
UserRegistry::~UserRegistry() { m_removeTimer->stop(); }
 

	
 
void UserRegistry::isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) {
 
	if (!CONFIG_STRING(config, "service.admin_username").empty() && user.getNode() == CONFIG_STRING(config, "service.admin_username")) {
 
	if (!CONFIG_STRING(config, "service.admin_jid").empty() && user.toBare().toString() == CONFIG_STRING(config, "service.admin_jid")) {
 
		if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) {
 
			session->handlePasswordValid();
 
		}
0 comments (0 inline, 0 general)