Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final step in process mgmt refactoring #275

Merged
merged 8 commits into from Jan 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 29 additions & 15 deletions src/enums.h
Expand Up @@ -2,22 +2,36 @@
#define ENUMS_H

/*!
\class Enums
\brief Enumerators for configuration items
\namespace Enums
\brief Enumerators for configuration and runtime items
*/
class Enums {
public:
/**
* @brief Enums::clipBoardType enum
* 0 Never
* 1 Always
* 2 On demand
*/
enum clipBoardType {
CLIPBOARD_NEVER = 0,
CLIPBOARD_ALWAYS = 1,
CLIPBOARD_ON_DEMAND = 2
};
namespace Enums {

enum clipBoardType {
CLIPBOARD_NEVER = 0,
CLIPBOARD_ALWAYS = 1,
CLIPBOARD_ON_DEMAND = 2
};

enum PROCESS {
GIT_INIT = 0,
GIT_ADD,
GIT_COMMIT,
GIT_RM,
GIT_PULL,
GIT_PUSH,
PASS_SHOW,
PASS_INSERT,
PASS_REMOVE,
PASS_INIT,
GPG_GENKEYS,
PASS_MOVE,
PASS_COPY,
GIT_MOVE,
GIT_COPY,
PROCESS_COUNT,
INVALID
};
}

#endif // ENUMS_H
12 changes: 12 additions & 0 deletions src/executor.cpp
Expand Up @@ -172,6 +172,18 @@ void Executor::setEnvironment(const QStringList &env) {
m_process.setEnvironment(env);
}

/**
* @brief Executor::cancelNext cancels execution of first process in queue
* if it's not already running
*
* @return id of the cancelled process or -1 on error
*/
int Executor::cancelNext() {
if (running || m_execQueue.isEmpty())
return -1; // TODO(bezet): definitely throw here
return m_execQueue.dequeue().id;
}

/**
* @brief Executor::finished called when an executed process finishes
* @param exitCode
Expand Down
2 changes: 2 additions & 0 deletions src/executor.h
Expand Up @@ -82,6 +82,8 @@ class Executor : public QObject {
QString *process_out, QString *process_err = Q_NULLPTR);

void setEnvironment(const QStringList &env);

int cancelNext();
private slots:
void finished(int exitCode, QProcess::ExitStatus exitStatus);
signals:
Expand Down
92 changes: 81 additions & 11 deletions src/imitatepass.cpp
Expand Up @@ -3,6 +3,8 @@
#include "qtpasssettings.h"
#include <QDirIterator>

using namespace Enums;

/**
* @brief ImitatePass::ImitatePass for situaions when pass is not available
* we imitate the behavior of pass https://www.passwordstore.org/
Expand Down Expand Up @@ -57,6 +59,7 @@ void ImitatePass::Show(QString file) {
*/
void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
file = file + ".gpg";
transactionHelper trans(this, PASS_INSERT);
QStringList recipients = Pass::getRecipientList(file);
if (recipients.isEmpty()) {
// TODO(bezet): probably throw here
Expand All @@ -80,8 +83,8 @@ void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
executeGit(GIT_ADD, {"add", file});
QString path = QDir(QtPassSettings::getPassStore()).relativeFilePath(file);
path.replace(QRegExp("\\.gpg$"), "");
QString msg = QString(overwrite ? "Edit" : "\"Add") + " for " + path +
" using QtPass.";
QString msg =
QString(overwrite ? "Edit" : "Add") + " for " + path + " using QtPass.";
GitCommit(file, msg);
}
}
Expand All @@ -97,10 +100,11 @@ void ImitatePass::GitCommit(const QString &file, const QString &msg) {
}

/**
* @brief ImitatePass::Remove git init wrapper
* @brief ImitatePass::Remove custom implementation of "pass remove"
*/
void ImitatePass::Remove(QString file, bool isDir) {
file = QtPassSettings::getPassStore() + file;
transactionHelper trans(this, PASS_REMOVE);
if (!isDir)
file += ".gpg";
if (QtPassSettings::isUseGit()) {
Expand Down Expand Up @@ -132,6 +136,7 @@ void ImitatePass::Init(QString path, const QList<UserInfo> &users) {
QString gpgIdFile = path + ".gpg-id";
QFile gpgId(gpgIdFile);
bool addFile = false;
transactionHelper trans(this, PASS_INIT);
if (QtPassSettings::isAddGPGId(true)) {
QFileInfo checkFile(gpgIdFile);
if (!checkFile.exists() || !checkFile.isFile())
Expand Down Expand Up @@ -290,6 +295,7 @@ void ImitatePass::reencryptPath(QString dir) {
}
if (QtPassSettings::isAutoPush()) {
emit statusMsg(tr("Updating password-store"), 2000);
// TODO(bezet): this is non-blocking and shall be done outside
GitPush();
}
emit endReencryptPath();
Expand All @@ -298,6 +304,7 @@ void ImitatePass::reencryptPath(QString dir) {
void ImitatePass::Move(const QString src, const QString dest,
const bool force) {
QFileInfo destFileInfo(dest);
transactionHelper trans(this, PASS_MOVE);
if (QtPassSettings::isUseGit()) {
QStringList args;
args << "mv";
Expand All @@ -311,10 +318,6 @@ void ImitatePass::Move(const QString src, const QString dest,
QString message = QString("moved from %1 to %2 using QTPass.");
message = message.arg(src).arg(dest);
GitCommit("", message);
if (QtPassSettings::isAutoPush()) {
GitPush();
}

} else {
QDir qDir;
QFileInfo srcFileInfo(src);
Expand All @@ -339,6 +342,7 @@ void ImitatePass::Move(const QString src, const QString dest,
void ImitatePass::Copy(const QString src, const QString dest,
const bool force) {
QFileInfo destFileInfo(dest);
transactionHelper trans(this, PASS_COPY);
if (QtPassSettings::isUseGit()) {
QStringList args;
args << "cp";
Expand All @@ -352,10 +356,6 @@ void ImitatePass::Copy(const QString src, const QString dest,
QString message = QString("copied from %1 to %2 using QTPass.");
message = message.arg(src).arg(dest);
GitCommit("", message);
if (QtPassSettings::isAutoPush()) {
GitPush();
}

} else {
QDir qDir;
if (force) {
Expand All @@ -370,3 +370,73 @@ void ImitatePass::Copy(const QString src, const QString dest,
reencryptPath(destFileInfo.dir().path());
}
}

/**
* @brief ImitatePass::executeGpg easy wrapper for running gpg commands
* @param args
*/
void ImitatePass::executeGpg(PROCESS id, const QStringList &args, QString input,
bool readStdout, bool readStderr) {
executeWrapper(id, QtPassSettings::getGpgExecutable(), args, input,
readStdout, readStderr);
}
/**
* @brief ImitatePass::executeGit easy wrapper for running git commands
* @param args
*/
void ImitatePass::executeGit(PROCESS id, const QStringList &args, QString input,
bool readStdout, bool readStderr) {
executeWrapper(id, QtPassSettings::getGitExecutable(), args, input,
readStdout, readStderr);
}

/**
* @brief ImitatePass::finished this function is overloaded to ensure
* identical behaviour to RealPass ie. only PASS_*
* processes are visible inside Pass::finish, so
* that interface-wise it all looks the same
* @param id
* @param exitCode
* @param out
* @param err
*/
void ImitatePass::finished(int id, int exitCode, const QString &out,
const QString &err) {
dbg() << "Imitate Pass";
static QString transactionOutput;
PROCESS pid = transactionIsOver(static_cast<PROCESS>(id));
transactionOutput.append(out);

if (exitCode == 0) {
if (pid == INVALID)
return;
} else {
while (pid == INVALID) {
id = exec.cancelNext();
if (id == -1) {
// this is probably irrecoverable and shall not happen
dbg() << "No such transaction!";
return;
}
pid = transactionIsOver(static_cast<PROCESS>(id));
}
}
Pass::finished(pid, exitCode, transactionOutput, err);
transactionOutput.clear();
}

/**
* @brief executeWrapper overrided so that every execution is a transaction
* @param id
* @param app
* @param args
* @param input
* @param readStdout
* @param readStderr
*/
void ImitatePass::executeWrapper(PROCESS id, const QString &app,
const QStringList &args, QString input,
bool readStdout, bool readStderr) {
transactionAdd(id);
Pass::executeWrapper(id, app, args, input, readStdout, readStderr);
}
36 changes: 29 additions & 7 deletions src/imitatepass.h
Expand Up @@ -2,24 +2,46 @@
#define IMITATEPASS_H

#include "pass.h"
#include "simpletransaction.h"

/*!
\class ImitatePass
\brief Imitates pass features when pass is not enabled or available
*/
class ImitatePass : public Pass {
class ImitatePass : public Pass, private simpleTransaction {
Q_OBJECT

bool removeDir(const QString &dirName);

void executeWrapper(int id, const QString &app, const QStringList &args,
bool readStdout = true, bool readStderr = true);
void GitCommit(const QString &file, const QString &msg);

void executeWrapper(int id, const QString &app, const QStringList &args,
QString input, bool readStdout = true,
bool readStderr = true);
void executeGit(PROCESS id, const QStringList &args,
QString input = QString(), bool readStdout = true,
bool readStderr = true);
void executeGpg(PROCESS id, const QStringList &args,
QString input = QString(), bool readStdout = true,
bool readStderr = true);

void GitCommit(const QString &file, const QString &msg);
class transactionHelper {
simpleTransaction *m_transaction;
PROCESS m_result;

public:
transactionHelper(simpleTransaction *trans, PROCESS result)
: m_transaction(trans), m_result(result) {
m_transaction->transactionStart();
}
~transactionHelper() { m_transaction->transactionEnd(m_result); }
};

protected:
virtual void finished(int id, int exitCode, const QString &out,
const QString &err) Q_DECL_OVERRIDE;

virtual void executeWrapper(PROCESS id, const QString &app,
const QStringList &args, QString input,
bool readStdout = true,
bool readStderr = true) Q_DECL_OVERRIDE;

public:
ImitatePass();
Expand Down