Libtransport: Rename user when he tries to connect to room from second client with different nickname than he used with first client

This commit is contained in:
Jan Kaluza 2016-02-10 17:02:06 +01:00
parent 5c595ccf83
commit c80c02ccb1
4 changed files with 76 additions and 30 deletions

View file

@ -139,7 +139,7 @@ class Conversation {
void destroyRoom();
std::string getParticipants();
void sendParticipants(const Swift::JID &to);
void sendParticipants(const Swift::JID &to, const std::string &nickname);
void sendCachedMessages(const Swift::JID &to = Swift::JID());
@ -160,6 +160,7 @@ class Conversation {
bool m_sentInitialPresence;
bool m_nicknameChanged;
bool m_mucEscaping;
bool m_sentInitialSubject;
// TODO: Move this to some extra class to cache the most used
// rooms across different accounts. Just now if we have 10 users

View file

@ -47,6 +47,7 @@ Conversation::Conversation(ConversationManager *conversationManager, const std::
m_sentInitialPresence = false;
m_nicknameChanged = false;
m_mucEscaping = false;
m_sentInitialSubject = false;
if (CONFIG_BOOL_DEFAULTED(conversationManager->getComponent()->getConfig(), "features.rawxml", false)) {
m_sentInitialPresence = true;
@ -128,9 +129,11 @@ void Conversation::handleRawMessage(boost::shared_ptr<Swift::Message> &message)
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
message->setTo(jid);
// Subject has to be sent after our own presence (the one with code 110)
if (!message->getSubject().empty() && m_sentInitialPresence == false) {
if (!message->getSubject().empty()) {
m_subject = message;
return;
if (m_sentInitialPresence == false) {
return;
}
}
m_conversationManager->getComponent()->getFrontend()->sendMessage(message);
}
@ -227,7 +230,33 @@ std::string Conversation::getParticipants() {
return ret;
}
void Conversation::sendParticipants(const Swift::JID &to) {
void Conversation::sendParticipants(const Swift::JID &to, const std::string &nickname) {
// When user tries to join this room from another resource using
// different nickname than the original one has, we have to rename
// him.
if (m_nickname != nickname && !nickname.empty()) {
Swift::Presence::ref presence;
std::string tmp = m_nickname;
// At first connect the user.
m_nickname = nickname;
presence = generatePresence(nickname, 0, (int) Swift::StatusShow::Online, "", "", "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
// Now change his nickname to the right one.
m_nicknameChanged = true;
presence = generatePresence(nickname, 0, (int) Swift::StatusShow::Online, "", tmp, "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
// And send the presence from as new user
m_nickname = tmp;
presence = generatePresence(m_nickname, 0, (int) Swift::StatusShow::Online, "", "", "");
presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence(presence);
}
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
(*it).second.presence->setTo(to);
m_conversationManager->getComponent()->getFrontend()->sendPresence((*it).second.presence);
@ -385,9 +414,9 @@ void Conversation::handleParticipantChanged(const std::string &nick, Conversatio
handleParticipantChanged(newname, flag, status, statusMessage, "", iconhash);
}
if (m_sentInitialPresence && m_subject) {
if (m_sentInitialPresence && !m_sentInitialSubject && m_subject) {
m_sentInitialSubject = true;
m_conversationManager->getComponent()->getFrontend()->sendMessage(m_subject);
m_subject.reset();
}
// We send error presences only to inform user that he is disconnected

View file

@ -259,7 +259,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
}
else {
conv->addJID(presence->getFrom());
conv->sendParticipants(presence->getFrom());
conv->sendParticipants(presence->getFrom(), presence->getTo().getResource());
conv->sendCachedMessages(presence->getFrom());
}

View file

@ -122,7 +122,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
// this user presence - status code 110
conv->handleParticipantChanged("nickname", Conversation::PARTICIPANT_FLAG_MODERATOR, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(2, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[1])));
CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast<Swift::Message *>(getStanza(received[1]))->getSubject());
@ -410,21 +410,29 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
injectPresence(response);
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(4, (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_EQUAL(7, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[2])));
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getType());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/hanzz"), dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getFrom().toString());
CPPUNIT_ASSERT(getStanza(received[2])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(std::string("nickname"), *getStanza(received[2])->getPayload<Swift::MUCUserPayload>()->getItems()[0].nick);
CPPUNIT_ASSERT_EQUAL(303, getStanza(received[2])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[2].code);
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
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[4])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[3])));
CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast<Swift::Message *>(getStanza(received[3]))->getSubject());
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());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[5])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[6])));
CPPUNIT_ASSERT_EQUAL(std::string("subject"), dynamic_cast<Swift::Message *>(getStanza(received[6]))->getSubject());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[6]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[6]))->getFrom().toString());
}
void handleGroupchatMessagesBouncerLeave() {
@ -479,16 +487,24 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
injectPresence(response);
loop->processEvents();
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_EQUAL(6, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[2])));
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Unavailable, dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getType());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/hanzz"), dynamic_cast<Swift::Presence *>(getStanza(received[2]))->getFrom().toString());
CPPUNIT_ASSERT(getStanza(received[2])->getPayload<Swift::MUCUserPayload>());
CPPUNIT_ASSERT_EQUAL(std::string("nickname"), *getStanza(received[2])->getPayload<Swift::MUCUserPayload>()->getItems()[0].nick);
CPPUNIT_ASSERT_EQUAL(303, getStanza(received[2])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[2].code);
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[2])));
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[4])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[4]))->getFrom().toString());
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received[5])));
CPPUNIT_ASSERT_EQUAL(std::string("hi there2!"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getBody());
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getTo().toString());
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received[5]))->getFrom().toString());
}