From e589abd10c11c7b1d847b3ee5f527f8e12bc43e4 Mon Sep 17 00:00:00 2001 From: Quentin Rouland Date: Wed, 15 Jan 2025 23:15:00 +0100 Subject: [PATCH] Refactor gpg for more clean job handling --- plugins/Pass/gpg.cpp | 191 +++++++++++++++--------------- plugins/Pass/gpg.h | 102 ++++++++++------ plugins/Pass/pass.cpp | 95 +++++++++++---- plugins/Pass/pass.h | 48 ++++++-- plugins/Pass/passkeymodel.h | 23 ++-- plugins/Pass/passphraseprovider.h | 66 ++++++----- po/utpass.qrouland.pot | 16 +-- qml/Main.qml | 38 +++--- qml/components/FileDir.qml | 17 +-- qml/pages/Password.qml | 10 +- qml/pages/PasswordList.qml | 17 ++- 11 files changed, 381 insertions(+), 242 deletions(-) diff --git a/plugins/Pass/gpg.cpp b/plugins/Pass/gpg.cpp index 948bab0..189810a 100644 --- a/plugins/Pass/gpg.cpp +++ b/plugins/Pass/gpg.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -22,9 +23,11 @@ #include #include + #include "gpg.h" +#include "passkeymodel.h" #include "passphraseprovider.h" -#include "qprocess.h" + @@ -32,9 +35,9 @@ using namespace GpgME; using namespace QGpgME; -Gpg::Gpg() +Gpg::Gpg(QObject* windows) { - m_window = nullptr; + this->m_passphrase_provider = new UTPassphraseProvider(windows); Gpg::initGpgConfig(); @@ -50,6 +53,10 @@ Gpg::Gpg() qDebug() << "GNUPG Home is :" << engineInfo(OpenPGP).homeDirectory(); } +Gpg::~Gpg(){ + delete this->m_passphrase_provider; +} + QString Gpg::initGpgHome() { @@ -124,37 +131,28 @@ void Gpg::initGpgConfig() } -QPair Gpg::decrypt(QByteArray cipherText) +Error Gpg::decrypt(QByteArray cipher_text) { auto job = openpgp()->decryptJob(); + auto ctx = DecryptJob::context(job); - auto provider = new UTPassphraseProvider; - ctx->setPassphraseProvider(provider); + ctx->setPassphraseProvider(this->m_passphrase_provider); ctx->setPinentryMode(Context::PinentryLoopback); - QByteArray plain_text; - auto decResult = job->exec(cipherText, plain_text); + QObject::connect(job, &DecryptJob::result, + this, &Gpg::decryptResultSlot); - delete job; - delete provider; - - if (decResult.error()) { - qWarning() << "something gone wrong on decrypt"; - qDebug() << "Code Error : " << decResult.error().code(); - qDebug() << "Error str : " << decResult.error().asString(); - } - return QPair(decResult.error(), QString::fromUtf8(plain_text)); + return job->start(cipher_text); } - -QPair Gpg::decryptFromFile(QString path) +Error Gpg::decryptFromFile(QString path) { qDebug() << "Decrypt from " << path; QFile file(path); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Can't open the File"; - return QPair(Error(), QString());; + return Error(); } QByteArray cipherText = file.readAll(); file.close(); @@ -162,77 +160,83 @@ QPair Gpg::decryptFromFile(QString path) } -QPair Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode) + +void Gpg::decryptResultSlot(const GpgME::DecryptionResult &result, const QByteArray &plainText, const QString &auditLogAsHtml, const GpgME::Error &auditLogError) { - - qDebug() << "Encrypt to QByteArray"; - auto keys = getKeys(uid); - if (keys.first) { - return QPair(keys.first, QByteArray()); + if (result.error()) { + qWarning() << "Something gone wrong on decrypt"; + qDebug() << "Code Error : " << result.error().code(); + qDebug() << "Error str : " << result.error().asString(); } - - auto job = std::unique_ptr(openpgp()->encryptJob(ascii_armor, text_mode)); - - QByteArray cipherText; - auto result = job->exec(keys.second, str.toUtf8(), Context::AlwaysTrust, cipherText); - - qDebug() << "Encrypted to QByteArray"; - return QPair(result.error(), cipherText); + emit decryptResult(result.error(), QString::fromUtf8(plainText)); } -Error Gpg::encryptToFile(QString str, QString path, QString uid, bool ascii_armor, - bool text_mode) -{ - qDebug() << "Encrypting to file " << path; - QFile file(path); - if (!file.open(QIODevice::WriteOnly)) { - qWarning() << "Can't open the file to write it" ; - return Error(); - } - auto encrypt_ret = encrypt(str, uid, ascii_armor, text_mode); - if (encrypt_ret.first) { - file.write(encrypt_ret.second); - } - qDebug() << "Encrypting to file " << path; - return encrypt_ret.first; -} +// QPair Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode) +// { + +// qDebug() << "Encrypt to QByteArray"; +// auto keys = getKeys(uid); +// if (keys.first) { +// return QPair(keys.first, QByteArray()); +// } + +// auto job = std::unique_ptr(openpgp()->encryptJob(ascii_armor, text_mode)); + +// QByteArray cipherText; +// auto result = job->exec(keys.second, str.toUtf8(), Context::AlwaysTrust, cipherText); + +// qDebug() << "Encrypted to QByteArray"; +// return QPair(result.error(), cipherText); +// } -QPair> Gpg::getAllKeys ( bool remote, const bool include_sigs, +// Error Gpg::encryptToFile(QString str, QString path, QString uid, bool ascii_armor, +// bool text_mode) +// { +// qDebug() << "Encrypting to file " << path; +// QFile file(path); +// if (!file.open(QIODevice::WriteOnly)) { +// qWarning() << "Can't open the file to write it" ; +// return Error(); +// } +// auto encrypt_ret = encrypt(str, uid, ascii_armor, text_mode); +// if (encrypt_ret.first) { +// file.write(encrypt_ret.second); +// } +// qDebug() << "Encrypting to file " << path; +// return encrypt_ret.first; +// } + + +Error Gpg::getAllKeys ( bool remote, const bool include_sigs, bool validate ) { return getKeys(QString(""), remote, include_sigs, validate); } -QPair> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs, +Error Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs, bool validate) { qDebug() << "Getting the keys " << pattern_uid; - auto job = std::unique_ptr(openpgp()->keyListJob(remote, include_sigs, validate)); + auto job = openpgp()->keyListJob(remote, include_sigs, validate); - std::vector keys; - auto result = job->exec(QStringList() << pattern_uid, false, keys); + QObject::connect(job, &KeyListJob::result, + this, &Gpg::getKeysJobResultSlot); - qDebug() << "Got the keys " << pattern_uid; - return QPair> (result.error(), keys); + return job->start(QStringList() << pattern_uid, false); } - -QPair Gpg::getKey(QString uid, bool remote, bool include_sigs, bool validate) +void Gpg::getKeysJobResultSlot(const GpgME::KeyListResult &result, const std::vector &keys, const QString &auditLogAsHtml , const GpgME::Error &auditLogError) { - qDebug() << "Getting the key " << uid; - auto keys = getKeys(uid, remote, include_sigs, validate); - - if (keys.first or keys.second.size() != 1) { - qWarning() << "Bad id"; - return QPair(keys.first, Key::null); + if (result.error()) { + qWarning() << "Something gone wrong on decrypt"; + qDebug() << "Code Error : " << result.error().code(); + qDebug() << "Error str : " << result.error().asString(); } - qDebug() << "Got the key " << uid; - return QPair(keys.first, keys.second.front()); + emit getKeysResult(result.error(), keys); } - Error Gpg::importKeysFromFile(QString path) { qDebug() << "Importing the key file" << path; @@ -242,51 +246,52 @@ Error Gpg::importKeysFromFile(QString path) qWarning() << "Can't open the File"; return Error(); } + auto data = file.readAll(); + file.close(); auto job = openpgp()->importJob(); - auto ctx = ImportJob::context(job); - auto result = job->exec(file.readAll()); + QObject::connect(job, &ImportJob::result, + this, &Gpg::importKeysFromFileSlot); + + return job->start(data); +} + +void Gpg::importKeysFromFileSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError) +{ qDebug() << "numImported" << result.numImported(); qDebug() << "numSecretKeysImported" << result.numSecretKeysImported(); qDebug() << "numSecretKeysConsidered" << result.numSecretKeysConsidered(); qDebug() << "numSecretKeysUnchanged" << result.numSecretKeysUnchanged(); qDebug() << "numUnchanged" << result.numUnchanged(); - file.close(); - delete job; if (result.error()) { - qWarning() << "Import go wrong"; + qWarning() << "Something gone wrong on decrypt"; qDebug() << "Code Error : " << result.error().code(); qDebug() << "Error str : " << result.error().asString(); } - qDebug() << "Imported the key file" << path; - return result.error(); + emit importKeysFromFileResult(result.error()); } -Error Gpg::deleteKeyId(QString uid) +Error Gpg::deleteKey(const Key key) { - qDebug() << "Deleting key id " << uid; - auto key = getKey(uid); + auto job = openpgp()->deleteJob(); - if (key.first) { - return key.first; - } + QObject::connect(job, &DeleteJob::result, + this, &Gpg::deleteKeySlot); - auto ctx = std::unique_ptr(Context::createForProtocol(OpenPGP)); - auto err = ctx->deleteKey(key.second, true); - - if (err) { - qWarning() << "Delete go wrong"; - qDebug() << "Code Error : " << err.code(); - qDebug() << "Error str : " << err.asString(); - return err; - } - - qDebug() << "Deleted key id" << uid; - return err; + return openpgp()->deleteJob()->start(key, true); } +void Gpg::deleteKeySlot(const GpgME::Error &error, const QString &auditLogAsHtml, const GpgME::Error &auditLogError) { + + if (error) { + qWarning() << "Something gone wrong on decrypt"; + qDebug() << "Code Error : " << error.code(); + qDebug() << "Error str : " << error.asString(); + } + emit deleteKeyResult(error); +} diff --git a/plugins/Pass/gpg.h b/plugins/Pass/gpg.h index 4f4c349..fd7dfa6 100644 --- a/plugins/Pass/gpg.h +++ b/plugins/Pass/gpg.h @@ -1,61 +1,95 @@ #ifndef GPG_H #define GPG_H +#include "passkeymodel.h" +#include "passphraseprovider.h" #include #include #include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include using namespace GpgME; +using namespace QGpgME; -class Gpg +class Gpg: public QObject { -private: - Gpg(); + Q_OBJECT + Q_PROPERTY(UTPassphraseProvider* passphrase_provider READ passphrase_provider MEMBER m_passphrase_provider ) - QObject *m_window; +private slots: + void decryptResultSlot( + const DecryptionResult &result, + const QByteArray &plain_text, + const QString &auditLogAsHtml, + const Error &auditLogError + ); + void getKeysJobResultSlot( + const GpgME::KeyListResult &result, + const std::vector &keys, + const QString &auditLogAsHtml , + const GpgME::Error &auditLogError + ); + + void importKeysFromFileSlot( + const GpgME::ImportResult &result, + const QString &auditLogAsHtml, + const GpgME::Error &auditLogError + ); + + void deleteKeySlot( + const GpgME::Error &result, + const QString &auditLogAsHtml, + const GpgME::Error &auditLogError + ); + +signals: + void importKeysFromFileResult(Error err); + void getKeysResult(Error err, std::vector keys); + void deleteKeyResult(Error err); + void decryptResult(Error err, QString plain_text); + +private: + UTPassphraseProvider* m_passphrase_provider; QString findCommandPath(const QString &command); QString initGpgHome(); QString initGpgExec(); void initGpgConfig(); + Error getKey(QString uid, bool remote = false, bool include_sigs = false, + bool validate = false); public: - static std::shared_ptr instance() + Gpg(QObject* window); + ~Gpg(); + + UTPassphraseProvider* passphrase_provider() const { - static std::shared_ptr s{new Gpg}; - return s; + return m_passphrase_provider; } - Gpg(Gpg const &) = delete; - void operator=(Gpg const &) = delete; - void setWindow(QObject *window) - { - m_window = window; - }; + Error importKeysFromFile(const QString path); + Error getKeys(const QString pattern_uid, const bool remote = false, + const bool include_sigs = false, + const bool validate = false); + Error getAllKeys (bool remote = false, bool include_sigs = {}, bool + validate = false); + Error deleteKey(const Key key); + Error decrypt(const QByteArray cipher_text); + Error decryptFromFile(const QString path); + //Error encrypt (QString str, QString uid, bool ascii_armor = true, + // bool text_mode = true); - QObject *getWindow() - { - return m_window; - }; - - - QPair> getAllKeys(bool remote = false, bool include_sigs = {}, bool - validate = false); - QPair> getKeys( QString pattern_uid, bool remote = false, - bool include_sigs = false, - bool validate = false); - QPair getKey( QString uid, bool remote = false, bool include_sigs = false, - bool validate = false); - QPair decrypt( QByteArray cipherText); - QPair decryptFromFile( QString path); - QPair encrypt( QString str, QString uid, bool ascii_armor = true, - bool text_mode = true); - Error encryptToFile( QString str, QString path, QString uid, bool ascii_armor = true, - bool text_mode = true); - Error importKeysFromFile( QString path); - Error deleteKeyId( QString uid); }; #endif diff --git a/plugins/Pass/pass.cpp b/plugins/Pass/pass.cpp index 6472b72..768aca1 100644 --- a/plugins/Pass/pass.cpp +++ b/plugins/Pass/pass.cpp @@ -8,8 +8,11 @@ -Pass::Pass(): m_password_store (QStandardPaths::writableLocation( - QStandardPaths::AppDataLocation).append("/.password-store")) +Pass::Pass(): + m_password_store (QStandardPaths::writableLocation( + QStandardPaths::AppDataLocation).append("/.password-store")), + m_sem(std::unique_ptr(new QSemaphore(1))), + m_show_filename(QString()) {} void Pass::initialize(QObject *window) @@ -18,7 +21,13 @@ void Pass::initialize(QObject *window) qFatal("window is invalid. Abording."); } - Gpg::instance()->setWindow(window); + this->m_gpg = std::unique_ptr(new Gpg(window)); + + QObject::connect(this, &Pass::responsePassphraseDialogPropagate, this->m_gpg->passphrase_provider(), &UTPassphraseProvider::handleResponse); + QObject::connect(this->m_gpg.get(), &Gpg::importKeysFromFileResult, this, &Pass::importGPGKeyResult); + QObject::connect(this->m_gpg.get(), &Gpg::getKeysResult, this, &Pass::getAllGPGKeysResult); + QObject::connect(this->m_gpg.get(), &Gpg::deleteKeyResult, this, &Pass::deleteGPGKeyResult); + QObject::connect(this->m_gpg.get(), &Gpg::decryptResult, this, &Pass::showResult); QDir dir(m_password_store); if (!dir.exists()) { @@ -27,38 +36,78 @@ void Pass::initialize(QObject *window) qInfo() << "Password Store is :" << m_password_store; } -void Pass::show(QUrl url) +bool Pass::show(QUrl url) { - qInfo() << "Decrypting"; - auto decrypt_ret = Gpg::instance()->decryptFromFile(url.toLocalFile()); - if (decrypt_ret.first) { - qInfo() << "Decrypt Failed"; - emit decryptFailed(); - } else if (decrypt_ret.second.isNull()) { - qInfo() << "Decrypt Canceled"; - emit decryptCanceled(); - } else { - qInfo() << "Decrypt OK"; - emit decrypted(url.fileName(), decrypt_ret.second); - } + if (!this->m_sem->tryAcquire(1, 500)){ return false; } + auto path = url.toLocalFile(); + qInfo() << "Staring decrypting job for " << path; + QFileInfo file_info(path); + this->m_show_filename = file_info.completeBaseName(); + return this->m_gpg->decryptFromFile(path); } -bool Pass::deleteGPGKey(QString id) +void Pass::showResult(Error err, QString plain_text) { + qInfo() << "Result for decrypting job"; + if (err) { + qInfo() << "Decrypt Failed"; + emit showFailed(err.asString()); + } else { + qInfo() << "Decrypt OK"; + emit showSucceed(this->m_show_filename, plain_text); + } + this->m_show_filename = QString(); + this->m_sem->release(1); +} + +bool Pass::deleteGPGKey(Key key) { - qInfo() << "Deleting Key id " << id; - return !Gpg::instance()->deleteKeyId(id); + if (!this->m_sem->tryAcquire(1, 500)){ return false;} + qInfo() << "Deleting Key"; + return this->m_gpg->deleteKey(key); +} + +void Pass::deleteGPGKeyResult(Error err) { + if(err) { + emit deleteGPGKeyFailed(err.asString()); + } else { + emit deleteGPGKeySucceed(); + } + this->m_sem->release(1); } bool Pass::importGPGKey(QUrl url) { + if (!this->m_sem->tryAcquire(1, 500)){ return false;} qInfo() << "Importing Key from " << url; - return !Gpg::instance()->importKeysFromFile(url.toLocalFile()); + return this->m_gpg->importKeysFromFile(url.toLocalFile()); } -QVariant Pass::getAllGPGKeys() +void Pass::importGPGKeyResult(Error err) { + if(err) { + emit importGPGKeyFailed(err.asString()); + } else { + emit importGPGKeySucceed(); + } + this->m_sem->release(1); +} + +bool Pass::getAllGPGKeys() { + if (!this->m_sem->tryAcquire(1, 500)){ return false; } qInfo() << "Getting all key form gpg "; - return QVariant::fromValue(PassKeyModel::keysToPassKey( - Gpg::instance()->getAllKeys().second)); // TODO Error handling + return this->m_gpg->getAllKeys(); } +void Pass::getAllGPGKeysResult(Error err, std::vector keys_info) { + if(err) { + emit getAllGPGKeysFailed(err.asString()); + } else { + emit getAllGPGKeysSucceed(QVariant::fromValue(PassKeyModel::keysToPassKey(keys_info))); + } + this->m_sem->release(1); +} + +void Pass::responsePassphraseDialog(bool cancel, QString passphrase) { + qDebug() << "responsePassphraseDialog"; + emit responsePassphraseDialogPropagate(cancel, passphrase); +} diff --git a/plugins/Pass/pass.h b/plugins/Pass/pass.h index b11f450..95bfa52 100644 --- a/plugins/Pass/pass.h +++ b/plugins/Pass/pass.h @@ -4,20 +4,44 @@ #include #include #include +#include +#include "gpg.h" + +using namespace GpgME; class Pass : public QObject { Q_OBJECT - Q_PROPERTY(QString password_store READ password_store) + Q_PROPERTY(QString password_store READ password_store MEMBER m_password_store CONSTANT) + +private slots: + void showResult(Error err, QString plain_text); + void deleteGPGKeyResult(Error err); + void importGPGKeyResult(Error err); + void getAllGPGKeysResult(Error err, std::vector< GpgME::Key > keys_info); + +signals: + // GPG + void deleteGPGKeySucceed(); + void deleteGPGKeyFailed(QString message); + void importGPGKeySucceed(); + void importGPGKeyFailed(QString message); + void getAllGPGKeysSucceed(QVariant keys_info); + void getAllGPGKeysFailed(QString message); + void responsePassphraseDialogPropagate(bool cancel, QString passphrase); + + // pass show + void showSucceed(QString name, QString text); + void showFailed(QString message); + + private: QString m_password_store; - -signals: - void decrypted(QString name, QString text); - void decryptCanceled(); - void decryptFailed(); + std::unique_ptr m_gpg; + std::unique_ptr m_sem; + QString m_show_filename; public: Pass(); @@ -29,10 +53,16 @@ public: } Q_INVOKABLE void initialize(QObject *window); - Q_INVOKABLE void show(QUrl url); - Q_INVOKABLE bool deleteGPGKey(QString id); + + // GPG + Q_INVOKABLE bool deleteGPGKey(Key key); Q_INVOKABLE bool importGPGKey(QUrl url); - Q_INVOKABLE QVariant getAllGPGKeys(); + Q_INVOKABLE bool getAllGPGKeys(); + Q_INVOKABLE void responsePassphraseDialog(bool cancel, QString passphrase); + + // PASS + Q_INVOKABLE bool show(QUrl url); + }; #endif diff --git a/plugins/Pass/passkeymodel.h b/plugins/Pass/passkeymodel.h index 9d5fa9d..638ec58 100644 --- a/plugins/Pass/passkeymodel.h +++ b/plugins/Pass/passkeymodel.h @@ -9,14 +9,13 @@ using namespace GpgME; class UserIdModel : public QObject { Q_OBJECT - Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT) - Q_PROPERTY(QString name READ name MEMBER m_name CONSTANT) - Q_PROPERTY(QString email READ email MEMBER m_email CONSTANT) + Q_PROPERTY(QString uid READ uid CONSTANT) + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString email READ email CONSTANT) +private: UserID m_user_id; public: - - UserIdModel(UserID key): m_user_id(key) {}; @@ -38,10 +37,11 @@ public: class PassKeyModel : public QObject { Q_OBJECT - Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT) - Q_PROPERTY(QList userIds READ userIds MEMBER m_user_ids CONSTANT) - Q_PROPERTY(bool isSecret READ isSecret MEMBER m_secret CONSTANT) - Q_PROPERTY(bool isExpired READ isExpired MEMBER m_expired CONSTANT) + Q_PROPERTY(Key key READ key MEMBER m_key CONSTANT) + Q_PROPERTY(QString uid READ uid CONSTANT) + Q_PROPERTY(QList userIds READ userIds CONSTANT) + Q_PROPERTY(bool isSecret READ isSecret CONSTANT) + Q_PROPERTY(bool isExpired READ isExpired CONSTANT) Key m_key; public: @@ -58,6 +58,11 @@ public: return ret; }; + Key key() const + { + return m_key; + }; + QString uid() const { return QString::fromUtf8(m_key.keyID()); diff --git a/plugins/Pass/passphraseprovider.h b/plugins/Pass/passphraseprovider.h index 65c9509..31e2adf 100644 --- a/plugins/Pass/passphraseprovider.h +++ b/plugins/Pass/passphraseprovider.h @@ -1,6 +1,7 @@ #ifndef UTPASSPHRASEPROVIDER_H #define UTPASSPHRASEPROVIDER_H +#include #include #include #include @@ -14,48 +15,57 @@ class UTPassphraseProvider : public QObject, public PassphraseProvider { Q_OBJECT -private: - std::unique_ptr m_loop; - std::unique_ptr m_sem; - char *m_passphrase; - bool m_canceled; public slots: void handleResponse(bool canceled, QString p) - { - if (!canceled) - gpgrt_asprintf(&m_passphrase, "%s", p.toUtf8().constData()); - else - m_canceled = true; - m_loop->quit(); - }; + { + qDebug() << "call handleResponse"; + if (!canceled) + gpgrt_asprintf(&m_passphrase, "%s", p.toUtf8().constData()); + else + m_canceled = true; + emit unlockEventLoop(); + }; + +signals: + void unlockEventLoop(); + +private: + std::unique_ptr m_sem; + char *m_passphrase; + bool m_canceled; + QObject* m_window; public: - UTPassphraseProvider(): - m_loop(std::unique_ptr(new QEventLoop)), + UTPassphraseProvider(QObject* window): m_sem(std::unique_ptr(new QSemaphore(1))), m_passphrase(nullptr), - m_canceled(false) - {} + m_canceled(false), + m_window(window) + { + qDebug() << "Initialize UTPassphraseProviderr"; + + } char *getPassphrase( const char *useridHint, const char *description, bool previousWasBad, bool &canceled ) Q_DECL_OVERRIDE { - if (!m_sem->tryAcquire(1, 3000)) + qDebug() << "Call the getPassphrase"; + if (!this->m_sem->tryAcquire(1, 500)) { qWarning() << "Cannot acquire UTPassphraseProvider semaphore."; canceled = true; return nullptr; } - m_passphrase = nullptr; - m_canceled = false; + this->m_passphrase = nullptr; + this->m_canceled = false; qDebug() << "Call the QML Dialog Passphrase Provider"; QMetaObject::invokeMethod( - Gpg::instance()->getWindow(), "callPassphraseDialog", + this->m_window, "callPassphraseDialog", Q_ARG(QVariant, useridHint), Q_ARG(QVariant, description), Q_ARG(QVariant, previousWasBad) @@ -63,24 +73,22 @@ public: qDebug() << "Waiting for response"; - QObject::connect( - Gpg::instance()->getWindow(), SIGNAL(responsePassphraseDialog(bool, QString)), - this, SLOT(handleResponse(bool, QString)) - ); - m_loop->exec(); + QEventLoop loop; + QObject::connect(this, &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit); + loop.exec(); qDebug() << "Prepare Returns"; char *ret; gpgrt_asprintf(&ret, "%s", m_passphrase); - canceled = m_canceled; + canceled = this->m_canceled; qDebug() << "Clean"; - if (m_passphrase) + if (this->m_passphrase) { free(m_passphrase); } - m_canceled = false; - m_sem->release(1); + this->m_canceled = false; + this->m_sem->release(1); return ret; }; }; diff --git a/po/utpass.qrouland.pot b/po/utpass.qrouland.pot index b77b775..bdda7d1 100644 --- a/po/utpass.qrouland.pot +++ b/po/utpass.qrouland.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: utpass.qrouland\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-14 13:57+0100\n" +"POT-Creation-Date: 2025-01-15 23:14+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,10 +17,6 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../qml/components/FileDir.qml:59 -msgid "Decryption failed !" -msgstr "" - #: ../qml/dialogs/ErrorDialog.qml:12 msgid "Error !" msgstr "" @@ -83,21 +79,25 @@ msgstr "" msgid "Info" msgstr "" -#: ../qml/pages/PasswordList.qml:22 +#: ../qml/pages/PasswordList.qml:37 msgid "" "No password found
You can import a password store by cloning or importing " "a zip in the settings" msgstr "" -#: ../qml/pages/PasswordList.qml:61 +#: ../qml/pages/PasswordList.qml:76 msgid "Back" msgstr "" -#: ../qml/pages/PasswordList.qml:68 ../qml/pages/headers/MainHeader.qml:9 +#: ../qml/pages/PasswordList.qml:83 ../qml/pages/headers/MainHeader.qml:9 #: ../qml/pages/headers/StackHeader.qml:9 UTPass.desktop.in.h:1 msgid "UTPass" msgstr "" +#: ../qml/pages/PasswordList.qml:96 +msgid "Decryption failed !" +msgstr "" + #: ../qml/pages/headers/MainHeader.qml:26 ../qml/pages/settings/Settings.qml:70 msgid "Settings" msgstr "" diff --git a/qml/Main.qml b/qml/Main.qml index 6e48640..bf800db 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -10,8 +10,6 @@ MainView { id: root - signal responsePassphraseDialog(bool canceled, string passphrase) - function initPass(rootView) { Pass.initialize(rootView); pageStack.push(Qt.resolvedUrl("pages/PasswordList.qml")); @@ -19,30 +17,36 @@ MainView { function callPassphraseDialog(useridHint, description, previousWasBad) { //TODO use parameters to impove passphrase dialog - var passphraseDialog = PopupUtils.open(Qt.resolvedUrl("dialogs/PassphraseDialog.qml")); - passphraseDialog.activateFocus(); - var validated = function validated(passphrase) { - responsePassphraseDialog(false, passphrase); - }; - var canceled = function canceled() { - responsePassphraseDialog(true, ""); - }; - passphraseDialog.validated.connect(validated); - passphraseDialog.canceled.connect(canceled); + var pop = PopupUtils.open(passphraseDialog); + pop.activateFocus(); } objectName: "mainView" applicationName: "utpass.qrouland" - automaticOrientation: false - width: units.gu(48) - height: units.gu(80) + automaticOrientation: true + + width: units.gu(45) + height: units.gu(75) PageStack { id: pageStack anchors.fill: parent - Component.onCompleted: { - } } + Component { + id: passphraseDialog + + PassphraseDialog { + onValidated: { + console.info("valided"); + Pass.responsePassphraseDialog(false, passphrase); + } + onCanceled: { + console.info("canceled"); + Pass.responsePassphraseDialog(true, ""); + } + } + + } } diff --git a/qml/components/FileDir.qml b/qml/components/FileDir.qml index fb50b71..1eb4376 100644 --- a/qml/components/FileDir.qml +++ b/qml/components/FileDir.qml @@ -33,12 +33,14 @@ Component { MouseArea { anchors.fill: parent onClicked: { - if (fileIsDir) { - folderModel.folder = folderModel.folder + "/" + fileName; + var path = folderModel.folder + "/" + fileName; + if (fileIsDir) { + folderModel.folder = path; backAction.visible = true; passwordListHeader.title = fileName; } else { - Pass.show(folderModel.folder + "/" + fileName); + console.debug("pass show %1".arg(path)) + Pass.show(path); } } } @@ -52,15 +54,6 @@ Component { borderColor: LomiriColors.warmGrey } - Component { - id: passwordPageDecryptError - - ErrorDialog { - textError: i18n.tr("Decryption failed !") - } - - } - } } diff --git a/qml/pages/Password.qml b/qml/pages/Password.qml index f4d4b15..f97acfb 100644 --- a/qml/pages/Password.qml +++ b/qml/pages/Password.qml @@ -49,11 +49,11 @@ Page { iconName: "back" text: "Back" onTriggered: { - // passwordPage.plainText = ""; - // for (var object in objects) { - // object.text = ""; - // object.destroy(); - // } + passwordPage.plainText = null; + for (var object in objects) { + object.text = null; + object.destroy(); + } pageStack.pop(); } } diff --git a/qml/pages/PasswordList.qml b/qml/pages/PasswordList.qml index a2ee897..e592ddb 100644 --- a/qml/pages/PasswordList.qml +++ b/qml/pages/PasswordList.qml @@ -1,9 +1,11 @@ +import "headers" import "../components" +import "../dialogs" import Lomiri.Components 1.3 import Pass 1.0 import Qt.labs.folderlistmodel 2.1 import QtQuick 2.4 -import "headers" +import Lomiri.Components.Popups 1.3 Page { id: passwordListPage @@ -13,13 +15,13 @@ Page { anchors.fill: parent Component.onCompleted: { passwordStorePath = "file:" + Pass.password_store; - Pass.onDecrypted.connect(function(filename, text) { + Pass.onShowSucceed.connect(function(filename, text) { pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), { "plainText": text, "title": filename }); }); - Pass.onDecryptFailed.connect(function() { + Pass.onShowFailed.connect(function(message) { PopupUtils.open(passwordPageDecryptError); }); } @@ -87,4 +89,13 @@ Page { ] } + Component { + id: passwordPageDecryptError + + ErrorDialog { + textError: i18n.tr("Decryption failed !") + } + + } + }