diff options
| author | Kevin Smith <git@kismith.co.uk> | 2012-02-17 16:57:01 (GMT) |
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2012-02-21 14:34:55 (GMT) |
| commit | 3605b6622bc8b4abb810fac6b53f7f71be0fa7de (patch) | |
| tree | 638a8fd6449dd235931fe307e50119adf9c9fe22 /Swift/Controllers/MainController.cpp | |
| parent | b05f8fcb285d2d13d2be50a3eb1062048fbe30f5 (diff) | |
| download | swift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.zip swift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.tar.bz2 | |
Introduce system settings policies.
Release-Notes: It is now possible for sysadmins to deploy files with policies for configuration options, such as making it impossible for users to save passwords or to force sound notifications off, or to set defaults.
Also allow changing an option so that Swift disconnects on idle timeout, instead of going away.
Diffstat (limited to 'Swift/Controllers/MainController.cpp')
| -rw-r--r-- | Swift/Controllers/MainController.cpp | 97 |
1 files changed, 45 insertions, 52 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 6f93dd3..06f8c3a 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -1,664 +1,657 @@ /* - * Copyright (c) 2010-2011 Kevin Smith + * Copyright (c) 2010-2012 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/Controllers/MainController.h> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include <boost/shared_ptr.hpp> #include <boost/smart_ptr/make_shared.hpp> #include <string> #include <stdlib.h> #include <Swiften/Base/format.h> #include <Swiften/Base/Algorithm.h> #include <Swift/Controllers/Intl.h> #include <Swift/Controllers/UIInterfaces/UIFactory.h> #include "Swiften/Network/TimerFactory.h" #include "Swift/Controllers/BuildVersion.h" #include "Swiften/Client/Storages.h" #include "Swiften/VCards/VCardManager.h" #include "Swift/Controllers/Chat/UserSearchController.h" #include "Swift/Controllers/Chat/ChatsManager.h" #include "Swift/Controllers/XMPPEvents/EventController.h" #include "Swift/Controllers/EventWindowController.h" #include "Swift/Controllers/UIInterfaces/LoginWindow.h" #include "Swift/Controllers/UIInterfaces/LoginWindowFactory.h" #include "Swift/Controllers/UIInterfaces/MainWindow.h" #include "Swift/Controllers/Chat/MUCController.h" #include "Swiften/Client/NickResolver.h" #include "Swift/Controllers/Roster/RosterController.h" #include "Swift/Controllers/SoundEventController.h" #include "Swift/Controllers/SoundPlayer.h" #include "Swift/Controllers/StatusTracker.h" #include "Swift/Controllers/SystemTray.h" #include "Swift/Controllers/SystemTrayController.h" #include "Swift/Controllers/XMLConsoleController.h" #include "Swift/Controllers/FileTransferListController.h" #include "Swift/Controllers/UIEvents/UIEventStream.h" #include "Swift/Controllers/PresenceNotifier.h" #include "Swift/Controllers/EventNotifier.h" #include "Swift/Controllers/Storages/StoragesFactory.h" #include "SwifTools/Dock/Dock.h" #include "SwifTools/Notifier/TogglableNotifier.h" #include "Swiften/Base/foreach.h" #include "Swiften/Client/Client.h" #include "Swiften/Presence/PresenceSender.h" #include "Swiften/Elements/ChatState.h" #include "Swiften/Elements/Presence.h" #include "Swiften/Elements/VCardUpdate.h" #include "Swift/Controllers/Settings/SettingsProvider.h" #include "Swiften/Elements/DiscoInfo.h" #include "Swiften/Disco/CapsInfoGenerator.h" #include "Swiften/Disco/GetDiscoInfoRequest.h" #include "Swiften/Disco/ClientDiscoManager.h" #include "Swiften/VCards/GetVCardRequest.h" #include "Swiften/StringCodecs/SHA1.h" #include "Swiften/StringCodecs/Hexify.h" #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h" -#include "Swift/Controllers/UIEvents/ToggleNotificationsUIEvent.h" -#include "Swift/Controllers/UIEvents/ToggleRequestDeliveryReceiptsUIEvent.h" #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h" #include "Swift/Controllers/Storages/CertificateStorageFactory.h" #include "Swift/Controllers/Storages/CertificateStorageTrustChecker.h" #include "Swiften/Network/NetworkFactories.h" #include <Swift/Controllers/ProfileController.h> #include <Swift/Controllers/ContactEditController.h> #include <Swift/Controllers/XMPPURIController.h> #include "Swift/Controllers/AdHocManager.h" #include <SwifTools/Idle/IdleDetector.h> #include <Swift/Controllers/FileTransfer/FileTransferOverview.h> #include <Swiften/FileTransfer/FileTransferManager.h> #include <Swiften/Client/ClientXMLTracer.h> +#include <Swift/Controllers/SettingConstants.h> namespace Swift { static const std::string CLIENT_NAME = "Swift"; static const std::string CLIENT_NODE = "http://swift.im"; -static const std::string SHOW_NOTIFICATIONS = "showNotifications"; -static const std::string REQUEST_DELIVERYRECEIPTS = "requestDeliveryReceipts"; MainController::MainController( EventLoop* eventLoop, NetworkFactories* networkFactories, UIFactory* uiFactories, - SettingsProvider *settings, + SettingsProvider* settings, SystemTray* systemTray, SoundPlayer* soundPlayer, StoragesFactory* storagesFactory, CertificateStorageFactory* certificateStorageFactory, Dock* dock, Notifier* notifier, URIHandler* uriHandler, IdleDetector* idleDetector, - bool useDelayForLatency, - bool eagleMode) : + bool useDelayForLatency) : eventLoop_(eventLoop), networkFactories_(networkFactories), uiFactory_(uiFactories), storagesFactory_(storagesFactory), certificateStorageFactory_(certificateStorageFactory), settings_(settings), uriHandler_(uriHandler), idleDetector_(idleDetector), loginWindow_(NULL) , useDelayForLatency_(useDelayForLatency), - eagleMode_(eagleMode), ftOverview_(NULL) { storages_ = NULL; certificateStorage_ = NULL; statusTracker_ = NULL; presenceNotifier_ = NULL; eventNotifier_ = NULL; rosterController_ = NULL; chatsManager_ = NULL; eventWindowController_ = NULL; profileController_ = NULL; contactEditController_ = NULL; userSearchControllerChat_ = NULL; userSearchControllerAdd_ = NULL; adHocManager_ = NULL; quitRequested_ = false; clientInitialized_ = false; offlineRequested_ = false; timeBeforeNextReconnect_ = -1; dock_ = dock; uiEventStream_ = new UIEventStream(); notifier_ = new TogglableNotifier(notifier); eventController_ = new EventController(); eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1)); systemTrayController_ = new SystemTrayController(eventController_, systemTray); loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_); loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured()); - soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, uiEventStream_); + soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings); xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_); - std::string selectedLoginJID = settings_->getStringSetting("lastLoginJID"); - bool loginAutomatically = settings_->getBoolSetting("loginAutomatically", false); + std::string selectedLoginJID = settings_->getSetting(SettingConstants::LAST_LOGIN_JID); + bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY); std::string cachedPassword; std::string cachedCertificate; - if (!eagleMode_) { + bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); + if (!eagle) { foreach (std::string profile, settings->getAvailableProfiles()) { ProfileSettingsProvider profileSettings(profile, settings); - std::string password = eagleMode ? "" : profileSettings.getStringSetting("pass"); + std::string password = profileSettings.getStringSetting("pass"); std::string certificate = profileSettings.getStringSetting("certificate"); std::string jid = profileSettings.getStringSetting("jid"); loginWindow_->addAvailableAccount(jid, password, certificate); if (jid == selectedLoginJID) { cachedPassword = password; cachedCertificate = certificate; } } loginWindow_->selectUser(selectedLoginJID); loginWindow_->setLoginAutomatically(loginAutomatically); } loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5)); loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1)); loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this)); loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this)); - idleDetector_->setIdleTimeSeconds(600); + idleDetector_->setIdleTimeSeconds(settings->getSetting(SettingConstants::IDLE_TIMEOUT)); idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_); fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_); - uiEventStream_->onUIEvent.connect(boost::bind(&MainController::handleUIEvent, this, _1)); - bool enabled = settings_->getBoolSetting(SHOW_NOTIFICATIONS, true); - uiEventStream_->send(boost::shared_ptr<ToggleNotificationsUIEvent>(new ToggleNotificationsUIEvent(enabled))); + settings_->onSettingChanged.connect(boost::bind(&MainController::handleSettingChanged, this, _1)); if (loginAutomatically) { profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_); handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, true, true); } else { profileSettings_ = NULL; } } MainController::~MainController() { idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); purgeCachedCredentials(); //setManagersOffline(); eventController_->disconnectAll(); resetClient(); delete fileTransferListController_; delete xmlConsoleController_; delete xmppURIController_; delete soundEventController_; delete systemTrayController_; delete eventController_; delete notifier_; delete uiEventStream_; } void MainController::purgeCachedCredentials() { safeClear(password_); } void MainController::resetClient() { purgeCachedCredentials(); resetCurrentError(); resetPendingReconnects(); vCardPhotoHash_.clear(); delete contactEditController_; contactEditController_ = NULL; delete profileController_; profileController_ = NULL; delete eventWindowController_; eventWindowController_ = NULL; delete chatsManager_; chatsManager_ = NULL; delete ftOverview_; ftOverview_ = NULL; delete rosterController_; rosterController_ = NULL; delete eventNotifier_; eventNotifier_ = NULL; delete presenceNotifier_; presenceNotifier_ = NULL; delete certificateStorage_; certificateStorage_ = NULL; delete storages_; storages_ = NULL; delete statusTracker_; statusTracker_ = NULL; delete profileSettings_; profileSettings_ = NULL; delete userSearchControllerChat_; userSearchControllerChat_ = NULL; delete userSearchControllerAdd_; userSearchControllerAdd_ = NULL; delete adHocManager_; adHocManager_ = NULL; clientInitialized_ = false; } -void MainController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<ToggleNotificationsUIEvent> notificationsEvent = boost::dynamic_pointer_cast<ToggleNotificationsUIEvent>(event); - if (notificationsEvent) { - bool enabled = notificationsEvent->getEnabled(); - notifier_->setPersistentEnabled(enabled); - settings_->storeBool(SHOW_NOTIFICATIONS, enabled); +void MainController::handleSettingChanged(const std::string& settingPath) { + if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) { + notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS)); } - boost::shared_ptr<ToggleRequestDeliveryReceiptsUIEvent> deliveryReceiptEvent = boost::dynamic_pointer_cast<ToggleRequestDeliveryReceiptsUIEvent>(event); - if (deliveryReceiptEvent) { - settings_->storeBool(REQUEST_DELIVERYRECEIPTS, deliveryReceiptEvent->getEnabled()); - } - } void MainController::resetPendingReconnects() { timeBeforeNextReconnect_ = -1; if (reconnectTimer_) { reconnectTimer_->stop(); reconnectTimer_.reset(); } resetCurrentError(); } void MainController::resetCurrentError() { if (lastDisconnectError_) { lastDisconnectError_->conclude(); lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(); } } void MainController::handleConnected() { boundJID_ = client_->getJID(); resetCurrentError(); resetPendingReconnects(); - if (eagleMode_) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { purgeCachedCredentials(); } bool freshLogin = rosterController_ == NULL; myStatusLooksOnline_ = true; if (freshLogin) { profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_); srand(time(NULL)); int randomPort = 10000 + rand() % 10000; client_->getFileTransferManager()->startListeningOnPort(randomPort); ftOverview_ = new FileTransferOverview(client_->getFileTransferManager()); fileTransferListController_->setFileTransferOverview(ftOverview_); rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_); rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2)); rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); contactEditController_ = new ContactEditController(rosterController_, uiFactory_, uiEventStream_); - chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), eagleMode_); + chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_); client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1)); chatsManager_->setAvatarManager(client_->getAvatarManager()); eventWindowController_ = new EventWindowController(eventController_, uiFactory_); loginWindow_->morphInto(rosterController_->getWindow()); DiscoInfo discoInfo; discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); discoInfo.addFeature(DiscoInfo::ChatStatesFeature); discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature); discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature); #ifdef SWIFT_EXPERIMENTAL_FT discoInfo.addFeature(DiscoInfo::JingleFeature); discoInfo.addFeature(DiscoInfo::JingleFTFeature); discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); #endif discoInfo.addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); client_->getDiscoManager()->setCapsNode(CLIENT_NODE); client_->getDiscoManager()->setDiscoInfo(discoInfo); userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_); userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_); adHocManager_ = new AdHocManager(boundJID_, uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow()); } loginWindow_->setIsLoggingIn(false); client_->requestRoster(); GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(boundJID_.toBare(), client_->getIQRouter()); discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2)); discoInfoRequest->send(); client_->getVCardManager()->requestOwnVCard(); rosterController_->setEnabled(true); profileController_->setAvailable(true); contactEditController_->setAvailable(true); /* Send presence later to catch all the incoming presences. */ sendPresence(statusTracker_->getNextPresence()); /* Enable chats last of all, so rejoining MUCs has the right sent presence */ chatsManager_->setOnline(true); - // notify world about current delivey receipt request setting state. - uiEventStream_->send(boost::make_shared<ToggleRequestDeliveryReceiptsUIEvent>(settings_->getBoolSetting(REQUEST_DELIVERYRECEIPTS, false))); } void MainController::handleEventQueueLengthChange(int count) { dock_->setNumberOfPendingMessages(count); } void MainController::reconnectAfterError() { if (reconnectTimer_) { reconnectTimer_->stop(); } performLoginFromCachedCredentials(); } void MainController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) { boost::shared_ptr<Presence> presence(new Presence()); if (show == StatusShow::None) { // Note: this is misleading, None doesn't mean unavailable on the wire. presence->setType(Presence::Unavailable); resetPendingReconnects(); myStatusLooksOnline_ = false; offlineRequested_ = true; } else { offlineRequested_ = false; presence->setShow(show); } presence->setStatus(statusText); statusTracker_->setRequestedPresence(presence); if (presence->getType() != Presence::Unavailable) { profileSettings_->storeInt("lastShow", presence->getShow()); profileSettings_->storeString("lastStatus", presence->getStatus()); } if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) { performLoginFromCachedCredentials(); } else { sendPresence(presence); } } void MainController::sendPresence(boost::shared_ptr<Presence> presence) { rosterController_->getWindow()->setMyStatusType(presence->getShow()); rosterController_->getWindow()->setMyStatusText(presence->getStatus()); systemTrayController_->setMyStatusType(presence->getShow()); notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND); // Add information and send if (!vCardPhotoHash_.empty()) { presence->updatePayload(boost::shared_ptr<VCardUpdate>(new VCardUpdate(vCardPhotoHash_))); } client_->getPresenceSender()->sendPresence(presence); if (presence->getType() == Presence::Unavailable) { logout(); } } void MainController::handleInputIdleChanged(bool idle) { if (!statusTracker_) { //Haven't logged in yet. return; } - if (idle) { - if (statusTracker_->goAutoAway()) { - if (client_ && client_->isAvailable()) { - sendPresence(statusTracker_->getNextPresence()); - } + + if (settings_->getSetting(SettingConstants::IDLE_GOES_OFFLINE)) { + if (idle) { + logout(); } - } else { - if (statusTracker_->goAutoUnAway()) { - if (client_ && client_->isAvailable()) { - sendPresence(statusTracker_->getNextPresence()); + } + else { + if (idle) { + if (statusTracker_->goAutoAway()) { + if (client_ && client_->isAvailable()) { + sendPresence(statusTracker_->getNextPresence()); + } + } + } else { + if (statusTracker_->goAutoUnAway()) { + if (client_ && client_->isAvailable()) { + sendPresence(statusTracker_->getNextPresence()); + } } } } } void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificateFile, bool remember, bool loginAutomatically) { jid_ = JID(username); if (!jid_.isValid() || jid_.getNode().empty()) { loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'")); loginWindow_->setIsLoggingIn(false); } else { loginWindow_->setMessage(""); loginWindow_->setIsLoggingIn(true); profileSettings_ = new ProfileSettingsProvider(username, settings_); - if (!eagleMode_) { + if (!settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { profileSettings_->storeString("jid", username); profileSettings_->storeString("certificate", certificateFile); profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : ""); - settings_->storeString("lastLoginJID", username); - settings_->storeBool("loginAutomatically", loginAutomatically); + settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username); + settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically); loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate")); } password_ = password; certificateFile_ = certificateFile; performLoginFromCachedCredentials(); } } void MainController::handlePurgeSavedLoginRequest(const std::string& username) { settings_->removeProfile(username); loginWindow_->removeAvailableAccount(username); } void MainController::performLoginFromCachedCredentials() { - if (eagleMode_ && password_.empty()) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS) && password_.empty()) { /* Then we can't try to login again. */ return; } /* If we logged in with a bare JID, and we have a full bound JID, re-login with the * bound JID to try and keep dynamically assigned resources */ JID clientJID = jid_; if (boundJID_.isValid() && jid_.isBare() && boundJID_.toBare() == jid_) { clientJID = boundJID_; } if (!statusTracker_) { statusTracker_ = new StatusTracker(); } if (!clientInitialized_) { storages_ = storagesFactory_->createStorages(jid_.toBare()); certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare()); certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_); client_ = boost::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_); clientInitialized_ = true; client_->setCertificateTrustChecker(certificateTrustChecker_); client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1)); client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1)); client_->onDisconnected.connect(boost::bind(&MainController::handleDisconnected, this, _1)); client_->onConnected.connect(boost::bind(&MainController::handleConnected, this)); client_->setSoftwareVersion(CLIENT_NAME, buildVersion); client_->getVCardManager()->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2)); presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, client_->getMUCRegistry(), client_->getAvatarManager(), client_->getNickResolver(), client_->getPresenceOracle(), networkFactories_->getTimerFactory()); presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); eventNotifier_ = new EventNotifier(eventController_, notifier_, client_->getAvatarManager(), client_->getNickResolver()); eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); if (!certificateFile_.empty()) { client_->setCertificate(certificateFile_); } boost::shared_ptr<Presence> presence(new Presence()); presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online))); presence->setStatus(profileSettings_->getStringSetting("lastStatus")); statusTracker_->setRequestedPresence(presence); } else { /* In case we're in the middle of another login, make sure they don't overlap */ client_->disconnect(); } systemTrayController_->setConnecting(); if (rosterController_) { rosterController_->getWindow()->setConnecting(); } ClientOptions clientOptions; - clientOptions.forgetPassword = eagleMode_; - clientOptions.useTLS = eagleMode_ ? ClientOptions::RequireTLS : ClientOptions::UseTLSWhenAvailable; + bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); + clientOptions.forgetPassword = eagle; + clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : ClientOptions::UseTLSWhenAvailable; /*if (clientJID.getDomain() == "doomsong.co.uk") { clientOptions.boshURL = URL("https", "channels.doomsong.co.uk", 11443, "http-bind/"); clientOptions.boshHTTPConnectProxyURL = URL("http", "squidproxy.doomsong.co.uk", 8123, ""); }*/ client_->connect(clientOptions); } void MainController::handleDisconnected(const boost::optional<ClientError>& error) { - if (eagleMode_) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { purgeCachedCredentials(); } if (quitRequested_) { resetClient(); loginWindow_->quit(); } else if (error) { std::string message; std::string certificateErrorMessage; switch(error->getType()) { case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break; case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break; case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break; case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break; case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break; case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break; case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break; case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break; case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break; case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break; case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break; case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break; case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break; case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break; case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break; case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid password?)"); break; case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break; case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break; case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break; case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break; case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break; case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break; case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break; case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encrypting your connection"); break; case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break; case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break; case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break; case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break; } bool forceReconnectAfterCertificateTrust = false; if (!certificateErrorMessage.empty()) { Certificate::ref certificate = certificateTrustChecker_->getLastCertificate(); if (loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificate)) { certificateStorage_->addCertificate(certificate); forceReconnectAfterCertificateTrust = true; } else { message = QT_TRANSLATE_NOOP("", "Certificate error"); } } if (forceReconnectAfterCertificateTrust) { performLoginFromCachedCredentials(); } else if (!rosterController_) { //hasn't been logged in yet signOut(); loginWindow_->setMessage(message); loginWindow_->setIsLoggingIn(false); } else { logout(); - if (eagleMode_) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message); } else { if (!offlineRequested_) { setReconnectTimer(); } if (lastDisconnectError_) { message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_)); lastDisconnectError_->conclude(); } else { message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message); } lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message)); eventController_->handleIncomingEvent(lastDisconnectError_); } } } else if (!rosterController_) { //hasn't been logged in yet loginWindow_->setIsLoggingIn(false); } } void MainController::setReconnectTimer() { if (timeBeforeNextReconnect_ < 0) { timeBeforeNextReconnect_ = 1; } else { timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2; // Randomly selected by roll of a die, as required by 3920bis } if (reconnectTimer_) { reconnectTimer_->stop(); } reconnectTimer_ = networkFactories_->getTimerFactory()->createTimer(timeBeforeNextReconnect_ * 1000); reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this)); reconnectTimer_->start(); } void MainController::handleCancelLoginRequest() { signOut(); } void MainController::signOut() { - if (eagleMode_) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { purgeCachedCredentials(); } eventController_->clear(); logout(); loginWindow_->loggedOut(); resetClient(); } void MainController::logout() { - if (eagleMode_) { + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { purgeCachedCredentials(); } systemTrayController_->setMyStatusType(StatusShow::None); if (clientInitialized_ /*&& client_->isAvailable()*/) { client_->disconnect(); } if (rosterController_ && myStatusLooksOnline_) { rosterController_->getWindow()->setMyStatusType(StatusShow::None); rosterController_->getWindow()->setMyStatusText(""); myStatusLooksOnline_ = false; } setManagersOffline(); } void MainController::setManagersOffline() { if (chatsManager_) { chatsManager_->setOnline(false); } if (rosterController_) { rosterController_->setEnabled(false); } if (profileController_) { profileController_->setAvailable(false); } if (contactEditController_) { contactEditController_->setAvailable(false); } } void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) { if (!error) { chatsManager_->setServerDiscoInfo(info); adHocManager_->setServerDiscoInfo(info); } } |
Swift