Changeset - 10d29c265be5
[Not reviewed]
0 4 0
Jan Kaluza - 10 years ago 2016-02-04 15:12:23
jkaluza@redhat.com
Conversation: Use full JID escaping when \40 found in the room JID
4 files changed with 41 insertions and 4 deletions:
0 comments (0 inline, 0 general)
include/transport/Conversation.h
Show inline comments
 
@@ -148,12 +148,14 @@ class Conversation {
 

	
 
		std::string getParticipants();
 
		void sendParticipants(const Swift::JID &to);
 

	
 
		void sendCachedMessages(const Swift::JID &to = Swift::JID());
 

	
 
		void setMUCEscaping(bool mucEscaping);
 

	
 
	private:
 
		Swift::Presence::ref generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname = "");
 
		void cacheMessage(boost::shared_ptr<Swift::Message> &message);
 

	
 
	private:
 
		ConversationManager *m_conversationManager;
 
@@ -162,12 +164,13 @@ class Conversation {
 
		std::string m_room;
 
		bool m_muc;
 
		Swift::JID m_jid;
 
		std::list<Swift::JID> m_jids;
 
		bool m_sentInitialPresence;
 
		bool m_nicknameChanged;
 
		bool m_mucEscaping;
 

	
 
		// TODO: Move this to some extra class to cache the most used
 
		// rooms across different accounts. Just now if we have 10 users
 
		// connected to single room, we store all those things 10 times.
 
		// It would be also great to store last 100 messages per room
 
		// every time, so we can get history messages for IRC for example.
libtransport/Conversation.cpp
Show inline comments
 
@@ -42,26 +42,32 @@ DEFINE_LOGGER(logger, "Conversation");
 
Conversation::Conversation(ConversationManager *conversationManager, const std::string &legacyName, bool isMUC) : m_conversationManager(conversationManager) {
 
	m_legacyName = legacyName;
 
	m_muc = isMUC;
 
	m_jid = m_conversationManager->getUser()->getJID().toBare();
 
	m_sentInitialPresence = false;
 
	m_nicknameChanged = false;
 
	m_mucEscaping = false;
 

	
 
	if (CONFIG_BOOL_DEFAULTED(conversationManager->getComponent()->getConfig(), "features.rawxml", false)) {
 
		m_sentInitialPresence = true;
 
	}
 
}
 

	
 
Conversation::~Conversation() {
 
}
 

	
 
void Conversation::setMUCEscaping(bool mucEscaping) {
 
	LOG4CXX_INFO(logger, m_jid.toString() << ": Setting MUC escaping to " << mucEscaping);
 
	m_mucEscaping = mucEscaping;
 
}
 

	
 
void Conversation::destroyRoom() {
 
	if (m_muc) {
 
		Swift::Presence::ref presence = Swift::Presence::create();
 
		std::string legacyName = m_legacyName;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
		if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
		legacyName = Swift::JID::getEscapedNode(legacyName);
 
		presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), m_nickname));
 
		presence->setType(Swift::Presence::Unavailable);
 

	
 
@@ -177,23 +183,23 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
 
		else {
 
			if (m_room.empty()) {
 
				message->setFrom(Swift::JID(n, m_conversationManager->getComponent()->getJID().toBare(), "user"));
 
			}
 
			else {
 
				std::string legacyName = m_room;
 
				if (legacyName.find_last_of("@") != std::string::npos) {
 
				if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
 
					legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
				}
 
				legacyName = Swift::JID::getEscapedNode(legacyName);
 
				message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
 
			}
 
		}
 
	}
 
	else {
 
		std::string legacyName = m_legacyName;
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
		if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
		legacyName = Swift::JID::getEscapedNode(legacyName);
 

	
 
		std::string n = nickname;
 
		if (n.empty()) {
 
@@ -248,13 +254,13 @@ void Conversation::sendCachedMessages(const Swift::JID &to) {
 

	
 
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
 
	std::string nickname = nick;
 
	Swift::Presence::ref presence = Swift::Presence::create();
 
	std::string legacyName = m_legacyName;
 
	if (m_muc) {
 
		if (legacyName.find_last_of("@") != std::string::npos) {
 
		if (!m_mucEscaping && legacyName.find_last_of("@") != std::string::npos) {
 
			legacyName.replace(legacyName.find_last_of("@"), 1, "%"); // OK
 
		}
 
		legacyName = Swift::JID::getEscapedNode(legacyName);
 
	}
 
	presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
 
	presence->setType(Swift::Presence::Available);
libtransport/User.cpp
Show inline comments
 
@@ -289,12 +289,16 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
 

	
 
			conv = m_component->getFactory()->createConversation(m_conversationManager, room, true);
 
			m_conversationManager->addConversation(conv);
 
			conv->setNickname(presence->getTo().getResource());
 
			conv->addJID(presence->getFrom());
 

	
 
			if (presence->getTo().toString().find("\\40") != std::string::npos) {
 
				conv->setMUCEscaping(true);
 
			}
 

	
 
			onRawPresenceReceived(presence);
 
			onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password);
 

	
 
			return;
 
		}
 

	
tests/libtransport/conversationmanager.cpp
Show inline comments
 
@@ -23,12 +23,13 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
	CPPUNIT_TEST(handleGroupchatMessagesBouncerLeave);
 
	CPPUNIT_TEST(handleGroupchatMessagesTwoResources);
 
	CPPUNIT_TEST(handleChatstateMessages);
 
	CPPUNIT_TEST(handleSubjectMessages);
 
	CPPUNIT_TEST(handleParticipantChanged);
 
	CPPUNIT_TEST(handleParticipantChangedEscaped);
 
	CPPUNIT_TEST(handleParticipantChangedEscaped2);
 
	CPPUNIT_TEST(handleParticipantChangedTwoResources);
 
	CPPUNIT_TEST(handlePMFromXMPP);
 
	CPPUNIT_TEST(handleGroupchatRemoved);
 
	CPPUNIT_TEST(handleNicknameConflict);
 
	CPPUNIT_TEST(handleNotAuthorized);
 
	CPPUNIT_TEST(handleSetNickname);
 
@@ -568,12 +569,35 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
 
		CPPUNIT_ASSERT_EQUAL(std::string("19\\3a70027094a9c84c518535a610766bed65%thread.skype@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getFrom().toString());
 
		CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::MUCUserPayload>());
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
 
		CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
 
	}
 

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

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

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

	
 
	void handleParticipantChangedTwoResources() {
 
		connectSecondResource();
 
		received2.clear();
 
		User *user = userManager->getUser("user@localhost");
 
		TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
 
		
0 comments (0 inline, 0 general)