#include "syncresult.h"
#include "ignorelisttablewidget.h"
#include "wizard/owncloudwizard.h"
+#include "ui_mnemonicdialog.h"
#include <cmath>
namespace {
constexpr auto propertyFolder = "folder";
constexpr auto propertyPath = "path";
+constexpr auto e2eUiActionIdKey = "id";
+constexpr auto e2EeUiActionEnableEncryptionId = "enable_encryption";
+constexpr auto e2EeUiActionDisplayMnemonicId = "display_mnemonic";
}
namespace OCC {
_ui->quotaProgressBar->setStyleSheet(QString::fromLatin1(progressBarStyleC).arg(color.name()));*/
// Connect E2E stuff
- connect(this, &AccountSettings::requestMnemonic, _accountState->account()->e2e(), &ClientSideEncryption::slotRequestMnemonic);
- connect(_accountState->account()->e2e(), &ClientSideEncryption::showMnemonic, this, &AccountSettings::slotShowMnemonic);
-
- connect(_accountState->account()->e2e(), &ClientSideEncryption::mnemonicGenerated, this, &AccountSettings::slotNewMnemonicGenerated);
- if (_accountState->account()->e2e()->newMnemonicGenerated()) {
- slotNewMnemonicGenerated();
- } else {
- _ui->encryptionMessage->setText(tr("This account supports End-to-End encryption"));
-
- auto *mnemonic = new QAction(tr("Display mnemonic"), this);
- connect(mnemonic, &QAction::triggered, this, &AccountSettings::requestMnemonic);
- _ui->encryptionMessage->addAction(mnemonic);
- _ui->encryptionMessage->hide();
- }
+ initializeE2eEncryption();
_ui->connectLabel->setText(tr("No account configured."));
customizeStyle();
}
-void AccountSettings::slotNewMnemonicGenerated()
+void AccountSettings::slotE2eEncryptionMnemonicReady()
{
+ auto *const actionDisplayMnemonic = addActionToEncryptionMessage(tr("Display mnemonic"), e2EeUiActionDisplayMnemonicId);
+ connect(actionDisplayMnemonic, &QAction::triggered, this, [this]() {
+ displayMnemonic(_accountState->account()->e2e()->_mnemonic);
+ });
_ui->encryptionMessage->setText(tr("This account supports End-to-End encryption"));
+ _ui->encryptionMessage->show();
+
+}
- auto *mnemonic = new QAction(tr("Enable encryption"), this);
- connect(mnemonic, &QAction::triggered, this, &AccountSettings::requestMnemonic);
- connect(mnemonic, &QAction::triggered, _ui->encryptionMessage, &KMessageWidget::hide);
+void AccountSettings::slotE2eEncryptionGenerateKeys()
+{
+ connect(_accountState->account()->e2e(), &ClientSideEncryption::initializationFinished, this, &AccountSettings::slotE2eEncryptionInitializationFinished);
+ _accountState->account()->setE2eEncryptionKeysGenerationAllowed(true);
+ _accountState->account()->e2e()->initialize(_accountState->account());
+}
- _ui->encryptionMessage->addAction(mnemonic);
- _ui->encryptionMessage->show();
+void AccountSettings::slotE2eEncryptionInitializationFinished(bool isNewMnemonicGenerated)
+{
+ disconnect(_accountState->account()->e2e(), &ClientSideEncryption::initializationFinished, this, &AccountSettings::slotE2eEncryptionInitializationFinished);
+ if (!_accountState->account()->e2e()->_mnemonic.isEmpty()) {
+ removeActionFromEncryptionMessage(e2EeUiActionEnableEncryptionId);
+ slotE2eEncryptionMnemonicReady();
+ if (isNewMnemonicGenerated) {
+ displayMnemonic(_accountState->account()->e2e()->_mnemonic);
+ }
+ }
}
void AccountSettings::slotEncryptFolderFinished(int status)
}
}
-void AccountSettings::slotShowMnemonic(const QString &mnemonic)
-{
- AccountManager::instance()->displayMnemonic(mnemonic);
-}
-
bool AccountSettings::canEncryptOrDecrypt (const FolderStatusModel::SubFolderInfo* info) {
if (info->_folder->syncResult().status() != SyncResult::Status::Success) {
QMessageBox msgBox;
folder->scheduleThisFolderSoon();
}
+void AccountSettings::displayMnemonic(const QString &mnemonic)
+{
+ auto widget = QDialog(this);
+ Ui_Dialog ui;
+ ui.setupUi(&widget);
+ widget.setWindowTitle(tr("End-to-End encryption mnemonic"));
+ ui.label->setText(
+ tr("To protect your Cryptographic Identity, we encrypt it with a mnemonic of 12 dictionary words. "
+ "Please note these down and keep them safe. "
+ "They will be needed to add other devices to your account (like your mobile phone or laptop)."));
+ QFont monoFont(QStringLiteral("Monospace"));
+ monoFont.setStyleHint(QFont::TypeWriter);
+ ui.lineEdit->setFont(monoFont);
+ ui.lineEdit->setText(mnemonic);
+ ui.lineEdit->setReadOnly(true);
+
+ ui.lineEdit->setStyleSheet(QStringLiteral("QLineEdit{ color: black; background: lightgrey; border-style: inset;}"));
+
+ ui.lineEdit->focusWidget();
+ ui.lineEdit->selectAll();
+ ui.lineEdit->setAlignment(Qt::AlignCenter);
+
+ const QFont font(QStringLiteral(""), 0);
+ QFontMetrics fm(font);
+ ui.lineEdit->setFixedWidth(fm.horizontalAdvance(mnemonic));
+ widget.resize(widget.sizeHint());
+ widget.exec();
+}
+
void AccountSettings::showConnectionLabel(const QString &message, QStringList errors)
{
const auto errStyle = QLatin1String("color:#ffffff; background-color:#bb4d4d;padding:5px;"
_ui->quotaProgressBar->setStyleSheet(QString::fromLatin1(progressBarStyleC).arg(color.name()));
}
+void AccountSettings::initializeE2eEncryption()
+{
+ if (!_accountState->account()->e2e()->_mnemonic.isEmpty()) {
+ slotE2eEncryptionMnemonicReady();
+ } else {
+ _ui->encryptionMessage->setText(tr("This account supports End-to-End encryption"));
+ _ui->encryptionMessage->hide();
+
+ auto *const actionEnableE2e = addActionToEncryptionMessage(tr("Enable encryption"), e2EeUiActionEnableEncryptionId);
+ connect(actionEnableE2e, &QAction::triggered, this, &AccountSettings::slotE2eEncryptionGenerateKeys);
+ }
+}
+
+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) {
+ return action->property(e2eUiActionIdKey).toString() == actionId;
+ });
+ if (foundEnableEncryptionActionIt != std::cend(_ui->encryptionMessage->actions())) {
+ _ui->encryptionMessage->removeAction(*foundEnableEncryptionActionIt);
+ (*foundEnableEncryptionActionIt)->deleteLater();
+ }
+}
+
+QAction *AccountSettings::addActionToEncryptionMessage(const QString &actionTitle, const QString &actionId)
+{
+ for (const auto &action : _ui->encryptionMessage->actions()) {
+ if (action->property(e2eUiActionIdKey) == actionId) {
+ return action;
+ }
+ }
+
+ auto *const action = new QAction(actionTitle, this);
+ if (!actionId.isEmpty()) {
+ action->setProperty(e2eUiActionIdKey, actionId);
+ }
+ _ui->encryptionMessage->addAction(action);
+ return action;
+}
+
} // namespace OCC
#include "accountsettings.moc"
startDeleteJob(user + e2e_mnemonic);
}
-void ClientSideEncryption::slotRequestMnemonic()
-{
- emit showMnemonic(_mnemonic);
-}
-
void ClientSideEncryption::generateKeyPair(const AccountPtr &account)
{
// AES/GCM/NoPadding,
{
QStringList list = WordList::getRandomWords(12);
_mnemonic = list.join(' ');
- _newMnemonicGenerated = true;
qCInfo(lcCse()) << "mnemonic Generated:" << _mnemonic;
- emit mnemonicGenerated(_mnemonic);
-
QString passPhrase = list.join(QString()).toLower();
qCInfo(lcCse()) << "Passphrase Generated:" << passPhrase;
writePrivateKey(account);
writeCertificate(account);
writeMnemonic(account);
- emit initializationFinished();
+ emit initializationFinished(true);
break;
default:
qCInfo(lcCse()) << "Store private key failed, return code:" << retCode;
job->start();
}
-bool ClientSideEncryption::newMnemonicGenerated() const
-{
- return _newMnemonicGenerated;
-}
-
void ClientSideEncryption::decryptPrivateKey(const AccountPtr &account, const QByteArray &key) {
QString msg = tr("Please enter your End-to-End encryption passphrase:<br>"
"<br>"
fetchAndValidatePublicKeyFromServer(account);
} else if (retCode == 404) {
qCInfo(lcCse()) << "No public key on the server";
+ if (!account->e2eEncryptionKeysGenerationAllowed()) {
+ qCInfo(lcCse()) << "User did not allow E2E keys generation.";
+ emit initializationFinished();
+ return;
+ }
generateKeyPair(account);
} else {
qCInfo(lcCse()) << "Error while requesting public key: " << retCode;