From 57a8dcfa359dc134afb3ce35a3ab4bd1842d491d Mon Sep 17 00:00:00 2001
From: atraczyk <andreastraczyk@gmail.com>
Date: Thu, 17 Aug 2017 16:34:12 -0400
Subject: [PATCH] accounts: fix account updates and contact management
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Fixes the details that modified per account type.

- Uses setCredentials to modify SIP account creds.

- Reports correct SIP account status on the account
  management panel.

Change-Id: I31416885f2137ad8194291a050500ba4fb6d58e7
Reviewed-by: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
---
 Converters.cpp      | 19 ++++++---
 RingD.cpp           | 35 +++++++++++------
 SmartPanel.xaml.cpp | 93 +++++++++++++++++++++++----------------------
 3 files changed, 85 insertions(+), 62 deletions(-)

diff --git a/Converters.cpp b/Converters.cpp
index f39710d..3b8f5ea 100644
--- a/Converters.cpp
+++ b/Converters.cpp
@@ -337,13 +337,17 @@ Object^
 AccountRegistrationStateToString::Convert(Object ^ value, TypeName targetType, Object ^ parameter, String ^ language)
 {
     auto account = static_cast<Account^>(value);
-    auto registrationState = account->_registrationState;
-
-    if (account->accountType_ == "SIP")
-        return "Ready";
 
-    if (registrationState == RegistrationState::REGISTERED) {
-        return "Online";
+    if (!account->_active) {
+        return "Disabled";
+    }
+    else {
+        if (account->accountType_ == "SIP") {
+            return "Ready";
+        }
+        if (account->_registrationState == RegistrationState::REGISTERED) {
+            return "Online";
+        }
     }
     return "Offline";
 }
@@ -354,6 +358,9 @@ AccountRegistrationStateToForeground::Convert(Object ^ value, TypeName targetTyp
     auto account = static_cast<Account^>(value);
     auto registrationState = account->_registrationState;
 
+    if (!account->_active) {
+        return ref new SolidColorBrush(Utils::ColorFromString(ErrorColor));
+    }
     if (registrationState == RegistrationState::REGISTERED || account->accountType_ == "SIP") {
         return ref new SolidColorBrush(Utils::ColorFromString(SuccessColor));
     }
diff --git a/RingD.cpp b/RingD.cpp
index 64cee6a..6e5b828 100644
--- a/RingD.cpp
+++ b/RingD.cpp
@@ -26,7 +26,6 @@
 #include "presencemanager_interface.h"
 #include "videomanager_interface.h"
 #include "fileutils.h"
-#include "account_schema.h"
 #include "account_const.h"
 #include "string_utils.h"
 #include "gnutls\gnutls.h"
@@ -490,32 +489,36 @@ RingD::updateAccount(String^ accountId)
         auto account = AccountListItemsViewModel::instance->findItem(accountId)->_account;
         std::map<std::string, std::string> accountDetails = DRing::getAccountDetails(_accountId);
         std::map<std::string, std::string> accountDetailsOld(accountDetails);
+        std::vector<std::map<std::string, std::string>> credentials = DRing::getCredentials(_accountId);
+        std::vector<std::map<std::string, std::string>> credentialsOld(credentials);
 
         accountDetails[DRing::Account::ConfProperties::ALIAS] = Utils::toString(account->name_);
         accountDetails[DRing::Account::ConfProperties::ENABLED] = (account->_active) ? ring::TRUE_STR : ring::FALSE_STR;
-        accountDetails[DRing::Account::ConfProperties::RING_DEVICE_NAME] = Utils::toString(account->_deviceName);
+        accountDetails[DRing::Account::ConfProperties::AUTOANSWER] = (account->_autoAnswer) ? ring::TRUE_STR : ring::FALSE_STR;
 
         bool userNameAdded = false;
         auto newUsername = Utils::toString(account->_username);
         if (accountDetails[DRing::Account::ConfProperties::TYPE] == "RING") {
-            if (account->_username != "" &&
-                newUsername.compare(accountDetails[DRing::Account::VolatileProperties::REGISTERED_NAME]) != 0) {
-                userNameAdded = true;
+            if (account->_username != "") {
+                auto oldUsername = registeredName(account);
+                userNameAdded = newUsername.compare(oldUsername) != 0;
             }
-
+            accountDetails[DRing::Account::ConfProperties::RING_DEVICE_NAME] = Utils::toString(account->_deviceName);
             accountDetails[DRing::Account::ConfProperties::UPNP_ENABLED] = (account->_upnpState) ? ring::TRUE_STR : ring::FALSE_STR;
-            accountDetails[DRing::Account::ConfProperties::AUTOANSWER] = (account->_autoAnswer) ? ring::TRUE_STR : ring::FALSE_STR;
             accountDetails[DRing::Account::ConfProperties::DHT::PUBLIC_IN_CALLS] = (account->_dhtPublicInCalls) ? ring::TRUE_STR : ring::FALSE_STR;
             accountDetails[DRing::Account::ConfProperties::TURN::ENABLED] = (account->_turnEnabled) ? ring::TRUE_STR : ring::FALSE_STR;
             accountDetails[DRing::Account::ConfProperties::TURN::SERVER] = Utils::toString(account->_turnAddress);
         }
         else {
             accountDetails[DRing::Account::ConfProperties::HOSTNAME] = Utils::toString(account->_sipHostname);
-            accountDetails[DRing::Account::ConfProperties::PASSWORD] = Utils::toString(account->_sipPassword);
-            accountDetails[DRing::Account::ConfProperties::USERNAME] = Utils::toString(account->_sipUsername);
+            credentials.at(0)[DRing::Account::ConfProperties::PASSWORD] = Utils::toString(account->_sipPassword);
+            credentials.at(0)[DRing::Account::ConfProperties::USERNAME] = Utils::toString(account->_sipUsername);
         }
 
-        if (accountDetails == accountDetailsOld && !userNameAdded) {
+        bool detailsChanged = (accountDetails != accountDetailsOld || userNameAdded);
+        bool credentialsChanged = (credentials != credentialsOld);
+
+        if (!detailsChanged && !credentialsChanged) {
             OnaccountUpdated();
             return;
         }
@@ -526,6 +529,10 @@ RingD::updateAccount(String^ accountId)
             mainPage->showLoadingOverlay(true, true);
         });
 
+        if (credentialsChanged) {
+            DRing::setCredentials(_accountId, credentials);
+        }
+
         DRing::setAccountDetails(_accountId, accountDetails);
         if (userNameAdded) {
             registerName(account->accountID_, "", account->_username);
@@ -630,6 +637,10 @@ RingD::revokeDevice(const std::string& accountId, const std::string& password, c
 void
 RingD::registerName(String^ accountId, String^ password, String^ username)
 {
+    auto account = AccountsViewModel::instance->findItem(accountId);
+    if (!account || account->accountType_ != "RING" || !account->ringID_)
+        return;
+
     tasks_.add_task([this, accountId, password, username]() {
         auto _accountId = Utils::toString(accountId);
         auto _password = Utils::toString(password);
@@ -1063,6 +1074,8 @@ RingD::registerCallbacks()
                     registrationStateErrorGeneric(account_id);
                     if (isAddingAccount)
                         OnaccountAdded(account_id);
+                    else if (isUpdatingAccount)
+                        OnaccountUpdated();
                 });
             }
         }),
@@ -1629,7 +1642,7 @@ RingD::hideLoadingOverlay(String^ text, String^ color, int delayInMilliseconds)
 }
 
 std::map<std::string, std::string>
-RingClientUWP::RingD::getVolatileAccountDetails(Account^ account)
+RingD::getVolatileAccountDetails(Account^ account)
 {
     return DRing::getVolatileAccountDetails(Utils::toString(account->accountID_));
 }
diff --git a/SmartPanel.xaml.cpp b/SmartPanel.xaml.cpp
index bb3da2d..d333449 100644
--- a/SmartPanel.xaml.cpp
+++ b/SmartPanel.xaml.cpp
@@ -896,13 +896,13 @@ void RingClientUWP::Views::SmartPanel::_acceptAccountModification__Click(Platfor
     auto accountId = account->accountID_;
 
     account->name_ = _accountAliasTextBoxEdition_->Text;
+    account->_active = _enabledState_->IsOn;
+    account->_autoAnswer = _autoAnswerToggle_->IsOn;
 
     if (account->accountType_ == "RING") {
         if (_RegisterStateEdition_->IsOn)
             account->_username = _usernameTextBoxEdition_->Text;
-        account->_active = _enabledState_->IsOn;
         account->_upnpState = _upnpState_->IsOn;
-        account->_autoAnswer = _autoAnswerToggle_->IsOn;
         account->_dhtPublicInCalls = _dhtPublicInCallsToggle_->IsOn;
         account->_turnEnabled = _turnEnabledToggle_->IsOn;
         if (_turnEditionTextBox_->Text != "")
@@ -1694,59 +1694,62 @@ SmartPanel::addToContactList(String^ uri)
     auto selectedAccountId = AccountListItemsViewModel::instance->getSelectedAccountId();
 
     auto account = AccountsViewModel::instance->findItem(selectedAccountId);
-    auto hasInternet = Utils::hasInternet();
-    if (account->accountType_ == "RING" && (!hasInternet || account->_registrationState != RegistrationState::REGISTERED)) {
-        auto loader = ref new Windows::ApplicationModel::Resources::ResourceLoader();
-        ringTxtBxPlaceHolderDelay(loader->GetString("_accountNotRegistered_"), 5000);
-        return;
-    }
-
     auto contactListModel = AccountsViewModel::instance->getContactListModel(Utils::toString(selectedAccountId));
-    for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
-        if ((item->_contact->_name == uri || item->_contact->ringID_ == uri) &&
-            selectedAccountId == item->_contact->_accountIdAssociated &&
-            item->_contact->_trustStatus >= TrustStatus::CONTACT_REQUEST_SENT) {
-            SmartPanelItemsViewModel::instance->_selectedItem = item;
-            summonMessageTextPage();
+
+    if (account->accountType_ == "RING") {
+        if (!Utils::hasInternet() || account->_registrationState != RegistrationState::REGISTERED) {
+            auto loader = ref new Windows::ApplicationModel::Resources::ResourceLoader();
+            ringTxtBxPlaceHolderDelay(loader->GetString("_accountNotRegistered_"), 5000);
             return;
         }
-        else if ((item->_contact->_name == uri || item->_contact->ringID_ == uri) &&
-            item->_contact->_trustStatus == TrustStatus::INCOMING_CONTACT_REQUEST) {
-            // In this case, we are potentially attempting to send a trust request to a
-            // peer who has already sent us one. For now we shall just send a trust request,
-            // so they receive our vcard and remove our corresponding contact request control item.
-            /* DRing::acceptTrustRequest(  Utils::toString(item->_contact->_accountIdAssociated),
-            Utils::toString(item->_contact->ringID_)); */
-            auto vcard = Configuration::UserPreferences::instance->getVCard();
-            RingD::instance->sendContactRequest(Utils::toString(item->_contact->_accountIdAssociated),
-                Utils::toString(item->_contact->ringID_),
-                vcard->asString());
-            item->_contact->_trustStatus = TrustStatus::TRUSTED;
-            contactListModel->saveContactsToFile();
+        for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
+            if ((item->_contact->_name == uri || item->_contact->ringID_ == uri) &&
+                selectedAccountId == item->_contact->_accountIdAssociated &&
+                item->_contact->_trustStatus >= TrustStatus::CONTACT_REQUEST_SENT) {
+                SmartPanelItemsViewModel::instance->_selectedItem = item;
+                summonMessageTextPage();
+                return;
+            }
+            else if ((item->_contact->_name == uri || item->_contact->ringID_ == uri) &&
+                item->_contact->_trustStatus == TrustStatus::INCOMING_CONTACT_REQUEST) {
+                // In this case, we are potentially attempting to send a trust request to a
+                // peer who has already sent us one. For now we shall just send a trust request,
+                // so they receive our vcard and remove our corresponding contact request control item.
+                /* DRing::acceptTrustRequest(  Utils::toString(item->_contact->_accountIdAssociated),
+                Utils::toString(item->_contact->ringID_)); */
+                auto vcard = Configuration::UserPreferences::instance->getVCard();
+                RingD::instance->sendContactRequest(Utils::toString(item->_contact->_accountIdAssociated),
+                    Utils::toString(item->_contact->ringID_),
+                    vcard->asString());
+                item->_contact->_trustStatus = TrustStatus::TRUSTED;
+                contactListModel->saveContactsToFile();
 
-            auto spi = SmartPanelItemsViewModel::instance->findItem(item->_contact);
-            SmartPanelItemsViewModel::instance->moveItemToTheTop(spi);
-            SmartPanelItemsViewModel::instance->refreshFilteredItemsList();
-            SmartPanelItemsViewModel::instance->update(ViewModel::NotifyStrings::notifySmartPanelItem);
+                auto spi = SmartPanelItemsViewModel::instance->findItem(item->_contact);
+                SmartPanelItemsViewModel::instance->moveItemToTheTop(spi);
+                SmartPanelItemsViewModel::instance->refreshFilteredItemsList();
+                SmartPanelItemsViewModel::instance->update(ViewModel::NotifyStrings::notifySmartPanelItem);
 
-            if (auto cri = ContactRequestItemsViewModel::instance->findItem(item->_contact))
-                ContactRequestItemsViewModel::instance->removeItem(cri);
+                if (auto cri = ContactRequestItemsViewModel::instance->findItem(item->_contact))
+                    ContactRequestItemsViewModel::instance->removeItem(cri);
 
-            ContactRequestItemsViewModel::instance->refreshFilteredItemsList();
-            ContactRequestItemsViewModel::instance->update(ViewModel::NotifyStrings::notifyContactRequestItem);
+                ContactRequestItemsViewModel::instance->refreshFilteredItemsList();
+                ContactRequestItemsViewModel::instance->update(ViewModel::NotifyStrings::notifyContactRequestItem);
 
-            MSG_("Auto-accepted Contact Request from: " + item->_contact->ringID_);
-            return;
+                MSG_("Auto-accepted Contact Request from: " + item->_contact->ringID_);
+                return;
+            }
+        }
+        if (isRingId) {
+            contactListModel->addNewContact(uri, uri, TrustStatus::UNKNOWN, false, ContactStatus::READY);
+            RingD::instance->lookUpAddress(Utils::toString(selectedAccountId), uri);
+        }
+        else {
+            contactListModel->addNewContact(uri, nullptr, TrustStatus::UNKNOWN, false, ContactStatus::WAITING_FOR_ACTIVATION);
+            RingD::instance->lookUpName(Utils::toString(selectedAccountId), uri);
         }
-    }
-
-    if (isRingId) {
-        contactListModel->addNewContact(uri, uri, TrustStatus::UNKNOWN, false, ContactStatus::READY);
-        RingD::instance->lookUpAddress(Utils::toString(selectedAccountId), uri);
     }
     else {
-        contactListModel->addNewContact(uri, nullptr, TrustStatus::UNKNOWN, false, ContactStatus::WAITING_FOR_ACTIVATION);
-        RingD::instance->lookUpName(Utils::toString(selectedAccountId), uri);
+        contactListModel->addNewContact(uri, nullptr, TrustStatus::TRUSTED, false, ContactStatus::READY);
     }
 
     for (auto item : SmartPanelItemsViewModel::instance->itemsList) {
-- 
GitLab