1
0
mirror of https://github.com/QRouland/UTPass.git synced 2025-02-11 15:07:16 +00:00

Complete rewrite from gpgme to rnp

This commit is contained in:
Quentin Rouland 2025-02-03 21:46:21 +01:00
parent e56c16f27b
commit ba52ddac5c
20 changed files with 333 additions and 171 deletions

View File

@ -7,11 +7,12 @@ set(
pass.cpp
passkeyringmodel.h
passphraseprovider.h
jobs/rmjob.cpp
jobs/rnpjob.cpp
jobs/decryptjob.cpp
jobs/deletekeyjob.cpp
jobs/getkeysjob.cpp
jobs/importkeyjob.cpp
jobs/decryptjob.cpp
jobs/rmjob.cpp
jobs/rnpjob.cpp
)
set(CMAKE_AUTOMOC ON)

View File

@ -16,12 +16,13 @@ DecryptJob::DecryptJob(QDir rnp_homedir, QString path):
void DecryptJob::run()
{
qDebug() << "[DecryptJob] Starting";
this->load_sec_keyring(NULL);
this->loadFullKeyring(NULL);
rnp_input_t input = NULL;
rnp_output_t output = NULL;
uint8_t * buf = NULL;
uint8_t *buf = NULL;
size_t buf_len = 0;
QString data = QString::Null();
auto ret = rnp_input_from_path(&input, this->m_encrypted_file_path.toLocal8Bit().data());
if (ret == RNP_SUCCESS) {
@ -34,14 +35,13 @@ void DecryptJob::run()
ret = rnp_output_memory_get_buf(output, &buf, &buf_len, false);
}
if (ret == RNP_SUCCESS) {
emit resultSuccess(this->m_encrypted_file_path, QString::fromUtf8((char*)buf));
data = QString::fromUtf8((char*)buf);
}
rnp_input_destroy(input);
rnp_output_destroy(output);
terminateOnError(ret);
emit resultSuccess(this->m_encrypted_file_path, QString::fromUtf8((char*)buf));
emit resultSuccess(this->m_encrypted_file_path, data);
qDebug() << "[DecryptJob] Finished Successfully ";
}

View File

@ -18,8 +18,7 @@ class DecryptJob : public RnpJob
* @brief Executes the decryption operation.
*
* This method performs the actual decryption of the encrypted file specified during
* object construction. The operation is carried out in a separate background thread
* to prevent blocking the main application thread.
* object construction.
*/
void run() override;

View File

@ -0,0 +1,42 @@
#include <QDebug>
#include <QString>
#include <QJsonDocument>
#include "deletekeyjob.h"
extern "C" {
#include <rnp/rnp.h>
#include <rnp/rnp_err.h>
}
DeleteKeyJob::DeleteKeyJob(QDir rnp_homedir, QString fingerprint):
RnpJob(rnp_homedir),
m_fingerprint(fingerprint)
{
this->setObjectName("ImportKeyJob");
}
void DeleteKeyJob::run()
{
qDebug() << "[DeleteKeyJob] Starting";
// Loading keyring
this->loadFullKeyring(NULL);
// Delete key
rnp_key_handle_t key = NULL;
auto ret = rnp_locate_key(this->m_ffi, "fingerprint", this->m_fingerprint.toLocal8Bit().data(), &key);
if (ret == RNP_SUCCESS) {
ret = rnp_key_remove(key, RNP_KEY_REMOVE_PUBLIC | RNP_KEY_REMOVE_SECRET | RNP_KEY_REMOVE_SUBKEYS);
};
rnp_key_handle_destroy(key);
// Save resulting keyring
this->saveFullKeyring();
// Emit result
terminateOnError(ret);
emit resultSuccess();
qDebug() << "[DeleteKeyJob] Finished Successfully ";
}

View File

@ -0,0 +1,46 @@
#ifndef DELETEKEYJOB_H
#define DELETEKEYJOB_H
#include "rnpjob.h"
/**
* @class DeleteKeyJob
* @brief A job to handle the deletion of a key in a separate thread.
*
*/
class DeleteKeyJob : public RnpJob
{
Q_OBJECT
/**
* @brief Executes the key deletion operation.
*
* This function performs the actual process of deleting the GPG key from the keyring.
*/
void run() override;
signals:
/**
* @brief Emitted when the key deletion operation is successful.
*
* This signal is emitted when the key is successfully deleted from the keyring..
*/
void resultSuccess();
private:
QString m_fingerprint; /**< The fingerprint of the key to delete. */
public:
/**
* @brief Constructs a DeleteKeyJob object with the specified fingerprint and keyring directory.
*
* This constructor initializes the DeleteKeyJob instance with the directory containing
* the keyrings and the fingerprint of the GPG key to delete.
*
* @param rnp_homedir The directory containing the keyrings where the key will be deleted.
* @param fingerprint The fingerprint of the key to delete.
*/
DeleteKeyJob(QDir rnp_homedir, QString fingerprint);
};
#endif // DELETEKEYJOB_H

View File

@ -30,7 +30,7 @@ void GetKeysJob::run()
// Loading keyring
QSet<QString> fingerprints = QSet<QString>();
this->load_full_keyring(&fingerprints);
this->loadFullKeyring(&fingerprints);
//Get infos keys
auto key_infos = QList<QJsonDocument>();

View File

@ -16,8 +16,7 @@ class GetKeysJob : public RnpJob
/**
* @brief Executes the process of fetching all GPG keys.
*
* This function performs the task of retrieving all keys from the keyrings. It is executed
* in a separate thread to avoid blocking the main application thread.
* This function performs the task of retrieving all keys from the keyrings.
*/
void run() override;

View File

@ -19,6 +19,11 @@ ImportKeyJob::ImportKeyJob(QDir rnp_homedir, QString key_file_path):
void ImportKeyJob::run()
{
qDebug() << "[ImportKeyJob] Starting";
// Loading keyring
this->loadFullKeyring(NULL);
// Import new key
rnp_input_t input = NULL;
auto ret = rnp_input_from_path(&input, this->m_key_file_path.toLocal8Bit().constData());
if (ret == RNP_SUCCESS) {
@ -35,29 +40,33 @@ void ImportKeyJob::run()
rnp_input_destroy(input);
terminateOnError(ret);
rnp_output_t output = NULL;
qDebug() << "[ImportKeyJob] Writing pubring to " << this->pubringPath();
ret = rnp_output_to_file(&output, this->pubringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE);
if (ret == RNP_SUCCESS) {
qDebug() << "[ImportKeyJob] Saving key pubring ";
ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_PUBLIC_KEYS);
// Save resulting keyring
this->saveFullKeyring();
// rnp_output_t output = NULL;
// qDebug() << "[ImportKeyJob] Writing pubring to " << this->pubringPath();
// ret = rnp_output_to_file(&output, this->pubringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE);
// if (ret == RNP_SUCCESS) {
// qDebug() << "[ImportKeyJob] Saving key pubring ";
// ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_PUBLIC_KEYS);
}
if (ret == RNP_SUCCESS) {
ret = rnp_output_finish(output);
}
rnp_output_destroy(output);
terminateOnError(ret);
// }
// if (ret == RNP_SUCCESS) {
// ret = rnp_output_finish(output);
// }
// rnp_output_destroy(output);
// terminateOnError(ret);
qDebug() << "[ImportKeyJob] Writing secring to " << this->secringPath();
ret = rnp_output_to_file(&output, this->secringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE);
if (ret == RNP_SUCCESS) {
qDebug() << "[ImportKeyJob] Saving key secring ";
ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS);
}
// qDebug() << "[ImportKeyJob] Writing secring to " << this->secringPath();
// ret = rnp_output_to_file(&output, this->secringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE);
// if (ret == RNP_SUCCESS) {
// qDebug() << "[ImportKeyJob] Saving key secring ";
// ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS);
// }
rnp_output_destroy(output);
terminateOnError(ret);
// rnp_output_destroy(output);
// terminateOnError(ret);
// Emit result
emit resultSuccess();
qDebug() << "[ImportKeyJob] Finished Successfully ";
}

View File

@ -16,8 +16,7 @@ class ImportKeyJob : public RnpJob
* @brief Executes the key import operation.
*
* This function handles the actual process of importing the GPG key file into the
* keyring. It is executed in a separate thread to prevent UI freezing or blocking
* of the main application thread during the import.
* keyring.
*/
void run() override;

View File

@ -17,8 +17,6 @@ class RmJob : public QThread
* @brief Executes the recursive remove operation.
*
* This method performs the recursive removal of the specified target path.
* The operation is performed in the background to prevent blocking of the main
* application thread.
*/
void run() override;

View File

@ -50,7 +50,7 @@ bool RnpJob::passProvider(rnp_ffi_t ffi,
}
void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString path, const uint32_t flags)
void RnpJob::loadKeyFile(QSet<QString> *result_fingerprints, const QString path, const uint32_t flags)
{
qDebug() << "[RnpJob] Load keyring at" << path;
rnp_input_t input = NULL;
@ -65,7 +65,7 @@ void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString pat
}
QJsonDocument json_document = QJsonDocument::fromJson(json);
qDebug() << "[RnpJob] json" << json_document;
if(result_fingerprints) {
if (result_fingerprints) {
foreach (const QJsonValue fingerprint, json_document.object()["keys"].toArray()) {
qDebug() << "[RnpJob] Add fingerprint" << fingerprint["fingerprint"].toString();
result_fingerprints->insert(fingerprint["fingerprint"].toString());
@ -82,18 +82,53 @@ void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString pat
}
void RnpJob::load_pub_keyring(QSet<QString> *result_fingerprints = NULL)
void RnpJob::loadPubKeyring(QSet<QString> *result_fingerprints = NULL)
{
this->load_key_file(result_fingerprints, this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS);
this->loadKeyFile(result_fingerprints, this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS);
}
void RnpJob::load_sec_keyring(QSet<QString> *result_fingerprints = NULL)
void RnpJob::loadSecKeyring(QSet<QString> *result_fingerprints = NULL)
{
this->load_key_file(result_fingerprints, this->secringPath(), RNP_LOAD_SAVE_SECRET_KEYS);
this->loadKeyFile(result_fingerprints, this->secringPath(), RNP_LOAD_SAVE_SECRET_KEYS);
}
void RnpJob::load_full_keyring(QSet<QString> *result_fingerprints = NULL)
void RnpJob::loadFullKeyring(QSet<QString> *result_fingerprints = NULL)
{
this->load_pub_keyring(result_fingerprints);
this->load_sec_keyring(result_fingerprints);
this->loadPubKeyring(result_fingerprints);
this->loadSecKeyring(result_fingerprints);
}
void RnpJob::saveKeyFile(const QString path, const uint32_t flags)
{
qDebug() << "[RnpJob] Saving keyring at" << path;
rnp_output_t output = NULL;
auto ret = rnp_output_to_file(&output, path.toLocal8Bit().data(), RNP_OUTPUT_FILE_OVERWRITE);
if (ret == RNP_SUCCESS) {
qDebug() << "[ImportKeyJob] Saving key pubring ";
ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, flags);
}
if (ret == RNP_SUCCESS) {
ret = rnp_output_finish(output);
}
rnp_output_destroy(output);
terminateOnError(ret);
}
void RnpJob::savePubKeyring()
{
this->saveKeyFile(this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS);
}
void RnpJob::saveSecKeyring()
{
this->saveKeyFile(this->secringPath(), RNP_LOAD_SAVE_SECRET_KEYS);
}
void RnpJob::saveFullKeyring()
{
this->savePubKeyring();
this->saveSecKeyring();
}

View File

@ -16,14 +16,14 @@ if(ret != RNP_SUCCESS) { \
return; \
} \
/**
/**
* @class RnpJob
* @brief A base class that manages OpenPGP-related tasks using the librnp library.
*
* The RnpJob class serves as an abstraction for performing OpenPGP (RNP) operations, such as
* encryption, decryption, and key management, using the RNP library.
*/
class RnpJob : public QThread
class RnpJob : public QThread
{
Q_OBJECT
@ -73,7 +73,19 @@ private:
* @param path The path to the key file.
* @param flags Flags specifying options for loading keys (e.g., overwrite, secret keys, etc.).
*/
void load_key_file(QSet<QString> *result_fingerprints, const QString path, const uint32_t flags);
void loadKeyFile(QSet<QString> *result_fingerprints, const QString path, const uint32_t flags);
/**
* @brief Saves keys to the keyring file in the specified directory.
*
* This method saves a keyring to a file. It allows you to specify options such as overwriting
* existing files or including secret keys.
*
* @param path The path to the keyring file where the keys should be saved.
* @param flags Flags specifying options for saving the keys (e.g., overwrite, include secret keys, etc.).
*/
void saveKeyFile(const QString path, const uint32_t flags);
protected:
rnp_ffi_t m_ffi; /**< RNP FFI (Foreign Function Interface) handle, used for interacting with the RNP library. */
@ -105,34 +117,43 @@ protected:
}
/**
* @brief Loads the secret keyring into the RNP system.
*
* This method loads the secret keyring file (secring.pgp) into the system, adding keys
* to the keyring based on their fingerprints.
* @brief Loads the secret keyring into RNP.
*
* @param result_fingerprints A set that will hold the fingerprints of the loaded secret keys.
*/
void load_sec_keyring(QSet<QString> *result_fingerprints);
void loadSecKeyring(QSet<QString> *result_fingerprints);
/**
* @brief Loads the public keyring into the RNP system.
*
* This method loads the public keyring file (pubring.pgp) into the system, adding keys
* to the keyring based on their fingerprints.
* @brief Loads the public keyring into RNP.
*
* @param result_fingerprints A set that will hold the fingerprints of the loaded public keys.
*/
void load_pub_keyring(QSet<QString> *result_fingerprints);
void loadPubKeyring(QSet<QString> *result_fingerprints);
/**
* @brief Loads both the public and secret keyrings into the RNP system.
*
* This method loads both the public and secret keyring files into the system, adding keys
* to the keyring based on their fingerprints. It is a combined operation for full keyring loading.
* @brief Loads both the public and secret keyrings into RNP.
*
* @param result_fingerprints A set that will hold the fingerprints of all loaded keys.
*/
void load_full_keyring(QSet<QString> *result_fingerprints);
void loadFullKeyring(QSet<QString> *result_fingerprints);
/**
* @brief Saves the secret keyring to the RNP homedir.
*
*/
void saveSecKeyring();
/**
* @brief Saves the public keyring to the RNP homedir.
*
*/
void savePubKeyring();
/**
* @brief Saves both the public and secret keyrings to the RNP homedir.
*
*/
void saveFullKeyring();
public:
/**
@ -155,7 +176,8 @@ public:
~RnpJob();
void setPassProvider(rnp_password_cb pass_provider_cb) {
void setPassProvider(rnp_password_cb pass_provider_cb)
{
rnp_ffi_set_pass_provider(this->m_ffi, pass_provider_cb, NULL);
}
};

View File

@ -3,8 +3,10 @@
#include <QtCore/QDir>
#include "jobs/decryptjob.h"
#include "jobs/deletekeyjob.h"
#include "jobs/getkeysjob.h"
#include "jobs/importkeyjob.h"
#include "jobs/rmjob.h"
#include "pass.h"
#include "passphraseprovider.h"
@ -91,57 +93,62 @@ void Pass::slotShowSucceed(QString encrypted_file_path, QString plain_text)
this->m_sem->release(1);
}
// bool Pass::deletePasswordStore()
// {
// if (!this->m_sem->tryAcquire(1, 500)) {
// return false;
// }
// qInfo() << "Pass delete Password Store";
// auto job = new RmJob(this->password_store());
// qDebug() << "Delete Password Store at " << this->password_store();
// connect(job, &RmJob::resultReady, this, &Pass::deletePasswordStoreResult);
// connect(job, &RmJob::finished, job, &QObject::deleteLater);
// job->start();
// return true;
// }
bool Pass::deletePasswordStore()
{
qInfo() << "[Pass] Delete Password Store at" << this->password_store();
if (!this->m_sem->tryAcquire(1, 500)) {
qInfo() << "[Pass] A command is already running";
return false;
}
auto job = new RmJob(this->password_store());
connect(job, &RmJob::resultReady, this, &Pass::slotDeletePasswordStoreResult);
connect(job, &RmJob::finished, job, &QObject::deleteLater);
job->start();
return true;
}
// void Pass::deletePasswordStoreResult(bool err)
// {
// qDebug() << "Pass delete Password StoreResult";
// if (err) { //dir.removeRecursively()) {
// qInfo() << "Pass delete Password Store Failed";
// emit deletePasswordStoreFailed("failed to delete password store");
// } else {
// qInfo() << "Pass delete Password Store Succeed";
// emit deletePasswordStoreSucceed();
// }
// this->m_sem->release(1);
// }
void Pass::slotDeletePasswordStoreResult(bool err)
{
if (err) {
qInfo() << "[Pass] delete Password Store Failed";
emit deletePasswordStoreFailed("failed to delete password store");
} else {
qInfo() << "[Pass] Delete Password Store Succeed";
emit deletePasswordStoreSucceed();
}
this->m_sem->release(1);
}
// bool Pass::deleteGPGKey(PassKeyModel* key)
// {
// if (!this->m_sem->tryAcquire(1, 500)) {
// return false;
// }
// qInfo() << "Delete Key " << key->uid();
// return this->m_gpg->deleteKey(key->key());
// }
bool Pass::deleteGPGKey(PassKeyModel* key)
{
qInfo() << "[Pass] Delete GPG key fingerprint " << key->property("keyid").toString();
if (!this->m_sem->tryAcquire(1, 500)) {
qInfo() << "[Pass] A command is already running";
return false;
}
auto job = new DeleteKeyJob(this->m_gpg_home, key->property("fingerprint").toString());
QObject::connect(job, &DeleteKeyJob::resultError, this, &Pass::slotDeleteGPGKeyError);
QObject::connect(job, &DeleteKeyJob::resultSuccess, this, &Pass::slotDeleteGPGKeySucceed);
connect(job, &DeleteKeyJob::finished, job, &QObject::deleteLater);
job->start();
return true;
}
void Pass::slotDeleteGPGKeyError(rnp_result_t err)
{
qInfo() << "[Pass] Delete GPG key Failed";
emit deleteGPGKeyFailed(rnp_result_to_string(err));
this->m_sem->release(1);
}
void Pass::slotDeleteGPGKeySucceed()
{
qInfo() << "[Pass] Delete GPG key Succesfull";
emit deleteGPGKeySucceed();
this->m_sem->release(1);
}
// void Pass::deleteGPGKeyResult(Error err)
// {
// qDebug() << "Delete Ke yResult";
// if (err) {
// qInfo() << "Delete Key Failed";
// emit deleteGPGKeyFailed(err.asString());
// } else {
// qInfo() << "Delete Key Succeed";
// emit deleteGPGKeySucceed();
// }
// this->m_sem->release(1);
// }
bool Pass::importGPGKey(QUrl url)
{
@ -206,6 +213,6 @@ void Pass::slotGetAllGPGKeysSucceed(QList<QJsonDocument> result)
void Pass::responsePassphraseDialog(bool cancel, QString passphrase)
{
qDebug() << "Propagate responsePassphraseDialog";
qDebug() << "[Pass] Propagate responsePassphraseDialog to UTPassphraseProvider";
emit responsePassphraseDialogPropagate(cancel, passphrase);
}

View File

@ -35,11 +35,9 @@ private slots:
void slotShowSucceed(QString encrypted_file_path, QString plain_text);
/**
* @brief Slot to handle the result of a GPG key deletion operation.
* @param err The error that occurred during the operation.
*/
// void deleteGPGKeyResult(Error err);
void slotDeleteGPGKeyError(rnp_result_t err);
void slotDeleteGPGKeySucceed();
/**
* @brief Slot to handle the error result of a GPG key import operation.
@ -67,7 +65,7 @@ private slots:
* @brief Slot to handle the result of a delete Password Store operation.
* @param err True if an error occurred during the operation.
*/
void deletePasswordStoreResult(bool err);
void slotDeletePasswordStoreResult(bool err);
signals:
// GPG-related signals
@ -146,7 +144,8 @@ signals:
private:
QString m_password_store; /**< The path to the password store. */
QString m_gpg_home; /**< The path to the gpg home. */
std::unique_ptr<PassKeyringModel> m_keyring_model; /**< Meta data on the keyring uid, name, secrecy ... of the availble keys. */
std::unique_ptr<PassKeyringModel>
m_keyring_model; /**< Meta data on the keyring uid, name, secrecy ... of the availble keys. */
rnp_password_cb m_passphrase_provider; /**< Pointer on passphrase povider for operations using secret keys. */
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */

View File

@ -39,10 +39,10 @@ public:
PassKeyModel(QJsonDocument key_info)
{
this->m_fingerprint = key_info["fingerprint"].toString();
qDebug() << "fingerprint : " << this->m_fingerprint;
qDebug() << "[PassKeyModel] fingerprint : " << this->m_fingerprint;
this->m_keyid = key_info["keyid"].toString();
qDebug() << "keyid : " << this->m_keyid;
qDebug() << "[PassKeyModel] keyid : " << this->m_keyid;
auto user_ids_json_array = key_info["userids"].toArray();
auto userids = QList<QString>();
@ -50,10 +50,10 @@ public:
userids.append((*i).toString());
}
this->m_userids = QVariant(userids);
qDebug() << "userids : " << this->m_userids;
qDebug() << "[PassKeyModel] userids : " << this->m_userids;
this->m_hasSecret = key_info["secret key"]["present"].toBool();
qDebug() << "hasSecret : " << this->m_hasSecret;
qDebug() << "[PassKeyModel] hasSecret : " << this->m_hasSecret;
}
};
@ -92,13 +92,13 @@ public:
PassKeyringModel(QList<QJsonDocument> key_infos)
{
for (auto i = key_infos.begin(), end = key_infos.end(); i != end; ++i) {
qDebug() << *i;
qDebug() << "[PassKeyringModel]" << *i;
// Ignore subkeys and only add primary keys to the model.
if ((*i)["primary key grip"].isUndefined()) {
this->m_keys.append(new PassKeyModel(*i));
} else {
qDebug() << "Subkey info " << (*i)["keyid"].toString() << "ignored";
qDebug() << "[PassKeyringModel] Subkey info " << (*i)["keyid"].toString() << "ignored";
}
}
}

View File

@ -66,8 +66,8 @@ private:
*/
explicit UTPassphraseProvider(QObject * parent = nullptr)
: m_sem(std::make_unique<QSemaphore>(1)),
m_passphrase(QString::Null()),
m_canceled(true)
m_passphrase(QString::Null()),
m_canceled(true)
{}
QObject *m_window; /**< The window object that triggers the QML dialog. */
@ -85,7 +85,7 @@ public:
*
* @return The singleton instance of UTPassphraseProvider.
*/
static UTPassphraseProvider& instance()
static UTPassphraseProvider &instance()
{
static UTPassphraseProvider instance;
return instance;
@ -125,11 +125,11 @@ public:
*/
static bool
get_pass_provider( rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char buf[],
size_t buf_len)
void *app_ctx,
rnp_key_handle_t key,
const char *pgp_context,
char buf[],
size_t buf_len)
{
qDebug() << "[UTPassphraseProvider] Call the getPassphrase";
@ -138,8 +138,7 @@ public:
return false;
}
if (!UTPassphraseProvider::instance().m_sem->tryAcquire(1, 500))
{
if (!UTPassphraseProvider::instance().m_sem->tryAcquire(1, 500)) {
qWarning() << "[UTPassphraseProvider] Aborting : Cannot acquire UTPassphraseProvider semaphore";
return false;
}
@ -153,7 +152,7 @@ public:
Q_ARG(QVariant, "useridHint"), // TODO
Q_ARG(QVariant, "description"), // TODO
Q_ARG(QVariant, "previousWasBad") // TODO
);
);
qDebug() << "[UTPassphraseProvider] Waiting for response";
@ -163,7 +162,7 @@ public:
qDebug() << "[UTPassphraseProvider] Prepare Returns";
auto ret = false;
if(!UTPassphraseProvider::instance().m_canceled) {
if (!UTPassphraseProvider::instance().m_canceled) {
strncpy(buf, UTPassphraseProvider::instance().m_passphrase.toLocal8Bit().data(), buf_len);
ret = true;
};
@ -182,7 +181,8 @@ public:
*
* @param window The window object to set.
*/
void setWindow(QObject* window){
void setWindow(QObject* window)
{
this->m_window = window;
}
};

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: utpass.qrouland\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-03 19:54+0100\n"
"POT-Creation-Date: 2025-02-03 21:35+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -123,7 +123,7 @@ msgstr ""
#: ../qml/pages/settings/DeleteRepo.qml:56
#: ../qml/pages/settings/ImportZip.qml:64
#: ../qml/pages/settings/InfoKeys.qml:167
#: ../qml/pages/settings/InfoKeys.qml:170
#: ../qml/pages/settings/git/ImportGitClone.qml:56
msgid "Yes"
msgstr ""
@ -137,7 +137,7 @@ msgid "Password Store deleted !"
msgstr ""
#: ../qml/pages/settings/DeleteRepo.qml:90
#: ../qml/pages/settings/InfoKeys.qml:209
#: ../qml/pages/settings/InfoKeys.qml:212
msgid "Info Keys"
msgstr ""
@ -179,27 +179,27 @@ msgstr ""
msgid "Key ID :"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:117
#: ../qml/pages/settings/InfoKeys.qml:120
msgid "Users IDs : "
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:144
#: ../qml/pages/settings/InfoKeys.qml:147
msgid "Delete this key"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:166
#: ../qml/pages/settings/InfoKeys.qml:169
msgid "You're are about to delete<br>%1.<br>Continue ?"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:180
#: ../qml/pages/settings/InfoKeys.qml:183
msgid "Key removal failed !"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:189
#: ../qml/pages/settings/InfoKeys.qml:192
msgid "Key successfully deleted !"
msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:201
#: ../qml/pages/settings/InfoKeys.qml:204
msgid "An Error occured getting GPG keys !"
msgstr ""

View File

@ -88,7 +88,13 @@ Page {
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: model.modelData.keyid
text: {
if (!model.modelData) {
"";
} else {
model.modelData.keyid;
}
}
color: theme.palette.normal.backgroundText
}
@ -102,10 +108,12 @@ Page {
id: userIdsModel
Component.onCompleted: {
for (var i = 0; i < model.modelData.userids.length; ++i) {
userIdsModel.append({
"model": model.modelData.userids[i]
});
if (model.modelData) {
for (var i = 0; i < model.modelData.userids.length; ++i) {
userIdsModel.append({
"model": model.modelData.userids[i]
});
}
}
}
}
@ -125,7 +133,7 @@ Page {
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: modelData.uid
text: modelData
color: theme.palette.normal.backgroundText
}
@ -163,7 +171,7 @@ Page {
id: infoKeysPageDeleteValidation
SimpleValidationDialog {
text: i18n.tr("You're are about to delete<br>%1.<br>Continue ?").arg(infoKeysPage.__currentKey.uid)
text: i18n.tr("You're are about to delete<br>%1.<br>Continue ?").arg(infoKeysPage.__currentKey.keyid)
continueText: i18n.tr("Yes")
continueColor: theme.palette.normal.negative
onValidated: {

View File

@ -17,7 +17,7 @@ private:
public:
~TesTPassphraseProvider() = default;
static TesTPassphraseProvider& instance()
static TesTPassphraseProvider &instance()
{
static TesTPassphraseProvider instance;
return instance;
@ -26,15 +26,16 @@ public:
void operator=(TesTPassphraseProvider const &) = delete;
static bool
example_pass_provider(rnp_ffi_t ffi,
void * app_ctx,
rnp_key_handle_t key,
const char * pgp_context,
char buf[],
size_t buf_len)
{ strncpy(buf, "utpasspassphrase", buf_len);
static bool
example_pass_provider(rnp_ffi_t ffi,
void *app_ctx,
rnp_key_handle_t key,
const char *pgp_context,
char buf[],
size_t buf_len)
{
strncpy(buf, "utpasspassphrase", buf_len);
return true;
}
}
};
#endif

View File

@ -21,9 +21,8 @@ PassTestCase {
}
function test_pass_show(data) {
if (data.add_home_gpg_data === true) {
if (data.add_home_gpg_data === true)
TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home));
}
var fname, ctext;
Pass.showSucceed.connect(function(file_name, clear_text) {
@ -34,14 +33,12 @@ PassTestCase {
Pass.showFailed.connect(function(err) {
err_msg = err;
});
Pass.show(Qt.resolvedUrl(data.file));
data.spy.wait();
if (data.err_msg) {
if (data.err_msg)
verify(err_msg === data.err_msg, "Should return %1 but return %2".arg(data.err_msg).arg(err_msg));
} else {
else
verify(false);
}
}
SignalSpy {