diff options
| author | Tobias Markmann <tm@ayena.de> | 2015-01-22 22:24:16 (GMT) | 
|---|---|---|
| committer | Kevin Smith <kevin.smith@isode.com> | 2015-02-16 16:55:03 (GMT) | 
| commit | 645a7a47c8105e7cad3fecd7bb66c8c16757eafe (patch) | |
| tree | 3230a784bddfa6b7fd5d327e735451e625672af4 | |
| parent | 45eec1d00d5b9fabee1ce44f7dd8addd7d0cf6b3 (diff) | |
| download | swift-645a7a47c8105e7cad3fecd7bb66c8c16757eafe.zip swift-645a7a47c8105e7cad3fecd7bb66c8c16757eafe.tar.bz2 | |
Show a warning notice when trying to enter a blocked room
When the user tries to enter a blocked room, we now show a warning
notice and describing how the room can be unblocked. Swift will not
send the joining presence when trying to enter a blocked room.
Test-Information:
Tested on Mac OS X 10.9.5 against a popular open source server and its
MUC and Blocking Command implementation.
Change-Id: I875db056f21f97845c5a9a43167b0f2a16bdaa36
| -rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 4 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 67 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 14 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 58 | ||||
| -rw-r--r-- | Swift/QtUI/QtChatWindow.cpp | 2 | 
5 files changed, 105 insertions, 40 deletions
| diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index f69ce6f..fe098de 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited.   * All rights reserved.   * See the COPYING file for more information.   */ @@ -811,7 +811,7 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti  			chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow);  		}  		boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */ -		controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_); +		controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_);  		if (chatWindowFactoryAdapter) {  			/* The adapters are only passed to chat windows, which are deleted in their  			 * controllers' dtor, which are deleted in ChatManager's dtor. The adapters diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 10d63a7..b5a8d2c 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -11,10 +11,12 @@  #include <boost/algorithm/string.hpp>  #include <Swiften/Avatars/AvatarManager.h> +#include <Swiften/Base/Log.h>  #include <Swiften/Base/foreach.h>  #include <Swiften/Base/foreach.h>  #include <Swiften/Base/format.h> -#include <Swiften/Base/Log.h> +#include <Swiften/Client/BlockList.h> +#include <Swiften/Client/ClientBlockListManager.h>  #include <Swiften/Client/StanzaChannel.h>  #include <Swiften/Disco/EntityCapsProvider.h>  #include <Swiften/Elements/Delay.h> @@ -39,6 +41,7 @@  #include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>  #include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>  #include <Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h> +#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>  #include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>  #include <Swift/Controllers/UIEvents/UIEventStream.h>  #include <Swift/Controllers/UIInterfaces/ChatWindow.h> @@ -71,11 +74,12 @@ MUCController::MUCController (  		HistoryController* historyController,  		MUCRegistry* mucRegistry,  		HighlightManager* highlightManager, +		ClientBlockListManager* clientBlockListManager,  		boost::shared_ptr<ChatMessageParser> chatMessageParser,  		bool isImpromptu,  		AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider,  		VCardManager* vcardManager) : -	ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false) { +	ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager) {  	parting_ = true;  	joined_ = false;  	lastWasPresence_ = false; @@ -100,6 +104,7 @@ MUCController::MUCController (  	chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1));  	chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this));  	chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); +	chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this));  	muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));  	muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));  	muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); @@ -605,16 +610,23 @@ void MUCController::setOnline(bool online) {  	} else {  		if (shouldJoinOnReconnect_) {  			renameCounter_ = 0; -			if (isImpromptu_) { -				lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection); -			} else { -				lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection); +			boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); +			if (blockList && blockList->isBlocked(muc_->getJID())) { +				handleBlockingStateChanged(); +				lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")), ChatWindow::DefaultDirection);  			} -			if (loginCheckTimer_) { -				loginCheckTimer_->start(); +			else { +				if (isImpromptu_) { +					lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection); +				} else { +					lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection); +				} +				if (loginCheckTimer_) { +					loginCheckTimer_->start(); +				} +				setNick(desiredNick_); +				rejoin();  			} -			setNick(desiredNick_); -			rejoin();  		}  	}  } @@ -970,6 +982,28 @@ void MUCController::handleChangeAffiliationsRequest(const std::vector<std::pair<  	}  } +void MUCController::handleUnblockUserRequest() { +	eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, muc_->getJID())); +} + +void MUCController::handleBlockingStateChanged() { +	boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); +	if (blockList->getState() == BlockList::Available) { +		if (blockList->isBlocked(toJID_)) { +			if (!blockedContactAlert_) { +				blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")); +			} +			chatWindow_->setBlockingState(ChatWindow::IsBlocked); +		} else { +			if (blockedContactAlert_) { +				chatWindow_->removeAlert(*blockedContactAlert_); +				blockedContactAlert_.reset(); +			} +			chatWindow_->setBlockingState(ChatWindow::IsUnblocked); +		} +	} +} +  void MUCController::handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) {  	chatWindow_->setAffiliations(affiliation, jids);  } @@ -1095,4 +1129,17 @@ void MUCController::handleRoomUnlocked() {  	}  } +void MUCController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { +	ChatControllerBase::setAvailableServerFeatures(info); +	if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) { +		boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + +		blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); +		blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); +		blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); + +		handleBlockingStateChanged(); +	} +} +  } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 5e033ed..7c24ae2 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -39,6 +39,7 @@ namespace Swift {  	class UIEvent;  	class VCardManager;  	class RosterVCardProvider; +	class ClientBlockListManager;  	enum JoinPart {Join, Part, JoinThenPart, PartThenJoin}; @@ -50,13 +51,14 @@ namespace Swift {  	class MUCController : public ChatControllerBase {  		public: -			MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager); +			MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager);  			virtual ~MUCController();  			boost::signal<void ()> onUserLeft;  			boost::signal<void ()> onUserJoined;  			boost::signal<void ()> onImpromptuConfigCompleted;  			boost::signal<void (const std::string&, const std::string& )> onUserNicknameChanged;  			virtual void setOnline(bool online); +			virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);  			void rejoin();  			static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent);  			static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu); @@ -132,6 +134,9 @@ namespace Swift {  			void configureAsImpromptuRoom(Form::ref form);  			Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm); +			void handleUnblockUserRequest(); +			void handleBlockingStateChanged(); +  		private:  			MUC::ref muc_;  			UIEventStream* events_; @@ -157,6 +162,13 @@ namespace Swift {  			bool isImpromptuAlreadyConfigured_;  			RosterVCardProvider* rosterVCardProvider_;  			std::string lastJoinMessageUID_; + +			ClientBlockListManager* clientBlockListManager_; +			boost::bsignals::scoped_connection blockingOnStateChangedConnection_; +			boost::bsignals::scoped_connection blockingOnItemAddedConnection_; +			boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; + +			boost::optional<ChatWindow::AlertID> blockedContactAlert_;  	};  } diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 5a4d3b8..0b7b793 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -1,5 +1,5 @@  /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited.   * All rights reserved.   * See the COPYING file for more information.   */ @@ -7,37 +7,40 @@  #include <cppunit/extensions/HelperMacros.h>  #include <cppunit/extensions/TestFactoryRegistry.h>  #include <boost/algorithm/string.hpp> +  #include <hippomocks.h> -#include "Swiften/Base/foreach.h" -#include "Swift/Controllers/XMPPEvents/EventController.h" -#include "Swiften/Presence/DirectedPresenceSender.h" -#include "Swiften/Presence/StanzaChannelPresenceSender.h" -#include "Swiften/Avatars/NullAvatarManager.h" -#include "Swift/Controllers/Chat/MUCController.h" -#include "Swift/Controllers/UIInterfaces/ChatWindow.h" -#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" -#include "Swiften/Client/NickResolver.h" -#include "Swiften/Roster/XMPPRoster.h" -#include "Swift/Controllers/UIEvents/UIEventStream.h" -#include "Swift/Controllers/UnitTest/MockChatWindow.h" -#include "Swiften/MUC/UnitTest/MockMUC.h" -#include "Swiften/Client/DummyStanzaChannel.h" -#include "Swiften/Queries/DummyIQChannel.h" -#include "Swiften/Presence/PresenceOracle.h" -#include "Swiften/Network/TimerFactory.h" -#include "Swiften/Elements/MUCUserPayload.h" -#include "Swiften/Disco/DummyEntityCapsProvider.h" -#include <Swiften/VCards/VCardMemoryStorage.h> +#include <Swiften/Avatars/NullAvatarManager.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Client/ClientBlockListManager.h> +#include <Swiften/Client/DummyStanzaChannel.h> +#include <Swiften/Client/NickResolver.h> +#include <Swiften/Crypto/CryptoProvider.h>  #include <Swiften/Crypto/PlatformCryptoProvider.h> +#include <Swiften/Disco/DummyEntityCapsProvider.h> +#include <Swiften/Elements/MUCUserPayload.h> +#include <Swiften/MUC/UnitTest/MockMUC.h> +#include <Swiften/Network/TimerFactory.h> +#include <Swiften/Presence/DirectedPresenceSender.h> +#include <Swiften/Presence/PresenceOracle.h> +#include <Swiften/Presence/StanzaChannelPresenceSender.h> +#include <Swiften/Queries/DummyIQChannel.h> +#include <Swiften/Roster/XMPPRoster.h>  #include <Swiften/VCards/VCardManager.h> -#include <Swift/Controllers/Settings/DummySettingsProvider.h> +#include <Swiften/VCards/VCardMemoryStorage.h> +  #include <Swift/Controllers/Chat/ChatMessageParser.h> +#include <Swift/Controllers/Chat/MUCController.h>  #include <Swift/Controllers/Chat/UserSearchController.h> -#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h> -#include <Swift/Controllers/Roster/Roster.h>  #include <Swift/Controllers/Roster/GroupRosterItem.h> -#include <Swiften/Crypto/CryptoProvider.h> +#include <Swift/Controllers/Roster/Roster.h> +#include <Swift/Controllers/Settings/DummySettingsProvider.h> +#include <Swift/Controllers/UIEvents/UIEventStream.h> +#include <Swift/Controllers/UIInterfaces/ChatWindow.h> +#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> +#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h> +#include <Swift/Controllers/UnitTest/MockChatWindow.h> +#include <Swift/Controllers/XMPPEvents/EventController.h>  using namespace Swift; @@ -84,11 +87,13 @@ public:  		chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true);  		vcardStorage_ = new VCardMemoryStorage(crypto_.get());  		vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_); -		controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, chatMessageParser_, false, NULL, vcardManager_); +		clientBlockListManager_ = new ClientBlockListManager(iqRouter_); +		controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_);  	}  	void tearDown() {  		delete controller_; +		delete clientBlockListManager_;  		delete vcardManager_;  		delete vcardStorage_;  		delete highlightManager_; @@ -432,6 +437,7 @@ private:  	boost::shared_ptr<CryptoProvider> crypto_;  	VCardManager* vcardManager_;  	VCardMemoryStorage* vcardStorage_; +	ClientBlockListManager* clientBlockListManager_;  };  CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index 6324e9d..33bec75 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -653,7 +653,7 @@ void QtChatWindow::handleActionButtonClicked() {  			unblock = contextMenu.addAction(tr("Unblock"));  			unblock->setEnabled(isOnline_);  		} -		else if (blockingState_ == IsUnblocked) { +		else if (!isMUC_ && blockingState_ == IsUnblocked) {  			block = contextMenu.addAction(tr("Block"));  			block->setEnabled(isOnline_);  		} | 
 Swift
 Swift