From cc6bdc9bd50a9912191fcd0243ae323fc37756ae Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 11 Nov 2022 16:01:04 +0100 Subject: [PATCH] Add ability to remove local encryption keys through settings Signed-off-by: Claudio Cambra --- src/gui/accountsettings.cpp | 69 +++++++++++++++++++++++----- src/gui/accountsettings.h | 3 ++ src/libsync/clientsideencryption.cpp | 8 ++-- src/libsync/clientsideencryption.h | 6 +-- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp index 3fa71150b..b51cc1188 100644 --- a/src/gui/accountsettings.cpp +++ b/src/gui/accountsettings.cpp @@ -66,6 +66,7 @@ constexpr auto propertyFolder = "folder"; constexpr auto propertyPath = "path"; constexpr auto e2eUiActionIdKey = "id"; constexpr auto e2EeUiActionEnableEncryptionId = "enable_encryption"; +constexpr auto e2EeUiActionDisableEncryptionId = "disable_encryption"; constexpr auto e2EeUiActionDisplayMnemonicId = "display_mnemonic"; } @@ -243,7 +244,12 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) void AccountSettings::slotE2eEncryptionMnemonicReady() { - auto *const actionDisplayMnemonic = addActionToEncryptionMessage(tr("Display mnemonic"), e2EeUiActionDisplayMnemonicId); + const auto actionDisableEncryption = addActionToEncryptionMessage(tr("Disable encryption"), e2EeUiActionDisableEncryptionId); + connect(actionDisableEncryption, &QAction::triggered, this, [this] { + disableEncryptionForAccount(_accountState->account()); + }); + + const auto actionDisplayMnemonic = addActionToEncryptionMessage(tr("Display mnemonic"), e2EeUiActionDisplayMnemonicId); connect(actionDisplayMnemonic, &QAction::triggered, this, [this]() { displayMnemonic(_accountState->account()->e2e()->_mnemonic); }); @@ -1024,6 +1030,31 @@ void AccountSettings::displayMnemonic(const QString &mnemonic) widget.exec(); } +void AccountSettings::disableEncryptionForAccount(const AccountPtr &account) const +{ + QMessageBox dialog; + dialog.setWindowTitle(tr("Disable end-to-end encryption")); + dialog.setText(tr("Disable end-to-end encryption for %1?").arg(account->davUser())); + dialog.setInformativeText(tr("Removing end-to-end encryption will remove locally-synced files that are encrypted." + "
" + "Encrypted files will remain on the server.")); + dialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + dialog.setDefaultButton(QMessageBox::Ok); + dialog.adjustSize(); + + const auto ret = dialog.exec(); + switch(ret) { + case QMessageBox::Ok: + connect(account->e2e(), &ClientSideEncryption::sensitiveDataForgotten, + this, &AccountSettings::resetE2eEncryption); + account->e2e()->forgetSensitiveData(account); + break; + case QMessageBox::Cancel: + break; + Q_UNREACHABLE(); + } +} + void AccountSettings::showConnectionLabel(const QString &message, QStringList errors) { const auto errStyle = QLatin1String("color:#ffffff; background-color:#bb4d4d;padding:5px;" @@ -1257,16 +1288,21 @@ void AccountSettings::slotAccountStateChanged() refreshSelectiveSyncStatus(); if (state == AccountState::State::Connected) { - /* TODO: We should probably do something better here. - * Verify if the user has a private key already uploaded to the server, - * if it has, do not offer to create one. - */ - qCInfo(lcAccountSettings) << "Account" << accountsState()->account()->displayName() - << "Client Side Encryption" << accountsState()->account()->capabilities().clientSideEncryptionAvailable(); - - if (_accountState->account()->capabilities().clientSideEncryptionAvailable()) { - _ui->encryptionMessage->show(); - } + checkClientSideEncryptionState(); + } +} + +void AccountSettings::checkClientSideEncryptionState() +{ + /* TODO: We should probably do something better here. + * Verify if the user has a private key already uploaded to the server, + * if it has, do not offer to create one. + */ + qCInfo(lcAccountSettings) << "Account" << accountsState()->account()->displayName() + << "Client Side Encryption" << accountsState()->account()->capabilities().clientSideEncryptionAvailable(); + + if (_accountState->account()->capabilities().clientSideEncryptionAvailable()) { + _ui->encryptionMessage->show(); } } @@ -1569,6 +1605,17 @@ void AccountSettings::initializeE2eEncryption() } } +void AccountSettings::resetE2eEncryption() +{ + for (const auto action : _ui->encryptionMessage->actions()) { + _ui->encryptionMessage->removeAction(action); + } + _ui->encryptionMessage->setText({}); + _ui->encryptionMessage->setIcon({}); + initializeE2eEncryption(); + checkClientSideEncryptionState(); +} + void AccountSettings::removeActionFromEncryptionMessage(const QString &actionId) { const auto foundEnableEncryptionActionIt = std::find_if(std::cbegin(_ui->encryptionMessage->actions()), std::cend(_ui->encryptionMessage->actions()), [&actionId](const QAction *action) { diff --git a/src/gui/accountsettings.h b/src/gui/accountsettings.h index 395a83c5d..f3384ef76 100644 --- a/src/gui/accountsettings.h +++ b/src/gui/accountsettings.h @@ -119,11 +119,14 @@ private slots: private slots: void displayMnemonic(const QString &mnemonic); + void disableEncryptionForAccount(const AccountPtr &account) const; void showConnectionLabel(const QString &message, QStringList errors = QStringList()); void openIgnoredFilesDialog(const QString & absFolderPath); void customizeStyle(); void initializeE2eEncryption(); + void resetE2eEncryption(); + void checkClientSideEncryptionState(); void removeActionFromEncryptionMessage(const QString &actionId); private: diff --git a/src/libsync/clientsideencryption.cpp b/src/libsync/clientsideencryption.cpp index 49b528dc6..4277af839 100644 --- a/src/libsync/clientsideencryption.cpp +++ b/src/libsync/clientsideencryption.cpp @@ -1066,7 +1066,7 @@ void ClientSideEncryption::forgetSensitiveData(const AccountPtr &account) { _publicKey = QSslKey(); - const auto createDeleteJob = [account](QString user) { + const auto createDeleteJob = [account](const QString user) { auto *job = new DeletePasswordJob(Theme::instance()->appName()); job->setInsecureFallback(false); job->setKey(AbstractCredentials::keychainKey(account->url().toString(), user, account->id())); @@ -1086,7 +1086,7 @@ void ClientSideEncryption::forgetSensitiveData(const AccountPtr &account) deleteMnemonicJob->start(); } -void ClientSideEncryption::handlePrivateKeyDeleted(QKeychain::Job *incoming) +void ClientSideEncryption::handlePrivateKeyDeleted(const QKeychain::Job* const incoming) { if (incoming->error() != QKeychain::NoError) { qCWarning(lcCse) << "Private key could not be deleted:" << incoming->errorString(); @@ -1099,7 +1099,7 @@ void ClientSideEncryption::handlePrivateKeyDeleted(QKeychain::Job *incoming) checkAllSensitiveDataDeleted(); } -void ClientSideEncryption::handleCertificateDeleted(QKeychain::Job *incoming) +void ClientSideEncryption::handleCertificateDeleted(const QKeychain::Job* const incoming) { if (incoming->error() != QKeychain::NoError) { qCWarning(lcCse) << "Certificate could not be deleted:" << incoming->errorString(); @@ -1112,7 +1112,7 @@ void ClientSideEncryption::handleCertificateDeleted(QKeychain::Job *incoming) checkAllSensitiveDataDeleted(); } -void ClientSideEncryption::handleMnemonicDeleted(QKeychain::Job *incoming) +void ClientSideEncryption::handleMnemonicDeleted(const QKeychain::Job* const incoming) { if (incoming->error() != QKeychain::NoError) { qCWarning(lcCse) << "Mnemonic could not be deleted:" << incoming->errorString(); diff --git a/src/libsync/clientsideencryption.h b/src/libsync/clientsideencryption.h index 037d231ea..335c76746 100644 --- a/src/libsync/clientsideencryption.h +++ b/src/libsync/clientsideencryption.h @@ -145,9 +145,9 @@ private slots: void privateKeyFetched(QKeychain::Job *incoming); void mnemonicKeyFetched(QKeychain::Job *incoming); - void handlePrivateKeyDeleted(QKeychain::Job *incoming); - void handleCertificateDeleted(QKeychain::Job *incoming); - void handleMnemonicDeleted(QKeychain::Job *incoming); + void handlePrivateKeyDeleted(const QKeychain::Job* const incoming); + void handleCertificateDeleted(const QKeychain::Job* const incoming); + void handleMnemonicDeleted(const QKeychain::Job* const incoming); void checkAllSensitiveDataDeleted(); void getPrivateKeyFromServer(const AccountPtr &account); -- 2.30.2