diff options
Diffstat (limited to 'Swiften/MUC')
-rw-r--r-- | Swiften/MUC/MUC.cpp | 98 | ||||
-rw-r--r-- | Swiften/MUC/MUC.h | 27 | ||||
-rw-r--r-- | Swiften/MUC/MUCBookmark.h | 4 | ||||
-rw-r--r-- | Swiften/MUC/MUCBookmarkManager.cpp | 9 | ||||
-rw-r--r-- | Swiften/MUC/MUCBookmarkManager.h | 8 | ||||
-rw-r--r-- | Swiften/MUC/MUCManager.cpp | 2 | ||||
-rw-r--r-- | Swiften/MUC/MUCManager.h | 2 | ||||
-rw-r--r-- | Swiften/MUC/MUCRegistry.cpp | 6 | ||||
-rw-r--r-- | Swiften/MUC/MUCRegistry.h | 2 | ||||
-rw-r--r-- | Swiften/MUC/UnitTest/MUCTest.cpp | 65 |
10 files changed, 185 insertions, 38 deletions
diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index 68a5a86..6fe8f19 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -4,21 +4,25 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUC.h" +#include <Swiften/MUC/MUC.h> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/smart_ptr/make_shared.hpp> -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/Client/StanzaChannel.h" -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Elements/Form.h" -#include "Swiften/Elements/IQ.h" -#include "Swiften/Elements/MUCUserPayload.h" -#include "Swiften/Elements/MUCPayload.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Queries/GenericRequest.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/Client/StanzaChannel.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/Form.h> +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/IQ.h> +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Elements/MUCAdminPayload.h> +#include <Swiften/Elements/MUCPayload.h> +#include <Swiften/Elements/MUCDestroyPayload.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Queries/GenericRequest.h> namespace Swift { @@ -93,7 +97,7 @@ void MUC::handleIncomingPresence(Presence::ref presence) { MUCUserPayload::ref mucPayload; foreach (MUCUserPayload::ref payload, presence->getPayloads<MUCUserPayload>()) { - if (payload->getItems().size() > 0 || payload->getStatusCodes().size() > 0) { + if (!payload->getItems().empty() || !payload->getStatusCodes().empty()) { mucPayload = payload; } } @@ -120,8 +124,8 @@ void MUC::handleIncomingPresence(Presence::ref presence) { MUCOccupant::Affiliation affiliation(MUCOccupant::NoAffiliation); boost::optional<JID> realJID; if (mucPayload && mucPayload->getItems().size() > 0) { - role = mucPayload->getItems()[0].role; - affiliation = mucPayload->getItems()[0].affiliation; + role = mucPayload->getItems()[0].role ? mucPayload->getItems()[0].role.get() : MUCOccupant::NoRole; + affiliation = mucPayload->getItems()[0].affiliation ? mucPayload->getItems()[0].affiliation.get() : MUCOccupant::NoAffiliation; realJID = mucPayload->getItems()[0].realJID; } @@ -196,7 +200,6 @@ void MUC::handleIncomingPresence(Presence::ref presence) { } } } - } void MUC::handleCreationConfigResponse(MUCOwnerPayload::ref /*unused*/, ErrorPayload::ref error) { @@ -216,7 +219,72 @@ MUCOccupant MUC::getOccupant(const std::string& nick) { return occupants.find(nick)->second; } -//FIXME: Recognise Topic changes +void MUC::kickUser(const JID& jid) { + MUCAdminPayload::ref mucPayload = boost::make_shared<MUCAdminPayload>(); + MUCItem item; + item.role = MUCOccupant::NoRole; + item.nick = jid.getResource(); + mucPayload->addItem(item); + GenericRequest<MUCAdminPayload>* request = new GenericRequest<MUCAdminPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleKickResponse, this, _1, _2, jid)); + request->send(); +} + +void MUC::handleKickResponse(MUCAdminPayload::ref /*unused*/, ErrorPayload::ref error, const JID& jid) { + if (error) { + onKickFailed(error, jid); + } +} + +void MUC::changeSubject(const std::string& subject) { + Message::ref message = boost::make_shared<Message>(); + message->setSubject(subject); + message->setType(Message::Groupchat); + message->setTo(ownMUCJID.toBare()); + stanzaChannel->sendMessage(message); +} + +void MUC::requestConfigurationForm() { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Get, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationFormReceived, this, _1, _2)); + request->send(); +} + +void MUC::handleConfigurationFormReceived(MUCOwnerPayload::ref payload, ErrorPayload::ref error) { + Form::ref form; + if (payload) { + form = payload->getForm(); + } + if (error || !form) { + onConfigurationFailed(error); + } else { + onConfigurationFormReceived(form); + } +} + +void MUC::handleConfigurationResultReceived(MUCOwnerPayload::ref /*payload*/, ErrorPayload::ref error) { + if (error) { + onConfigurationFailed(error); + } +} + +void MUC::configureRoom(Form::ref form) { + MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload()); + mucPayload->setPayload(form); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + request->send(); +} + +void MUC::destroyRoom() { + MUCOwnerPayload::ref mucPayload = boost::make_shared<MUCOwnerPayload>(); + MUCDestroyPayload::ref mucDestroyPayload = boost::make_shared<MUCDestroyPayload>(); + mucPayload->setPayload(mucDestroyPayload); + GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + request->send(); +} //TODO: Invites(direct/mediated) diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 278ef95..b99c4b4 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -6,16 +6,18 @@ #pragma once -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> #include <string> -#include "Swiften/Elements/Message.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/MUCOccupant.h" -#include "Swiften/MUC/MUCRegistry.h" -#include "Swiften/Elements/MUCOwnerPayload.h" +#include <Swiften/Elements/Message.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Elements/MUCOccupant.h> +#include <Swiften/MUC/MUCRegistry.h> +#include <Swiften/Elements/MUCOwnerPayload.h> +#include <Swiften/Elements/MUCAdminPayload.h> +#include <Swiften/Elements/Form.h> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/signals/connection.hpp> #include <map> @@ -54,14 +56,22 @@ namespace Swift { /** Get occupant information*/ MUCOccupant getOccupant(const std::string& nick); bool hasOccupant(const std::string& nick); + void kickUser(const JID& jid); + void changeSubject(const std::string& subject); + void requestConfigurationForm(); + void configureRoom(Form::ref); + void destroyRoom(); public: boost::signal<void (const std::string& /*nick*/)> onJoinComplete; boost::signal<void (ErrorPayload::ref)> onJoinFailed; + boost::signal<void (ErrorPayload::ref, const JID&)> onKickFailed; + boost::signal<void (ErrorPayload::ref)> onConfigurationFailed; boost::signal<void (Presence::ref)> onOccupantPresenceChange; boost::signal<void (const std::string&, const MUCOccupant& /*now*/, const MUCOccupant::Role& /*old*/)> onOccupantRoleChanged; boost::signal<void (const std::string&, const MUCOccupant::Affiliation& /*new*/, const MUCOccupant::Affiliation& /*old*/)> onOccupantAffiliationChanged; boost::signal<void (const MUCOccupant&)> onOccupantJoined; boost::signal<void (const MUCOccupant&, LeavingType, const std::string& /*reason*/)> onOccupantLeft; + boost::signal<void (Form::ref)> onConfigurationFormReceived; /* boost::signal<void (const MUCInfo&)> onInfoResult; */ /* boost::signal<void (const blah&)> onItemsResult; */ @@ -79,6 +89,9 @@ namespace Swift { void handleIncomingPresence(Presence::ref presence); void internalJoin(const std::string& nick); void handleCreationConfigResponse(MUCOwnerPayload::ref, ErrorPayload::ref); + void handleKickResponse(MUCAdminPayload::ref, ErrorPayload::ref, const JID&); + void handleConfigurationFormReceived(MUCOwnerPayload::ref, ErrorPayload::ref); + void handleConfigurationResultReceived(MUCOwnerPayload::ref, ErrorPayload::ref); private: JID ownMUCJID; diff --git a/Swiften/MUC/MUCBookmark.h b/Swiften/MUC/MUCBookmark.h index 10e1b78..3f612c4 100644 --- a/Swiften/MUC/MUCBookmark.h +++ b/Swiften/MUC/MUCBookmark.h @@ -9,8 +9,8 @@ #include <boost/optional.hpp> #include <string> -#include "Swiften/JID/JID.h" -#include "Swiften/Elements/Storage.h" +#include <Swiften/JID/JID.h> +#include <Swiften/Elements/Storage.h> namespace Swift { class MUCBookmark { diff --git a/Swiften/MUC/MUCBookmarkManager.cpp b/Swiften/MUC/MUCBookmarkManager.cpp index d0855cd..643a8c4 100644 --- a/Swiften/MUC/MUCBookmarkManager.cpp +++ b/Swiften/MUC/MUCBookmarkManager.cpp @@ -9,9 +9,10 @@ #include <boost/bind.hpp> #include <iostream> -#include "Swiften/Queries/IQRouter.h" -#include "Swiften/Queries/Requests/GetPrivateStorageRequest.h" -#include "Swiften/Queries/Requests/SetPrivateStorageRequest.h" +#include <Swiften/Base/foreach.h> +#include <Swiften/Queries/IQRouter.h> +#include <Swiften/Queries/Requests/GetPrivateStorageRequest.h> +#include <Swiften/Queries/Requests/SetPrivateStorageRequest.h> namespace Swift { @@ -85,7 +86,7 @@ void MUCBookmarkManager::addBookmark(const MUCBookmark& bookmark) { void MUCBookmarkManager::removeBookmark(const MUCBookmark& bookmark) { if (!ready_) return; std::vector<MUCBookmark>::iterator it; - for (it = bookmarks_.begin(); it != bookmarks_.end(); it++) { + for (it = bookmarks_.begin(); it != bookmarks_.end(); ++it) { if ((*it) == bookmark) { bookmarks_.erase(it); onBookmarkRemoved(bookmark); diff --git a/Swiften/MUC/MUCBookmarkManager.h b/Swiften/MUC/MUCBookmarkManager.h index 39699df..ccea46c 100644 --- a/Swiften/MUC/MUCBookmarkManager.h +++ b/Swiften/MUC/MUCBookmarkManager.h @@ -9,12 +9,12 @@ #include <vector> #include <boost/shared_ptr.hpp> -#include "Swiften/Base/boost_bsignals.h" +#include <Swiften/Base/boost_bsignals.h> #include <boost/optional.hpp> -#include "Swiften/MUC/MUCBookmark.h" -#include "Swiften/Elements/Storage.h" -#include "Swiften/Elements/ErrorPayload.h" +#include <Swiften/MUC/MUCBookmark.h> +#include <Swiften/Elements/Storage.h> +#include <Swiften/Elements/ErrorPayload.h> namespace Swift { class IQRouter; diff --git a/Swiften/MUC/MUCManager.cpp b/Swiften/MUC/MUCManager.cpp index 8950029..6e9b820 100644 --- a/Swiften/MUC/MUCManager.cpp +++ b/Swiften/MUC/MUCManager.cpp @@ -4,7 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUCManager.h" +#include <Swiften/MUC/MUCManager.h> namespace Swift { diff --git a/Swiften/MUC/MUCManager.h b/Swiften/MUC/MUCManager.h index 0efdf9a..36ae61e 100644 --- a/Swiften/MUC/MUCManager.h +++ b/Swiften/MUC/MUCManager.h @@ -6,7 +6,7 @@ #pragma once -#include "Swiften/MUC/MUC.h" +#include <Swiften/MUC/MUC.h> namespace Swift { class IQRouter; diff --git a/Swiften/MUC/MUCRegistry.cpp b/Swiften/MUC/MUCRegistry.cpp index e433165..f4d061e 100644 --- a/Swiften/MUC/MUCRegistry.cpp +++ b/Swiften/MUC/MUCRegistry.cpp @@ -4,9 +4,9 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/MUC/MUCRegistry.h" +#include <Swiften/MUC/MUCRegistry.h> -#include <algorithm> +#include <Swiften/Base/Algorithm.h> namespace Swift { @@ -22,7 +22,7 @@ void MUCRegistry::addMUC(const JID& j) { } void MUCRegistry::removeMUC(const JID& j) { - mucs.erase(std::remove(mucs.begin(), mucs.end(), j), mucs.end()); + erase(mucs, j); } diff --git a/Swiften/MUC/MUCRegistry.h b/Swiften/MUC/MUCRegistry.h index 6356931..0ed2d2e 100644 --- a/Swiften/MUC/MUCRegistry.h +++ b/Swiften/MUC/MUCRegistry.h @@ -8,7 +8,7 @@ #include <vector> -#include "Swiften/JID/JID.h" +#include <Swiften/JID/JID.h> namespace Swift { class JID; diff --git a/Swiften/MUC/UnitTest/MUCTest.cpp b/Swiften/MUC/UnitTest/MUCTest.cpp index 117760c..427e938 100644 --- a/Swiften/MUC/UnitTest/MUCTest.cpp +++ b/Swiften/MUC/UnitTest/MUCTest.cpp @@ -15,6 +15,11 @@ #include <Swiften/Presence/StanzaChannelPresenceSender.h> #include <Swiften/Presence/DirectedPresenceSender.h> #include <Swiften/Queries/IQRouter.h> +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/Elements/MUCOwnerPayload.h> +#include <Swiften/Elements/VCard.h> +#include <Swiften/Elements/CapsInfo.h> + using namespace Swift; @@ -23,6 +28,8 @@ class MUCTest : public CppUnit::TestFixture { CPPUNIT_TEST(testJoin); CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinDoesNotSendPresenceBeforeJoinSuccess); CPPUNIT_TEST(testJoin_ChangePresenceDuringJoinResendsPresenceAfterJoinSuccess); + CPPUNIT_TEST(testCreateInstant); + CPPUNIT_TEST(testReplicateBug); /*CPPUNIT_TEST(testJoin_Success); CPPUNIT_TEST(testJoin_Fail);*/ CPPUNIT_TEST_SUITE_END(); @@ -76,6 +83,64 @@ class MUCTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(std::string("Test"), p->getStatus()); } + void testCreateInstant() { + MUC::ref testling = createMUC(JID("rabbithole@wonderland.lit")); + testling->joinAs("Alice"); + Presence::ref serverRespondsLocked = boost::make_shared<Presence>(); + serverRespondsLocked->setFrom(JID("rabbithole@wonderland.lit/Alice")); + MUCUserPayload::ref mucPayload(new MUCUserPayload()); + MUCItem myItem; + myItem.affiliation = MUCOccupant::Owner; + myItem.role = MUCOccupant::Moderator; + mucPayload->addItem(myItem); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(110)); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(201)); + serverRespondsLocked->addPayload(mucPayload); + channel->onPresenceReceived(serverRespondsLocked); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(channel->sentStanzas.size())); + IQ::ref iq = channel->getStanzaAtIndex<IQ>(1); + CPPUNIT_ASSERT(iq); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()->getForm()); + CPPUNIT_ASSERT_EQUAL(Form::SubmitType, iq->getPayload<MUCOwnerPayload>()->getForm()->getType()); + } + + void testReplicateBug() { + Presence::ref initialPresence = boost::make_shared<Presence>(); + initialPresence->setStatus(""); + VCard::ref vcard = boost::make_shared<VCard>(); + vcard->setPhoto(createByteArray("15c30080ae98ec48be94bf0e191d43edd06e500a")); + initialPresence->addPayload(vcard); + CapsInfo::ref caps = boost::make_shared<CapsInfo>(); + caps->setNode("http://swift.im"); + caps->setVersion("p2UP0DrcVgKM6jJqYN/B92DKK0o="); + initialPresence->addPayload(caps); + channel->sendPresence(initialPresence); + + MUC::ref testling = createMUC(JID("test@rooms.swift.im")); + testling->joinAs("Test"); + Presence::ref serverRespondsLocked = boost::make_shared<Presence>(); + serverRespondsLocked->setFrom(JID("test@rooms.swift.im/Test")); + serverRespondsLocked->setTo(JID("test@swift.im/6913d576d55f0b67")); + serverRespondsLocked->addPayload(vcard); + serverRespondsLocked->addPayload(caps); + serverRespondsLocked->setStatus(""); + MUCUserPayload::ref mucPayload(new MUCUserPayload()); + MUCItem myItem; + myItem.affiliation = MUCOccupant::Owner; + myItem.role = MUCOccupant::Moderator; + mucPayload->addItem(myItem); + mucPayload->addStatusCode(MUCUserPayload::StatusCode(201)); + serverRespondsLocked->addPayload(mucPayload); + channel->onPresenceReceived(serverRespondsLocked); + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(channel->sentStanzas.size())); + IQ::ref iq = channel->getStanzaAtIndex<IQ>(2); + CPPUNIT_ASSERT(iq); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()); + CPPUNIT_ASSERT(iq->getPayload<MUCOwnerPayload>()->getForm()); + CPPUNIT_ASSERT_EQUAL(Form::SubmitType, iq->getPayload<MUCOwnerPayload>()->getForm()->getType()); + } + /*void testJoin_Success() { MUC::ref testling = createMUC(JID("foo@bar.com")); testling->onJoinFinished.connect(boost::bind(&MUCTest::handleJoinFinished, this, _1, _2)); |