mirror of
https://github.com/QRouland/UTPass.git
synced 2025-01-24 07:36:39 +00:00
Refactor gpg for more clean job handling
This commit is contained in:
parent
00116aea8c
commit
e589abd10c
@ -3,6 +3,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
#include <gpgme++/data.h>
|
#include <gpgme++/data.h>
|
||||||
@ -22,9 +23,11 @@
|
|||||||
#include <qgpgme/keylistjob.h>
|
#include <qgpgme/keylistjob.h>
|
||||||
#include <qgpgme/changeownertrustjob.h>
|
#include <qgpgme/changeownertrustjob.h>
|
||||||
|
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
|
#include "passkeymodel.h"
|
||||||
#include "passphraseprovider.h"
|
#include "passphraseprovider.h"
|
||||||
#include "qprocess.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -32,9 +35,9 @@
|
|||||||
using namespace GpgME;
|
using namespace GpgME;
|
||||||
using namespace QGpgME;
|
using namespace QGpgME;
|
||||||
|
|
||||||
Gpg::Gpg()
|
Gpg::Gpg(QObject* windows)
|
||||||
{
|
{
|
||||||
m_window = nullptr;
|
this->m_passphrase_provider = new UTPassphraseProvider(windows);
|
||||||
|
|
||||||
Gpg::initGpgConfig();
|
Gpg::initGpgConfig();
|
||||||
|
|
||||||
@ -50,6 +53,10 @@ Gpg::Gpg()
|
|||||||
qDebug() << "GNUPG Home is :" << engineInfo(OpenPGP).homeDirectory();
|
qDebug() << "GNUPG Home is :" << engineInfo(OpenPGP).homeDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gpg::~Gpg(){
|
||||||
|
delete this->m_passphrase_provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString Gpg::initGpgHome()
|
QString Gpg::initGpgHome()
|
||||||
{
|
{
|
||||||
@ -124,37 +131,28 @@ void Gpg::initGpgConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QPair<Error, QString> Gpg::decrypt(QByteArray cipherText)
|
Error Gpg::decrypt(QByteArray cipher_text)
|
||||||
{
|
{
|
||||||
auto job = openpgp()->decryptJob();
|
auto job = openpgp()->decryptJob();
|
||||||
|
|
||||||
auto ctx = DecryptJob::context(job);
|
auto ctx = DecryptJob::context(job);
|
||||||
|
|
||||||
auto provider = new UTPassphraseProvider;
|
ctx->setPassphraseProvider(this->m_passphrase_provider);
|
||||||
ctx->setPassphraseProvider(provider);
|
|
||||||
ctx->setPinentryMode(Context::PinentryLoopback);
|
ctx->setPinentryMode(Context::PinentryLoopback);
|
||||||
|
|
||||||
QByteArray plain_text;
|
QObject::connect(job, &DecryptJob::result,
|
||||||
auto decResult = job->exec(cipherText, plain_text);
|
this, &Gpg::decryptResultSlot);
|
||||||
|
|
||||||
delete job;
|
return job->start(cipher_text);
|
||||||
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<Error, QString>(decResult.error(), QString::fromUtf8(plain_text));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error Gpg::decryptFromFile(QString path)
|
||||||
QPair<Error, QString> Gpg::decryptFromFile(QString path)
|
|
||||||
{
|
{
|
||||||
qDebug() << "Decrypt from " << path;
|
qDebug() << "Decrypt from " << path;
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qWarning() << "Can't open the File";
|
qWarning() << "Can't open the File";
|
||||||
return QPair<Error, QString>(Error(), QString());;
|
return Error();
|
||||||
}
|
}
|
||||||
QByteArray cipherText = file.readAll();
|
QByteArray cipherText = file.readAll();
|
||||||
file.close();
|
file.close();
|
||||||
@ -162,77 +160,83 @@ QPair<Error, QString> Gpg::decryptFromFile(QString path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QPair<Error, QByteArray> 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)
|
||||||
{
|
{
|
||||||
|
if (result.error()) {
|
||||||
qDebug() << "Encrypt to QByteArray";
|
qWarning() << "Something gone wrong on decrypt";
|
||||||
auto keys = getKeys(uid);
|
qDebug() << "Code Error : " << result.error().code();
|
||||||
if (keys.first) {
|
qDebug() << "Error str : " << result.error().asString();
|
||||||
return QPair<Error, QByteArray>(keys.first, QByteArray());
|
|
||||||
}
|
}
|
||||||
|
emit decryptResult(result.error(), QString::fromUtf8(plainText));
|
||||||
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,
|
// QPair<Error, QByteArray> Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode)
|
||||||
bool text_mode)
|
// {
|
||||||
{
|
|
||||||
qDebug() << "Encrypting to file " << path;
|
// qDebug() << "Encrypt to QByteArray";
|
||||||
QFile file(path);
|
// auto keys = getKeys(uid);
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
// if (keys.first) {
|
||||||
qWarning() << "Can't open the file to write it" ;
|
// return QPair<Error, QByteArray>(keys.first, QByteArray());
|
||||||
return Error();
|
// }
|
||||||
}
|
|
||||||
auto encrypt_ret = encrypt(str, uid, ascii_armor, text_mode);
|
// auto job = std::unique_ptr<EncryptJob>(openpgp()->encryptJob(ascii_armor, text_mode));
|
||||||
if (encrypt_ret.first) {
|
|
||||||
file.write(encrypt_ret.second);
|
// QByteArray cipherText;
|
||||||
}
|
// auto result = job->exec(keys.second, str.toUtf8(), Context::AlwaysTrust, cipherText);
|
||||||
qDebug() << "Encrypting to file " << path;
|
|
||||||
return encrypt_ret.first;
|
// qDebug() << "Encrypted to QByteArray";
|
||||||
}
|
// return QPair<Error, QByteArray>(result.error(), cipherText);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
QPair<Error, std::vector< GpgME::Key >> 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 )
|
bool validate )
|
||||||
{
|
{
|
||||||
return getKeys(QString(""), remote, include_sigs, validate);
|
return getKeys(QString(""), remote, include_sigs, validate);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<Error, std::vector<Key >> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
|
Error Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
|
||||||
bool validate)
|
bool validate)
|
||||||
{
|
{
|
||||||
qDebug() << "Getting the keys " << pattern_uid;
|
qDebug() << "Getting the keys " << pattern_uid;
|
||||||
auto job = std::unique_ptr<KeyListJob>(openpgp()->keyListJob(remote, include_sigs, validate));
|
auto job = openpgp()->keyListJob(remote, include_sigs, validate);
|
||||||
|
|
||||||
std::vector<Key> keys;
|
QObject::connect(job, &KeyListJob::result,
|
||||||
auto result = job->exec(QStringList() << pattern_uid, false, keys);
|
this, &Gpg::getKeysJobResultSlot);
|
||||||
|
|
||||||
qDebug() << "Got the keys " << pattern_uid;
|
return job->start(QStringList() << pattern_uid, false);
|
||||||
return QPair<Error, std::vector< Key >> (result.error(), keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gpg::getKeysJobResultSlot(const GpgME::KeyListResult &result, const std::vector<GpgME::Key> &keys, const QString &auditLogAsHtml , const GpgME::Error &auditLogError)
|
||||||
QPair<Error, Key> Gpg::getKey(QString uid, bool remote, bool include_sigs, bool validate)
|
|
||||||
{
|
{
|
||||||
qDebug() << "Getting the key " << uid;
|
if (result.error()) {
|
||||||
auto keys = getKeys(uid, remote, include_sigs, validate);
|
qWarning() << "Something gone wrong on decrypt";
|
||||||
|
qDebug() << "Code Error : " << result.error().code();
|
||||||
if (keys.first or keys.second.size() != 1) {
|
qDebug() << "Error str : " << result.error().asString();
|
||||||
qWarning() << "Bad id";
|
|
||||||
return QPair<Error, Key>(keys.first, Key::null);
|
|
||||||
}
|
}
|
||||||
qDebug() << "Got the key " << uid;
|
emit getKeysResult(result.error(), keys);
|
||||||
return QPair<Error, Key>(keys.first, keys.second.front());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Error Gpg::importKeysFromFile(QString path)
|
Error Gpg::importKeysFromFile(QString path)
|
||||||
{
|
{
|
||||||
qDebug() << "Importing the key file" << path;
|
qDebug() << "Importing the key file" << path;
|
||||||
@ -242,51 +246,52 @@ Error Gpg::importKeysFromFile(QString path)
|
|||||||
qWarning() << "Can't open the File";
|
qWarning() << "Can't open the File";
|
||||||
return Error();
|
return Error();
|
||||||
}
|
}
|
||||||
|
auto data = file.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
auto job = openpgp()->importJob();
|
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() << "numImported" << result.numImported();
|
||||||
qDebug() << "numSecretKeysImported" << result.numSecretKeysImported();
|
qDebug() << "numSecretKeysImported" << result.numSecretKeysImported();
|
||||||
qDebug() << "numSecretKeysConsidered" << result.numSecretKeysConsidered();
|
qDebug() << "numSecretKeysConsidered" << result.numSecretKeysConsidered();
|
||||||
qDebug() << "numSecretKeysUnchanged" << result.numSecretKeysUnchanged();
|
qDebug() << "numSecretKeysUnchanged" << result.numSecretKeysUnchanged();
|
||||||
qDebug() << "numUnchanged" << result.numUnchanged();
|
qDebug() << "numUnchanged" << result.numUnchanged();
|
||||||
|
|
||||||
file.close();
|
|
||||||
delete job;
|
|
||||||
|
|
||||||
if (result.error()) {
|
if (result.error()) {
|
||||||
qWarning() << "Import go wrong";
|
qWarning() << "Something gone wrong on decrypt";
|
||||||
qDebug() << "Code Error : " << result.error().code();
|
qDebug() << "Code Error : " << result.error().code();
|
||||||
qDebug() << "Error str : " << result.error().asString();
|
qDebug() << "Error str : " << result.error().asString();
|
||||||
}
|
}
|
||||||
qDebug() << "Imported the key file" << path;
|
emit importKeysFromFileResult(result.error());
|
||||||
return result.error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Gpg::deleteKeyId(QString uid)
|
Error Gpg::deleteKey(const Key key)
|
||||||
{
|
{
|
||||||
qDebug() << "Deleting key id " << uid;
|
auto job = openpgp()->deleteJob();
|
||||||
auto key = getKey(uid);
|
|
||||||
|
|
||||||
if (key.first) {
|
QObject::connect(job, &DeleteJob::result,
|
||||||
return key.first;
|
this, &Gpg::deleteKeySlot);
|
||||||
}
|
|
||||||
|
|
||||||
auto ctx = std::unique_ptr<Context>(Context::createForProtocol(OpenPGP));
|
return openpgp()->deleteJob()->start(key, true);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,61 +1,95 @@
|
|||||||
#ifndef GPG_H
|
#ifndef GPG_H
|
||||||
#define GPG_H
|
#define GPG_H
|
||||||
|
|
||||||
|
#include "passkeymodel.h"
|
||||||
|
#include "passphraseprovider.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <gpgme++/context.h>
|
#include <gpgme++/context.h>
|
||||||
#include <qgpgme/changeownertrustjob.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 GpgME;
|
||||||
|
using namespace QGpgME;
|
||||||
|
|
||||||
class Gpg
|
class Gpg: public QObject
|
||||||
{
|
{
|
||||||
private:
|
Q_OBJECT
|
||||||
Gpg();
|
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<GpgME::Key> &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<GpgME::Key> keys);
|
||||||
|
void deleteKeyResult(Error err);
|
||||||
|
void decryptResult(Error err, QString plain_text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UTPassphraseProvider* m_passphrase_provider;
|
||||||
|
|
||||||
QString findCommandPath(const QString &command);
|
QString findCommandPath(const QString &command);
|
||||||
QString initGpgHome();
|
QString initGpgHome();
|
||||||
QString initGpgExec();
|
QString initGpgExec();
|
||||||
void initGpgConfig();
|
void initGpgConfig();
|
||||||
|
Error getKey(QString uid, bool remote = false, bool include_sigs = false,
|
||||||
|
bool validate = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<Gpg> instance()
|
Gpg(QObject* window);
|
||||||
|
~Gpg();
|
||||||
|
|
||||||
|
UTPassphraseProvider* passphrase_provider() const
|
||||||
{
|
{
|
||||||
static std::shared_ptr<Gpg> s{new Gpg};
|
return m_passphrase_provider;
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
Gpg(Gpg const &) = delete;
|
|
||||||
void operator=(Gpg const &) = delete;
|
|
||||||
|
|
||||||
void setWindow(QObject *window)
|
Error importKeysFromFile(const QString path);
|
||||||
{
|
Error getKeys(const QString pattern_uid, const bool remote = false,
|
||||||
m_window = window;
|
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<Error, std::vector<Key >> getAllKeys(bool remote = false, bool include_sigs = {}, bool
|
|
||||||
validate = false);
|
|
||||||
QPair<Error, std::vector<Key >> getKeys( QString pattern_uid, bool remote = false,
|
|
||||||
bool include_sigs = false,
|
|
||||||
bool validate = false);
|
|
||||||
QPair<Error, Key> getKey( QString uid, bool remote = false, bool include_sigs = false,
|
|
||||||
bool validate = false);
|
|
||||||
QPair<Error, QString> decrypt( QByteArray cipherText);
|
|
||||||
QPair<Error, QString> decryptFromFile( QString path);
|
|
||||||
QPair<Error, QByteArray> 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
|
#endif
|
||||||
|
@ -8,8 +8,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Pass::Pass(): m_password_store (QStandardPaths::writableLocation(
|
Pass::Pass():
|
||||||
QStandardPaths::AppDataLocation).append("/.password-store"))
|
m_password_store (QStandardPaths::writableLocation(
|
||||||
|
QStandardPaths::AppDataLocation).append("/.password-store")),
|
||||||
|
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
||||||
|
m_show_filename(QString())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Pass::initialize(QObject *window)
|
void Pass::initialize(QObject *window)
|
||||||
@ -18,7 +21,13 @@ void Pass::initialize(QObject *window)
|
|||||||
qFatal("window is invalid. Abording.");
|
qFatal("window is invalid. Abording.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpg::instance()->setWindow(window);
|
this->m_gpg = std::unique_ptr<Gpg>(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);
|
QDir dir(m_password_store);
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
@ -27,38 +36,78 @@ void Pass::initialize(QObject *window)
|
|||||||
qInfo() << "Password Store is :" << m_password_store;
|
qInfo() << "Password Store is :" << m_password_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::show(QUrl url)
|
bool Pass::show(QUrl url)
|
||||||
{
|
{
|
||||||
qInfo() << "Decrypting";
|
if (!this->m_sem->tryAcquire(1, 500)){ return false; }
|
||||||
auto decrypt_ret = Gpg::instance()->decryptFromFile(url.toLocalFile());
|
auto path = url.toLocalFile();
|
||||||
if (decrypt_ret.first) {
|
qInfo() << "Staring decrypting job for " << path;
|
||||||
qInfo() << "Decrypt Failed";
|
QFileInfo file_info(path);
|
||||||
emit decryptFailed();
|
this->m_show_filename = file_info.completeBaseName();
|
||||||
} else if (decrypt_ret.second.isNull()) {
|
return this->m_gpg->decryptFromFile(path);
|
||||||
qInfo() << "Decrypt Canceled";
|
|
||||||
emit decryptCanceled();
|
|
||||||
} else {
|
|
||||||
qInfo() << "Decrypt OK";
|
|
||||||
emit decrypted(url.fileName(), decrypt_ret.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
if (!this->m_sem->tryAcquire(1, 500)){ return false;}
|
||||||
return !Gpg::instance()->deleteKeyId(id);
|
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)
|
bool Pass::importGPGKey(QUrl url)
|
||||||
{
|
{
|
||||||
|
if (!this->m_sem->tryAcquire(1, 500)){ return false;}
|
||||||
qInfo() << "Importing Key from " << url;
|
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 ";
|
qInfo() << "Getting all key form gpg ";
|
||||||
return QVariant::fromValue(PassKeyModel::keysToPassKey(
|
return this->m_gpg->getAllKeys();
|
||||||
Gpg::instance()->getAllKeys().second)); // TODO Error handling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pass::getAllGPGKeysResult(Error err, std::vector<GpgME::Key> 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);
|
||||||
|
}
|
||||||
|
@ -4,20 +4,44 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <gpgme++/context.h>
|
||||||
|
|
||||||
|
#include "gpg.h"
|
||||||
|
|
||||||
|
using namespace GpgME;
|
||||||
|
|
||||||
class Pass : public QObject
|
class Pass : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
private:
|
||||||
QString m_password_store;
|
QString m_password_store;
|
||||||
|
std::unique_ptr<Gpg> m_gpg;
|
||||||
signals:
|
std::unique_ptr<QSemaphore> m_sem;
|
||||||
void decrypted(QString name, QString text);
|
QString m_show_filename;
|
||||||
void decryptCanceled();
|
|
||||||
void decryptFailed();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pass();
|
Pass();
|
||||||
@ -29,10 +53,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_INVOKABLE void initialize(QObject *window);
|
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 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
|
#endif
|
||||||
|
@ -9,14 +9,13 @@ using namespace GpgME;
|
|||||||
class UserIdModel : public QObject
|
class UserIdModel : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT)
|
Q_PROPERTY(QString uid READ uid CONSTANT)
|
||||||
Q_PROPERTY(QString name READ name MEMBER m_name CONSTANT)
|
Q_PROPERTY(QString name READ name CONSTANT)
|
||||||
Q_PROPERTY(QString email READ email MEMBER m_email CONSTANT)
|
Q_PROPERTY(QString email READ email CONSTANT)
|
||||||
|
|
||||||
|
private:
|
||||||
UserID m_user_id;
|
UserID m_user_id;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
UserIdModel(UserID key):
|
UserIdModel(UserID key):
|
||||||
m_user_id(key)
|
m_user_id(key)
|
||||||
{};
|
{};
|
||||||
@ -38,10 +37,11 @@ public:
|
|||||||
class PassKeyModel : public QObject
|
class PassKeyModel : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT)
|
Q_PROPERTY(Key key READ key MEMBER m_key CONSTANT)
|
||||||
Q_PROPERTY(QList<QObject *> userIds READ userIds MEMBER m_user_ids CONSTANT)
|
Q_PROPERTY(QString uid READ uid CONSTANT)
|
||||||
Q_PROPERTY(bool isSecret READ isSecret MEMBER m_secret CONSTANT)
|
Q_PROPERTY(QList<QObject *> userIds READ userIds CONSTANT)
|
||||||
Q_PROPERTY(bool isExpired READ isExpired MEMBER m_expired CONSTANT)
|
Q_PROPERTY(bool isSecret READ isSecret CONSTANT)
|
||||||
|
Q_PROPERTY(bool isExpired READ isExpired CONSTANT)
|
||||||
|
|
||||||
Key m_key;
|
Key m_key;
|
||||||
public:
|
public:
|
||||||
@ -58,6 +58,11 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Key key() const
|
||||||
|
{
|
||||||
|
return m_key;
|
||||||
|
};
|
||||||
|
|
||||||
QString uid() const
|
QString uid() const
|
||||||
{
|
{
|
||||||
return QString::fromUtf8(m_key.keyID());
|
return QString::fromUtf8(m_key.keyID());
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef UTPASSPHRASEPROVIDER_H
|
#ifndef UTPASSPHRASEPROVIDER_H
|
||||||
#define UTPASSPHRASEPROVIDER_H
|
#define UTPASSPHRASEPROVIDER_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlProperty>
|
#include <QQmlProperty>
|
||||||
@ -14,48 +15,57 @@
|
|||||||
class UTPassphraseProvider : public QObject, public PassphraseProvider
|
class UTPassphraseProvider : public QObject, public PassphraseProvider
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
|
||||||
std::unique_ptr<QEventLoop> m_loop;
|
|
||||||
std::unique_ptr<QSemaphore> m_sem;
|
|
||||||
char *m_passphrase;
|
|
||||||
bool m_canceled;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleResponse(bool canceled, QString p)
|
void handleResponse(bool canceled, QString p)
|
||||||
{
|
{
|
||||||
if (!canceled)
|
qDebug() << "call handleResponse";
|
||||||
gpgrt_asprintf(&m_passphrase, "%s", p.toUtf8().constData());
|
if (!canceled)
|
||||||
else
|
gpgrt_asprintf(&m_passphrase, "%s", p.toUtf8().constData());
|
||||||
m_canceled = true;
|
else
|
||||||
m_loop->quit();
|
m_canceled = true;
|
||||||
};
|
emit unlockEventLoop();
|
||||||
|
};
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void unlockEventLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<QSemaphore> m_sem;
|
||||||
|
char *m_passphrase;
|
||||||
|
bool m_canceled;
|
||||||
|
QObject* m_window;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UTPassphraseProvider():
|
UTPassphraseProvider(QObject* window):
|
||||||
m_loop(std::unique_ptr<QEventLoop>(new QEventLoop)),
|
|
||||||
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
||||||
m_passphrase(nullptr),
|
m_passphrase(nullptr),
|
||||||
m_canceled(false)
|
m_canceled(false),
|
||||||
{}
|
m_window(window)
|
||||||
|
{
|
||||||
|
qDebug() << "Initialize UTPassphraseProviderr";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
char *getPassphrase( const char *useridHint,
|
char *getPassphrase( const char *useridHint,
|
||||||
const char *description,
|
const char *description,
|
||||||
bool previousWasBad,
|
bool previousWasBad,
|
||||||
bool &canceled ) Q_DECL_OVERRIDE {
|
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.";
|
qWarning() << "Cannot acquire UTPassphraseProvider semaphore.";
|
||||||
canceled = true;
|
canceled = true;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_passphrase = nullptr;
|
this->m_passphrase = nullptr;
|
||||||
m_canceled = false;
|
this->m_canceled = false;
|
||||||
|
|
||||||
qDebug() << "Call the QML Dialog Passphrase Provider";
|
qDebug() << "Call the QML Dialog Passphrase Provider";
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
Gpg::instance()->getWindow(), "callPassphraseDialog",
|
this->m_window, "callPassphraseDialog",
|
||||||
Q_ARG(QVariant, useridHint),
|
Q_ARG(QVariant, useridHint),
|
||||||
Q_ARG(QVariant, description),
|
Q_ARG(QVariant, description),
|
||||||
Q_ARG(QVariant, previousWasBad)
|
Q_ARG(QVariant, previousWasBad)
|
||||||
@ -63,24 +73,22 @@ public:
|
|||||||
|
|
||||||
qDebug() << "Waiting for response";
|
qDebug() << "Waiting for response";
|
||||||
|
|
||||||
QObject::connect(
|
QEventLoop loop;
|
||||||
Gpg::instance()->getWindow(), SIGNAL(responsePassphraseDialog(bool, QString)),
|
QObject::connect(this, &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit);
|
||||||
this, SLOT(handleResponse(bool, QString))
|
loop.exec();
|
||||||
);
|
|
||||||
m_loop->exec();
|
|
||||||
|
|
||||||
qDebug() << "Prepare Returns";
|
qDebug() << "Prepare Returns";
|
||||||
char *ret;
|
char *ret;
|
||||||
gpgrt_asprintf(&ret, "%s", m_passphrase);
|
gpgrt_asprintf(&ret, "%s", m_passphrase);
|
||||||
canceled = m_canceled;
|
canceled = this->m_canceled;
|
||||||
|
|
||||||
qDebug() << "Clean";
|
qDebug() << "Clean";
|
||||||
if (m_passphrase)
|
if (this->m_passphrase)
|
||||||
{
|
{
|
||||||
free(m_passphrase);
|
free(m_passphrase);
|
||||||
}
|
}
|
||||||
m_canceled = false;
|
this->m_canceled = false;
|
||||||
m_sem->release(1);
|
this->m_sem->release(1);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -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-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"
|
"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"
|
||||||
@ -17,10 +17,6 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: ../qml/components/FileDir.qml:59
|
|
||||||
msgid "Decryption failed !"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../qml/dialogs/ErrorDialog.qml:12
|
#: ../qml/dialogs/ErrorDialog.qml:12
|
||||||
msgid "Error !"
|
msgid "Error !"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -83,21 +79,25 @@ msgstr ""
|
|||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../qml/pages/PasswordList.qml:22
|
#: ../qml/pages/PasswordList.qml:37
|
||||||
msgid ""
|
msgid ""
|
||||||
"No password found<br>You can import a password store by cloning or importing "
|
"No password found<br>You can import a password store by cloning or importing "
|
||||||
"a zip in the settings"
|
"a zip in the settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../qml/pages/PasswordList.qml:61
|
#: ../qml/pages/PasswordList.qml:76
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr ""
|
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
|
#: ../qml/pages/headers/StackHeader.qml:9 UTPass.desktop.in.h:1
|
||||||
msgid "UTPass"
|
msgid "UTPass"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../qml/pages/PasswordList.qml:96
|
||||||
|
msgid "Decryption failed !"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ../qml/pages/headers/MainHeader.qml:26 ../qml/pages/settings/Settings.qml:70
|
#: ../qml/pages/headers/MainHeader.qml:26 ../qml/pages/settings/Settings.qml:70
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
38
qml/Main.qml
38
qml/Main.qml
@ -10,8 +10,6 @@ MainView {
|
|||||||
|
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
signal responsePassphraseDialog(bool canceled, string passphrase)
|
|
||||||
|
|
||||||
function initPass(rootView) {
|
function initPass(rootView) {
|
||||||
Pass.initialize(rootView);
|
Pass.initialize(rootView);
|
||||||
pageStack.push(Qt.resolvedUrl("pages/PasswordList.qml"));
|
pageStack.push(Qt.resolvedUrl("pages/PasswordList.qml"));
|
||||||
@ -19,30 +17,36 @@ MainView {
|
|||||||
|
|
||||||
function callPassphraseDialog(useridHint, description, previousWasBad) {
|
function callPassphraseDialog(useridHint, description, previousWasBad) {
|
||||||
//TODO use parameters to impove passphrase dialog
|
//TODO use parameters to impove passphrase dialog
|
||||||
var passphraseDialog = PopupUtils.open(Qt.resolvedUrl("dialogs/PassphraseDialog.qml"));
|
var pop = PopupUtils.open(passphraseDialog);
|
||||||
passphraseDialog.activateFocus();
|
pop.activateFocus();
|
||||||
var validated = function validated(passphrase) {
|
|
||||||
responsePassphraseDialog(false, passphrase);
|
|
||||||
};
|
|
||||||
var canceled = function canceled() {
|
|
||||||
responsePassphraseDialog(true, "");
|
|
||||||
};
|
|
||||||
passphraseDialog.validated.connect(validated);
|
|
||||||
passphraseDialog.canceled.connect(canceled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
objectName: "mainView"
|
objectName: "mainView"
|
||||||
applicationName: "utpass.qrouland"
|
applicationName: "utpass.qrouland"
|
||||||
automaticOrientation: false
|
automaticOrientation: true
|
||||||
width: units.gu(48)
|
|
||||||
height: units.gu(80)
|
width: units.gu(45)
|
||||||
|
height: units.gu(75)
|
||||||
|
|
||||||
PageStack {
|
PageStack {
|
||||||
id: pageStack
|
id: pageStack
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Component.onCompleted: {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: passphraseDialog
|
||||||
|
|
||||||
|
PassphraseDialog {
|
||||||
|
onValidated: {
|
||||||
|
console.info("valided");
|
||||||
|
Pass.responsePassphraseDialog(false, passphrase);
|
||||||
|
}
|
||||||
|
onCanceled: {
|
||||||
|
console.info("canceled");
|
||||||
|
Pass.responsePassphraseDialog(true, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,14 @@ Component {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (fileIsDir) {
|
var path = folderModel.folder + "/" + fileName;
|
||||||
folderModel.folder = folderModel.folder + "/" + fileName;
|
if (fileIsDir) {
|
||||||
|
folderModel.folder = path;
|
||||||
backAction.visible = true;
|
backAction.visible = true;
|
||||||
passwordListHeader.title = fileName;
|
passwordListHeader.title = fileName;
|
||||||
} else {
|
} else {
|
||||||
Pass.show(folderModel.folder + "/" + fileName);
|
console.debug("pass show %1".arg(path))
|
||||||
|
Pass.show(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,15 +54,6 @@ Component {
|
|||||||
borderColor: LomiriColors.warmGrey
|
borderColor: LomiriColors.warmGrey
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
|
||||||
id: passwordPageDecryptError
|
|
||||||
|
|
||||||
ErrorDialog {
|
|
||||||
textError: i18n.tr("Decryption failed !")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,11 @@ Page {
|
|||||||
iconName: "back"
|
iconName: "back"
|
||||||
text: "Back"
|
text: "Back"
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
// passwordPage.plainText = "";
|
passwordPage.plainText = null;
|
||||||
// for (var object in objects) {
|
for (var object in objects) {
|
||||||
// object.text = "";
|
object.text = null;
|
||||||
// object.destroy();
|
object.destroy();
|
||||||
// }
|
}
|
||||||
pageStack.pop();
|
pageStack.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import "headers"
|
||||||
import "../components"
|
import "../components"
|
||||||
|
import "../dialogs"
|
||||||
import Lomiri.Components 1.3
|
import Lomiri.Components 1.3
|
||||||
import Pass 1.0
|
import Pass 1.0
|
||||||
import Qt.labs.folderlistmodel 2.1
|
import Qt.labs.folderlistmodel 2.1
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
import "headers"
|
import Lomiri.Components.Popups 1.3
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
id: passwordListPage
|
id: passwordListPage
|
||||||
@ -13,13 +15,13 @@ Page {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
passwordStorePath = "file:" + Pass.password_store;
|
passwordStorePath = "file:" + Pass.password_store;
|
||||||
Pass.onDecrypted.connect(function(filename, text) {
|
Pass.onShowSucceed.connect(function(filename, text) {
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), {
|
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), {
|
||||||
"plainText": text,
|
"plainText": text,
|
||||||
"title": filename
|
"title": filename
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Pass.onDecryptFailed.connect(function() {
|
Pass.onShowFailed.connect(function(message) {
|
||||||
PopupUtils.open(passwordPageDecryptError);
|
PopupUtils.open(passwordPageDecryptError);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -87,4 +89,13 @@ Page {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: passwordPageDecryptError
|
||||||
|
|
||||||
|
ErrorDialog {
|
||||||
|
textError: i18n.tr("Decryption failed !")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user