summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/MUC')
-rw-r--r--Swiften/MUC/MUC.cpp98
-rw-r--r--Swiften/MUC/MUC.h27
-rw-r--r--Swiften/MUC/MUCBookmark.h4
-rw-r--r--Swiften/MUC/MUCBookmarkManager.cpp9
-rw-r--r--Swiften/MUC/MUCBookmarkManager.h8
-rw-r--r--Swiften/MUC/MUCManager.cpp2
-rw-r--r--Swiften/MUC/MUCManager.h2
-rw-r--r--Swiften/MUC/MUCRegistry.cpp6
-rw-r--r--Swiften/MUC/MUCRegistry.h2
-rw-r--r--Swiften/MUC/UnitTest/MUCTest.cpp65
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));