summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--imitatepass.cpp286
-rw-r--r--imitatepass.h6
-rw-r--r--mainwindow.cpp725
-rw-r--r--mainwindow.h45
-rw-r--r--pass.cpp304
-rw-r--r--pass.h52
-rw-r--r--qtpass.pro11
-rw-r--r--realpass.cpp87
8 files changed, 904 insertions, 612 deletions
diff --git a/imitatepass.cpp b/imitatepass.cpp
new file mode 100644
index 00000000..74131247
--- /dev/null
+++ b/imitatepass.cpp
@@ -0,0 +1,286 @@
+#include "imitatepass.h"
+#include "mainwindow.h"
+#include "qtpasssettings.h"
+
+ImitatePass::ImitatePass()
+{
+
+}
+
+/**
+ * @brief ImitatePass::GitInit git init wrapper
+ */
+void ImitatePass::GitInit() {
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "init \"" + QtPassSettings::getPassStore() + '"');
+}
+
+/**
+ * @brief ImitatePass::GitPull git init wrapper
+ */
+void ImitatePass::GitPull() {
+ executeWrapper(QtPassSettings::getGitExecutable(), "pull");
+}
+
+/**
+ * @brief ImitatePass::GitPush git init wrapper
+ */
+void ImitatePass::GitPush() {
+ executeWrapper(QtPassSettings::getGitExecutable(), "push");
+}
+
+/**
+ * @brief ImitatePass::Show git init wrapper
+ */
+QProcess::ExitStatus ImitatePass::Show(QString file, bool block) {
+ // TODO(bezet): apparently not yet needed
+ // file += ".gpg";
+ executeWrapper(QtPassSettings::getGpgExecutable(),
+ "-d --quiet --yes --no-encrypt-to --batch --use-agent \"" +
+ file + '"');
+ if(block)
+ return waitForProcess();
+ return QProcess::NormalExit;
+}
+
+/**
+ * @brief ImitatePass::Insert git init wrapper
+ *
+ * @param file file to be created
+ * @param value value to be stored in file
+ * @param overwrite whether to overwrite existing file
+ */
+void ImitatePass::Insert(QString file, QString newValue, bool overwrite) {
+ file += ".gpg";
+ // TODO(bezet): getRecipientString is in MainWindow for now - fix this ;)
+ QString recipients = Pass::getRecipientString(file, " -r ");
+ if (recipients.isEmpty()) {
+ // TODO(bezet): probably throw here
+ emit critical(tr("Can not edit"),
+ tr("Could not read encryption key to use, .gpg-id "
+ "file missing or invalid."));
+ return;
+ }
+ QString force(overwrite ? " --yes " : " ");
+ executeWrapper(QtPassSettings::getGpgExecutable(),
+ force + "--batch -eq --output \"" + file + "\" " +
+ recipients + " -",
+ newValue);
+ if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit()) {
+ if (!overwrite)
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "add \"" + file + '"');
+ QString path =
+ QDir(QtPassSettings::getPassStore()).relativeFilePath(file);
+ path.replace(QRegExp("\\.gpg$"), "");
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "commit \"" + file + "\" -m \"" +
+ (overwrite ? "Edit" : "Add") + " for " + path +
+ " using QtPass.\"");
+ }
+}
+
+/**
+ * @brief ImitatePass::Remove git init wrapper
+ */
+void ImitatePass::Remove(QString file, bool isDir) {
+ if (QtPassSettings::isUseGit()) {
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ QString("rm ") + (isDir?"-rf ":"-f ") + '"' + file + '"');
+ // TODO(bezet): commit message used to have pass-like file name inside(ie. getFile(file, true)
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "commit \"" + file + "\" -m \"Remove for " +
+ file +
+ " using QtPass.\"");
+ } else {
+ if(isDir) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ QDir dir(file);
+ dir.removeRecursively();
+#else
+ removeDir(QtPassSettings::getPassStore() + file);
+#endif
+ } else
+ QFile(file).remove();
+ }
+}
+
+/**
+ * @brief ImitatePass::Init initialize pass repository
+ *
+ * @param path path in which new password-store will be created
+ * @param users list of users who shall be able to decrypt passwords in path
+ */
+void ImitatePass::Init(QString path, const QList<UserInfo> &users) {
+ QString gpgIdFile = path + ".gpg-id";
+ QFile gpgId(gpgIdFile);
+ bool addFile = false;
+ if (QtPassSettings::isAddGPGId(true)) {
+ QFileInfo checkFile(gpgIdFile);
+ if (!checkFile.exists() || !checkFile.isFile())
+ addFile = true;
+ }
+ if (!gpgId.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ emit critical(tr("Cannot update"),
+ tr("Failed to open .gpg-id for writing."));
+ return;
+ }
+ bool secret_selected = false;
+ foreach (const UserInfo &user, users) {
+ if (user.enabled) {
+ gpgId.write((user.key_id + "\n").toUtf8());
+ secret_selected |= user.have_secret;
+ }
+ }
+ gpgId.close();
+ if (!secret_selected) {
+ emit critical(tr("Check selected users!"),
+ tr("None of the selected keys have a secret key available.\n"
+ "You will not be able to decrypt any newly added passwords!"));
+ return;
+ }
+
+ if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit() &&
+ !QtPassSettings::getGitExecutable().isEmpty()) {
+ if (addFile)
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "add \"" + gpgIdFile + '"');
+ QString path = gpgIdFile;
+ path.replace(QRegExp("\\.gpg$"), "");
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "commit \"" + gpgIdFile + "\" -m \"Added " + path +
+ " using QtPass.\"");
+ }
+ reencryptPath(path);
+}
+
+/**
+ * @brief ImitatePass::removeDir delete folder recursive.
+ * @param dirName which folder.
+ * @return was removal succesful?
+ */
+bool ImitatePass::removeDir(const QString &dirName) {
+ bool result = true;
+ QDir dir(dirName);
+
+ if (dir.exists(dirName)) {
+ Q_FOREACH (QFileInfo info,
+ dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System |
+ QDir::Hidden | QDir::AllDirs | QDir::Files,
+ QDir::DirsFirst)) {
+ if (info.isDir())
+ result = removeDir(info.absoluteFilePath());
+ else
+ result = QFile::remove(info.absoluteFilePath());
+
+ if (!result)
+ return result;
+ }
+ result = dir.rmdir(dirName);
+ }
+ return result;
+}
+
+/**
+ * @brief MainWindow::reencryptPath reencrypt all files under the chosen
+ * directory
+ *
+ * This is stil quite experimental..
+ * @param dir
+ */
+void ImitatePass::reencryptPath(QString dir) {
+ emit statusMsg(tr("Re-encrypting from folder %1").arg(dir), 3000);
+ emit startReencryptPath();
+ if (QtPassSettings::isAutoPull()) {
+ // TODO(bezet): move statuses inside actions?
+ emit statusMsg(tr("Updating password-store"), 2000);
+ GitPull();
+ }
+ waitFor(50);
+ process.waitForFinished();
+ QDir currentDir;
+ QDirIterator gpgFiles(dir, QStringList() << "*.gpg", QDir::Files,
+ QDirIterator::Subdirectories);
+ QStringList gpgId;
+ while (gpgFiles.hasNext()) {
+ QString fileName = gpgFiles.next();
+ if (gpgFiles.fileInfo().path() != currentDir.path()) {
+ gpgId = getRecipientList(fileName);
+ gpgId.sort();
+ }
+ process.waitForFinished();
+ executeWrapper(QtPassSettings::getGpgExecutable(),
+ "-v --no-secmem-warning "
+ "--no-permission-warning --list-only "
+ "--keyid-format long " +
+ fileName);
+ process.waitForFinished(3000);
+ QStringList actualKeys;
+ QString keys =
+ process.readAllStandardOutput() + process.readAllStandardError();
+ QStringList key = keys.split("\n");
+ QListIterator<QString> itr(key);
+ while (itr.hasNext()) {
+ QString current = itr.next();
+ QStringList cur = current.split(" ");
+ if (cur.length() > 4) {
+ QString actualKey = cur.takeAt(4);
+ if (actualKey.length() == 16) {
+ actualKeys << actualKey;
+ }
+ }
+ }
+ actualKeys.sort();
+ if (actualKeys != gpgId) {
+ // qDebug() << actualKeys << gpgId << getRecipientList(fileName);
+ qDebug() << "reencrypt " << fileName << " for " << gpgId;
+ QString local_lastDecrypt = "Could not decrypt";
+ emit lastDecrypt(local_lastDecrypt);
+ executeWrapper(QtPassSettings::getGpgExecutable(),
+ "-d --quiet --yes --no-encrypt-to --batch --use-agent \"" +
+ fileName + '"');
+ process.waitForFinished(30000); // long wait (passphrase stuff)
+ local_lastDecrypt = process.readAllStandardOutput();
+ emit lastDecrypt(local_lastDecrypt);
+
+ if (!local_lastDecrypt.isEmpty() && local_lastDecrypt != "Could not decrypt") {
+ if (local_lastDecrypt.right(1) != "\n")
+ local_lastDecrypt += "\n";
+
+ emit lastDecrypt(local_lastDecrypt);
+ QString recipients = getRecipientString(fileName, " -r ");
+ if (recipients.isEmpty()) {
+ emit critical(tr("Can not edit"),
+ tr("Could not read encryption key to use, .gpg-id "
+ "file missing or invalid."));
+ return;
+ }
+ executeWrapper(QtPassSettings::getGpgExecutable(),
+ "--yes --batch -eq --output \"" + fileName + "\" " +
+ recipients + " -",
+ local_lastDecrypt);
+ process.waitForFinished(3000);
+
+ if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit()) {
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "add \"" + fileName + '"');
+ QString path =
+ QDir(QtPassSettings::getPassStore()).relativeFilePath(fileName);
+ path.replace(QRegExp("\\.gpg$"), "");
+ executeWrapper(QtPassSettings::getGitExecutable(),
+ "commit \"" + fileName + "\" -m \"" + "Edit for " +
+ path + " using QtPass.\"");
+ process.waitForFinished(3000);
+ }
+
+ } else {
+ qDebug() << "Decrypt error on re-encrypt";
+ }
+ }
+ }
+ if (QtPassSettings::isAutoPush()) {
+ emit statusMsg(tr("Updating password-store"), 2000);
+ GitPush();
+ }
+ emit endReencryptPath();
+}
diff --git a/imitatepass.h b/imitatepass.h
index 017671dd..26cb0fab 100644
--- a/imitatepass.h
+++ b/imitatepass.h
@@ -5,6 +5,7 @@
class ImitatePass : public Pass
{
+ Q_OBJECT
bool removeDir(const QString &dirName);
public:
@@ -19,6 +20,11 @@ public:
virtual void Init(QString path, const QList<UserInfo> &list) override;
void reencryptPath(QString dir);
+signals:
+ void startReencryptPath();
+ void endReencryptPath();
+ void lastDecrypt(QString);
+
};
#endif // IMITATEPASS_H
diff --git a/mainwindow.cpp b/mainwindow.cpp
index fdcddea0..4e285b35 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -33,17 +33,43 @@
* @param parent
*/
MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent), ui(new Ui::MainWindow), process(new QProcess(this)),
- fusedav(this), keygen(NULL), tray(NULL) {
+ : QMainWindow(parent), ui(new Ui::MainWindow),
+ fusedav(this), keygen(NULL), tray(NULL), pass(nullptr) {
// connect(process.data(), SIGNAL(readyReadStandardOutput()), this,
// SLOT(readyRead()));
- connect(process.data(), SIGNAL(error(QProcess::ProcessError)), this,
+
+ // TODO(bezet): this should be reconnected dynamically when pass changes
+ connect(&rpass, SIGNAL(error(QProcess::ProcessError)), this,
+ SLOT(processError(QProcess::ProcessError)));
+ connect(&rpass, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+ SLOT(processFinished(int,QProcess::ExitStatus)));
+ connect(&rpass, SIGNAL(startingExecuteWrapper()), this,
+ SLOT(executeWrapperStarted()));
+ connect(&rpass, SIGNAL(statusMsg(QString,int)), this,
+ SLOT(showStatusMessage(QString,int)));
+ connect(&rpass, SIGNAL(critical(QString,QString)), this,
+ SLOT(critical(QString,QString)));
+
+ connect(&ipass, SIGNAL(error(QProcess::ProcessError)), this,
SLOT(processError(QProcess::ProcessError)));
- connect(process.data(), SIGNAL(finished(int, QProcess::ExitStatus)), this,
- SLOT(processFinished(int, QProcess::ExitStatus)));
+ connect(&ipass, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+ SLOT(processFinished(int,QProcess::ExitStatus)));
+ connect(&ipass, SIGNAL(startingExecuteWrapper()), this,
+ SLOT(executeWrapperStarted()));
+ connect(&ipass, SIGNAL(statusMsg(QString,int)), this,
+ SLOT(showStatusMessage(QString,int)));
+ connect(&ipass, SIGNAL(critical(QString,QString)), this,
+ SLOT(critical(QString,QString)));
+ // only for ipass
+ connect(&ipass, SIGNAL(startReencryptPath()), this,
+ SLOT(startReencryptPath()));
+ connect(&ipass, SIGNAL(endReencryptPath()), this,
+ SLOT(endReencryptPath()));
+ connect(&ipass, SIGNAL(lastDecrypt(QString)), this,
+ SLOT(setLastDecrypt(QString)));
+
ui->setupUi(this);
enableUiElements(true);
- wrapperRunning = false;
execQueue = new QQueue<execQueueItem>;
ui->statusBar->showMessage(tr("Welcome to QtPass %1").arg(VERSION), 2000);
freshStart = true;
@@ -319,12 +345,6 @@ bool MainWindow::checkConfig() {
updateProfileBox();
- env = QProcess::systemEnvironment();
- if (!QtPassSettings::getGpgHome().isEmpty()) {
- QDir absHome(QtPassSettings::getGpgHome());
- absHome.makeAbsolute();
- env << "GNUPGHOME=" + absHome.path();
- }
#ifdef __APPLE__
// If it exists, add the gpgtools to PATH
if (QFile("/usr/local/MacGPG2/bin").exists())
@@ -336,7 +356,14 @@ bool MainWindow::checkConfig() {
#endif
// QMessageBox::information(this, "env", env.join("\n"));
- updateEnv();
+ // TODO(bezet): make this check unnecessary
+ if (pass == nullptr) {
+ if (QtPassSettings::isUsePass())
+ pass = &rpass;
+ else
+ pass = &ipass;
+ }
+ pass->updateEnv();
if (!QtPassSettings::isUseGit() ||
(QtPassSettings::getGitExecutable().isEmpty() &&
@@ -366,6 +393,7 @@ void MainWindow::config() {
// Automatically default to pass if it's available
if (freshStart && QFile(QtPassSettings::getPassExecutable()).exists()) {
QtPassSettings::setUsePass(true);
+ pass = &rpass;
}
d->setPassPath(QtPassSettings::getPassExecutable());
@@ -413,6 +441,10 @@ void MainWindow::config() {
QtPassSettings::setPassStore(
Util::normalizeFolderPath(d->getStorePath()));
QtPassSettings::setUsePass(d->usePass());
+ if(d->usePass())
+ pass = &rpass;
+ else
+ pass = &ipass;
QtPassSettings::setClipBoardType(d->useClipboard());
QtPassSettings::setUseAutoclear(d->useAutoclear());
QtPassSettings::setAutoclearSeconds(d->getAutoclear());
@@ -462,7 +494,7 @@ void MainWindow::config() {
if (freshStart && Util::checkConfig())
config();
- updateEnv();
+ pass->updateEnv();
if (!QtPassSettings::isUseGit() ||
(QtPassSettings::getGitExecutable().isEmpty() &&
QtPassSettings::getPassExecutable().isEmpty())) {
@@ -488,13 +520,11 @@ void MainWindow::config() {
/**
* @brief MainWindow::on_updateButton_clicked do a git pull
*/
+// TODO(bezet): add bool block and wait for process to finish
void MainWindow::on_updateButton_clicked() {
ui->statusBar->showMessage(tr("Updating password-store"), 2000);
currentAction = GIT;
- if (QtPassSettings::isUsePass())
- executePass("git pull");
- else
- executeWrapper(QtPassSettings::getGitExecutable(), "pull");
+ pass->GitPull();
}
/**
@@ -503,10 +533,7 @@ void MainWindow::on_updateButton_clicked() {
void MainWindow::on_pushButton_clicked() {
ui->statusBar->showMessage(tr("Updating password-store"), 2000);
currentAction = GIT;
- if (QtPassSettings::isUsePass())
- executePass("git push");
- else
- executeWrapper(QtPassSettings::getGitExecutable(), "push");
+ pass->GitPush();
}
/**
@@ -532,7 +559,7 @@ QString MainWindow::getDir(const QModelIndex &index, bool forPass) {
/**
* @brief MainWindow::getFile get the selected file path
* @param index
- * @param forPass short or full path
+ * @param forPass returns relative path without '.gpg' extension
* @return path
* @return
*/
@@ -563,12 +590,7 @@ void MainWindow::on_treeView_clicked(const QModelIndex &index) {
ui->passwordName->setText(getFile(index, true));
if (!file.isEmpty() && !cleared) {
currentAction = GPG;
- if (QtPassSettings::isUsePass())
- executePass("show \"" + file + '"');
- else
- executeWrapper(QtPassSettings::getGpgExecutable(),
- "-d --quiet --yes --no-encrypt-to --batch --use-agent \"" +
- file + '"');
+ pass->Show(file);
} else {
clearPanel(false);
ui->editButton->setEnabled(false);
@@ -610,68 +632,24 @@ void MainWindow::deselect() {
}
/**
- * @brief MainWindow::executePass easy wrapper for running pass
- * @param args
- */
-void MainWindow::executePass(QString args, QString input) {
- executeWrapper(QtPassSettings::getPassExecutable(), args, input);
-}
-
-/**
* @brief MainWindow::executePassGitInit git init wrapper
*/
void MainWindow::executePassGitInit() {
qDebug() << "Pass git init called";
- if (QtPassSettings::isUsePass())
- executePass("git init");
- else
- executeWrapper(QtPassSettings::getGitExecutable(),
- "init \"" + QtPassSettings::getPassStore() + '"');
+ pass->GitInit();
}
-/**
- * @brief MainWindow::executeWrapper run an application, queue when needed.
- * @param app path to application to run
- * @param args required arguements
- * @param input optional input
- */
-void MainWindow::executeWrapper(QString app, QString args, QString input) {
- // qDebug() << app + " " + args;
- // Happens a lot if e.g. git binary is not set.
- // This will result in bogus "QProcess::FailedToStart" messages,
- // also hiding legitimate errors from the gpg commands.
- if (app.isEmpty()) {
- qDebug() << "Trying to execute nothing..";
- return;
- }
- // Convert to absolute path, just in case
- app = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(app);
- if (wrapperRunning) {
- execQueueItem item;
- item.app = app;
- item.args = args;
- item.input = input;
-
- execQueue->enqueue(item);
- qDebug() << item.app + "," + item.args + "," + item.input;
- return;
- }
- wrapperRunning = true;
- process->setWorkingDirectory(QtPassSettings::getPassStore());
- process->setEnvironment(env);
- clearTemplateWidgets();
- ui->textBrowser->clear();
- ui->textBrowser->setTextColor(Qt::black);
- enableUiElements(false);
- if (autoclearTimer != NULL) {
- autoclearTimer->stop();
- delete autoclearTimer;
- autoclearTimer = NULL;
- }
- process->start('"' + app + "\" " + args);
- if (!input.isEmpty())
- process->write(input.toUtf8());
- process->closeWriteChannel();
+void MainWindow::executeWrapperStarted() {
+ clearTemplateWidgets();
+ ui->textBrowser->clear();
+ ui->textBrowser->setTextColor(Qt::black);
+ enableUiElements(false);
+ if (autoclearTimer != NULL) {
+ autoclearTimer->stop();
+ // TODO(bezet): why dynamic allocation?
+ delete autoclearTimer;
+ autoclearTimer = NULL;
+ }
}
/**
@@ -683,8 +661,8 @@ void MainWindow::readyRead(bool finished = false) {
QString output = "";
QString error = "";
if (currentAction != GPG_INTERNAL) {
- error = process->readAllStandardError();
- QByteArray processOutBytes = process->readAllStandardOutput();
+ error = pass->readAllStandardError();
+ QByteArray processOutBytes = pass->readAllStandardOutput();
QTextCodec *codec = QTextCodec::codecForLocale();
output = codec->toUnicode(processOutBytes);
if (finished && currentAction == GPG) {
@@ -832,16 +810,11 @@ void MainWindow::clearPanel(bool notify = true) {
*/
void MainWindow::processFinished(int exitCode,
QProcess::ExitStatus exitStatus) {
- wrapperRunning = false;
bool error = exitStatus != QProcess::NormalExit || exitCode > 0;
readyRead(true);
enableUiElements(true);
if (!error && currentAction == EDIT)
on_treeView_clicked(ui->treeView->currentIndex());
- if (!execQueue->isEmpty()) {
- execQueueItem item = execQueue->dequeue();
- executeWrapper(item.app, item.args, item.input);
- }
}
/**
@@ -892,7 +865,8 @@ void MainWindow::processError(QProcess::ProcessError error) {
}
ui->textBrowser->setTextColor(Qt::red);
ui->textBrowser->setText(errorString);
- if (process->state() == QProcess::NotRunning)
+ // TODO(bezet): this probably shall be done in finished handler(I guess it finishes even on error)
+ if (pass->state() == QProcess::NotRunning)
enableUiElements(true);
}
@@ -958,58 +932,6 @@ QModelIndex MainWindow::firstFile(QModelIndex parentIndex) {
}
/**
- * @brief MainWindow::getRecipientList return list op gpg-id's to encrypt for
- * @param for_file which file (folder) would you like recepients for
- * @return recepients gpg-id contents
- */
-QStringList MainWindow::getRecipientList(QString for_file) {
- QDir gpgIdPath(QFileInfo(for_file.startsWith(QtPassSettings::getPassStore())
- ? for_file
- : QtPassSettings::getPassStore() + for_file)
- .absoluteDir());
- bool found = false;
- while (gpgIdPath.exists() &&
- gpgIdPath.absolutePath().startsWith(QtPassSettings::getPassStore())) {
- if (QFile(gpgIdPath.absoluteFilePath(".gpg-id")).exists()) {
- found = true;
- break;
- }
- if (!gpgIdPath.cdUp())
- break;
- }
- QFile gpgId(found ? gpgIdPath.absoluteFilePath(".gpg-id")
- : QtPassSettings::getPassStore() + ".gpg-id");
- if (!gpgId.open(QIODevice::ReadOnly | QIODevice::Text))
- return QStringList();
- QStringList recipients;
- while (!gpgId.atEnd()) {
- QString recipient(gpgId.readLine());
- recipient = recipient.trimmed();
- if (!recipient.isEmpty())
- recipients += recipient;
- }
- return recipients;
-}
-
-/**
- * @brief MainWindow::getRecipientString formated string for use with GPG
- * @param for_file which file (folder) would you like recepients for
- * @param separator formating separator eg: " -r "
- * @param count
- * @return recepient string
- */
-QString MainWindow::getRecipientString(QString for_file, QString separator,
- int *count) {
- QString recipients_str;
- QStringList recipients_list = getRecipientList(for_file);
- if (count)
- *count = recipients_list.size();
- foreach (const QString recipient, recipients_list)
- recipients_str += separator + '"' + recipient + '"';
- return recipients_str;
-}
-
-/**
* @brief MainWindow::setPassword open passworddialog and save file (if not
* canceled)
* @param file which pgp file
@@ -1042,37 +964,10 @@ void MainWindow::setPassword(QString file, bool overwrite, bool isNew = false) {
newValue += "\n";
currentAction = EDIT;
- if (QtPassSettings::isUsePass()) {
- QString force(overwrite ? " -f " : " ");
- executePass("insert" + force + "-m \"" + file + '"', newValue);
- } else {
- QString recipients = getRecipientString(file, " -r ");
- if (recipients.isEmpty()) {
- QMessageBox::critical(this, tr("Can not edit"),
- tr("Could not read encryption key to use, .gpg-id "
- "file missing or invalid."));
- return;
- }
- QString force(overwrite ? " --yes " : " ");
- executeWrapper(QtPassSettings::getGpgExecutable(),
- force + "--batch -eq --output \"" + file + "\" " +
- recipients + " -",
- newValue);
- if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit()) {
- if (!overwrite)
- executeWrapper(QtPassSettings::getGitExecutable(),
- "add \"" + file + '"');
- QString path =
- QDir(QtPassSettings::getPassStore()).relativeFilePath(file);
- path.replace(QRegExp("\\.gpg$"), "");
- executeWrapper(QtPassSettings::getGitExecutable(),
- "commit \"" + file + "\" -m \"" +
- (overwrite ? "Edit" : "Add") + " for " + path +
- " using QtPass.\"");
- if (QtPassSettings::isAutoPush())
- on_pushButton_clicked();
- }
- }
+ pass->Insert(file, newValue, overwrite);
+
+ if (QtPassSettings::isUseGit() && QtPassSettings::isAutoPush())
+ on_pushButton_clicked();
}
/**
@@ -1108,8 +1003,6 @@ void MainWindow::on_addButton_clicked() {
if (!ok || file.isEmpty())
return;
file = dir + file;
- if (!QtPassSettings::isUsePass())
- file += ".gpg";
lastDecrypt = "";
setPassword(file, false, true);
}
@@ -1121,108 +1014,32 @@ void MainWindow::on_deleteButton_clicked() {
QFileInfo fileOrFolder =
model.fileInfo(proxyModel.mapToSource(ui->treeView->currentIndex()));
QString file = "";
+ bool isDir = false;
if (fileOrFolder.isFile()) {
file = getFile(ui->treeView->currentIndex(), QtPassSettings::isUsePass());
- if (QMessageBox::question(
- this, tr("Delete password?"),
- tr("Are you sure you want to delete %1?")
- .arg(QDir::separator() +
- getFile(ui->treeView->currentIndex(), true)),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
- return;
- if (QtPassSettings::isUsePass()) {
- currentAction = REMOVE;
- executePass("rm -f \"" + file + '"');
- if (QtPassSettings::isUseGit() && QtPassSettings::isAutoPush())
- on_pushButton_clicked();
- } else {
- if (QtPassSettings::isUseGit()) {
- executeWrapper(QtPassSettings::getGitExecutable(),
- "rm -f \"" + file + '"');
- executeWrapper(QtPassSettings::getGitExecutable(),
- "commit \"" + file + "\" -m \"Remove for " +
- getFile(ui->treeView->currentIndex(), true) +
- " using QtPass.\"");
- if (QtPassSettings::isAutoPush())
- on_pushButton_clicked();
- } else {
- QFile(file).remove();
- }
- }
- } else {
- file = getDir(ui->treeView->currentIndex(), QtPassSettings::isUsePass());
- // TODO: message box should accept enter key
- if (QMessageBox::question(
- this, tr("Delete folder?"),
- tr("Are you sure you want to delete %1?")
- .arg(QDir::separator() +
- getDir(ui->treeView->currentIndex(), true)),
- QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
- return;
- } else {
- if (QtPassSettings::isUsePass()) {
- currentAction = REMOVE;
- executePass("rm -rf \"" + file + '"');
- if (QtPassSettings::isUseGit() && QtPassSettings::isAutoPush()) {
- on_pushButton_clicked();
- }
- } else {
- if (QtPassSettings::isUseGit()) {
- executeWrapper(QtPassSettings::getGitExecutable(),
- "rm -rf \"" + file + '"');
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- QDir dir(file);
- dir.removeRecursively();
-#else
- removeDir(QtPassSettings::getPassStore() + file);
-#endif
- executeWrapper(QtPassSettings::getGitExecutable(),
- "commit \"" + file + "\" -m \"Remove for " +
- getFile(ui->treeView->currentIndex(), true) +
- " using QtPass.\"");
- if (QtPassSettings::isAutoPush()) {
- on_pushButton_clicked();
- }
- } else {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- QDir dir(file);
- dir.removeRecursively();
-#else
- removeDir(QtPassSettings::getPassStore() + file);
-#endif
- }
- }
- }
}
- lastDecrypt = "";
-}
+ else
+ {
+ file = getDir(ui->treeView->currentIndex(), QtPassSettings::isUsePass());
+ isDir = true;
+ }
-/**
- * @brief MainWindow::removeDir delete folder recursive.
- * @param dirName which folder.
- * @return was removal succesful?
- */
-bool MainWindow::removeDir(const QString &dirName) {
- bool result = true;
- QDir dir(dirName);
-
- if (dir.exists(dirName)) {
- Q_FOREACH (QFileInfo info,
- dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System |
- QDir::Hidden | QDir::AllDirs | QDir::Files,
- QDir::DirsFirst)) {
- if (info.isDir())
- result = removeDir(info.absoluteFilePath());
- else
- result = QFile::remove(info.absoluteFilePath());
+ if (QMessageBox::question(
+ this, isDir?tr("Delete folder?"):tr("Delete password?"),
+ tr("Are you sure you want to delete %1?")
+ .arg(QDir::separator() +
+ getFile(ui->treeView->currentIndex(), true)),
+ QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
+ return;
- if (!result)
- return result;
- }
- result = dir.rmdir(dirName);
- }
- return result;
+ currentAction = REMOVE;
+ pass->Remove(file, isDir);
+ // TODO(bezet): hide inside interface?
+ if (QtPassSettings::isUseGit() && QtPassSettings::isAutoPush())
+ on_pushButton_clicked();
+
+ lastDecrypt = "";
}
/**
@@ -1241,50 +1058,6 @@ void MainWindow::on_editButton_clicked() {
}
/**
- * @brief MainWindow::listKeys list users
- * @param keystring
- * @param secret list private keys
- * @return QList<UserInfo> users
- */
-QList<UserInfo> MainWindow::listKeys(QString keystring, bool secret) {
- waitFor(5);
- QList<UserInfo> users;
- currentAction = GPG_INTERNAL;
- QString listopt = secret ? "--list-secret-keys " : "--list-keys ";
- executeWrapper(QtPassSettings::getGpgExecutable(),
- "--no-tty --with-colons " + listopt + keystring);
- process->waitForFinished(2000);
- if (process->exitStatus() != QProcess::NormalExit)
- return users;
- QByteArray processOutBytes = process->readAllStandardOutput();
- QTextCodec *codec = QTextCodec::codecForLocale();
- QString processOutString = codec->toUnicode(processOutBytes);
- QStringList keys = QString(processOutString)
- .split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
- UserInfo current_user;
- foreach (QString key, keys) {
- QStringList props = key.split(':');
- if (props.size() < 10)
- continue;
- if (props[0] == (secret ? "sec" : "pub")) {
- if (!current_user.key_id.isEmpty())
- users.append(current_user);
- current_user = UserInfo();
- current_user.key_id = props[4];
- current_user.name = props[9].toUtf8();
- current_user.validity = props[1][0].toLatin1();
- current_user.created.setTime_t(props[5].toUInt());
- current_user.expiry.setTime_t(props[6].toUInt());
- } else if (current_user.name.isEmpty() && props[0] == "uid") {
- current_user.name = props[9];
- }
- }
- if (!current_user.key_id.isEmpty())
- users.append(current_user);
- return users;
-}
-
-/**
* @brief MainWindow::userDialog see MainWindow::on_usersButton_clicked()
* @param dir folder to edit users for.
*/
@@ -1294,6 +1067,12 @@ void MainWindow::userDialog(QString dir) {
on_usersButton_clicked();
}
+// TODO(bezet): temporary wrapper
+QList<UserInfo> MainWindow::listKeys(QString keystring, bool secret) {
+ currentAction = GPG_INTERNAL;
+ return pass->listKeys(keystring, secret);
+}
+
/**
* @brief MainWindow::on_usersButton_clicked edit users for the current folder,
* gets lists and opens UserDialog.
@@ -1317,7 +1096,7 @@ void MainWindow::on_usersButton_clicked() {
: currentDir;
int count = 0;
QString recipients =
- getRecipientString(dir.isEmpty() ? "" : dir, " ", &count);
+ pass->getRecipientString(dir.isEmpty() ? "" : dir, " ", &count);
if (!recipients.isEmpty())
selected_users = listKeys(recipients);
foreach (const UserInfo &sel, selected_users) {
@@ -1327,7 +1106,7 @@ void MainWindow::on_usersButton_clicked() {
}
if (count > selected_users.size()) {
// Some keys seem missing from keyring, add them separately
- QStringList recipients = getRecipientList(dir.isEmpty() ? "" : dir);
+ QStringList recipients = pass->getRecipientList(dir.isEmpty() ? "" : dir);
foreach (const QString recipient, recipients) {
if (listKeys(recipient).size() < 1) {
UserInfo i;
@@ -1346,64 +1125,10 @@ void MainWindow::on_usersButton_clicked() {
}
d.setUsers(NULL);
- if (QtPassSettings::isUsePass()) {
- QString gpgIds = "";
- foreach (const UserInfo &user, users) {
- if (user.enabled) {
- gpgIds += user.key_id + " ";
- }
- }
- // remove the passStore directory otherwise,
- // pass would create a passStore/passStore/dir
- // but you want passStore/dir
- QString dirWithoutPassdir =
- dir.remove(0, QtPassSettings::getPassStore().size());
- executePass("init --path=" + dirWithoutPassdir + " " + gpgIds);
- } else {
- QString gpgIdFile = dir + ".gpg-id";
- QFile gpgId(gpgIdFile);
- bool addFile = false;
- if (QtPassSettings::isAddGPGId(true)) {
- QFileInfo checkFile(gpgIdFile);
- if (!checkFile.exists() || !checkFile.isFile())
- addFile = true;
- }
- if (!gpgId.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QMessageBox::critical(this, tr("Cannot update"),
- tr("Failed to open .gpg-id for writing."));
- return;
- }
- bool secret_selected = false;
- foreach (const UserInfo &user, users) {
- if (user.enabled) {
- gpgId.write((user.key_id + "\n").toUtf8());
- secret_selected |= user.have_secret;
- }
- }
- gpgId.close();
- if (!secret_selected) {
- QMessageBox::critical(
- this, tr("Check selected users!"),
- tr("None of the selected keys have a secret key available.\n"
- "You will not be able to decrypt any newly added passwords!"));
- }
-
- if (!QtPassSettings::isUseWebDav() && QtPassSettings::isUseGit() &&
- !QtPassSettings::getGitExecutable().isEmpty()) {
- if (addFile)
- executeWrapper(QtPassSettings::getGitExecutable(),
- "add \"" + gpgIdFile + '"');
- QString path = gpgIdFile;
- path.replace(QRegExp("\\.gpg$"), "");
- executeWrapper(QtPassSettings::getGitExecutable(),
- "commit \"" + gpgIdFile + "\" -m \"Added " + path +
- " using QtPass.\"");
- if (QtPassSettings::isAutoPush())
- on_pushButton_clicked();
- }
+ pass->Init(dir, users);
- reencryptPath(dir);
- }
+ if (QtPassSettings::isAutoPush())
+ on_pushButton_clicked();
}