diff --git a/.gitignore b/.gitignore index a641ca336..0121d8d18 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ ui_*.h localization/*.qm build/ .idea +.vscode diff --git a/src/configdialog.cpp b/src/configdialog.cpp index e7ba895e5..92a900538 100644 --- a/src/configdialog.cpp +++ b/src/configdialog.cpp @@ -45,6 +45,11 @@ ConfigDialog::ConfigDialog(MainWindow *parent) ui->checkBoxAutoPush->setChecked(QtPassSettings::isAutoPush()); ui->checkBoxAlwaysOnTop->setChecked(QtPassSettings::isAlwaysOnTop()); + #if defined(Q_OS_WIN ) || defined(__APPLE__) + ui->checkBoxUseOtp->hide(); + ui->label_10->hide(); + #endif + setProfiles(QtPassSettings::getProfiles(), QtPassSettings::getProfile()); setPwgenPath(QtPassSettings::getPwgenExecutable()); setPasswordConfiguration(QtPassSettings::getPasswordConfiguration()); @@ -54,6 +59,7 @@ ConfigDialog::ConfigDialog(MainWindow *parent) useAutoclearPanel(QtPassSettings::isUseAutoclearPanel()); useTrayIcon(QtPassSettings::isUseTrayIcon()); useGit(QtPassSettings::isUseGit()); + useOtp(QtPassSettings::isUseOtp()); usePwgen(QtPassSettings::isUsePwgen()); useTemplate(QtPassSettings::isUseTemplate()); @@ -137,6 +143,7 @@ void ConfigDialog::on_accepted() { QtPassSettings::setStartMinimized(ui->checkBoxStartMinimized->isChecked()); QtPassSettings::setProfiles(getProfiles()); QtPassSettings::setUseGit(ui->checkBoxUseGit->isChecked()); + QtPassSettings::setUseOtp(ui->checkBoxUseOtp->isChecked()); QtPassSettings::setPwgenExecutable(ui->pwgenPath->text()); QtPassSettings::setUsePwgen(ui->checkBoxUsePwgen->isChecked()); QtPassSettings::setAvoidCapitals(ui->checkBoxAvoidCapitals->isChecked()); @@ -558,6 +565,14 @@ void ConfigDialog::useGit(bool useGit) { on_checkBoxUseGit_clicked(); } +/** + * @brief ConfigDialog::useOtp set preference for using otp plugin. + * @param useOtp + */ +void ConfigDialog::useOtp(bool useOtp) { + ui->checkBoxUseOtp->setChecked(useOtp); +} + /** * @brief ConfigDialog::on_checkBoxUseGit_clicked enable or disable related * checkboxes. diff --git a/src/configdialog.h b/src/configdialog.h index af1767dfa..4db4f24cb 100644 --- a/src/configdialog.h +++ b/src/configdialog.h @@ -36,6 +36,7 @@ class ConfigDialog : public QDialog { bool hideOnClose(); void useTrayIcon(bool useTrayIdon); void useGit(bool useGit); + void useOtp(bool useOtp); void setPwgenPath(QString); void usePwgen(bool usePwgen); void setPasswordConfiguration(const PasswordConfiguration &config); diff --git a/src/configdialog.ui b/src/configdialog.ui index 5c7d3b5e1..80ae5da63 100644 --- a/src/configdialog.ui +++ b/src/configdialog.ui @@ -502,6 +502,37 @@ + + + + + + + 75 + true + + + + Extensions: + + + + + + + + + true + + + Use pass otp extension + + + + + + + diff --git a/src/enums.h b/src/enums.h index 49014bba2..1551cb778 100644 --- a/src/enums.h +++ b/src/enums.h @@ -30,7 +30,8 @@ enum PROCESS { GIT_MOVE, GIT_COPY, PROCESS_COUNT, - INVALID + INVALID, + PASS_OTP_GENERATE, }; } // namespace Enums diff --git a/src/imitatepass.cpp b/src/imitatepass.cpp index 9a9b7e6f3..783fb250a 100644 --- a/src/imitatepass.cpp +++ b/src/imitatepass.cpp @@ -42,14 +42,19 @@ void ImitatePass::GitPush() { /** * @brief ImitatePass::Show shows content of file */ - void ImitatePass::Show(QString file) { file = QtPassSettings::getPassStore() + file + ".gpg"; QStringList args = {"-d", "--quiet", "--yes", "--no-encrypt-to", "--batch", "--use-agent", file}; executeGpg(PASS_SHOW, args); + } +/** + * @brief ImitatePass::OtpGenerate generates an otp code + */ +void ImitatePass::OtpGenerate(QString file) {} + /** * @brief ImitatePass::Insert create new file with encrypted content * diff --git a/src/imitatepass.h b/src/imitatepass.h index 32f5a6397..7c402aa6e 100644 --- a/src/imitatepass.h +++ b/src/imitatepass.h @@ -51,6 +51,7 @@ class ImitatePass : public Pass, private simpleTransaction { virtual void GitPull_b() Q_DECL_OVERRIDE; virtual void GitPush() Q_DECL_OVERRIDE; virtual void Show(QString file) Q_DECL_OVERRIDE; + virtual void OtpGenerate(QString file) Q_DECL_OVERRIDE; virtual void Insert(QString file, QString value, bool overwrite = false) Q_DECL_OVERRIDE; virtual void Remove(QString file, bool isDir = false) Q_DECL_OVERRIDE; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bc913ccf7..e894b3122 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -103,6 +103,7 @@ void MainWindow::initToolBarButtons() { connect(ui->actionUpdate, SIGNAL(triggered()), this, SLOT(onUpdate())); connect(ui->actionUsers, SIGNAL(triggered()), this, SLOT(onUsers())); connect(ui->actionConfig, SIGNAL(triggered()), this, SLOT(onConfig())); + connect(ui->actionOtp, SIGNAL(triggered()), this, SLOT(onOtp())); ui->actionAddPassword->setIcon( QIcon::fromTheme("document-new", QIcon(":/icons/document-new.svg"))); @@ -196,6 +197,7 @@ void MainWindow::connectPassSignalHandlers(Pass *pass) { connect(pass, &Pass::finishedGitPull, this, &MainWindow::processFinished); connect(pass, &Pass::finishedGitPush, this, &MainWindow::processFinished); connect(pass, &Pass::finishedShow, this, &MainWindow::passShowHandler); + connect(pass, &Pass::finishedOtpGenerate, this, &MainWindow::passOtpHandler); connect(pass, &Pass::finishedInsert, this, &MainWindow::finishedInsert); connect(pass, &Pass::finishedRemove, this, &MainWindow::passStoreChanged); connect(pass, &Pass::finishedInit, this, &MainWindow::passStoreChanged); @@ -377,6 +379,7 @@ bool MainWindow::checkConfig() { QtPassSettings::getAutoclearPanelSeconds()); clearClipboardTimer.setInterval(1000 * QtPassSettings::getAutoclearSeconds()); updateGitButtonVisibility(); + updateOtpButtonVisibility(); startupPhase = false; return true; @@ -419,6 +422,7 @@ void MainWindow::config() { QtPassSettings::getAutoclearSeconds()); updateGitButtonVisibility(); + updateOtpButtonVisibility(); if (QtPassSettings::isUseTrayIcon() && tray == NULL) initTrayIcon(); else if (!QtPassSettings::isUseTrayIcon() && tray != NULL) { @@ -592,6 +596,17 @@ void MainWindow::passShowHandler(const QString &p_output) { enableUiElements(true); } +void MainWindow::passOtpHandler(const QString &p_output) { + if (!p_output.isEmpty()) { + addToGridLayout(ui->gridLayout->count()+1, tr("OTP Code"), p_output); + copyTextToClipboard(p_output); + } + if (QtPassSettings::isUseAutoclearPanel()) { + clearPanelTimer.start(); + } + enableUiElements(true); +} + void MainWindow::passStoreChanged(const QString &p_out, const QString &p_err) { processFinished(p_out, p_err); doGitPush(); @@ -723,6 +738,7 @@ void MainWindow::enableUiElements(bool state) { ui->actionDelete->setEnabled(state); ui->actionEdit->setEnabled(state); updateGitButtonVisibility(); + updateOtpButtonVisibility(); } void MainWindow::restoreWindow() { @@ -915,6 +931,17 @@ void MainWindow::onDelete() { QtPassSettings::getPass()->Remove(file, isDir); } +/** + * @brief MainWindow::onOTP try and generate (selected) OTP code. + */ +void MainWindow::onOtp() { + QString file = getFile(ui->treeView->currentIndex(), true); + if (!file.isEmpty()) { + if (QtPassSettings::isUseOtp()) + QtPassSettings::getPass()->OtpGenerate(file); + } +} + /** * @brief MainWindow::onEdit try and edit (selected) password. */ @@ -1428,6 +1455,16 @@ void MainWindow::updateGitButtonVisibility() { } } +void MainWindow::updateOtpButtonVisibility() { + #if defined(Q_OS_WIN ) || defined(__APPLE__) + ui->actionOtp->setVisible(false); + #endif + if (!QtPassSettings::isUseOtp()) + ui->actionOtp->setEnabled(false); + else + ui->actionOtp->setEnabled(true); +} + void MainWindow::enableGitButtons(const bool &state) { // Following GNOME guidelines is preferable disable buttons instead of hide ui->actionPush->setEnabled(state); diff --git a/src/mainwindow.h b/src/mainwindow.h index d93e3b855..ab8911bb6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -63,6 +63,7 @@ private slots: void addFolder(); void onEdit(); void onDelete(); + void onOtp(); void onPush(); void onUpdate(bool block = false); void onUsers(); @@ -92,6 +93,7 @@ private slots: void endReencryptPath(); void critical(QString, QString); void passShowHandler(const QString &); + void passOtpHandler(const QString &); void passStoreChanged(const QString &, const QString &); void doGitPush(); @@ -139,6 +141,7 @@ private slots: void connectPassSignalHandlers(Pass *pass); void updateGitButtonVisibility(); + void updateOtpButtonVisibility(); void enableGitButtons(const bool &); }; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 65a6747b5..574a3254d 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -319,6 +319,7 @@ p, li { white-space: pre-wrap; } + @@ -361,6 +362,17 @@ p, li { white-space: pre-wrap; } Delete + + + OTP + + + Generate OTP and copy to clipboard + + + Ctrl+G + + Push diff --git a/src/pass.cpp b/src/pass.cpp index 99216c54c..24b371c42 100644 --- a/src/pass.cpp +++ b/src/pass.cpp @@ -181,6 +181,9 @@ void Pass::finished(int id, int exitCode, const QString &out, case PASS_SHOW: emit finishedShow(out); break; + case PASS_OTP_GENERATE: + emit finishedOtpGenerate(out); + break; case PASS_INSERT: emit finishedInsert(out, err); break; diff --git a/src/pass.h b/src/pass.h index 25f246cc3..ed1b08c5f 100644 --- a/src/pass.h +++ b/src/pass.h @@ -43,6 +43,7 @@ class Pass : public QObject { virtual void GitPull_b() = 0; virtual void GitPush() = 0; virtual void Show(QString file) = 0; + virtual void OtpGenerate(QString file) = 0; virtual void Insert(QString file, QString value, bool force) = 0; virtual void Remove(QString file, bool isDir) = 0; virtual void Move(const QString srcDir, const QString dest, @@ -87,6 +88,7 @@ protected slots: void finishedGitPull(const QString &, const QString &); void finishedGitPush(const QString &, const QString &); void finishedShow(const QString &); + void finishedOtpGenerate(const QString &); void finishedInsert(const QString &, const QString &); void finishedRemove(const QString &, const QString &); void finishedInit(const QString &, const QString &); diff --git a/src/qtpasssettings.cpp b/src/qtpasssettings.cpp index ab1400f55..14b0c2508 100644 --- a/src/qtpasssettings.cpp +++ b/src/qtpasssettings.cpp @@ -380,6 +380,14 @@ void QtPassSettings::setUseGit(const bool &useGit) { getInstance()->setValue(SettingsConstants::useGit, useGit); } +bool QtPassSettings::isUseOtp(const bool &defaultValue) { + return getInstance()->value(SettingsConstants::useOtp, defaultValue).toBool(); +} + +void QtPassSettings::setUseOtp(const bool &useOtp) { + getInstance()->setValue(SettingsConstants::useOtp, useOtp); +} + bool QtPassSettings::isUsePwgen(const bool &defaultValue) { return getInstance() ->value(SettingsConstants::usePwgen, defaultValue) diff --git a/src/qtpasssettings.h b/src/qtpasssettings.h index 197f80c5b..5d7872777 100644 --- a/src/qtpasssettings.h +++ b/src/qtpasssettings.h @@ -141,6 +141,9 @@ class QtPassSettings : public QSettings { static bool isUseGit(const bool &defaultValue = QVariant().toBool()); static void setUseGit(const bool &useGit); + static bool isUseOtp(const bool &defaultValue = QVariant().toBool()); + static void setUseOtp(const bool &useOtp); + static bool isUsePwgen(const bool &defaultValue = QVariant().toBool()); static void setUsePwgen(const bool &usePwgen); diff --git a/src/realpass.cpp b/src/realpass.cpp index 5684eccd9..798ebb83e 100644 --- a/src/realpass.cpp +++ b/src/realpass.cpp @@ -44,6 +44,15 @@ void RealPass::Show(QString file) { executePass(PASS_SHOW, {"show", file}, "", true); } +/** + * @brief RealPass::OtpGenerate pass otp + * @param file file containig OTP uri + */ +void RealPass::OtpGenerate(QString file) { + executePass(PASS_OTP_GENERATE, {"otp", file}, "", true); +} + + /** * @brief RealPass::Insert pass insert */ diff --git a/src/realpass.h b/src/realpass.h index 2c17a0f25..abf96f1a4 100644 --- a/src/realpass.h +++ b/src/realpass.h @@ -20,6 +20,7 @@ class RealPass : public Pass { virtual void GitPull_b() Q_DECL_OVERRIDE; virtual void GitPush() Q_DECL_OVERRIDE; virtual void Show(QString file) Q_DECL_OVERRIDE; + virtual void OtpGenerate(QString file) Q_DECL_OVERRIDE; virtual void Insert(QString file, QString value, bool overwrite = false) Q_DECL_OVERRIDE; virtual void Remove(QString file, bool isDir = false) Q_DECL_OVERRIDE; diff --git a/src/settingsconstants.cpp b/src/settingsconstants.cpp index 8b8c31cef..066931f31 100644 --- a/src/settingsconstants.cpp +++ b/src/settingsconstants.cpp @@ -43,6 +43,7 @@ const QString SettingsConstants::webDavPassword = "webDavPassword"; const QString SettingsConstants::profile = "profile"; const QString SettingsConstants::groupProfiles = "profiles"; const QString SettingsConstants::useGit = "useGit"; +const QString SettingsConstants::useOtp = "useOtp"; const QString SettingsConstants::useClipboard = "useClipboard"; const QString SettingsConstants::usePwgen = "usePwgen"; const QString SettingsConstants::avoidCapitals = "avoidCapitals"; diff --git a/src/settingsconstants.h b/src/settingsconstants.h index 0f436085a..1b719c8ef 100644 --- a/src/settingsconstants.h +++ b/src/settingsconstants.h @@ -40,6 +40,7 @@ class SettingsConstants { const static QString profile; const static QString groupProfiles; const static QString useGit; + const static QString useOtp; const static QString useClipboard; const static QString usePwgen; const static QString avoidCapitals;