From aac0ec9149b10085332ebd03a0b69da9220d5a1a Mon Sep 17 00:00:00 2001
From: Adrien Beraud <adrien.beraud@savoirfairelinux.com>
Date: Sat, 16 Sep 2017 12:34:32 +0200
Subject: [PATCH] ringaccount: remember if archive has a password

When saving the account archive, remember if it has a
password to avoid asking for a password if there is none.
If the information if unknown, assume there is a password
(the user can still enter en empty password in this case).

This information if exposed with the read-only account property
ConfProperties::ARCHIVE_HAS_PASSWORD

Change-Id: Ib19d6225b07b4e222dfd099f6922a874168af542
Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
---
 src/dring/account_const.h   | 1 +
 src/ringdht/ringaccount.cpp | 7 +++++++
 src/ringdht/ringaccount.h   | 1 +
 3 files changed, 9 insertions(+)

diff --git a/src/dring/account_const.h b/src/dring/account_const.h
index 8258a36294..d3ea1705ab 100644
--- a/src/dring/account_const.h
+++ b/src/dring/account_const.h
@@ -130,6 +130,7 @@ constexpr static const char ALLOW_CERT_FROM_HISTORY [] = "Account.allowCertFromH
 constexpr static const char ALLOW_CERT_FROM_CONTACT [] = "Account.allowCertFromContact";
 constexpr static const char ALLOW_CERT_FROM_TRUSTED [] = "Account.allowCertFromTrusted";
 constexpr static const char ARCHIVE_PASSWORD        [] = "Account.archivePassword";
+constexpr static const char ARCHIVE_HAS_PASSWORD    [] = "Account.archiveHasPassword";
 constexpr static const char ARCHIVE_PATH            [] = "Account.archivePath";
 constexpr static const char ARCHIVE_PIN             [] = "Account.archivePIN";
 constexpr static const char RING_DEVICE_ID          [] = "Account.deviceID";
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 301ae8b9a5..693b9b2e50 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -621,6 +621,7 @@ void RingAccount::serialize(YAML::Emitter &out)
 #endif
 
     out << YAML::Key << DRing::Account::ConfProperties::ARCHIVE_PATH << YAML::Value << archivePath_;
+    out << YAML::Key << DRing::Account::ConfProperties::ARCHIVE_HAS_PASSWORD << YAML::Value << archiveHasPassword_;
     out << YAML::Key << Conf::RING_ACCOUNT_RECEIPT << YAML::Value << receipt_;
     out << YAML::Key << Conf::RING_ACCOUNT_RECEIPT_SIG << YAML::Value << YAML::Binary(receiptSignature_.data(), receiptSignature_.size());
     out << YAML::Key << DRing::Account::ConfProperties::RING_DEVICE_NAME << YAML::Value << ringDeviceName_;
@@ -667,8 +668,10 @@ void RingAccount::unserialize(const YAML::Node &node)
 
     try {
         parsePath(node, DRing::Account::ConfProperties::ARCHIVE_PATH, archivePath_, idPath_);
+        parseValue(node, DRing::Account::ConfProperties::ARCHIVE_HAS_PASSWORD, archiveHasPassword_);
     } catch (const std::exception& e) {
         RING_WARN("can't read archive path: %s", e.what());
+        archiveHasPassword_ = true;
     }
 
     try {
@@ -920,6 +923,7 @@ RingAccount::saveArchive(AccountArchive& archive, const std::string& pwd)
         if (archivePath_.empty())
             archivePath_ = "export.gz";
         archive.save(fileutils::getFullPath(idPath_, archivePath_), pwd);
+        archiveHasPassword_ = not pwd.empty();
     } catch (const std::runtime_error& ex) {
         RING_ERR("[Account %s] Can't export archive: %s", getAccountID().c_str(), ex.what());
         return;
@@ -932,6 +936,7 @@ RingAccount::changeArchivePassword(const std::string& password_old, const std::s
     auto path = fileutils::getFullPath(idPath_, archivePath_);
     try {
         AccountArchive(path, password_old).save(path, password_new);
+        archiveHasPassword_ = not password_new.empty();
     } catch (const std::exception& ex) {
         RING_ERR("[Account %s] Can't change archive password: %s", getAccountID().c_str(), ex.what());
         return false;
@@ -1451,6 +1456,8 @@ RingAccount::getAccountDetails() const
     a.emplace(DRing::Account::ConfProperties::RING_DEVICE_ID, ringDeviceId_);
     a.emplace(DRing::Account::ConfProperties::RING_DEVICE_NAME, ringDeviceName_);
     a.emplace(DRing::Account::ConfProperties::Presence::SUPPORT_SUBSCRIBE, TRUE_STR);
+    if (not archivePath_.empty())
+        a.emplace(DRing::Account::ConfProperties::ARCHIVE_HAS_PASSWORD, archiveHasPassword_ ? TRUE_STR : FALSE_STR);
 
     /* these settings cannot be changed (read only), but clients should still be
      * able to read what they are */
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index 472259cb37..5b36df9647 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -451,6 +451,7 @@ class RingAccount : public SIPAccountBase {
         std::string ethAccount_ {};
 
         std::string archivePath_ {};
+        bool archiveHasPassword_ {true};
 
         std::string receipt_ {};
         std::vector<uint8_t> receiptSignature_ {};
-- 
GitLab