This commit is contained in:
Vitaly Takmazov 2013-01-29 11:22:01 +04:00
commit 317b82998a
73 changed files with 722 additions and 282 deletions

View file

@ -29,7 +29,7 @@ option(ENABLE_TWITTER "Build Twitter plugin" ON)
option(ENABLE_YAHOO2 "Build Libyahoo2 plugin" ON)
option(ENABLE_DOCS "Build Docs" ON)
option(ENABLE_LOG "Build with logging using Log4cxx" ON)
# option(ENABLE_LOG "Build with logging using Log4cxx" ON)
option(ENABLE_TESTS "Build Tests using CppUnit" OFF)
MACRO(LIST_CONTAINS var value)
@ -225,7 +225,7 @@ if(ENABLE_DOCS)
find_package(Doxygen)
endif()
if(ENABLE_LOG)
# if(ENABLE_LOG)
if(LOG4CXX_INCLUDE_DIR AND LOG4CXX_LIBRARY)
set(LOG4CXX_LIBRARIES ${LOG4CXX_LIBRARY})
set(LOG4CXX_FOUND 1)
@ -234,7 +234,7 @@ if(ENABLE_LOG)
set(log4cxx_DIR "${CMAKE_SOURCE_DIR}/cmake_modules")
find_package(log4cxx)
endif()
endif()
# endif()
# FIND CPPUNIT
if(ENABLE_TESTS)
@ -423,10 +423,10 @@ if (LOG4CXX_FOUND)
ADD_DEFINITIONS(-DWITH_LOG4CXX)
else()
set(LOG4CXX_LIBRARIES "")
if(ENABLE_LOG)
if (WIN32)
message("Log4cxx : no (install log4cxx-devel)")
else(ENABLE_LOG)
message("Log4cxx : no (user disabled)")
else()
message(FATAL_ERROR "Log4cxx : no (install log4cxx-devel)")
endif()
endif()

View file

@ -56,6 +56,7 @@ void IRCNetworkPlugin::readData() {
if (m_servers.empty()) {
NetworkPlugin::PluginConfig cfg;
cfg.setNeedRegistration(false);
cfg.setSupportMUC(true);
sendConfig(cfg);
}
}

View file

@ -33,10 +33,10 @@ int main (int argc, char* argv[]) {
return 1;
}
QCoreApplication app(argc, argv);
Logging::initBackendLogging(cfg);
QCoreApplication app(argc, argv);
Swift::QtEventLoop eventLoop;

View file

@ -86,6 +86,9 @@ bool MyIrcSession::correctNickname(std::string &nickname) {
switch(nickname.at(0)) {
case '@': nickname = nickname.substr(1); flags = 1; break;
case '+': nickname = nickname.substr(1); break;
case '~': nickname = nickname.substr(1); break;
case '&': nickname = nickname.substr(1); break;
case '%': nickname = nickname.substr(1); break;
default: break;
}
return flags;
@ -96,9 +99,9 @@ void MyIrcSession::on_joined(IrcMessage *message) {
bool op = 0;
std::string nickname = TO_UTF8(m->sender().name());
op = correctNickname(nickname);
getIRCBuddy(TO_UTF8(m->channel()), nickname).setOp(op);
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel()) + suffix, op, pbnetwork::STATUS_ONLINE);
LOG4CXX_INFO(logger, user << ": " << nickname << " joined " << TO_UTF8(m->channel()) + suffix);
getIRCBuddy(TO_UTF8(m->channel().toLower()), nickname).setOp(op);
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel().toLower()) + suffix, op, pbnetwork::STATUS_ONLINE);
LOG4CXX_INFO(logger, user << ": " << nickname << " joined " << TO_UTF8(m->channel().toLower()) + suffix);
}
@ -107,9 +110,9 @@ void MyIrcSession::on_parted(IrcMessage *message) {
bool op = 0;
std::string nickname = TO_UTF8(m->sender().name());
op = correctNickname(nickname);
removeIRCBuddy(TO_UTF8(m->channel()), nickname);
LOG4CXX_INFO(logger, user << ": " << nickname << " parted " << TO_UTF8(m->channel()) + suffix);
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel()) + suffix, op, pbnetwork::STATUS_NONE, TO_UTF8(m->reason()));
removeIRCBuddy(TO_UTF8(m->channel().toLower()), nickname);
LOG4CXX_INFO(logger, user << ": " << nickname << " parted " << TO_UTF8(m->channel().toLower()) + suffix);
np->handleParticipantChanged(user, nickname, TO_UTF8(m->channel().toLower()) + suffix, op, pbnetwork::STATUS_NONE, TO_UTF8(m->reason()));
}
void MyIrcSession::on_quit(IrcMessage *message) {
@ -172,7 +175,7 @@ void MyIrcSession::on_topicChanged(IrcMessage *message) {
correctNickname(nickname);
LOG4CXX_INFO(logger, user << ": " << nickname << " topic changed to " << TO_UTF8(m->topic()));
np->handleSubject(user, TO_UTF8(m->channel()) + suffix, TO_UTF8(m->topic()), nickname);
np->handleSubject(user, TO_UTF8(m->channel().toLower()) + suffix, TO_UTF8(m->topic()), nickname);
}
void MyIrcSession::on_messageReceived(IrcMessage *message) {
@ -190,7 +193,7 @@ void MyIrcSession::on_messageReceived(IrcMessage *message) {
msg = QString("/me ") + msg;
}
std::string target = TO_UTF8(m->target());
std::string target = TO_UTF8(m->target().toLower());
LOG4CXX_INFO(logger, user << ": Message from " << target);
if (target.find("#") == 0) {
std::string nickname = TO_UTF8(m->sender().name());
@ -229,10 +232,10 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
if (nick.find("/") != std::string::npos) {
nick = nick.substr(0, nick.find("/"));
}
np->handleSubject(user, TO_UTF8(parameters[1]) + suffix, m_topicData, nick);
np->handleSubject(user, TO_UTF8(parameters[1].toLower()) + suffix, m_topicData, nick);
break;
case 352: {
channel = parameters[1];
channel = parameters[1].toLower();
nick = TO_UTF8(parameters[5]);
IRCBuddy &buddy = getIRCBuddy(TO_UTF8(channel), nick);
@ -249,7 +252,7 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
break;
}
case 353:
channel = parameters[2];
channel = parameters[2].toLower();
members = parameters[3].split(" ");
LOG4CXX_INFO(logger, user << ": Received members for " << TO_UTF8(channel) << suffix);
@ -265,13 +268,33 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
break;
case 366:
// ask /who to get away states
channel = parameters[1];
channel = parameters[1].toLower();
LOG4CXX_INFO(logger, user << "Asking /who for channel " << TO_UTF8(channel));
sendCommand(IrcCommand::createWho(channel));
break;
case 432:
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Erroneous Nickname");
break;
case 433:
for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
np->handleParticipantChanged(user, TO_UTF8(nickName()), it->second->getChannel() + suffix, pbnetwork::PARTICIPANT_FLAG_CONFLICT);
}
if (suffix.empty()) {
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Nickname is already in use");
}
break;
case 436:
for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
np->handleParticipantChanged(user, TO_UTF8(nickName()), it->second->getChannel() + suffix, pbnetwork::PARTICIPANT_FLAG_CONFLICT);
}
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Nickname collision KILL");
case 464:
for(AutoJoinMap::iterator it = m_autoJoin.begin(); it != m_autoJoin.end(); it++) {
np->handleParticipantChanged(user, TO_UTF8(nickName()), it->second->getChannel() + suffix, pbnetwork::PARTICIPANT_FLAG_NOT_AUTHORIZED);
}
if (suffix.empty()) {
np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Password incorrect");
}
case 321:
m_rooms.clear();
m_names.clear();
@ -287,6 +310,10 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) {
break;
}
if (m->code() >= 400 && m->code() < 500) {
LOG4CXX_INFO(logger, user << ": Error message received: " << message->toData().data());
}
//qDebug() << "numeric message received:" << receiver() << origin << code << params;
}

View file

@ -43,6 +43,7 @@ DEFINE_LOGGER(logger, "backend");
int main_socket;
static int writeInput;
bool firstPing = true;
using namespace Transport;
@ -549,6 +550,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
}
purple_blist_add_buddy_wrapped(buddy, NULL, group ,NULL);
purple_account_add_buddy_wrapped(account, buddy);
LOG4CXX_INFO(logger, "Adding new buddy " << buddyName.c_str() << " to legacy network roster");
}
}
}
@ -908,10 +910,6 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
// std::string msg = striped;
// g_free(striped);
std::string w = purple_normalize_wrapped(account, who);
size_t pos = w.find("/");
if (pos != std::string::npos)
w.erase((int) pos, w.length() - (int) pos);
// Escape HTML characters.
char *newline = purple_strdup_withhtml_wrapped(msg);
@ -948,11 +946,15 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
// LOG4CXX_INFO(logger, "Received message body='" << message_ << "' xhtml='" << xhtml_ << "'");
if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
std::string w = purple_normalize_wrapped(account, who);
size_t pos = w.find("/");
if (pos != std::string::npos)
w.erase((int) pos, w.length() - (int) pos);
np->handleMessage(np->m_accounts[account], w, message_, "", xhtml_, timestamp);
}
else {
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name_wrapped(conv) << "' " << w);
np->handleMessage(np->m_accounts[account], purple_conversation_get_name_wrapped(conv), message_, w, xhtml_, timestamp);
LOG4CXX_INFO(logger, "Received message body='" << message_ << "' name='" << purple_conversation_get_name_wrapped(conv) << "' " << who);
np->handleMessage(np->m_accounts[account], purple_conversation_get_name_wrapped(conv), message_, who, xhtml_, timestamp);
}
}
@ -1655,6 +1657,14 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
exit(errno);
}
std::string d = std::string(buffer, n);
if (firstPing) {
firstPing = false;
NetworkPlugin::PluginConfig cfg;
cfg.setSupportMUC(true);
np->sendConfig(cfg);
}
np->handleDataRead(d);
}
else {

View file

@ -202,6 +202,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
Skype *skype = m_sessions[user];
if (skype) {
skype->send_command("SET USER " + buddyName + " BUDDYSTATUS 1");
skype->send_command("SET USER " + buddyName + " ISAUTHORIZED FALSE");
}
}
@ -605,10 +606,12 @@ bool Skype::loadSkypeBuddies() {
void Skype::logout() {
if (m_pid != 0) {
send_command("SET USERSTATUS INVISIBLE");
send_command("SET USERSTATUS OFFLINE");
sleep(2);
g_object_unref(m_proxy);
if (m_proxy) {
send_command("SET USERSTATUS INVISIBLE");
send_command("SET USERSTATUS OFFLINE");
sleep(2);
g_object_unref(m_proxy);
}
LOG4CXX_INFO(logger, m_username << ": Terminating Skype instance (SIGTERM)");
kill((int) m_pid, SIGTERM);
// Give skype a chance
@ -695,20 +698,9 @@ static void handle_skype_message(std::string &message, Skype *sk) {
std::vector<std::string> groups;
np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text);
}
//TODO: handle RECEIVEDAUTHREQUEST and reply it with:
// void
// skype_auth_allow(gpointer sender)
// {
// skype_send_message("SET USER %s ISAUTHORIZED TRUE", sender);
// g_free(sender);
// }
//
// void
// skype_auth_deny(gpointer sender)
// {
// skype_send_message("SET USER %s ISAUTHORIZED FALSE", sender);
// g_free(sender);
// }
else if(cmd[2] == "RECEIVEDAUTHREQUEST") {
np->handleAuthorization(sk->getUser(), cmd[1]);
}
}
else if (cmd[0] == "CHATMESSAGE") {
if (cmd[3] == "RECEIVED") {

View file

@ -3,6 +3,8 @@
#include "transport/networkplugin.h"
#include "transport/logging.h"
#include "boost/date_time/posix_time/posix_time.hpp"
// Swiften
#include "Swiften/Swiften.h"
@ -32,7 +34,83 @@ Swift::SimpleEventLoop *loop_;
// Plugins
class SwiftenPlugin;
SwiftenPlugin *np = NULL;
NetworkPlugin *np = NULL;
class MUCController {
public:
MUCController(const std::string &user, boost::shared_ptr<Swift::Client> client, const std::string &room, const std::string &nickname, const std::string &password) {
m_user = user;
m_room = room;
muc = client->getMUCManager()->createMUC(room);
if (!password.empty()) {
muc->setPassword(password);
}
muc->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
muc->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));
muc->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
muc->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
muc->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
muc->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
muc->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3));
muc->joinAs(nickname);
}
virtual ~MUCController() {
muc->onJoinComplete.disconnect(boost::bind(&MUCController::handleJoinComplete, this, _1));
muc->onJoinFailed.disconnect(boost::bind(&MUCController::handleJoinFailed, this, _1));
muc->onOccupantJoined.disconnect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
muc->onOccupantPresenceChange.disconnect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
muc->onOccupantLeft.disconnect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
muc->onOccupantRoleChanged.disconnect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
muc->onOccupantAffiliationChanged.disconnect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3));
}
const std::string &getNickname() {
//return muc->getCurrentNick();
return m_nick;
}
void handleOccupantJoined(const Swift::MUCOccupant& occupant) {
np->handleParticipantChanged(m_user, occupant.getNick(), m_room, occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_ONLINE);
}
void handleOccupantLeft(const Swift::MUCOccupant& occupant, Swift::MUC::LeavingType type, const std::string& reason) {
np->handleParticipantChanged(m_user, occupant.getNick(), m_room, occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_NONE);
}
void handleOccupantPresenceChange(boost::shared_ptr<Swift::Presence> presence) {
const Swift::MUCOccupant& occupant = muc->getOccupant(presence->getFrom().getResource());
np->handleParticipantChanged(m_user, presence->getFrom().getResource(), m_room, (int) occupant.getRole() == Swift::MUCOccupant::Moderator, (pbnetwork::StatusType) presence->getShow(), presence->getStatus());
}
void handleOccupantRoleChanged(const std::string& nick, const Swift::MUCOccupant& occupant, const Swift::MUCOccupant::Role& oldRole) {
}
void handleOccupantAffiliationChanged(const std::string& nick, const Swift::MUCOccupant::Affiliation& affiliation, const Swift::MUCOccupant::Affiliation& oldAffiliation) {
// np->handleParticipantChanged(m_user, occupant->getNick(), m_room, (int) occupant.getRole() == Swift::MUCOccupant::Moderator, pbnetwork::STATUS_ONLINE);
}
void handleJoinComplete(const std::string& nick) {
m_nick = nick;
}
void handleJoinFailed(boost::shared_ptr<Swift::ErrorPayload> error) {
}
void part() {
muc->part();
}
private:
Swift::MUC::ref muc;
std::string m_user;
std::string m_room;
std::string m_nick;
};
class SwiftenPlugin : public NetworkPlugin {
public:
@ -106,6 +184,7 @@ class SwiftenPlugin : public NetworkPlugin {
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
m_users.erase(user);
m_mucs.erase(user);
}
#ifndef WIN32
@ -136,6 +215,11 @@ class SwiftenPlugin : public NetworkPlugin {
}
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
return;
}
LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
std::string message = presence->getStatus();
@ -160,7 +244,22 @@ class SwiftenPlugin : public NetworkPlugin {
std::string body = message->getBody();
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
handleMessage(user, message->getFrom().toBare().toString(), body, "", "");
if (message->getType() == Swift::Message::Groupchat) {
boost::shared_ptr<Swift::Delay> delay = message->getPayload<Swift::Delay>();
std::string timestamp = "";
if (delay) {
timestamp = boost::posix_time::to_iso_string(delay->getStamp());
}
handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", timestamp);
}
else {
if (client->getMUCRegistry()->isMUC(message->getFrom().toBare())) {
handleMessage(user, message->getFrom().toBare().toString(), body, message->getFrom().getResource(), "", "", false, true);
}
else {
handleMessage(user, message->getFrom().toBare().toString(), body, "", "");
}
}
}
}
@ -199,6 +298,8 @@ class SwiftenPlugin : public NetworkPlugin {
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
client->disconnect();
m_mucs.erase(user);
m_users.erase(user);
}
}
@ -210,6 +311,11 @@ class SwiftenPlugin : public NetworkPlugin {
message->setTo(Swift::JID(legacyName));
message->setFrom(client->getJID());
message->setBody(msg);
if (client->getMUCRegistry()->isMUC(legacyName)) {
message->setType(Swift::Message::Groupchat);
boost::shared_ptr<MUCController> muc = m_mucs[user][legacyName];
handleMessage(user, legacyName, msg, muc->getNickname(), xhtml);
}
client->sendMessage(message);
}
@ -226,17 +332,81 @@ class SwiftenPlugin : public NetworkPlugin {
}
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
// handleBuddyChanged(user, buddyName, alias, groups, pbnetwork::STATUS_ONLINE);
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
if (!client->getRoster()->containsJID(buddyName)) {
Swift::RosterItemPayload item;
item.setName(alias);
item.setJID(buddyName);
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
client->getSubscriptionManager()->requestSubscription(buddyName);
}
else {
Swift::JID contact(buddyName);
Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
item.setGroups(groups);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
}
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
roster->addItem(item);
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
}
}
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
if (client->getMUCRegistry()->isMUC(room)) {
return;
}
boost::shared_ptr<MUCController> muc = boost::shared_ptr<MUCController>( new MUCController(user, client, room, nickname, password));
m_mucs[user][room] = muc;
}
}
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
boost::shared_ptr<Swift::Client> client = m_users[user];
if (client) {
if (!client->getMUCRegistry()->isMUC(room)) {
return;
}
boost::shared_ptr<MUCController> muc = m_mucs[user][room];
if (!muc) {
m_mucs[user].erase(room);
return;
}
muc->part();
m_mucs[user].erase(room);
}
}
private:
Config *config;
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
std::map<std::string, std::map<std::string, boost::shared_ptr<MUCController> > > m_mucs;
};
#ifndef WIN32

View file

@ -23,7 +23,10 @@
#include <string>
#include <algorithm>
#include <map>
#include "Swiften/Swiften.h"
#include <time.h>
#include "Swiften/Elements/FormField.h"
#include "Swiften/Elements/Command.h"
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <algorithm>
#include <map>
#include "transport/adhoccommand.h"
#include "Swiften/Swiften.h"
namespace Transport {

View file

@ -23,7 +23,10 @@
#include <string>
#include <algorithm>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/Command.h"
#include "Swiften/Network/Timer.h"
namespace Transport {

View file

@ -22,7 +22,8 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/Elements/Message.h"
namespace Transport {

View file

@ -23,8 +23,8 @@
#include <string>
#include <algorithm>
#include "transport/transport.h"
#include "Swiften/Elements/VCard.h"
#include "Swiften/Swiften.h"
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <algorithm>
#include "transport/transport.h"
#include "Swiften/Swiften.h"
#include "Swiften/Elements/Message.h"
namespace Transport {
@ -34,15 +33,22 @@ class ConversationManager;
/// Represents one XMPP-Legacy network conversation.
class Conversation {
public:
typedef enum {
PARTICIPANT_FLAG_NONE = 0,
PARTICIPANT_FLAG_MODERATOR = 1,
PARTICIPANT_FLAG_CONFLICT = 2,
PARTICIPANT_FLAG_BANNED = 4,
PARTICIPANT_FLAG_NOT_AUTHORIZED = 8,
PARTICIPANT_FLAG_ME = 16,
PARTICIPANT_FLAG_KICKED = 32
} ParticipantFlag;
typedef struct _Participant {
int flag;
ParticipantFlag flag;
int status;
std::string statusMessage;
} Participant;
/// Type of participants in MUC rooms.
enum ParticipantFlag {None, Moderator};
/// Creates new conversation.
/// \param conversationManager ConversationManager associated with this Conversation.
@ -71,7 +77,7 @@ class Conversation {
/// \param status Current status of this participant.
/// \param statusMessage Current status message of this participant.
/// \param newname If participant was renamed, this variable contains his new name.
void handleParticipantChanged(const std::string &nickname, int flag, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "");
void handleParticipantChanged(const std::string &nickname, ParticipantFlag flag, int status = Swift::StatusShow::None, const std::string &statusMessage = "", const std::string &newname = "");
/// Sets XMPP user nickname in MUC rooms.

View file

@ -23,7 +23,8 @@
#include <string>
#include <algorithm>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/Elements/Message.h"
namespace Transport {

View file

@ -21,9 +21,9 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/GetResponder.h"
#include "Swiften/Elements/DiscoItems.h"
#include "Swiften/Elements/CapsInfo.h"
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <algorithm>
#include "transport/transport.h"
#include "Swiften/Swiften.h"
#include "Swiften/Elements/Message.h"
#include "transport/conversation.h"
#include "transport/buddy.h"

View file

@ -21,7 +21,6 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/GatewayPayload.h"

View file

@ -22,7 +22,8 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/FileTransfer/ReadBytestream.h"
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "transport/storagebackend.h"
#include "transport/config.h"
#include "mysql.h"

View file

@ -39,16 +39,18 @@ class NetworkPlugin {
class PluginConfig {
public:
PluginConfig() : m_needPassword(true), m_needRegistration(false) {}
PluginConfig() : m_needPassword(true), m_needRegistration(false), m_supportMUC(false) {}
virtual ~PluginConfig() {}
void setNeedRegistration(bool needRegistration = false) { m_needRegistration = needRegistration; }
void setNeedPassword(bool needPassword = true) { m_needPassword = needPassword; }
void setSupportMUC(bool supportMUC = true) { m_supportMUC = supportMUC; }
void setExtraFields(const std::vector<std::string> &fields) { m_extraFields = fields; }
private:
bool m_needPassword;
bool m_needRegistration;
bool m_supportMUC;
std::vector<std::string> m_extraFields;
friend class NetworkPlugin;
@ -111,7 +113,7 @@ class NetworkPlugin {
/// \param message Plain text message.
/// \param nickname Nickname of buddy in room. Empty if it's normal chat message.
/// \param xhtml XHTML message.
void handleMessage(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &nickname = "", const std::string &xhtml = "", const std::string &timestamp = "", bool headline = false);
void handleMessage(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &nickname = "", const std::string &xhtml = "", const std::string &timestamp = "", bool headline = false, bool pm = false);
void handleMessageAck(const std::string &user, const std::string &legacyName, const std::string &id);

View file

@ -21,11 +21,13 @@
#pragma once
#include <time.h>
#include "Swiften/Swiften.h"
#include "Swiften/Presence/PresenceOracle.h"
#include "Swiften/Disco/EntityCapsManager.h"
#include "Swiften/Network/BoostConnectionServer.h"
#include "Swiften/Network/Connection.h"
#include "Swiften/Elements/ChatState.h"
#include "Swiften/Elements/RosterItemPayload.h"
#include "Swiften/Elements/VCard.h"
#include "storagebackend.h"
#include "transport/filetransfermanager.h"
@ -125,6 +127,8 @@ class NetworkPluginServer {
void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleBuddyRemoved(Buddy *buddy);
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
void handleUserBuddyAdded(User *user, Buddy *buddy);
void handleUserBuddyRemoved(User *user, Buddy *buddy);
void handleBlockToggled(Buddy *buddy);

View file

@ -24,7 +24,6 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "transport/storagebackend.h"
#include "transport/config.h"
#include <pqxx/pqxx>

View file

@ -72,6 +72,7 @@ message ConversationMessage {
optional string timestamp = 6;
optional bool headline = 7;
optional string id = 8;
optional bool pm = 9;
}
message Room {
@ -86,6 +87,16 @@ message RoomList {
repeated string name = 2;
}
enum ParticipantFlag {
PARTICIPANT_FLAG_NONE = 0;
PARTICIPANT_FLAG_MODERATOR = 1;
PARTICIPANT_FLAG_CONFLICT = 2;
PARTICIPANT_FLAG_BANNED = 4;
PARTICIPANT_FLAG_NOT_AUTHORIZED = 8;
PARTICIPANT_FLAG_ME = 16;
PARTICIPANT_FLAG_KICKED = 32;
}
message Participant {
required string userName = 1;
required string room = 2;

View file

@ -25,8 +25,12 @@
#include <map>
#include <boost/pool/pool_alloc.hpp>
#include <boost/pool/object_pool.hpp>
#include "Swiften/Swiften.h"
// #include "rosterstorage.h"
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Queries/GenericRequest.h"
#include "Swiften/Roster/SetRosterRequest.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/Network/Timer.h"
namespace Transport {

View file

@ -21,10 +21,11 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/RosterPayload.h"
#include <boost/signal.hpp>
namespace Transport {
class UserManager;

View file

@ -22,7 +22,9 @@
#include <string>
#include <algorithm>
#include "Swiften/Swiften.h"
#include <map>
#include "Swiften/Network/Timer.h"
namespace Transport {

View file

@ -23,7 +23,6 @@
#include <string>
#include <algorithm>
#include <map>
#include "Swiften/Swiften.h"
#include "transport/adhoccommand.h"
#include "transport/adhoccommandfactory.h"

View file

@ -24,7 +24,6 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "transport/storagebackend.h"
#include "transport/config.h"
#include "sqlite3.h"

View file

@ -21,7 +21,6 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/SetResponder.h"
#include "Swiften/Elements/StatsPayload.h"

View file

@ -7,7 +7,7 @@
#include <queue>
#include <iostream>
#include "transport/logging.h"
#include "Swiften/Swiften.h"
#include "Swiften/EventLoop/EventLoop.h"
/*

View file

@ -21,7 +21,6 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Server/Server.h"
#include "Swiften/Disco/GetDiscoInfoRequest.h"
#include "Swiften/Disco/EntityCapsManager.h"
@ -32,6 +31,8 @@
#include "Swiften/Server/UserRegistry.h"
#include "Swiften/Base/SafeByteArray.h"
#include "Swiften/Jingle/JingleSessionManager.h"
#include "Swiften/Component/ComponentError.h"
#include "Swiften/Component/Component.h"
#include <boost/bind.hpp>
#include "transport/config.h"
@ -40,12 +41,6 @@
#include <Swiften/Network/BoostConnectionServer.h>
namespace Transport {
// typedef enum { CLIENT_FEATURE_ROSTERX = 2,
// CLIENT_FEATURE_XHTML_IM = 4,
// CLIENT_FEATURE_FILETRANSFER = 8,
// CLIENT_FEATURE_CHATSTATES = 16
// } SpectrumImportantFeatures;
//
class StorageBackend;
class Factory;
class UserRegistry;
@ -68,7 +63,9 @@ namespace Transport {
/// - service.server
/// - service.port
/// - service.server_mode
/// \param factories Swift::NetworkFactories.
/// \param factory Transport Abstract factory used to create basic transport structures.
/// \param userRegistery UserRegistry class instance. It's needed only when running transport in server-mode.
Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry = NULL);
/// Component destructor.
@ -96,9 +93,13 @@ namespace Transport {
/// \return True if the component is in server mode.
bool inServerMode() { return m_server != NULL; }
/// Connects the Jabber server.
/// Starts the Component.
/// In server-mode, it starts listening on particular port for new client connections.
/// In gateway-mode, it connects the XMPP server.
void start();
/// Stops the component.
void stop();
/// Returns Jabber ID of this transport.
@ -139,14 +140,17 @@ namespace Transport {
/// This signal is emitted when presence from XMPP user is received.
/// It's emitted only for presences addressed to transport itself
/// (for example to="j2j.domain.tld").
/// \param presence presence data
/// (for example to="j2j.domain.tld") and for presences comming to
/// MUC (for example to="#chat%irc.freenode.org@irc.domain.tld")
/// \param presence Presence.
boost::signal<void (Swift::Presence::ref presence)> onUserPresenceReceived;
/// Component class asks the XMPP clients automatically for their capabilities.
/// This signal is emitted when capabilities have been received or changed.
/// \param jid JID of the client for which we received capabilities
/// \param info disco#info with response.
boost::signal<void (const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info)> onUserDiscoInfoReceived;
// boost::signal<void (boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid)> onDiscoInfoResponse;
private:
void handleConnected();
void handleConnectionError(const Swift::ComponentError &error);

View file

@ -21,12 +21,13 @@
#pragma once
#include <time.h>
#include "Swiften/Swiften.h"
#include "Swiften/Disco/EntityCapsManager.h"
#include "Swiften/Disco/EntityCapsProvider.h"
#include "storagebackend.h"
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "Swiften/Network/Timer.h"
#include "Swiften/Network/Connection.h"
namespace Transport {

View file

@ -22,8 +22,12 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "transport/userregistry.h"
#include "Swiften/Elements/Message.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/Disco/EntityCapsProvider.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Network/Timer.h"
namespace Transport {
@ -133,6 +137,7 @@ class UserManager : public Swift::EntityCapsProvider {
void handleProbePresence(Swift::Presence::ref presence);
void handleErrorPresence(Swift::Presence::ref presence);
void handleSubscription(Swift::Presence::ref presence);
void handleMUCPresence(Swift::Presence::ref presence);
void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
void handleDiscoInfo(const Swift::JID& jid, boost::shared_ptr<Swift::DiscoInfo> info);
void addUser(User *user);

View file

@ -20,9 +20,10 @@
#pragma once
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/InBandRegistrationPayload.h"
#include "Swiften/Elements/RosterPayload.h"
#include <boost/signal.hpp>
namespace Transport {

View file

@ -22,8 +22,10 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/Server/UserRegistry.h"
#include "Swiften/Network/NetworkFactories.h"
#include "Swiften/Network/Timer.h"
#include "Swiften/Network/TimerFactory.h"
#include "transport/config.h"
namespace Transport {

View file

@ -23,7 +23,8 @@
#include <string>
#include <algorithm>
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Network/Timer.h"
namespace Transport {

View file

@ -21,9 +21,11 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/VCard.h"
#include "Swiften/Network/NetworkFactories.h"
#include "Swiften/Network/Timer.h"
#include <boost/signal.hpp>
namespace Transport {

View file

@ -71,6 +71,9 @@ void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
data += std::string("extraField=") + (*it) + "\n";
}
data += "[features]\n";
data += std::string("muc=") + (cfg.m_supportMUC ? "1" : "0") + "\n";
pbnetwork::BackendConfig m;
m.set_config(data);
@ -82,7 +85,7 @@ void NetworkPlugin::sendConfig(const PluginConfig &cfg) {
send(message);
}
void NetworkPlugin::handleMessage(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname, const std::string &xhtml, const std::string &timestamp, bool headline) {
void NetworkPlugin::handleMessage(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &nickname, const std::string &xhtml, const std::string &timestamp, bool headline, bool pm) {
pbnetwork::ConversationMessage m;
m.set_username(user);
m.set_buddyname(legacyName);
@ -91,6 +94,7 @@ void NetworkPlugin::handleMessage(const std::string &user, const std::string &le
m.set_xhtml(xhtml);
m.set_timestamp(timestamp);
m.set_headline(headline);
m.set_pm(pm);
std::string message;
m.SerializeToString(&message);

View file

@ -17,6 +17,7 @@
#include "transport/adhocmanager.h"
#include "transport/settingsadhoccommand.h"
#include "Swiften/EventLoop/SimpleEventLoop.h"
#include "Swiften/Network/BoostNetworkFactories.h"
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#ifndef WIN32

View file

@ -13,15 +13,15 @@ admin_password=test
#cert=server.pfx #patch to PKCS#12 certificate
#cert_password=test #password to that certificate if any
users_per_backend=10
backend=../..//backends/swiften/spectrum2_swiften_backend
#backend=../..//backends/swiften/spectrum2_swiften_backend
#backend=../../backends/twitter/spectrum2_twitter_backend
#backend=/home/hanzz/code/libtransport/backends/libcommuni/spectrum2_libcommuni_backend
backend=/home/hanzz/code/libtransport/backends/libcommuni/spectrum2_libcommuni_backend
protocol=prpl-jabber
#protocol=prpl-msn
#protocol=any
#protocol=prpl-icq
working_dir=./
portfile=$jid.port
portfile=./$jid.port
irc_server=irc.freenode.org
[backend]

View file

@ -41,7 +41,7 @@ users_per_backend=10
backend=/usr/bin/spectrum2_libpurple_backend
#backend=/usr/bin/spectrum2_libcommuni_backend
# For skype:
#backend=/usr/bin/xvfb-run -n BACKEND_ID -s "-screen 0 10x10x8" -f /tmp/x-skype-gw /usr/bin/spectrum2_skype_backend
#backend=/usr/bin/xvfb-run -a -s "-screen 0 10x10x8" -f /tmp/x-skype-gw /usr/bin/spectrum2_skype_backend
# Libpurple protocol-id for spectrum_libpurple_backend
protocol=prpl-jabber

View file

@ -138,6 +138,9 @@ int main(int argc, char **argv)
else if (command[0] == "list") {
std::vector<std::string> list = show_list(&config);
}
else if (command[0] == "restart") {
return restart_instances(&config);
}
else if (command[0] == "server") {
Server server(&config);
if (server.start() == false) {

View file

@ -24,7 +24,6 @@
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "transport/BlockPayload.h"
#include "Swiften/Swiften.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/buddy.h"

View file

@ -21,9 +21,9 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/SetResponder.h"
#include "transport/BlockPayload.h"
#include <boost/signal.hpp>
namespace Transport {

View file

@ -26,6 +26,8 @@
#include "transport/usermanager.h"
#include "transport/discoitemsresponder.h"
#include "Swiften/Elements/VCardUpdate.h"
namespace Transport {
Buddy::Buddy(RosterManager *rosterManager, long id, BuddyFlag flags) : m_id(id), m_flags(flags), m_rosterManager(rosterManager),

View file

@ -314,6 +314,7 @@ void Config::updateBackendConfig(const std::string &backendConfig) {
("registration.needRegistration", value<bool>()->default_value(false), "")
("registration.extraField", value<std::vector<std::string> >()->multitoken(), "")
("features.receipts", value<bool>()->default_value(false), "")
("features.muc", value<bool>()->default_value(false), "")
;
std::stringstream ifs(backendConfig);

View file

@ -26,6 +26,12 @@
#include "transport/buddy.h"
#include "transport/rostermanager.h"
#include "Swiften/Elements/MUCItem.h"
#include "Swiften/Elements/MUCOccupant.h"
#include "Swiften/Elements/MUCUserPayload.h"
#include "Swiften/Elements/Delay.h"
#include "Swiften/Elements/MUCPayload.h"
namespace Transport {
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
@ -124,7 +130,11 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
message->setFrom(Swift::JID(n, m_conversationManager->getComponent()->getJID().toBare(), "user"));
}
else {
message->setFrom(Swift::JID(m_room, m_conversationManager->getComponent()->getJID().toBare(), n));
std::string legacyName = m_room;
if (legacyName.find_last_of("@") != std::string::npos) {
legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
}
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
}
}
@ -225,19 +235,35 @@ Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int
Swift::MUCUserPayload *p = new Swift::MUCUserPayload ();
if (m_nickname == nickname) {
Swift::MUCUserPayload::StatusCode c;
c.code = 110;
p->addStatusCode(c);
m_sentInitialPresence = true;
if (flag & PARTICIPANT_FLAG_CONFLICT) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::Conflict)));
return presence;
}
else if (flag & PARTICIPANT_FLAG_NOT_AUTHORIZED) {
delete p;
presence->setType(Swift::Presence::Error);
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::ErrorPayload(Swift::ErrorPayload::NotAuthorized, Swift::ErrorPayload::Auth)));
return presence;
}
else {
Swift::MUCUserPayload::StatusCode c;
c.code = 110;
p->addStatusCode(c);
m_sentInitialPresence = true;
}
}
Swift::MUCItem item;
item.affiliation = Swift::MUCOccupant::Member;
item.role = Swift::MUCOccupant::Participant;
if (flag & Moderator) {
if (flag & PARTICIPANT_FLAG_MODERATOR) {
item.affiliation = Swift::MUCOccupant::Admin;
item.role = Swift::MUCOccupant::Moderator;
}
@ -249,13 +275,13 @@ Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int
p->addStatusCode(c);
presence->setType(Swift::Presence::Unavailable);
}
p->addItem(item);
presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
return presence;
}
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
void Conversation::handleParticipantChanged(const std::string &nick, Conversation::ParticipantFlag flag, int status, const std::string &statusMessage, const std::string &newname) {
Swift::Presence::ref presence = generatePresence(nick, flag, status, statusMessage, newname);
if (presence->getType() == Swift::Presence::Unavailable) {

View file

@ -26,9 +26,9 @@
#include "Swiften/Disco/DiscoInfoResponder.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Swiften.h"
#include "transport/config.h"
#include "transport/logging.h"
#include "Swiften/Disco/CapsInfoGenerator.h"
using namespace Swift;
using namespace boost;
@ -39,28 +39,31 @@ namespace Transport {
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
m_config = config;
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateBuddyFeatures, this));
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateFeatures, this));
m_buddyInfo = NULL;
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
CONFIG_STRING(m_config, "identity.category"),
CONFIG_STRING(m_config, "identity.type")));
std::list<std::string> features;
features.push_back("jabber:iq:register");
features.push_back("jabber:iq:gateway");
features.push_back("jabber:iq:private");
features.push_back("http://jabber.org/protocol/disco#info");
features.push_back("http://jabber.org/protocol/commands");
setTransportFeatures(features);
updateBuddyFeatures();
updateFeatures();
}
DiscoInfoResponder::~DiscoInfoResponder() {
delete m_buddyInfo;
}
void DiscoInfoResponder::updateBuddyFeatures() {
void DiscoInfoResponder::updateFeatures() {
std::list<std::string> features2;
features2.push_back("jabber:iq:register");
features2.push_back("jabber:iq:gateway");
features2.push_back("jabber:iq:private");
features2.push_back("http://jabber.org/protocol/disco#info");
features2.push_back("http://jabber.org/protocol/commands");
if (CONFIG_BOOL_DEFAULTED(m_config, "features.muc", false)) {
features2.push_back("http://jabber.org/protocol/muc");
}
setTransportFeatures(features2);
std::list<std::string> features;
features.push_back("http://jabber.org/protocol/disco#items");
features.push_back("http://jabber.org/protocol/disco#info");

View file

@ -21,7 +21,8 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include <list>
#include <boost/signal.hpp>
#include "Swiften/Queries/GetResponder.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Elements/CapsInfo.h"
@ -51,7 +52,7 @@ class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
private:
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> payload);
void updateBuddyFeatures();
void updateFeatures();
Swift::DiscoInfo m_transportInfo;
Swift::DiscoInfo *m_buddyInfo;

View file

@ -23,7 +23,6 @@
#include <iostream>
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Swiften.h"
#include "transport/transport.h"
#include "transport/logging.h"
#include "discoinforesponder.h"

View file

@ -24,6 +24,7 @@
#include "transport/user.h"
#include "transport/buddy.h"
#include "transport/logging.h"
#include "Swiften/Network/ConnectionServerFactory.h"
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/RawXMLPayload.h"
#include "Swiften/Swiften.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/transport.h"
@ -53,7 +52,14 @@ bool GatewayResponder::handleGetRequest(const Swift::JID& from, const Swift::JID
bool GatewayResponder::handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::GatewayPayload> payload) {
std::string prompt = payload->getPrompt();
std::string escaped = Swift::JID::getEscapedNode(prompt);
if (!CONFIG_BOOL_DEFAULTED(m_userManager->getComponent()->getConfig(), "service.jid_escaping", true)) {
escaped = prompt;
if (escaped.find_last_of("@") != std::string::npos) {
escaped.replace(escaped.find_last_of("@"), 1, "%");
}
}
// This code is here to workaround Gajim (and probably other clients bug too) bug
// https://trac.gajim.org/ticket/7277
if (prompt.find("\\40") != std::string::npos) {

View file

@ -136,30 +136,38 @@ static void initLogging(Config *config, std::string key, bool only_create_dir =
p.setProperty("id", id);
#endif
std::string dir;
std::vector<std::string> dirs;
BOOST_FOREACH(const log4cxx::LogString &prop, p.propertyNames()) {
// if (boost::ends_with(prop, ".File")) {
if (boost::ends_with(prop, ".File")) {
std::string dir;
log4cxx::helpers::Transcoder::encode(p.get(prop), dir);
boost::replace_all(dir, "${jid}", jid);
boost::replace_all(dir, "${pid}", pid);
boost::replace_all(dir, "${id}", id);
break;
// }
dirs.push_back(dir);
}
}
mode_t old_cmask;
if (!dir.empty()) {
// create directories
// create directories
#ifndef WIN32
old_cmask = umask(0007);
old_cmask = umask(0007);
#endif
try {
Transport::Util::createDirectories(config, boost::filesystem::path(dir).parent_path());
}
catch (const boost::filesystem::filesystem_error &e) {
std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ": " << e.what() << ".\n";
BOOST_FOREACH(std::string &dir, dirs) {
if (!dir.empty()) {
try {
Transport::Util::createDirectories(config, boost::filesystem::path(dir).parent_path());
}
catch (const boost::filesystem::filesystem_error &e) {
std::cerr << "Can't create logging directory directory " << boost::filesystem::path(dir).parent_path().string() << ": " << e.what() << ".\n";
}
}
}
#ifndef WIN32
umask(old_cmask);
#endif
if (only_create_dir) {
return;
}
@ -168,24 +176,20 @@ static void initLogging(Config *config, std::string key, bool only_create_dir =
// Change owner of main log file
#ifndef WIN32
if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) {
struct group *gr;
if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) {
std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n";
BOOST_FOREACH(std::string &dir, dirs) {
if (!CONFIG_STRING(config, "service.group").empty() && !CONFIG_STRING(config, "service.user").empty()) {
struct group *gr;
if ((gr = getgrnam(CONFIG_STRING(config, "service.group").c_str())) == NULL) {
std::cerr << "Invalid service.group name " << CONFIG_STRING(config, "service.group") << "\n";
}
struct passwd *pw;
if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) {
std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n";
}
chown(dir.c_str(), pw->pw_uid, gr->gr_gid);
}
struct passwd *pw;
if ((pw = getpwnam(CONFIG_STRING(config, "service.user").c_str())) == NULL) {
std::cerr << "Invalid service.user name " << CONFIG_STRING(config, "service.user") << "\n";
}
chown(dir.c_str(), pw->pw_uid, gr->gr_gid);
}
#endif
#ifndef WIN32
if (!dir.empty()) {
umask(old_cmask);
}
#endif
}
}

View file

@ -34,18 +34,24 @@
#include "transport/logging.h"
#include "transport/admininterface.h"
#include "blockresponder.h"
#include "Swiften/Swiften.h"
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Elements/StreamError.h"
#include "Swiften/Network/BoostConnectionServer.h"
#include "Swiften/Network/ConnectionServerFactory.h"
#include "Swiften/Elements/AttentionPayload.h"
#include "Swiften/Elements/XHTMLIMPayload.h"
#include "Swiften/Elements/Delay.h"
#include "Swiften/Elements/DeliveryReceipt.h"
#include "Swiften/Elements/DeliveryReceiptRequest.h"
#include "Swiften/Elements/InvisiblePayload.h"
#include "Swiften/Elements/SpectrumErrorPayload.h"
#include "transport/protocol.pb.h"
#include "transport/util.h"
#include "transport/discoitemsresponder.h"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/signal.hpp"
#include "utf8.h"
#include <Swiften/FileTransfer/ReadBytestream.h>
@ -619,7 +625,7 @@ void NetworkPluginServer::handleParticipantChangedPayload(const std::string &dat
return;
}
conv->handleParticipantChanged(payload.nickname(), payload.flag(), payload.status(), payload.statusmessage(), payload.newname());
conv->handleParticipantChanged(payload.nickname(), (Conversation::ParticipantFlag) payload.flag(), payload.status(), payload.statusmessage(), payload.newname());
}
void NetworkPluginServer::handleRoomChangedPayload(const std::string &data) {
@ -680,7 +686,6 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool
msg->addPayload(delay);
}
NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.buddyname());
// We can't create Conversation for payload with nickname, because this means the message is from room,
@ -689,6 +694,19 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool
return;
}
if (conv && payload.pm()) {
conv = (NetworkConversation *) user->getConversationManager()->getConversation(payload.buddyname() + "/" + payload.nickname());
if (!conv) {
conv = new NetworkConversation(user->getConversationManager(), payload.nickname());
std::string name = payload.buddyname();
conv->setRoom(name);
conv->setNickname(payload.buddyname() + "/" + payload.nickname());
user->getConversationManager()->addConversation(conv);
conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2));
}
}
// Create new Conversation if it does not exist
if (!conv) {
conv = new NetworkConversation(user->getConversationManager(), payload.buddyname());
@ -1247,6 +1265,9 @@ void NetworkPluginServer::handleUserCreated(User *user) {
user->onPresenceChanged.connect(boost::bind(&NetworkPluginServer::handleUserPresenceChanged, this, user, _1));
user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3, _4));
user->onRoomLeft.connect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
user->getRosterManager()->onBuddyAdded.connect(boost::bind(&NetworkPluginServer::handleUserBuddyAdded, this, user, _1));
user->getRosterManager()->onBuddyRemoved.connect(boost::bind(&NetworkPluginServer::handleUserBuddyRemoved, this, user, _1));
}
void NetworkPluginServer::handleUserReadyToConnect(User *user) {
@ -1352,6 +1373,9 @@ void NetworkPluginServer::handleUserDestroyed(User *user) {
user->onRoomJoined.disconnect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3, _4));
user->onRoomLeft.disconnect(boost::bind(&NetworkPluginServer::handleRoomLeft, this, user, _1));
user->getRosterManager()->onBuddyAdded.disconnect(boost::bind(&NetworkPluginServer::handleUserBuddyAdded, this, user, _1));
user->getRosterManager()->onBuddyRemoved.disconnect(boost::bind(&NetworkPluginServer::handleUserBuddyRemoved, this, user, _1));
pbnetwork::Logout logout;
logout.set_user(user->getJID().toBare());
logout.set_legacyname(userInfo.uin);
@ -1532,6 +1556,32 @@ void NetworkPluginServer::handleBuddyAdded(Buddy *buddy, const Swift::RosterItem
handleBuddyUpdated(buddy, item);
}
void NetworkPluginServer::handleUserBuddyAdded(User *user, Buddy *b) {
pbnetwork::Buddy buddy;
buddy.set_username(user->getJID().toBare());
buddy.set_buddyname(b->getName());
buddy.set_alias(b->getAlias());
BOOST_FOREACH(const std::string &g, b->getGroups()) {
buddy.add_group(g);
}
buddy.set_status(pbnetwork::STATUS_NONE);
std::string message;
buddy.SerializeToString(&message);
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_BUDDY_CHANGED);
Backend *c = (Backend *) user->getData();
if (!c) {
return;
}
send(c->connection, message);
}
void NetworkPluginServer::handleUserBuddyRemoved(User *user, Buddy *b) {
handleBuddyRemoved(b);
}
void NetworkPluginServer::handleBlockToggled(Buddy *b) {
User *user = b->getRosterManager()->getUser();

View file

@ -19,7 +19,7 @@
*/
#include "transport/presenceoracle.h"
#include "Swiften/Swiften.h"
#include "Swiften/Elements/MUCPayload.h"
#include <boost/bind.hpp>
@ -52,9 +52,8 @@ void PresenceOracle::clearPresences(const Swift::JID& bareJID) {
void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
// ignore presences for some contact, we're checking only presences for the transport itself here.
bool isMUC = presence->getPayload<MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
// filter out login/logout presence spam
if (!presence->getTo().getNode().empty() && isMUC == false)
if (!presence->getTo().getNode().empty())
return;
JID bareJID(presence->getFrom().toBare());
@ -62,29 +61,27 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
}
else {
Presence::ref passedPresence = presence;
if (!isMUC) {
if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) {
/* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
passedPresence = Presence::ref(new Presence());
passedPresence->setType(Presence::Unavailable);
passedPresence->setFrom(bareJID);
passedPresence->setStatus(presence->getStatus());
}
std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID];
if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
/* Have a bare-JID only presence of offline */
jidMap.clear();
} else if (passedPresence->getType() == Presence::Available) {
/* Don't have a bare-JID only offline presence once there are available presences */
jidMap.erase(bareJID);
}
if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) {
jidMap.erase(passedPresence->getFrom());
} else {
jidMap[passedPresence->getFrom()] = passedPresence;
}
entries_[bareJID] = jidMap;
if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) {
/* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
passedPresence = Presence::ref(new Presence());
passedPresence->setType(Presence::Unavailable);
passedPresence->setFrom(bareJID);
passedPresence->setStatus(presence->getStatus());
}
std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID];
if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
/* Have a bare-JID only presence of offline */
jidMap.clear();
} else if (passedPresence->getType() == Presence::Available) {
/* Don't have a bare-JID only offline presence once there are available presences */
jidMap.erase(bareJID);
}
if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) {
jidMap.erase(passedPresence->getFrom());
} else {
jidMap[passedPresence->getFrom()] = passedPresence;
}
entries_[bareJID] = jidMap;
onPresenceChange(passedPresence);
}
}

View file

@ -30,7 +30,10 @@
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Elements/RosterItemPayload.h"
#include "Swiften/Elements/RosterItemExchangePayload.h"
#include "Swiften/Elements/Nickname.h"
#include "Swiften/Queries/IQRouter.h"
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <map>
#include <iterator>
@ -151,12 +154,7 @@ void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
Swift::RosterItemPayload item;
item.setJID(buddy->getJID().toBare());
if (buddy->getAlias().empty()) {
item.setName(buddy->getJID().toBare().toString());
}
else {
item.setName(buddy->getAlias());
}
item.setName(buddy->getAlias());
item.setGroups(buddy->getGroups());
item.setSubscription(Swift::RosterItemPayload::Both);
@ -280,6 +278,15 @@ void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPa
LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server supports remote roster protoXEP");
m_supportRemoteRoster = true;
//If we receive empty RosterPayload on login (not register) initiate full RosterPush
if(!m_buddies.empty() && payload->getItems().empty()){
LOG4CXX_INFO(logger, "Received empty Roster upon login. Pushing full Roster.");
for(std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > >::const_iterator c_it = m_buddies.begin();
c_it != m_buddies.end(); c_it++) {
sendBuddyRosterPush(c_it->second);
}
}
return;
BOOST_FOREACH(const Swift::RosterItemPayload &item, payload->getItems()) {
@ -490,6 +497,7 @@ void RosterManager::handleSubscription(Swift::Presence::ref presence) {
buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
setBuddy(buddy);
onBuddyAdded(buddy);
LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received for new buddy " << buddyInfo.legacyName << " => adding to legacy network");
response->setType(Swift::Presence::Subscribed);
break;
case Swift::Presence::Unsubscribe:

View file

@ -23,7 +23,6 @@
#include <iostream>
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Swiften.h"
#include "transport/user.h"
#include "transport/usermanager.h"
#include "transport/rostermanager.h"

View file

@ -24,6 +24,8 @@
#include "transport/storagebackend.h"
#include "transport/logging.h"
#include "Swiften/Network/NetworkFactories.h"
DEFINE_LOGGER(logger, "RosterStorage");
namespace Transport {

View file

@ -24,7 +24,6 @@
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "transport/BlockPayload.h"
#include "Swiften/Swiften.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/buddy.h"

View file

@ -4,8 +4,8 @@
#include "transport/sqlite3backend.h"
#include "transport/mysqlbackend.h"
#include "transport/pqxxbackend.h"
#include "Swiften/StringCodecs/Base64.h"
#include "Swiften/Swiften.h"
namespace Transport {

View file

@ -24,7 +24,9 @@
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Elements/RawXMLPayload.h"
#include "Swiften/Swiften.h"
#include "Swiften/Elements/Storage.h"
#include "Swiften/Elements/Storage.h"
#include "Swiften/Serializer/PayloadSerializers/StorageSerializer.h"
#include "transport/usermanager.h"
#include "transport/user.h"
#include "transport/logging.h"

View file

@ -21,9 +21,9 @@
#pragma once
#include <vector>
#include "Swiften/Swiften.h"
#include "Swiften/Queries/Responder.h"
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Elements/PrivateStorage.h"
namespace Transport {

View file

@ -35,6 +35,8 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_TEST(handleParticipantChangedTwoResources);
CPPUNIT_TEST(handlePMFromXMPP);
CPPUNIT_TEST(handleGroupchatRemoved);
CPPUNIT_TEST(handleNicknameConflict);
CPPUNIT_TEST(handleNotAuthorized);
CPPUNIT_TEST_SUITE_END();
public:
@ -115,7 +117,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
// this user presence - status code 110
conv->handleParticipantChanged("nickname", 1, Swift::StatusShow::Away, "my status message");
conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
@ -343,17 +345,17 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
injectPresence(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(4, (int) received.size());
CPPUNIT_ASSERT_EQUAL(3, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[1])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[3])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getFrom().toString());
}
void handleGroupchatMessagesBouncerLeave() {
@ -408,17 +410,17 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
injectPresence(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(4, (int) received.size());
CPPUNIT_ASSERT_EQUAL(3, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[1])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[2]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[3])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getFrom().toString());
}
void handleGroupchatMessagesTwoResources() {
@ -472,7 +474,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
conv->addJID("user@localhost/resource");
// normal presence
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
@ -487,7 +489,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
received.clear();
// this user presence - status code 110
conv->handleParticipantChanged("nickname", 1, Swift::StatusShow::Away, "my status message");
conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
@ -503,7 +505,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
received.clear();
// renamed - status code 303
conv->handleParticipantChanged("anotheruser", 1, Swift::StatusShow::Away, "my status message", "hanzz");
conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message", "hanzz");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
@ -530,7 +532,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
conv->addJID("user@localhost/resource2");
// normal presence
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
@ -551,7 +553,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
conv->setNickname("nickname");
conv->setJID("user@localhost/resource");
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
loop->processEvents();
received.clear();
@ -593,6 +595,44 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
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());
}
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());
}
};
CPPUNIT_TEST_SUITE_REGISTRATION (ConversationManagerTest);

View file

@ -23,6 +23,7 @@ using namespace Transport;
class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_TEST_SUITE(RosterManagerTest);
CPPUNIT_TEST(setBuddy);
CPPUNIT_TEST(setBuddyNoAlias);
CPPUNIT_TEST(sendCurrentPresences);
CPPUNIT_TEST(sendUnavailablePresences);
CPPUNIT_TEST(sendCurrentPresence);
@ -72,6 +73,25 @@ class RosterManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
}
void setBuddyNoAlias() {
User *user = userManager->getUser("user@localhost");
CPPUNIT_ASSERT(user);
std::vector<std::string> grp;
grp.push_back("group1");
LocalBuddy *buddy = new LocalBuddy(user->getRosterManager(), -1, "buddy1", "", grp, BUDDY_JID_ESCAPING);
user->getRosterManager()->setBuddy(buddy);
CPPUNIT_ASSERT_EQUAL(1, (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(""), item.getName());
}
void setBuddy() {
add2Buddies();
CPPUNIT_ASSERT_EQUAL(4, (int) received.size());

View file

@ -125,7 +125,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
User *user = userManager->getUser("user@localhost");
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
Swift::MUCPayload *payload = new Swift::MUCPayload();
@ -134,11 +134,8 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
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(0, (int) received.size());
CPPUNIT_ASSERT_EQUAL(std::string("room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword);
@ -147,7 +144,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
roomPassword = "";
// simulate that backend joined the room
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "room", true);
conv->addJID("user@localhost/resource");
user->getConversationManager()->addConversation(conv);
@ -156,8 +153,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
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(0, (int) received.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
@ -169,14 +165,14 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
User *user = userManager->getUser("user@localhost");
// Add 1 participant
Conversation *conv = user->getConversationManager()->getConversation("#room");
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
Conversation *conv = user->getConversationManager()->getConversation("room");
conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message");
// Connect 2nd resource
connectSecondResource();
received2.clear();
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource2");
Swift::MUCPayload *payload = new Swift::MUCPayload();
@ -189,19 +185,20 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
CPPUNIT_ASSERT_EQUAL(2, (int) received2.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[1])));
CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getShow());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getFrom().toString());
CPPUNIT_ASSERT(getStanza(received2[1])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
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);
}
void handlePresenceLeaveRoom() {
received.clear();
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
response->setType(Swift::Presence::Unavailable);
@ -213,9 +210,9 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
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);
// CPPUNIT_ASSERT_EQUAL(std::string("room"), room);
// CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
// CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
}
void handlePresenceLeaveRoomTwoResources() {
@ -224,7 +221,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
// User is still connected from resource2, so he should not leave the room
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
response->setType(Swift::Presence::Unavailable);
@ -243,7 +240,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
// disconnect also from resource
// User is still connected from resource2, so he should not leave the room
response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource2");
response->setType(Swift::Presence::Unavailable);
@ -255,7 +252,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("room"), room);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
}
@ -278,7 +275,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
Conversation *conv = user->getConversationManager()->getConversation("#room");
Conversation *conv = user->getConversationManager()->getConversation("room");
CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size());
CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front());
}
@ -287,7 +284,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
User *user = userManager->getUser("user@localhost");
user->addUserSetting("stay_connected", "1");
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
response->setType(Swift::Presence::Unavailable);
@ -312,7 +309,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
// User is still connected from resource2, so he should not leave the room
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
response->setType(Swift::Presence::Unavailable);
@ -332,7 +329,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
// disconnect also from resource
// User is still connected from resource2, so he should not leave the room
response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource2");
response->setType(Swift::Presence::Unavailable);
@ -368,7 +365,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
Conversation *conv = user->getConversationManager()->getConversation("#room");
Conversation *conv = user->getConversationManager()->getConversation("room");
CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size());
CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front());
}
@ -377,12 +374,12 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
User *user = userManager->getUser("user@localhost");
handlePresenceJoinRoom();
CPPUNIT_ASSERT(user->getConversationManager()->getConversation("#room"));
CPPUNIT_ASSERT(user->getConversationManager()->getConversation("room"));
received.clear();
handlePresenceLeaveRoom();
CPPUNIT_ASSERT(!user->getConversationManager()->getConversation("#room"));
CPPUNIT_ASSERT(!user->getConversationManager()->getConversation("room"));
}
void handleDisconnected() {
@ -427,7 +424,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
user->setConnected(false);
Swift::Presence::ref response = Swift::Presence::create();
response->setTo("#room@localhost/hanzz");
response->setTo("room@localhost/hanzz");
response->setFrom("user@localhost/resource");
Swift::MUCPayload *payload = new Swift::MUCPayload();
@ -436,16 +433,13 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
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(0, (int) received.size());
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
user->setConnected(true);
CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword);
}
@ -460,7 +454,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
received.clear();
user->setConnected(true);
CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("room"), room);
CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname);
CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword);
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());

View file

@ -6,6 +6,8 @@
#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>
using namespace Transport;

View file

@ -51,7 +51,7 @@
#include "transport/BlockSerializer.h"
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
#include "Swiften/Swiften.h"
#include "Swiften/Parser/GenericPayloadParserFactory.h"
using namespace Swift;
using namespace boost;
@ -275,9 +275,8 @@ void Component::handleDataWritten(const Swift::SafeByteArray &data) {
}
void Component::handlePresence(Swift::Presence::ref presence) {
bool isMUC = presence->getPayload<MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
// filter out login/logout presence spam
if (!presence->getTo().getNode().empty() && isMUC == false)
if (!presence->getTo().getNode().empty())
return;
// filter out bad presences

View file

@ -26,7 +26,6 @@
#include "transport/conversationmanager.h"
#include "transport/presenceoracle.h"
#include "transport/logging.h"
#include "Swiften/Swiften.h"
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Elements/StreamError.h"
#include "Swiften/Elements/MUCPayload.h"
@ -195,11 +194,6 @@ void User::setCacheMessages(bool cacheMessages) {
}
void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size();
m_conversationManager->resetResources();
LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString());
if (!m_connected) {
// we are not connected to legacy network, so we should do it when disco#info arrive :)
@ -231,8 +225,9 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
}
}
bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
if (isMUC) {
if (!presence->getTo().getNode().empty()) {
bool isMUC = presence->getPayload<Swift::MUCPayload>() != NULL || *presence->getTo().getNode().c_str() == '#';
if (presence->getType() == Swift::Presence::Unavailable) {
std::string room = Buddy::JIDToLegacyName(presence->getTo());
Conversation *conv = m_conversationManager->getConversation(room);
@ -242,6 +237,9 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
return;
}
}
else {
return;
}
if (getUserSetting("stay_connected") != "1") {
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
@ -260,7 +258,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
}
}
}
else {
else if (isMUC) {
// force connection to legacy network to let backend to handle auto-join on connect.
if (!m_readyForConnect) {
LOG4CXX_INFO(logger, m_jid.toString() << ": Ready to be connected to legacy network");
@ -317,9 +315,29 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
}
return;
}
int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size();
m_conversationManager->resetResources();
if (presence->getType() == Swift::Presence::Unavailable) {
m_conversationManager->removeJID(presence->getFrom());
std::string presences;
std::vector<Swift::Presence::ref> ps = m_presenceOracle->getAllPresence(m_jid);
BOOST_FOREACH(Swift::Presence::ref p, ps) {
if (p != presence) {
presences += p->getFrom().toString() + " ";
}
};
if (!presences.empty()) {
LOG4CXX_INFO(logger, m_jid.toString() << ": User is still connected from following clients: " << presences);
}
else {
LOG4CXX_INFO(logger, m_jid.toString() << ": Last client disconnected");
}
}

View file

@ -29,9 +29,10 @@
#include "transport/discoitemsresponder.h"
#include "storageresponder.h"
#include "Swiften/Swiften.h"
#include "Swiften/Server/ServerStanzaChannel.h"
#include "Swiften/Elements/StreamError.h"
#include "Swiften/Elements/MUCPayload.h"
#include "Swiften/Elements/ChatState.h"
#ifndef __FreeBSD__
#include "malloc.h"
#endif
@ -229,7 +230,7 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
res.password = "";
res.uin = presence->getFrom().getNode();
res.jid = userkey;
if (res.uin.find_last_of("%") != std::string::npos) { // OK
while (res.uin.find_last_of("%") != std::string::npos) { // OK
res.uin.replace(res.uin.find_last_of("%"), 1, "@"); // OK
}
if (m_storageBackend) {
@ -399,6 +400,7 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) {
break;
case Swift::Presence::Available:
case Swift::Presence::Unavailable:
handleMUCPresence(presence);
break;
case Swift::Presence::Probe:
handleProbePresence(presence);
@ -411,6 +413,24 @@ void UserManager::handleGeneralPresenceReceived(Swift::Presence::ref presence) {
};
}
void UserManager::handleMUCPresence(Swift::Presence::ref presence) {
// Don't let RosterManager to handle presences for us
if (presence->getTo().getNode().empty()) {
return;
}
if (presence->getType() == Swift::Presence::Available) {
handlePresence(presence);
}
else if (presence->getType() == Swift::Presence::Unavailable) {
std::string userkey = presence->getFrom().toBare().toString();
User *user = getUser(userkey);
if (user) {
user->handlePresence(presence);
}
}
}
void UserManager::handleProbePresence(Swift::Presence::ref presence) {
// Don't let RosterManager to handle presences for us
if (presence->getTo().getNode().empty()) {

View file

@ -26,6 +26,9 @@
#include "transport/user.h"
#include "transport/logging.h"
#include "Swiften/Elements/ErrorPayload.h"
#include "Swiften/EventLoop/SimpleEventLoop.h"
#include "Swiften/Network/BoostNetworkFactories.h"
#include "Swiften/Client/Client.h"
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

View file

@ -20,7 +20,6 @@
#include <string>
#include <map>
#include "Swiften/Swiften.h"
#include "Swiften/Server/UserRegistry.h"
#include "transport/userregistry.h"
#include "transport/logging.h"
@ -79,9 +78,6 @@ void UserRegistry::stopLogin(const Swift::JID& user, Swift::ServerFromClientSess
LOG4CXX_WARN(logger, key << ": Stopping login process (user probably disconnected while logging in), but this is not active session");
}
}
else {
LOG4CXX_WARN(logger, key << ": Stopping login process (user probably disconnected while logging in) for invalid user");
}
// ::removeLater can be called only by libtransport, not by Swift and libtransport
// takes care about user disconnecting itself, so don't call our signal.
@ -96,21 +92,15 @@ void UserRegistry::onPasswordValid(const Swift::JID &user) {
users[key].session->handlePasswordValid();
users.erase(key);
}
else {
LOG4CXX_INFO(logger, key << ": onPasswordValid called for invalid user");
}
}
void UserRegistry::onPasswordInvalid(const Swift::JID &user, const std::string &error) {
std::string key = user.toBare().toString();
if (users.find(key) != users.end()) {
LOG4CXX_INFO(logger, key << ": Password is invalid");
LOG4CXX_INFO(logger, key << ": Password is invalid or there was an error when connecting the legacy network");
users[key].session->handlePasswordInvalid(error);
users.erase(key);
}
else {
LOG4CXX_INFO(logger, key << ": onPasswordInvalid called for invalid user");
}
}
void UserRegistry::handleRemoveTimeout(const Swift::JID &user) {

View file

@ -23,11 +23,12 @@
#include <iostream>
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Swiften.h"
#include "transport/storagebackend.h"
#include "transport/transport.h"
#include "transport/logging.h"
#include "Swiften/Network/NetworkFactories.h"
using namespace Swift;
using namespace boost;

View file

@ -23,7 +23,6 @@
#include <iostream>
#include <boost/bind.hpp>
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Swiften.h"
#include "transport/user.h"
#include "transport/usermanager.h"
#include "transport/rostermanager.h"