From 65ad5a210697f9e497ba1511bde24433b9bbee05 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 24 Jan 2013 08:35:24 +0100 Subject: [PATCH] Communi: Log 4xx errors and forward 433, 436 and 464 to XMPP client --- backends/libcommuni/session.cpp | 20 ++++++++++++ src/conversation.cpp | 29 +++++++++++++---- src/tests/conversationmanager.cpp | 52 +++++++++++++++++++++++++++---- src/tests/user.cpp | 2 +- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/backends/libcommuni/session.cpp b/backends/libcommuni/session.cpp index 64993a6c..203a748a 100644 --- a/backends/libcommuni/session.cpp +++ b/backends/libcommuni/session.cpp @@ -272,6 +272,22 @@ void MyIrcSession::on_numericMessageReceived(IrcMessage *message) { 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); + } + 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); + } + np->handleDisconnected(user, pbnetwork::CONNECTION_ERROR_INVALID_USERNAME, "Password incorrect"); case 321: m_rooms.clear(); m_names.clear(); @@ -287,6 +303,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; } diff --git a/src/conversation.cpp b/src/conversation.cpp index 44af07b4..c9be3d3d 100644 --- a/src/conversation.cpp +++ b/src/conversation.cpp @@ -30,6 +30,7 @@ #include "Swiften/Elements/MUCOccupant.h" #include "Swiften/Elements/MUCUserPayload.h" #include "Swiften/Elements/Delay.h" +#include "Swiften/Elements/MUCPayload.h" namespace Transport { @@ -230,13 +231,29 @@ 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(new Swift::MUCPayload())); + presence->addPayload(boost::shared_ptr(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(new Swift::MUCPayload())); + presence->addPayload(boost::shared_ptr(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; @@ -254,7 +271,7 @@ 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(p)); return presence; diff --git a/src/tests/conversationmanager.cpp b/src/tests/conversationmanager.cpp index 5c9851ec..cf3caf3d 100644 --- a/src/tests/conversationmanager.cpp +++ b/src/tests/conversationmanager.cpp @@ -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()); @@ -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()->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(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast(getStanza(received[0]))->getType()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::Conflict, getStanza(received[0])->getPayload()->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(getStanza(received[0]))); + CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast(getStanza(received[0]))->getType()); + CPPUNIT_ASSERT(getStanza(received[0])->getPayload()); + CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::NotAuthorized, getStanza(received[0])->getPayload()->getCondition()); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION (ConversationManagerTest); diff --git a/src/tests/user.cpp b/src/tests/user.cpp index 0575f979..d3e58e3b 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -170,7 +170,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { // Add 1 participant Conversation *conv = user->getConversationManager()->getConversation("#room"); - conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message"); + conv->handleParticipantChanged("anotheruser", Conversation::PARTICIPANT_FLAG_NONE, Swift::StatusShow::Away, "my status message"); // Connect 2nd resource connectSecondResource();