mirror of
https://github.com/QRouland/UTPass.git
synced 2025-02-11 15:07:16 +00:00
Rewrite import key with rnp
This commit is contained in:
parent
c01fae0c58
commit
2c9d82e0b1
@ -39,9 +39,13 @@ if(NOT TESTS_PATH)
|
|||||||
set(TESTS_PATH "./tests")
|
set(TESTS_PATH "./tests")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file(main.in.cpp main.cpp)
|
if(TESTS_RUNNER)
|
||||||
|
configure_file(tests.in.cpp tests.cpp)
|
||||||
|
add_executable(${PROJECT_NAME} tests.cpp)
|
||||||
|
else()
|
||||||
add_executable(${PROJECT_NAME} main.cpp)
|
add_executable(${PROJECT_NAME} main.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick QuickTest)
|
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick QuickTest)
|
||||||
|
|
||||||
if(TESTS_RUNNER)
|
if(TESTS_RUNNER)
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
#include <QtQml>
|
#include <QtQml>
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST_RUNNER
|
|
||||||
#include <QtQuickTest/quicktest.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
qDebug() << "Starting app from main.cpp";
|
qDebug() << "Starting app from main.cpp";
|
||||||
@ -17,7 +13,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QGuiApplication::setApplicationName("utpass.qrouland");
|
QGuiApplication::setApplicationName("utpass.qrouland");
|
||||||
|
|
||||||
#ifndef TEST_RUNNER
|
|
||||||
auto *view = new QQuickView();
|
auto *view = new QQuickView();
|
||||||
view->setSource(QUrl(QStringLiteral("qml/Main.qml")));
|
view->setSource(QUrl(QStringLiteral("qml/Main.qml")));
|
||||||
view->setResizeMode(QQuickView::SizeRootObjectToView);
|
view->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||||
@ -28,7 +23,4 @@ int main(int argc, char *argv[])
|
|||||||
Q_ARG(QVariant, QVariant::fromValue(mainView))
|
Q_ARG(QVariant, QVariant::fromValue(mainView))
|
||||||
);
|
);
|
||||||
return QGuiApplication::exec();
|
return QGuiApplication::exec();
|
||||||
#else
|
|
||||||
return quick_test_main(argc, argv, "@TESTS_PATH@", "@TESTS_PATH@");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef GITJOB_H
|
#ifndef GITJOB_H
|
||||||
#define GITJOB_H
|
#define GITJOB_H
|
||||||
|
|
||||||
#include "qthread.h"
|
#include <QThread>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ set(
|
|||||||
SRC
|
SRC
|
||||||
plugin.cpp
|
plugin.cpp
|
||||||
pass.cpp
|
pass.cpp
|
||||||
gpg.cpp
|
|
||||||
passkeymodel.h
|
passkeymodel.h
|
||||||
passphraseprovider.h
|
|
||||||
jobs/rmjob.cpp
|
jobs/rmjob.cpp
|
||||||
|
jobs/rnpjob.cpp
|
||||||
|
jobs/importkeyjob.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
@ -31,11 +31,16 @@ qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
|||||||
|
|
||||||
set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
||||||
|
|
||||||
|
find_package(OpenSSL REQUIRED)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include)
|
INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include)
|
||||||
|
|
||||||
add_library(rnp STATIC IMPORTED)
|
add_library(rnp STATIC IMPORTED)
|
||||||
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
|
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
|
||||||
|
|
||||||
|
add_library(sexpp STATIC IMPORTED)
|
||||||
|
set_property(TARGET sexpp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/libsexpp.a")
|
||||||
|
|
||||||
add_library(gpgerror SHARED IMPORTED)
|
add_library(gpgerror SHARED IMPORTED)
|
||||||
set_property(TARGET gpgerror PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpg-error.so.0.28.0")
|
set_property(TARGET gpgerror PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpg-error.so.0.28.0")
|
||||||
|
|
||||||
@ -52,8 +57,7 @@ add_library(libqgpgme SHARED IMPORTED)
|
|||||||
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so")
|
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so")
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(${PLUGIN} rnp gpgerror libassuan libgpgme libgpgmepp libqgpgme)
|
target_link_libraries(${PLUGIN} rnp sexpp gpgerror libassuan libgpgme libgpgmepp libqgpgme OpenSSL::Crypto)
|
||||||
|
|
||||||
|
|
||||||
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
||||||
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
||||||
|
@ -1,301 +0,0 @@
|
|||||||
#include <memory>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QtCore/QStandardPaths>
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
|
||||||
#include <gpgme++/data.h>
|
|
||||||
#include <gpgme++/global.h>
|
|
||||||
#include <gpgme++/context.h>
|
|
||||||
#include <gpgme++/engineinfo.h>
|
|
||||||
#include <gpgme++/keylistresult.h>
|
|
||||||
#include <gpgme++/importresult.h>
|
|
||||||
#include <gpgme++/encryptionresult.h>
|
|
||||||
#include <gpgme++/decryptionresult.h>
|
|
||||||
|
|
||||||
#include <qgpgme/importjob.h>
|
|
||||||
#include <qgpgme/deletejob.h>
|
|
||||||
#include <qgpgme/decryptjob.h>
|
|
||||||
#include <qgpgme/encryptjob.h>
|
|
||||||
#include <qgpgme/protocol.h>
|
|
||||||
#include <qgpgme/keylistjob.h>
|
|
||||||
#include <qgpgme/changeownertrustjob.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "gpg.h"
|
|
||||||
#include "passphraseprovider.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace GpgME;
|
|
||||||
using namespace QGpgME;
|
|
||||||
|
|
||||||
Gpg::Gpg(QObject* windows)
|
|
||||||
{
|
|
||||||
this->m_passphrase_provider = new UTPassphraseProvider(windows);
|
|
||||||
|
|
||||||
Gpg::initGpgConfig();
|
|
||||||
|
|
||||||
auto error = checkEngine(OpenPGP);
|
|
||||||
if (error) {
|
|
||||||
qDebug() << "Code Error : " << error.code();
|
|
||||||
qDebug() << "Error str : " << error.asString();
|
|
||||||
qFatal("GNUPG Engine check Fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "GNUPG Engine Version is :" << engineInfo(OpenPGP).version();
|
|
||||||
qDebug() << "GNUPG Executable is :" << engineInfo(OpenPGP).fileName();
|
|
||||||
qDebug() << "GNUPG Home is :" << engineInfo(OpenPGP).homeDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
Gpg::~Gpg()
|
|
||||||
{
|
|
||||||
delete this->m_passphrase_provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString Gpg::initGpgHome()
|
|
||||||
{
|
|
||||||
QString path = QStandardPaths::writableLocation(
|
|
||||||
QStandardPaths::AppDataLocation).append("/.gpghome");
|
|
||||||
QDir dir(path);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
dir.mkpath(".");
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString Gpg::findCommandPath(const QString &command)
|
|
||||||
{
|
|
||||||
// Retrieve the PATH environment variable
|
|
||||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
||||||
QString pathEnv = env.value("PATH");
|
|
||||||
|
|
||||||
// Split the PATH by colon
|
|
||||||
QStringList pathDirs = pathEnv.split(":", QString::SkipEmptyParts);
|
|
||||||
|
|
||||||
// Check each directory in the PATH
|
|
||||||
foreach (const QString &dir, pathDirs) {
|
|
||||||
QFileInfo fileInfo(QDir(dir).filePath(command));
|
|
||||||
|
|
||||||
// If the file exists and is executable, return the path
|
|
||||||
if (fileInfo.exists() && fileInfo.isExecutable()) {
|
|
||||||
return fileInfo.absoluteFilePath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString::null;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Gpg::initGpgExec()
|
|
||||||
{
|
|
||||||
QString path = findCommandPath("gpg");
|
|
||||||
if (path.isNull()) {
|
|
||||||
qFatal("No valid gpg exec found !");
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Gpg::initGpgConfig()
|
|
||||||
{
|
|
||||||
initializeLibrary();
|
|
||||||
gpgme_set_global_flag("disable-gpgconf", "1");
|
|
||||||
|
|
||||||
QString home = initGpgHome();
|
|
||||||
qDebug() << "Gpg home is " << home;
|
|
||||||
QString exec = initGpgExec();
|
|
||||||
qDebug() << "Gpg exec is " << exec;
|
|
||||||
|
|
||||||
QFile agentConf(home + QStringLiteral("/gpg-agent.conf"));
|
|
||||||
agentConf.remove();
|
|
||||||
agentConf.open(QIODevice::WriteOnly);
|
|
||||||
agentConf.write("allow-loopback-pinentry\n");
|
|
||||||
agentConf.close();
|
|
||||||
|
|
||||||
auto err = gpgme_set_engine_info (
|
|
||||||
GPGME_PROTOCOL_OpenPGP,
|
|
||||||
exec.toLocal8Bit().data(),
|
|
||||||
home.toLocal8Bit().data()
|
|
||||||
);
|
|
||||||
if (err != GPG_ERR_NO_ERROR) {
|
|
||||||
qDebug() << "Error code : " << err;
|
|
||||||
qDebug() << "Error str : " << gpg_strerror(err);
|
|
||||||
qFatal("GPGME set engine info failed !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Error Gpg::decrypt(QByteArray cipher_text)
|
|
||||||
{
|
|
||||||
auto job = openpgp()->decryptJob();
|
|
||||||
|
|
||||||
auto ctx = DecryptJob::context(job);
|
|
||||||
|
|
||||||
ctx->setPassphraseProvider(this->m_passphrase_provider);
|
|
||||||
ctx->setPinentryMode(Context::PinentryLoopback);
|
|
||||||
|
|
||||||
QObject::connect(job, &DecryptJob::result,
|
|
||||||
this, &Gpg::decryptResultSlot);
|
|
||||||
|
|
||||||
return job->start(cipher_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Gpg::decryptFromFile(QString path)
|
|
||||||
{
|
|
||||||
qDebug() << "Decrypt from " << path;
|
|
||||||
QFile file(path);
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning() << "Can't open the File";
|
|
||||||
return Error();
|
|
||||||
}
|
|
||||||
QByteArray cipherText = file.readAll();
|
|
||||||
file.close();
|
|
||||||
return decrypt(cipherText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Gpg::decryptResultSlot(const GpgME::DecryptionResult &result, const QByteArray &plainText,
|
|
||||||
const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
|
|
||||||
{
|
|
||||||
if (result.error()) {
|
|
||||||
qWarning() << "Something gone wrong on decrypt";
|
|
||||||
qDebug() << "Code Error : " << result.error().code();
|
|
||||||
qDebug() << "Error str : " << result.error().asString();
|
|
||||||
}
|
|
||||||
qDebug() << "Cancelled : " << result.error().isCanceled();
|
|
||||||
emit decryptResult(result.error(), QString::fromUtf8(plainText));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// QPair<Error, QByteArray> 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<Error, QByteArray>(keys.first, QByteArray());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// auto job = std::unique_ptr<EncryptJob>(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<Error, QByteArray>(result.error(), cipherText);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
|
|
||||||
bool validate)
|
|
||||||
{
|
|
||||||
qDebug() << "Getting the keys " << pattern_uid;
|
|
||||||
auto job = openpgp()->keyListJob(remote, include_sigs, validate);
|
|
||||||
|
|
||||||
QObject::connect(job, &KeyListJob::result,
|
|
||||||
this, &Gpg::getKeysJobResultSlot);
|
|
||||||
|
|
||||||
return job->start(QStringList() << pattern_uid, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpg::getKeysJobResultSlot(const GpgME::KeyListResult &result, const std::vector<GpgME::Key> &keys,
|
|
||||||
const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
|
|
||||||
{
|
|
||||||
if (result.error()) {
|
|
||||||
qWarning() << "Something gone wrong on getKeys";
|
|
||||||
qDebug() << "Code Error : " << result.error().code();
|
|
||||||
qDebug() << "Error str : " << result.error().asString();
|
|
||||||
}
|
|
||||||
emit getKeysResult(result.error(), keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Gpg::importKeysFromFile(QString path)
|
|
||||||
{
|
|
||||||
qDebug() << "Importing the key file" << path;
|
|
||||||
qDebug() << "Decrypt from " << path;
|
|
||||||
QFile file(path);
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning() << "Can't open the File";
|
|
||||||
return Error();
|
|
||||||
}
|
|
||||||
auto data = file.readAll();
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
auto job = openpgp()->importJob();
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
if (result.error()) {
|
|
||||||
qWarning() << "Something gone wrong on decrypt";
|
|
||||||
qDebug() << "Code Error : " << result.error().code();
|
|
||||||
qDebug() << "Error str : " << result.error().asString();
|
|
||||||
}
|
|
||||||
emit importKeysFromFileResult(result.error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Error Gpg::deleteKey(const Key key)
|
|
||||||
{
|
|
||||||
auto job = openpgp()->deleteJob();
|
|
||||||
|
|
||||||
QObject::connect(job, &DeleteJob::result,
|
|
||||||
this, &Gpg::deleteKeySlot);
|
|
||||||
|
|
||||||
return job->start(key, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gpg::deleteKeySlot(const GpgME::Error &error, const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
|
|
||||||
{
|
|
||||||
if (error) {
|
|
||||||
qWarning() << "Something gone wrong on deleteKey";
|
|
||||||
qDebug() << "Code Error : " << error.code();
|
|
||||||
qDebug() << "Error str : " << error.asString();
|
|
||||||
}
|
|
||||||
emit deleteKeyResult(error);
|
|
||||||
}
|
|
||||||
|
|
@ -1,227 +0,0 @@
|
|||||||
#ifndef GPG_H
|
|
||||||
#define GPG_H
|
|
||||||
|
|
||||||
#include "passkeymodel.h"
|
|
||||||
#include "passphraseprovider.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <QQuickWindow>
|
|
||||||
#include <gpgme++/context.h>
|
|
||||||
#include <qgpgme/changeownertrustjob.h>
|
|
||||||
#include <QSemaphore>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
|
||||||
#include <qgpgme/importjob.h>
|
|
||||||
#include <qgpgme/deletejob.h>
|
|
||||||
#include <qgpgme/decryptjob.h>
|
|
||||||
#include <qgpgme/encryptjob.h>
|
|
||||||
#include <qgpgme/protocol.h>
|
|
||||||
#include <qgpgme/keylistjob.h>
|
|
||||||
#include <qgpgme/changeownertrustjob.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace GpgME;
|
|
||||||
using namespace QGpgME;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class Gpg
|
|
||||||
* @brief A class for managing GPG key operations such as key import, decryption, and deletion.
|
|
||||||
*
|
|
||||||
* This class integrates with the GPGME (GnuPG Made Easy) library to provide functionalities
|
|
||||||
* for interacting with GPG keys, including decrypting messages, importing keys from files,
|
|
||||||
* listing keys, and deleting keys.
|
|
||||||
*/
|
|
||||||
class Gpg: public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(UTPassphraseProvider* passphrase_provider READ passphrase_provider MEMBER m_passphrase_provider )
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
/**
|
|
||||||
* @brief Slot to handle the result of a decryption operation.
|
|
||||||
* @param result The result of the decryption operation.
|
|
||||||
* @param plain_text The decrypted text.
|
|
||||||
* @param auditLogAsHtml The HTML formatted audit log for the operation.
|
|
||||||
* @param auditLogError The error associated with the audit log, if any.
|
|
||||||
*/
|
|
||||||
void decryptResultSlot(
|
|
||||||
const DecryptionResult &result,
|
|
||||||
const QByteArray &plain_text,
|
|
||||||
const QString &auditLogAsHtml,
|
|
||||||
const Error &auditLogError
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Slot to handle the result of a key retrieval operation.
|
|
||||||
* @param result The result of the key retrieval operation.
|
|
||||||
* @param keys A vector of keys retrieved.
|
|
||||||
* @param auditLogAsHtml The HTML formatted audit log for the operation, if any.
|
|
||||||
* @param auditLogError The error associated with the audit log, if any.
|
|
||||||
*/
|
|
||||||
void getKeysJobResultSlot(
|
|
||||||
const GpgME::KeyListResult &result,
|
|
||||||
const std::vector<GpgME::Key> &keys,
|
|
||||||
const QString &auditLogAsHtml,
|
|
||||||
const GpgME::Error &auditLogError
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Slot to handle the result of a key import operation.
|
|
||||||
* @param result The result of the import operation.
|
|
||||||
* @param auditLogAsHtml The HTML formatted audit log for the operation, if any.
|
|
||||||
* @param auditLogError The error associated with the audit log, if any.
|
|
||||||
*/
|
|
||||||
void importKeysFromFileSlot(
|
|
||||||
const GpgME::ImportResult &result,
|
|
||||||
const QString &auditLogAsHtml,
|
|
||||||
const GpgME::Error &auditLogError
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Slot to handle the result of a key deletion operation.
|
|
||||||
* @param result The error result of the deletion operation.
|
|
||||||
* @param auditLogAsHtml The HTML formatted audit log for the operation, if any.
|
|
||||||
* @param auditLogError The error associated with the audit log, if any.
|
|
||||||
*/
|
|
||||||
void deleteKeySlot(
|
|
||||||
const GpgME::Error &result,
|
|
||||||
const QString &auditLogAsHtml,
|
|
||||||
const GpgME::Error &auditLogError
|
|
||||||
);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when keys are imported from a file.
|
|
||||||
* @param err The error that occurred during the import operation, if any.
|
|
||||||
*/
|
|
||||||
void importKeysFromFileResult(Error err);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when keys are retrieved.
|
|
||||||
* @param err The error that occurred during the retrieval operation, if any.
|
|
||||||
* @param keys A vector of keys retrieved.
|
|
||||||
*/
|
|
||||||
void getKeysResult(Error err, std::vector<GpgME::Key> keys);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when a key is deleted.
|
|
||||||
* @param err The error that occurred during the deletion operation, if any.
|
|
||||||
*/
|
|
||||||
void deleteKeyResult(Error err);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when a decryption operation completes.
|
|
||||||
* @param err The error that occurred during decryption, if any.
|
|
||||||
* @param plain_text The decrypted message.
|
|
||||||
*/
|
|
||||||
void decryptResult(Error err, QString plain_text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
UTPassphraseProvider *m_passphrase_provider; /**< The passphrase provider used for authentication. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Finds the path of a command in the system's environment.
|
|
||||||
* @param command The name of the command to find.
|
|
||||||
* @return The full path to the command.
|
|
||||||
*/
|
|
||||||
QString findCommandPath(const QString &command);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes the GPG home directory.
|
|
||||||
* @return The path to the GPG home directory.
|
|
||||||
*/
|
|
||||||
QString initGpgHome();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes the GPG executable path.
|
|
||||||
* @return The path to the GPG executable.
|
|
||||||
*/
|
|
||||||
QString initGpgExec();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes the GPG configuration.
|
|
||||||
*/
|
|
||||||
void initGpgConfig();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves a GPG key by UID.
|
|
||||||
* @param uid The UID of the key to retrieve.
|
|
||||||
* @param remote Whether to fetch the key from a remote keyserver (default: false).
|
|
||||||
* @param include_sigs Whether to include signatures (default: false).
|
|
||||||
* @param validate Whether to validate the key (default: false).
|
|
||||||
* @return The error result of the operation.
|
|
||||||
*/
|
|
||||||
Error getKey(QString uid, bool remote = false, bool include_sigs = false, bool validate = false);
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Constructs a Gpg object and initializes necessary resources.
|
|
||||||
* @param window The window object for interacting with the user interface.
|
|
||||||
*/
|
|
||||||
Gpg(QObject* window);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Destroys the Gpg object and cleans up resources.
|
|
||||||
*/
|
|
||||||
~Gpg();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the passphrase provider used for GPG authentication.
|
|
||||||
* @return The passphrase provider.
|
|
||||||
*/
|
|
||||||
UTPassphraseProvider *passphrase_provider() const
|
|
||||||
{
|
|
||||||
return m_passphrase_provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Imports GPG keys from a file.
|
|
||||||
* @param path The path to the file containing the keys.
|
|
||||||
* @return The error result of the import operation.
|
|
||||||
*/
|
|
||||||
Error importKeysFromFile(const QString path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves keys matching the provided UID pattern.
|
|
||||||
* @param pattern_uid The UID pattern to search for.
|
|
||||||
* @param remote Whether to fetch the key from a remote keyserver (default: false).
|
|
||||||
* @param include_sigs Whether to include signatures (default: false).
|
|
||||||
* @param validate Whether to validate the key (default: false).
|
|
||||||
* @return The error result of the operation.
|
|
||||||
*/
|
|
||||||
Error getKeys(const QString pattern_uid, bool remote = false, bool include_sigs = false, bool validate = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Retrieves all keys from the GPG keyring.
|
|
||||||
* @param remote Whether to fetch the keys from a remote keyserver (default: false).
|
|
||||||
* @param include_sigs Whether to include signatures (default: false).
|
|
||||||
* @param validate Whether to validate the keys (default: false).
|
|
||||||
* @return The error result of the operation.
|
|
||||||
*/
|
|
||||||
Error getAllKeys(bool remote = false, bool include_sigs = false, bool validate = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deletes a specified GPG key.
|
|
||||||
* @param key The key to delete.
|
|
||||||
* @return The error result of the deletion operation.
|
|
||||||
*/
|
|
||||||
Error deleteKey(const Key key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Decrypts a given ciphertext.
|
|
||||||
* @param cipher_text The ciphertext to decrypt.
|
|
||||||
* @return The error result of the decryption operation.
|
|
||||||
*/
|
|
||||||
Error decrypt(const QByteArray cipher_text);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Decrypts the contents of a file.
|
|
||||||
* @param path The path to the file to decrypt.
|
|
||||||
* @return The error result of the decryption operation.
|
|
||||||
*/
|
|
||||||
Error decryptFromFile(const QString path);
|
|
||||||
|
|
||||||
// Error encrypt (QString str, QString uid, bool ascii_armor = true, bool text_mode = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
14
plugins/Pass/jobs/decryptjob.cpp
Normal file
14
plugins/Pass/jobs/decryptjob.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "decryptjob.h"
|
||||||
|
|
||||||
|
DecryptJob::DecryptJob(QString path, QString keyfile):
|
||||||
|
m_path(path)
|
||||||
|
{
|
||||||
|
this->setObjectName("DecryptJob");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DecryptJob::run()
|
||||||
|
{
|
||||||
|
rnp_input_from_path(&keyfile, "secring.pgp"));
|
||||||
|
qFatal("To be implemented !")
|
||||||
|
}
|
47
plugins/Pass/jobs/decryptjob.h
Normal file
47
plugins/Pass/jobs/decryptjob.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef DECRYPTJOB_H
|
||||||
|
#define DECRYPTJOB_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class DecryptJob
|
||||||
|
* @brief A class to handle decrypt a file in a separate thread.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class DecryptJob : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The main function that performs the decrypt operation.
|
||||||
|
*
|
||||||
|
* Handles the process of removing recursively a target path.
|
||||||
|
*/
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* @brief Signal emitted when the decrypt operation is complete.
|
||||||
|
*
|
||||||
|
* @param err A boolean indicating whether an error occurred during removing.
|
||||||
|
* `true` if an error occurred, `false` if the clone was successful.
|
||||||
|
*/
|
||||||
|
void resultReady(const bool err);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_encryped_file_path; ///< The path of the encrypted file.
|
||||||
|
QString m_keyfile_path; ///< The path of the key file.
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor for the RmJob class.
|
||||||
|
*
|
||||||
|
* Initializes the DecryptJob with the specified file to decrypt.
|
||||||
|
*
|
||||||
|
* @param path Path of the file to decrypt.
|
||||||
|
*/
|
||||||
|
DecryptJob(QString path);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECRYPTJO_H
|
46
plugins/Pass/jobs/importkeyjob.cpp
Normal file
46
plugins/Pass/jobs/importkeyjob.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <QDebug>
|
||||||
|
#include "importkeyjob.h"
|
||||||
|
extern "C" {
|
||||||
|
#include <rnp/rnp.h>
|
||||||
|
#include <rnp/rnp_err.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportKeyJob::ImportKeyJob(QDir rnp_homedir, QString key_file_path):
|
||||||
|
RnpJob(rnp_homedir),
|
||||||
|
m_key_file_path(key_file_path)
|
||||||
|
{
|
||||||
|
this->setObjectName("DecryptJob");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ImportKeyJob::run()
|
||||||
|
{
|
||||||
|
qDebug() << "ImportKeyJob Starting ";
|
||||||
|
rnp_input_t input = NULL;
|
||||||
|
auto ret = rnp_input_from_path(&input, this->m_key_file_path.toLocal8Bit().constData());
|
||||||
|
if(ret == RNP_SUCCESS) {
|
||||||
|
ret = rnp_load_keys(this->m_ffi,
|
||||||
|
"GPG",
|
||||||
|
input,
|
||||||
|
RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS);
|
||||||
|
}
|
||||||
|
rnp_input_destroy(input);
|
||||||
|
terminateWithError(ret);
|
||||||
|
|
||||||
|
rnp_output_t output = NULL;
|
||||||
|
ret = rnp_output_to_file(&output, this->pubringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_RANDOM);
|
||||||
|
if(ret == RNP_SUCCESS) {
|
||||||
|
ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS);
|
||||||
|
}
|
||||||
|
rnp_output_destroy(output);
|
||||||
|
terminateWithError(ret);
|
||||||
|
|
||||||
|
ret = rnp_output_to_file(&output, this->secringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE);
|
||||||
|
if(ret == RNP_SUCCESS) {
|
||||||
|
ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS);
|
||||||
|
}
|
||||||
|
rnp_output_destroy(output);
|
||||||
|
terminateWithError(ret);
|
||||||
|
emit resultSuccess();
|
||||||
|
qDebug() << "ImportKeyJob Finished Successfully ";
|
||||||
|
}
|
38
plugins/Pass/jobs/importkeyjob.h
Normal file
38
plugins/Pass/jobs/importkeyjob.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef IMPORTKEYJOB_H
|
||||||
|
#define IMPORTKEYJOB_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "rnpjob.h"
|
||||||
|
/**
|
||||||
|
* @class ImportKeyJob
|
||||||
|
* @brief A class to handle import a key file in a separate thread.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ImportKeyJob : public RnpJob
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The main function that performs the import operation.
|
||||||
|
*
|
||||||
|
* Handles the process of removing recursively a target path.
|
||||||
|
*/
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_key_file_path; ///< The path of the key file to import.
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor for the RmJob class.
|
||||||
|
*
|
||||||
|
* Initializes the ImportKeyJob with the file to import.
|
||||||
|
*
|
||||||
|
* @param path Path of the key file to import.
|
||||||
|
*/
|
||||||
|
ImportKeyJob(QDir rnp_homedir, QString key_file_path);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMPORTKEYJOB_H
|
42
plugins/Pass/jobs/rnpjob.cpp
Normal file
42
plugins/Pass/jobs/rnpjob.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "rnpjob.h"
|
||||||
|
extern "C" {
|
||||||
|
#include <rnp/rnp.h>
|
||||||
|
#include <rnp/rnp_err.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
RnpJob::RnpJob(QDir rnp_homedir):
|
||||||
|
m_rnp_homedir(rnp_homedir)
|
||||||
|
{
|
||||||
|
auto ret = rnp_ffi_create(&this->m_ffi,
|
||||||
|
RNP_KEYSTORE_GPG,
|
||||||
|
RNP_KEYSTORE_GPG);
|
||||||
|
if(ret != RNP_SUCCESS) {
|
||||||
|
qDebug() << "Err : " << ret;
|
||||||
|
qFatal("Error on rnp ffi init!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RnpJob::~RnpJob(){
|
||||||
|
auto ret = rnp_ffi_destroy(this->m_ffi);
|
||||||
|
if(ret != RNP_SUCCESS) {
|
||||||
|
qDebug() << "Err : " << ret;
|
||||||
|
qFatal("Something go wrong on rnp ffi detroy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RnpJob::passProvider(rnp_ffi_t ffi,
|
||||||
|
void * app_ctx,
|
||||||
|
rnp_key_handle_t key,
|
||||||
|
const char * pgp_context,
|
||||||
|
char buf[],
|
||||||
|
size_t buf_len)
|
||||||
|
{
|
||||||
|
if (strcmp(pgp_context, "protect")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(buf, "password", buf_len);
|
||||||
|
return true;
|
||||||
|
}
|
82
plugins/Pass/jobs/rnpjob.h
Normal file
82
plugins/Pass/jobs/rnpjob.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef RNPJOB_H
|
||||||
|
#define RNPJOB_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDir>
|
||||||
|
extern "C" {
|
||||||
|
#include <rnp/rnp.h>
|
||||||
|
}
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
|
||||||
|
#define terminateWithError(ret) \
|
||||||
|
if(ret != RNP_SUCCESS) { \
|
||||||
|
qDebug() << "Err : " << ret; \
|
||||||
|
qDebug() << "Err Msg : " << rnp_result_to_string(ret); \
|
||||||
|
emit resultError(ret); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class RmpJob
|
||||||
|
* @brief A class that manages Git-related tasks using libgit2.
|
||||||
|
*
|
||||||
|
* The GitJob class is used abstraction class to perform rnp (opengpg) operations,
|
||||||
|
* such as decrypt, encrypt, key managments operations
|
||||||
|
*/
|
||||||
|
class RnpJob : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void resultError(const rnp_result_t err);
|
||||||
|
void resultSuccess();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool passProvider(rnp_ffi_t ffi,
|
||||||
|
void * app_ctx,
|
||||||
|
rnp_key_handle_t key,
|
||||||
|
const char * pgp_context,
|
||||||
|
char buf[],
|
||||||
|
size_t buf_len);
|
||||||
|
QDir m_rnp_homedir; ///< rmp ffi.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
rnp_ffi_t m_ffi; ///< rmp ffi.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the path to public keys keyring.
|
||||||
|
*
|
||||||
|
* @return The path to public keys keyring
|
||||||
|
*/
|
||||||
|
QString pubringPath() {
|
||||||
|
return this->m_rnp_homedir.filePath("pubring.pgp");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the path to secret keys keyring.
|
||||||
|
*
|
||||||
|
* @return The path to secret keys keyring
|
||||||
|
*/
|
||||||
|
QString secringPath() {
|
||||||
|
return this->m_rnp_homedir.filePath("secring.pgp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor for the RnpJob class.
|
||||||
|
*
|
||||||
|
* Initializes the RnpJob instance.
|
||||||
|
*/
|
||||||
|
RnpJob(QDir rnp_homedir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor for the RnpJob class.
|
||||||
|
*
|
||||||
|
* Cleans up any resources used by the RnpJob.
|
||||||
|
*/
|
||||||
|
~RnpJob();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RNPJOB_H
|
@ -2,34 +2,36 @@
|
|||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
#include "jobs/rmjob.h"
|
#include "jobs/importkeyjob.h"
|
||||||
#include "pass.h"
|
#include "pass.h"
|
||||||
#include "gpg.h"
|
|
||||||
#include "passkeymodel.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Pass::Pass():
|
Pass::Pass():
|
||||||
m_password_store (QStandardPaths::writableLocation(
|
m_password_store (QStandardPaths::writableLocation(
|
||||||
QStandardPaths::AppDataLocation).append("/.password-store")),
|
QStandardPaths::AppDataLocation).append("/.password-store")),
|
||||||
|
m_gpg_home (QStandardPaths::writableLocation(
|
||||||
|
QStandardPaths::AppDataLocation).append("/.rnp")),
|
||||||
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
||||||
m_show_filename(QString())
|
m_show_filename(QString())
|
||||||
{}
|
{
|
||||||
|
qRegisterMetaType<rnp_result_t>("rnp_result_t");
|
||||||
|
}
|
||||||
|
|
||||||
void Pass::initialize(QObject *window)
|
void Pass::initialize(QObject *window)
|
||||||
{
|
{
|
||||||
if (!window) {
|
if (!window) {
|
||||||
qFatal("window is invalid. Abording.");
|
qWarning("Window should not be null unless your in testing");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_gpg = std::unique_ptr<Gpg>(new Gpg(window));
|
// this->m_gpg = std::unique_ptr<Gpg>(new Gpg(window));
|
||||||
|
// UTPassphraseProvider *passphrase_provider = dynamic_cast<UTPassphraseProvider*>(this->m_gpg->passphrase_provider());
|
||||||
|
// QObject::connect(this, &Pass::responsePassphraseDialogPropagate, passphrase_provider,
|
||||||
|
// &UTPassphraseProvider::handleResponse);
|
||||||
|
|
||||||
QObject::connect(this, &Pass::responsePassphraseDialogPropagate, this->m_gpg->passphrase_provider(),
|
// QObject::connect(this->m_gpg.get(), &Gpg::getKeysResult, this, &Pass::getAllGPGKeysResult);
|
||||||
&UTPassphraseProvider::handleResponse);
|
// QObject::connect(this->m_gpg.get(), &Gpg::deleteKeyResult, this, &Pass::deleteGPGKeyResult);
|
||||||
QObject::connect(this->m_gpg.get(), &Gpg::importKeysFromFileResult, this, &Pass::importGPGKeyResult);
|
// QObject::connect(this->m_gpg.get(), &Gpg::decryptResult, this, &Pass::showResult);
|
||||||
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);
|
QDir dir(m_password_store);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
@ -38,135 +40,142 @@ void Pass::initialize(QObject *window)
|
|||||||
qInfo() << "Password Store is :" << m_password_store;
|
qInfo() << "Password Store is :" << m_password_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pass::show(QUrl url)
|
// bool Pass::show(QUrl url)
|
||||||
|
// {
|
||||||
|
// if (!this->m_sem->tryAcquire(1, 500)) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// auto path = url.toLocalFile();
|
||||||
|
// qInfo() << "Pass show " << path;
|
||||||
|
// QFileInfo file_info(path);
|
||||||
|
// this->m_show_filename = file_info.completeBaseName();
|
||||||
|
// return this->m_gpg->decryptFromFile(path);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// void Pass::showResult(Error err, QString plain_text)
|
||||||
|
// {
|
||||||
|
// qDebug() << "Pass show Result";
|
||||||
|
// if (err) {
|
||||||
|
// qInfo() << "Pass show Failed";
|
||||||
|
// emit showFailed(err.asString());
|
||||||
|
|
||||||
|
// } else if (err.isCanceled()) {
|
||||||
|
// qInfo() << "Pass show Cancelled";
|
||||||
|
// emit showCancelled();
|
||||||
|
// } else {
|
||||||
|
// qInfo() << "Pass show Succeed";
|
||||||
|
// emit showSucceed(this->m_show_filename, plain_text);
|
||||||
|
// }
|
||||||
|
// this->m_show_filename = QString();
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 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)
|
||||||
{
|
{
|
||||||
|
qInfo() << "Import GPG Key from " << url;
|
||||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
if (!this->m_sem->tryAcquire(1, 500)) {
|
||||||
|
qInfo() << "A job is already running";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto path = url.toLocalFile();
|
auto job = new ImportKeyJob(this->m_gpg_home, url.toLocalFile());
|
||||||
qInfo() << "Pass show " << path;
|
QObject::connect(job, &ImportKeyJob::resultError, this, &Pass::slotImportGPGKeyError);
|
||||||
QFileInfo file_info(path);
|
QObject::connect(job, &ImportKeyJob::resultSuccess, this, &Pass::slotImportGPGKeySucceed);
|
||||||
this->m_show_filename = file_info.completeBaseName();
|
connect(job, &ImportKeyJob::finished, job, &QObject::deleteLater);
|
||||||
return this->m_gpg->decryptFromFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pass::showResult(Error err, QString plain_text)
|
|
||||||
{
|
|
||||||
qDebug() << "Pass show Result";
|
|
||||||
if (err) {
|
|
||||||
qInfo() << "Pass show Failed";
|
|
||||||
emit showFailed(err.asString());
|
|
||||||
|
|
||||||
} else if (err.isCanceled()) {
|
|
||||||
qInfo() << "Pass show Cancelled";
|
|
||||||
emit showCancelled();
|
|
||||||
} else {
|
|
||||||
qInfo() << "Pass show Succeed";
|
|
||||||
emit showSucceed(this->m_show_filename, plain_text);
|
|
||||||
}
|
|
||||||
this->m_show_filename = QString();
|
|
||||||
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();
|
job->start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::deletePasswordStoreResult(bool err)
|
void Pass::slotImportGPGKeyError(rnp_result_t err)
|
||||||
{
|
{
|
||||||
|
qDebug() << "Import GPG Key Failed";
|
||||||
qDebug() << "Pass delete Password StoreResult";
|
emit importGPGKeyFailed(rnp_result_to_string(err));
|
||||||
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);
|
this->m_sem->release(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pass::slotImportGPGKeySucceed()
|
||||||
bool Pass::deleteGPGKey(PassKeyModel* key)
|
|
||||||
{
|
{
|
||||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
qDebug() << "Import GPG Key Failed";
|
||||||
return false;
|
|
||||||
}
|
|
||||||
qInfo() << "Delete Key " << key->uid();
|
|
||||||
return this->m_gpg->deleteKey(key->key());
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
qInfo() << "Import GPG Key from " << url;
|
|
||||||
return this->m_gpg->importKeysFromFile(url.toLocalFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pass::importGPGKeyResult(Error err)
|
|
||||||
{
|
|
||||||
qDebug() << "Import GPG Key Result";
|
|
||||||
if (err) {
|
|
||||||
qInfo() << "Delete Key Failed";
|
|
||||||
emit importGPGKeyFailed(err.asString());
|
|
||||||
} else {
|
|
||||||
qInfo() << "Delete Key Succeed";
|
|
||||||
emit importGPGKeySucceed();
|
emit importGPGKeySucceed();
|
||||||
}
|
|
||||||
this->m_sem->release(1);
|
this->m_sem->release(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pass::getAllGPGKeys()
|
// bool Pass::getAllGPGKeys()
|
||||||
{
|
// {
|
||||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
// if (!this->m_sem->tryAcquire(1, 500)) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
qInfo() << "Get GPG keys";
|
// qInfo() << "Get GPG keys";
|
||||||
return this->m_gpg->getAllKeys();
|
// return this->m_gpg->getAllKeys();
|
||||||
}
|
// }
|
||||||
|
|
||||||
void Pass::getAllGPGKeysResult(Error err, std::vector<GpgME::Key> keys_info)
|
// void Pass::getAllGPGKeysResult(Error err, std::vector<GpgME::Key> keys_info)
|
||||||
{
|
// {
|
||||||
qDebug() << "Get GPG keys Result";
|
// qDebug() << "Get GPG keys Result";
|
||||||
if (err) {
|
// if (err) {
|
||||||
qInfo() << "Get GPG Failed";
|
// qInfo() << "Get GPG Failed";
|
||||||
emit getAllGPGKeysFailed(err.asString());
|
// emit getAllGPGKeysFailed(err.asString());
|
||||||
} else {
|
// } else {
|
||||||
qInfo() << "Get GPG Succeed";
|
// qInfo() << "Get GPG Succeed";
|
||||||
emit getAllGPGKeysSucceed(QVariant::fromValue(PassKeyModel::keysToPassKey(keys_info)));
|
// emit getAllGPGKeysSucceed(QVariant::fromValue(PassKeyModel::keysToPassKey(keys_info)));
|
||||||
}
|
// }
|
||||||
this->m_sem->release(1);
|
// this->m_sem->release(1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
void Pass::responsePassphraseDialog(bool cancel, QString passphrase)
|
// void Pass::responsePassphraseDialog(bool cancel, QString passphrase)
|
||||||
{
|
// {
|
||||||
qDebug() << "Propagate responsePassphraseDialog";
|
// qDebug() << "Propagate responsePassphraseDialog";
|
||||||
emit responsePassphraseDialogPropagate(cancel, passphrase);
|
// emit responsePassphraseDialogPropagate(cancel, passphrase);
|
||||||
}
|
// }
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
#ifndef PASS_H
|
#ifndef PASS_H
|
||||||
#define PASS_H
|
#define PASS_H
|
||||||
|
|
||||||
|
#include "passkeymodel.h"
|
||||||
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <gpgme++/context.h>
|
#include <gpgme++/context.h>
|
||||||
|
#include <QSemaphore>
|
||||||
#include "gpg.h"
|
extern "C" {
|
||||||
|
#include <rnp/rnp.h>
|
||||||
|
}
|
||||||
|
|
||||||
using namespace GpgME;
|
using namespace GpgME;
|
||||||
|
|
||||||
@ -20,7 +24,8 @@ using namespace GpgME;
|
|||||||
class Pass : public QObject
|
class Pass : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString password_store READ password_store MEMBER m_password_store CONSTANT)
|
Q_PROPERTY(QString password_store MEMBER m_password_store READ password_store WRITE set_password_store )
|
||||||
|
Q_PROPERTY(QString gpg_home MEMBER m_gpg_home READ gpg_home WRITE set_gpg_home )
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/**
|
/**
|
||||||
@ -37,11 +42,16 @@ private slots:
|
|||||||
void deleteGPGKeyResult(Error err);
|
void deleteGPGKeyResult(Error err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Slot to handle the result of a GPG key import operation.
|
* @brief Slot to handle the error result of a GPG key import operation.
|
||||||
* @param err The error that occurred during the operation.
|
* @param err The error that occurred during the operation.
|
||||||
*/
|
*/
|
||||||
void importGPGKeyResult(Error err);
|
void slotImportGPGKeyError(rnp_result_t err);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Slot to handle the succeed result of a GPG key import operation.
|
||||||
|
* @param err The error that occurred during the operation.
|
||||||
|
*/
|
||||||
|
void slotImportGPGKeySucceed();
|
||||||
/**
|
/**
|
||||||
* @brief Slot to handle the result of retrieving all GPG keys.
|
* @brief Slot to handle the result of retrieving all GPG keys.
|
||||||
* @param err The error that occurred during the operation.
|
* @param err The error that occurred during the operation.
|
||||||
@ -131,7 +141,8 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_password_store; /**< The path to the password store. */
|
QString m_password_store; /**< The path to the password store. */
|
||||||
std::unique_ptr<Gpg> m_gpg; /**< The GPG instance used for encryption/decryption. */
|
QString m_gpg_home; /**< The path to the gpg home. */
|
||||||
|
PassphraseProvider* m_passphrase_provider; /**< Semaphore for managing concurrent operations. */
|
||||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
|
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
|
||||||
QString m_show_filename; /**< The filename associated with the password to show. */
|
QString m_show_filename; /**< The filename associated with the password to show. */
|
||||||
|
|
||||||
@ -147,9 +158,50 @@ public:
|
|||||||
*/
|
*/
|
||||||
QString password_store() const
|
QString password_store() const
|
||||||
{
|
{
|
||||||
return m_password_store;
|
return this->m_password_store;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the path to the password store.
|
||||||
|
* @param The path to the password store.
|
||||||
|
*/
|
||||||
|
void set_password_store(QString password_store)
|
||||||
|
{
|
||||||
|
qInfo() << "Password Store changed to :" << password_store;
|
||||||
|
this->m_password_store = password_store;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the path to the gpg home.
|
||||||
|
* @return The path to the gpg home.
|
||||||
|
*/
|
||||||
|
QString gpg_home() const
|
||||||
|
{
|
||||||
|
return this->m_gpg_home;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the path to the gpg hom.
|
||||||
|
* @param The path to the gpg hom
|
||||||
|
*/
|
||||||
|
void set_gpg_home(QString gpg_home)
|
||||||
|
{
|
||||||
|
qInfo() << "GNUPG Home changed to :" << gpg_home;
|
||||||
|
this->m_gpg_home = gpg_home;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the window passphrase provider used for GPG authentication.
|
||||||
|
*
|
||||||
|
* PassphraseProvider will be deleted with destructor.
|
||||||
|
*
|
||||||
|
* @param The window used by passphrase provider.
|
||||||
|
*/
|
||||||
|
void set_passphrase_provider(PassphraseProvider* passphrase_provider)
|
||||||
|
{
|
||||||
|
this->m_passphrase_provider = passphrase_provider;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the Pass object with the given window.
|
* @brief Initializes the Pass object with the given window.
|
||||||
* @param window The QObject window to interact with.
|
* @param window The QObject window to interact with.
|
||||||
|
@ -2,13 +2,16 @@
|
|||||||
#define UTPASSPHRASEPROVIDER_H
|
#define UTPASSPHRASEPROVIDER_H
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <gpg-error.h>
|
||||||
|
#include <memory>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlProperty>
|
#include <QQmlProperty>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
#include <gpgme++/interfaces/passphraseprovider.h>
|
#include <gpgme++/interfaces/passphraseprovider.h>
|
||||||
#include "gpg.h"
|
|
||||||
|
using namespace GpgME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class UTPassphraseProvider
|
* @class UTPassphraseProvider
|
||||||
@ -17,7 +20,7 @@
|
|||||||
* This class implements the `PassphraseProvider` interface from GPGME and is responsible for
|
* This class implements the `PassphraseProvider` interface from GPGME and is responsible for
|
||||||
* obtaining passphrases for GPG operations.
|
* obtaining passphrases for GPG operations.
|
||||||
*/
|
*/
|
||||||
class UTPassphraseProvider : public QObject, public PassphraseProvider
|
class UTPassphraseProvider : public QObject, public GpgME::PassphraseProvider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: utpass.qrouland\n"
|
"Project-Id-Version: utpass.qrouland\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-01-28 12:44+0100\n"
|
"POT-Creation-Date: 2025-01-29 16:33+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
20
tests.in.cpp
Normal file
20
tests.in.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QString>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QtQml>
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtQuickTest/quicktest.h>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
qDebug() << "Starting app from tests.cpp";
|
||||||
|
new QGuiApplication(argc, argv);
|
||||||
|
|
||||||
|
QGuiApplication::setApplicationName("utpass.qrouland");
|
||||||
|
|
||||||
|
return quick_test_main(argc, argv, @TESTS_PATH@, @TESTS_PATH@);
|
||||||
|
}
|
BIN
tests/assets/gpg/test_key_invalid.gpg
Normal file
BIN
tests/assets/gpg/test_key_invalid.gpg
Normal file
Binary file not shown.
@ -5,6 +5,7 @@ set(
|
|||||||
SRC
|
SRC
|
||||||
plugin.cpp
|
plugin.cpp
|
||||||
utils.cpp
|
utils.cpp
|
||||||
|
passphraseprovider.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
@ -22,6 +23,31 @@ endif()
|
|||||||
add_library(${PLUGIN} MODULE ${SRC})
|
add_library(${PLUGIN} MODULE ${SRC})
|
||||||
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
||||||
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
||||||
|
set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include)
|
||||||
|
|
||||||
|
add_library(rnp STATIC IMPORTED)
|
||||||
|
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
|
||||||
|
|
||||||
|
add_library(gpgerror SHARED IMPORTED)
|
||||||
|
set_property(TARGET gpgerror PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpg-error.so.0.28.0")
|
||||||
|
|
||||||
|
add_library(libassuan SHARED IMPORTED)
|
||||||
|
set_property(TARGET libassuan PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libassuan.so")
|
||||||
|
|
||||||
|
add_library(libgpgme SHARED IMPORTED)
|
||||||
|
set_property(TARGET libgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpgme.so")
|
||||||
|
|
||||||
|
add_library(libgpgmepp SHARED IMPORTED)
|
||||||
|
set_property(TARGET libgpgmepp PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpgmepp.so")
|
||||||
|
|
||||||
|
add_library(libqgpgme SHARED IMPORTED)
|
||||||
|
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so")
|
||||||
|
|
||||||
|
|
||||||
|
target_link_libraries(${PLUGIN} rnp gpgerror libassuan libgpgme libgpgmepp libqgpgme)
|
||||||
|
|
||||||
|
|
||||||
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
||||||
|
|
||||||
|
24
tests/plugins/TestsUtils/passphraseprovider.h
Normal file
24
tests/plugins/TestsUtils/passphraseprovider.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef UTPASSPHRASEPROVIDER_H
|
||||||
|
#define UTPASSPHRASEPROVIDER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <gpg-error.h>
|
||||||
|
#include <gpgme++/interfaces/passphraseprovider.h>
|
||||||
|
|
||||||
|
class TesTPassphraseProvider : public QObject, public GpgME::PassphraseProvider
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
char *getPassphrase(const char *useridHint,
|
||||||
|
const char *description,
|
||||||
|
bool previousWasBad,
|
||||||
|
bool &canceled) override {
|
||||||
|
|
||||||
|
char *ret;
|
||||||
|
gpgrt_asprintf(&ret, "%s", "utpasspassphrase");
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -6,5 +6,5 @@
|
|||||||
void TestsUtilsPlugin::registerTypes(const char *uri)
|
void TestsUtilsPlugin::registerTypes(const char *uri)
|
||||||
{
|
{
|
||||||
//@uri TestUtils
|
//@uri TestUtils
|
||||||
qmlRegisterSingletonType<TestsUtilsPlugin>(uri, 1, 0, "TestUtils", [](QQmlEngine *, QJSEngine *) -> QObject * { return new TestsUtils; });
|
qmlRegisterSingletonType<TestsUtilsPlugin>(uri, 1, 0, "TestsUtils", [](QQmlEngine *, QJSEngine *) -> QObject * { return new TestsUtils; });
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
module TestUtils
|
module TestsUtils
|
||||||
plugin TestUtils
|
plugin TestsUtils
|
||||||
|
@ -3,17 +3,21 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <memory>
|
||||||
#include <quazip5/JlCompress.h>
|
#include <quazip5/JlCompress.h>
|
||||||
|
|
||||||
|
#include "passphraseprovider.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
TestsUtils::TestsUtils():
|
||||||
|
m_passphrase_povider(std::unique_ptr<TesTPassphraseProvider>(new TesTPassphraseProvider()))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
QString TestsUtils::getTempPath()
|
QString TestsUtils::getTempPath()
|
||||||
{
|
{
|
||||||
qFatal("yp");
|
|
||||||
// Get the system's temporary directory
|
// Get the system's temporary directory
|
||||||
QString tempDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
QString tempDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||||
qDebug() << "TempDir : " << tempDir;
|
|
||||||
|
|
||||||
// Generate a unique UUID
|
// Generate a unique UUID
|
||||||
QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
||||||
@ -22,17 +26,16 @@ QString TestsUtils::getTempPath()
|
|||||||
QString newTempDir = tempDir + "/" + uuid;
|
QString newTempDir = tempDir + "/" + uuid;
|
||||||
|
|
||||||
QDir dir;
|
QDir dir;
|
||||||
if (!dir.exists(newTempDir)) {
|
dir.mkpath(newTempDir);
|
||||||
// Create the directory
|
|
||||||
if (dir.mkpath(newTempDir)) {
|
qDebug() << "TempDir : " << newTempDir;
|
||||||
return newTempDir; // Return the path if successful
|
return newTempDir;
|
||||||
} else {
|
|
||||||
return "Failed to create directory"; // Return an error message
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return newTempDir; // If the directory already exists, return its path
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QObject* TestsUtils::getTestPassphraseProvider()
|
||||||
|
{
|
||||||
|
return this->m_passphrase_povider.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
#ifndef TESTSUTILS_H
|
#ifndef TESTSUTILS_H
|
||||||
#define TESTSUTILS_H
|
#define TESTSUTILS_H
|
||||||
|
|
||||||
|
#include "passphraseprovider.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class TestsUtils : public QObject
|
class TestsUtils : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<TesTPassphraseProvider> m_passphrase_povider;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TestsUtils() = default;
|
TestsUtils();
|
||||||
~TestsUtils() override = default;
|
~TestsUtils() override = default;
|
||||||
|
|
||||||
Q_INVOKABLE QString getTempPath();
|
Q_INVOKABLE QString getTempPath();
|
||||||
|
Q_INVOKABLE QObject* getTestPassphraseProvider();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import Git 1.0
|
|
||||||
import QtQuick 2.9
|
|
||||||
import QtTest 1.2
|
|
||||||
|
|
||||||
TestCase {
|
|
||||||
function test_git_clone() {
|
|
||||||
verify(Git.clone("", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
name: "git"
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import Git 1.0
|
|
||||||
import QtQuick 2.9
|
|
||||||
import QtTest 1.2
|
|
||||||
|
|
||||||
TestCase {
|
|
||||||
function test_git_clone() {
|
|
||||||
verify(Git.clone("", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
name: "git"
|
|
||||||
}
|
|
13
tests/units/pass/PassTestCase.qml
Normal file
13
tests/units/pass/PassTestCase.qml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtTest 1.2
|
||||||
|
import TestsUtils 1.0
|
||||||
|
import Pass 1.0
|
||||||
|
|
||||||
|
TestCase {
|
||||||
|
function init() {
|
||||||
|
Pass.initialize(null);
|
||||||
|
Pass.gpg_home = TestsUtils.getTempPath();
|
||||||
|
Pass.password_store = TestsUtils.getTempPath();
|
||||||
|
Pass.passphrase_provider = TestsUtils.getTestPassphraseProvider();
|
||||||
|
}
|
||||||
|
}
|
47
tests/units/pass/tst_import_key.qml
Normal file
47
tests/units/pass/tst_import_key.qml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtTest 1.2
|
||||||
|
import TestsUtils 1.0
|
||||||
|
import Pass 1.0
|
||||||
|
|
||||||
|
PassTestCase {
|
||||||
|
function init_data() {
|
||||||
|
return [
|
||||||
|
{ file: Qt.resolvedUrl("../../assets/gpg/test_key.gpg"), spy: importGPGKeySucceed, signal: Pass.importGPGKeySucceed, err_msg : null }
|
||||||
|
, { file: Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"), spy: importGPGKeyFailed, signal: Pass.importGPGKeyFailed, err_msg : "Error reading file" }
|
||||||
|
, { file: Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"), spy: importGPGKeyFailed, signal: Pass.importGPGKeyFailed, err_msg : "Bad format" }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalSpy {
|
||||||
|
id: importGPGKeySucceed
|
||||||
|
target: Pass
|
||||||
|
signalName: "importGPGKeySucceed"
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalSpy {
|
||||||
|
id: importGPGKeyFailed
|
||||||
|
target: Pass
|
||||||
|
signalName: "importGPGKeyFailed"
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalSpy {
|
||||||
|
id: importGPGKeyCancelled
|
||||||
|
target: Pass
|
||||||
|
signalName: "importGPGKeyCancelled"
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_import_key(data) {
|
||||||
|
var err_msg;
|
||||||
|
|
||||||
|
data.signal.connect(function(message) {
|
||||||
|
err_msg = message;
|
||||||
|
});
|
||||||
|
|
||||||
|
Pass.importGPGKey(data.file);
|
||||||
|
|
||||||
|
data.spy.wait();
|
||||||
|
if(data.err_msg) {
|
||||||
|
verify(err_msg === data.err_msg, "Should return arg msg %1 but return %2".arg(data.err_msg).arg(err_msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
tests/units/tst_git.qml
Normal file
13
tests/units/tst_git.qml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Pass 1.0
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtTest 1.2
|
||||||
|
|
||||||
|
TestCase {
|
||||||
|
function test_import_key(){
|
||||||
|
var homedir = TestUtils.getTempPath();
|
||||||
|
Pass
|
||||||
|
verify(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
name: "git"
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtTest 1.2
|
import QtTest 1.2
|
||||||
import TestUtils 1.0
|
import TestsUtils 1.0
|
||||||
import Utils 1.0
|
import Utils 1.0
|
||||||
|
|
||||||
TestCase {
|
TestCase {
|
Loading…
x
Reference in New Issue
Block a user