Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add joining a MIX channel by invitation #86

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add Channel Join and Leave capability to MIX
Add UpdateSubscription feature for subscribing to additional MIX nodes
Add Joining a channel with a preference form
Add requesting user preference form and updating the preferences

License:
This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

Test-Information:
Tests added for joining and leaving a channel as in XEP-0369, which passes.
Tests also added for updating subscription, joining channel with preference form and requesting user preference form as in XEP-0369, which passes.
Tested on Ubuntu 16.04 LTS.

Change-Id: Ibc2737f6154eeee1a85e98cb5f80c8bdbad35dcd
  • Loading branch information
tarun018 committed Jul 22, 2017
commit eb6c6120b3adc9f45c119085f2820ca450d963d8
14 changes: 14 additions & 0 deletions Swiften/MIX/MIX.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2017 Tarun Gupta
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/

#include <Swiften/MIX/MIX.h>

namespace Swift {

MIX::~MIX() {
}

}
72 changes: 72 additions & 0 deletions Swiften/MIX/MIX.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2017 Tarun Gupta
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/

#pragma once

#include <memory>
#include <string>
#include <unordered_set>

#include <boost/signals2.hpp>

#include <Swiften/Base/API.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/MIXJoin.h>
#include <Swiften/Elements/MIXLeave.h>
#include <Swiften/Elements/MIXUpdateSubscription.h>
#include <Swiften/Elements/MIXUserPreference.h>
#include <Swiften/Elements/ErrorPayload.h>

namespace Swift {
class SWIFTEN_API MIX {
public:
using ref = std::shared_ptr<MIX>;

public:
virtual ~MIX();

/**
* Join a MIX channel and subscribe to nodes.
*/
virtual void joinChannel(const std::unordered_set<std::string>& nodes) = 0;

/**
* Join Channel with a set of preferences.
*/
virtual void joinChannelWithPreferences(const std::unordered_set<std::string>& nodes, Form::ref form) = 0;

/**
* Update subscription of nodes.
*/
virtual void updateSubscription(const std::unordered_set<std::string>& nodes) = 0;

/**
* Leave a MIX channel and unsubcribe nodes.
*/
virtual void leaveChannel() = 0;

/**
* Request a configuration form for updating preferences.
*/
virtual void requestPreferencesForm() = 0;

/**
* Update preferences after requesting preference form.
*/
virtual void updatePreferences(Form::ref form) = 0;

public:
boost::signals2::signal<void (MIXJoin::ref /* joinResponse */)> onJoinComplete;
boost::signals2::signal<void (ErrorPayload::ref /* joinError */)> onJoinFailed;
boost::signals2::signal<void (MIXLeave::ref /* leaveResponse */)> onLeaveComplete;
boost::signals2::signal<void (ErrorPayload::ref /* leaveError */)> onLeaveFailed;
boost::signals2::signal<void (MIXUpdateSubscription::ref /* updateResponse */)> onSubscriptionUpdated;
boost::signals2::signal<void (ErrorPayload::ref /* updateError */)> onSubscriptionUpdateFailed;
boost::signals2::signal<void (Form::ref /* preferencesForm */)> onPreferencesFormReceived;
boost::signals2::signal<void (ErrorPayload::ref /* failedConfiguration */)> onPreferencesUpdateFailed;
};
}
115 changes: 115 additions & 0 deletions Swiften/MIX/MIXImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2017 Tarun Gupta
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/

#include <Swiften/MIX/MIXImpl.h>

#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Queries/GenericRequest.h>
#include <Swiften/Queries/IQRouter.h>

namespace Swift {

MIXImpl::MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter) : ownJID_(ownJID), channelJID_(channelJID), iqRouter_(iqRouter) {

}

MIXImpl::~MIXImpl() {

}

void MIXImpl::joinChannel(const std::unordered_set<std::string>& nodes) {
joinChannelWithPreferences(nodes, nullptr);
}

void MIXImpl::joinChannelWithPreferences(const std::unordered_set<std::string>& nodes, Form::ref form) {
auto joinPayload = std::make_shared<MIXJoin>();
joinPayload->setChannel(channelJID_);
for (auto node : nodes) {
joinPayload->addSubscription(node);
}
if (form) {
joinPayload->setForm(form);
}
auto request = std::make_shared<GenericRequest<MIXJoin>>(IQ::Set, getJID(), joinPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handleJoinResponse, this, _1, _2));
request->send();
}

void MIXImpl::handleJoinResponse(MIXJoin::ref payload, ErrorPayload::ref error) {
if (error) {
onJoinFailed(error);
} else {
onJoinComplete(payload);
}
}

void MIXImpl::updateSubscription(const std::unordered_set<std::string>& nodes) {
auto updateSubscriptionPayload = std::make_shared<MIXUpdateSubscription>();
updateSubscriptionPayload->setSubscriptions(nodes);
auto request = std::make_shared<GenericRequest<MIXUpdateSubscription>>(IQ::Set, channelJID_, updateSubscriptionPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handleUpdateSubscriptionResponse, this, _1, _2));
request->send();
}

void MIXImpl::handleUpdateSubscriptionResponse(MIXUpdateSubscription::ref payload, ErrorPayload::ref error) {
if (error) {
onSubscriptionUpdateFailed(error);
} else {
onSubscriptionUpdated(payload);
}
}

void MIXImpl::leaveChannel() {
auto leavePayload = std::make_shared<MIXLeave>();
leavePayload->setChannel(channelJID_);
auto request = std::make_shared<GenericRequest<MIXLeave>>(IQ::Set, getJID(), leavePayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handleLeaveResponse, this, _1, _2));
request->send();
}

void MIXImpl::handleLeaveResponse(MIXLeave::ref payload, ErrorPayload::ref error) {
if (error) {
onLeaveFailed(error);
} else {
onLeaveComplete(payload);
}
}

void MIXImpl::requestPreferencesForm() {
auto prefPayload = std::make_shared<MIXUserPreference>();
auto request = std::make_shared<GenericRequest<MIXUserPreference>>(IQ::Get, channelJID_, prefPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handlePreferencesFormReceived, this, _1, _2));
request->send();
}

void MIXImpl::handlePreferencesFormReceived(MIXUserPreference::ref payload, ErrorPayload::ref error) {
Form::ref form;
if (payload) {
form = payload->getData();
}
if (error || !form) {
onPreferencesUpdateFailed(error);
} else {
onPreferencesFormReceived(form);
}
}

void MIXImpl::handlePreferencesResultReceived(MIXUserPreference::ref /*payload*/, ErrorPayload::ref error) {
if (error) {
onPreferencesUpdateFailed(error);
}
}

void MIXImpl::updatePreferences(Form::ref form) {
auto prefPayload = std::make_shared<MIXUserPreference>();
prefPayload->setData(form);
auto request = std::make_shared<GenericRequest<MIXUserPreference>>(IQ::Set, channelJID_, prefPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handlePreferencesResultReceived, this, _1, _2));
request->send();
}

}
61 changes: 61 additions & 0 deletions Swiften/MIX/MIXImpl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2017 Tarun Gupta
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/

#pragma once

#include <Swiften/MIX/MIX.h>

namespace Swift {
class StanzaChannel;
class IQRouter;

class SWIFTEN_API MIXImpl : public MIX {
public:
using ref = std::shared_ptr<MIXImpl>;

public:
MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter);
virtual ~MIXImpl();

/**
* Returns the (bare) JID of the user.
*/
virtual JID getJID() const {
return ownJID_.toBare();
}

/**
* Returns the JID of MIX channel.
*/
virtual JID getChannelJID() const {
return channelJID_;
}

virtual void joinChannel(const std::unordered_set<std::string>& nodes) override;

virtual void joinChannelWithPreferences(const std::unordered_set<std::string>& nodes, Form::ref form) override;

virtual void updateSubscription(const std::unordered_set<std::string>& nodes) override;

virtual void leaveChannel() override;

virtual void requestPreferencesForm() override;

virtual void updatePreferences(Form::ref form) override;

private:
void handleJoinResponse(MIXJoin::ref, ErrorPayload::ref);
void handleLeaveResponse(MIXLeave::ref, ErrorPayload::ref);
void handleUpdateSubscriptionResponse(MIXUpdateSubscription::ref, ErrorPayload::ref);
void handlePreferencesFormReceived(MIXUserPreference::ref, ErrorPayload::ref);
void handlePreferencesResultReceived(MIXUserPreference::ref /*payload*/, ErrorPayload::ref error);

private:
JID ownJID_;
JID channelJID_;
IQRouter* iqRouter_;
};
}
Loading