From 2230a4bd61768dc0c7e5a66f2ef076f2154e6c33 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 4 Nov 2018 11:26:20 +0100 Subject: [PATCH] Lot of password related changes all over the place. Password is no longer saved with the connection list. Password is not entered along with other connection credentials. Password is now asked for when required. Still working on saving the password and auto retrieving it from the password manager. --- pglab/BackupDialog.h | 2 +- pglab/ConnectionList.cpp | 74 ++++++++++++----------- pglab/ConnectionList.h | 37 +++++------- pglab/ConnectionListModel.cpp | 30 +++++++++- pglab/ConnectionListModel.h | 5 +- pglab/ConnectionManagerWindow.cpp | 97 +++++++++---------------------- pglab/ConnectionManagerWindow.h | 5 +- pglab/ConnectionManagerWindow.ui | 50 ++++++---------- pglab/MasterController.cpp | 97 ++++++++++++++++++++++++++----- pglab/MasterController.h | 14 ++++- pglab/PassPhraseForm.cpp | 45 ++++++++++++++ pglab/PassPhraseForm.h | 22 +++++++ pglab/PassPhraseForm.ui | 75 ++++++++++++++++++++++++ pglab/PasswordPromptDialog.cpp | 70 ++++++++++++++++++++++ pglab/PasswordPromptDialog.h | 32 ++++++++++ pglab/TablesPage.cpp | 12 ++-- pglab/pglab.pro | 13 +++-- pglablib/ConnectionConfig.cpp | 16 +++++ pglablib/ConnectionConfig.h | 5 ++ pglablib/pglablib.pro | 2 +- readme.md | 0 21 files changed, 508 insertions(+), 195 deletions(-) create mode 100644 pglab/PassPhraseForm.cpp create mode 100644 pglab/PassPhraseForm.h create mode 100644 pglab/PassPhraseForm.ui create mode 100644 pglab/PasswordPromptDialog.cpp create mode 100644 pglab/PasswordPromptDialog.h create mode 100644 readme.md diff --git a/pglab/BackupDialog.h b/pglab/BackupDialog.h index 6ce44dd..d35e82a 100644 --- a/pglab/BackupDialog.h +++ b/pglab/BackupDialog.h @@ -16,7 +16,7 @@ class BackupDialog : public QDialog Q_OBJECT public: - explicit BackupDialog(QWidget *parent = 0); + explicit BackupDialog(QWidget *parent = nullptr); ~BackupDialog(); void ConnectTo(QProcess *process); diff --git a/pglab/ConnectionList.cpp b/pglab/ConnectionList.cpp index c373474..8476b6f 100644 --- a/pglab/ConnectionList.cpp +++ b/pglab/ConnectionList.cpp @@ -1,6 +1,7 @@ #include "ConnectionList.h" #include "ScopeGuard.h" #include "util.h" +#include "PasswordManager.h" #include #include #include @@ -19,31 +20,38 @@ namespace { settings.setValue("hostaddr", stdStrToQ(cc.hostAddr())); settings.setValue("port", cc.port()); settings.setValue("user", stdStrToQ(cc.user())); - settings.setValue("password", stdStrToQ(cc.password())); + //settings.setValue("password", stdStrToQ(cc.password())); settings.setValue("dbname", stdStrToQ(cc.dbname())); - settings.setValue("sslmode", (int)cc.sslMode()); + settings.setValue("sslmode", static_cast(cc.sslMode())); settings.setValue("sslcert", stdStrToQ(cc.sslCert())); settings.setValue("sslkey", stdStrToQ(cc.sslKey())); settings.setValue("sslrootcert", stdStrToQ(cc.sslRootCert())); settings.setValue("sslcrl", stdStrToQ(cc.sslCrl())); } + template + bool in_range(T value) + { + return value >= std::numeric_limits::min() && value <= std::numeric_limits::max(); + } + void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc) { cc.setName(qvarToStdStr(settings.value("name"))); cc.setHost(qvarToStdStr(settings.value("host"))); cc.setHostAddr(qvarToStdStr(settings.value("hostaddr"))); - cc.setPort(settings.value("port", 5432).toInt()); + int p = settings.value("port", 5432).toInt(); + if (!in_range(p)) { + p = 0; // let the user re-enter a valid value + } + + cc.setPort(static_cast(p)); cc.setUser(qvarToStdStr(settings.value("user"))); - // std::string encpw = qvarToStdStr(settings.value("encryptedpw")); - // if (encpw.empty()) { - cc.setPassword(qvarToStdStr(settings.value("password"))); - // } - // else { - // cc.setEncryptedPassword(encpw); - // } + + //cc.setPassword(qvarToStdStr(settings.value("password"))); + cc.setDbname(qvarToStdStr(settings.value("dbname"))); - cc.setSslMode((SslMode)settings.value("sslmode").toInt()); + cc.setSslMode(static_cast(settings.value("sslmode").toInt())); cc.setSslCert(qvarToStdStr(settings.value("sslcert"))); cc.setSslKey(qvarToStdStr(settings.value("sslkey"))); cc.setSslRootCert(qvarToStdStr(settings.value("sslrootcert"))); @@ -69,19 +77,20 @@ QString ConnectionList::iniFileName() ConnectionList::ConnectionList() { - } -int ConnectionList::createNew() +size_t ConnectionList::createNew() { - m_connections.emplace_back(QUuid::createUuid(), ConnectionConfig()); + ConnectionConfig cc; + cc.setUuid(QUuid::createUuid()); + m_connections.push_back(cc); return m_connections.size()-1; } -void ConnectionList::remove(int idx, int count) +void ConnectionList::remove(size_t idx, size_t count) { - auto f = m_connections.begin() + idx; - auto l = f + count; + auto f = m_connections.begin() + static_cast(idx); + auto l = f + static_cast(count); deleteFromIni(f, l); m_connections.erase(f, l); } @@ -91,7 +100,7 @@ void ConnectionList::deleteFromIni(t_Connections::iterator begin, t_Connections: QString file_name = iniFileName(); QSettings settings(file_name, QSettings::IniFormat); for (auto i = begin; i != end; ++i) { - settings.remove(i->m_uuid.toString()); + settings.remove(i->uuid().toString()); } } @@ -111,8 +120,9 @@ void ConnectionList::load() SCOPE_EXIT { settings.endGroup(); }; ConnectionConfig cc; + cc.setUuid(uuid); LoadConnectionConfig(settings, cc); - m_connections.emplace_back(uuid, cc); + m_connections.push_back(cc); } } } @@ -123,26 +133,24 @@ void ConnectionList::save() QString file_name = iniFileName(); QSettings settings(file_name, QSettings::IniFormat); for (auto& e : m_connections) { - settings.beginGroup(e.m_uuid.toString()); + settings.beginGroup(e.uuid().toString()); SCOPE_EXIT { settings.endGroup(); }; - SaveConnectionConfig(settings, e.m_config); - e.m_config.clean(); + SaveConnectionConfig(settings, e); + e.clean(); } settings.sync(); } -void ConnectionList::save(int index) +void ConnectionList::save(size_t index) { - if (index >= 0 && index < (int)m_connections.size()) { - auto& e = m_connections[index]; - if (e.m_config.dirty()) { - QString file_name = iniFileName(); - QSettings settings(file_name, QSettings::IniFormat); - settings.beginGroup(e.m_uuid.toString()); - SaveConnectionConfig(settings, e.m_config); - e.m_config.clean(); - settings.sync(); - } + auto& e = m_connections.at(index); + if (e.dirty()) { + QString file_name = iniFileName(); + QSettings settings(file_name, QSettings::IniFormat); + settings.beginGroup(e.uuid().toString()); + SaveConnectionConfig(settings, e); + e.clean(); + settings.sync(); } } diff --git a/pglab/ConnectionList.h b/pglab/ConnectionList.h index f9ba131..5916fa9 100644 --- a/pglab/ConnectionList.h +++ b/pglab/ConnectionList.h @@ -8,47 +8,42 @@ #include #include "Expected.h" - class ConnectionList { -private: - static QString iniFileName(); - public: ConnectionList(); - int size() const { return m_connections.size(); } + size_t size() const { return m_connections.size(); } - ConnectionConfig& getConfigByIdx(int idx) + ConnectionConfig& getConfigByIdx(size_t idx) { - return m_connections.at(idx).m_config; + return m_connections.at(idx); } - int createNew(); + size_t createNew(); - void remove(int idx, int count); + void remove(size_t idx, size_t count); void load(); void save(); - void save(int index); - + void save(size_t index); private: - class LijstElem { - public: - QUuid m_uuid; - ConnectionConfig m_config; +// class LijstElem { +// public: +// QUuid m_uuid; ///< Unique identifier, used as a key for storing password in psk db. +// ConnectionConfig m_config; - LijstElem(const QUuid id, const ConnectionConfig &cfg) - : m_uuid(id), m_config(cfg) - {} - }; +// LijstElem(const QUuid id, const ConnectionConfig &cfg) +// : m_uuid(id), m_config(cfg) +// {} +// }; - using t_Connections = std::vector; + using t_Connections = std::vector; t_Connections m_connections; void deleteFromIni(t_Connections::iterator begin, t_Connections::iterator end); - + static QString iniFileName(); }; #endif // CONNECTIONLIST_H diff --git a/pglab/ConnectionListModel.cpp b/pglab/ConnectionListModel.cpp index dfb87c2..f1f3649 100644 --- a/pglab/ConnectionListModel.cpp +++ b/pglab/ConnectionListModel.cpp @@ -150,6 +150,27 @@ Expected ConnectionListModel::get(int row) } } + +#include + +template +size_t as_size_t(T t); + +template <> +size_t as_size_t(int t) +{ + BOOST_ASSERT(t >= 0); + return static_cast(t); +} + +template <> +size_t as_size_t(long t) +{ + BOOST_ASSERT(t >= 0); + return static_cast(t); +} + + //void ConnectionListModel::del(const int idx) bool ConnectionListModel::removeRows(int row, int count, const QModelIndex &parent) { @@ -159,7 +180,7 @@ bool ConnectionListModel::removeRows(int row, int count, const QModelIndex &pare beginRemoveRows(parent, row, row + count -1); SCOPE_EXIT { endRemoveRows(); }; - m_connections->remove(row, count); + m_connections->remove(as_size_t(row), as_size_t(count)); result = true; } return result; @@ -176,7 +197,12 @@ void ConnectionListModel::save() m_connections->save(); } -void ConnectionListModel::save(int index) +void ConnectionListModel::save(size_t index) { m_connections->save(index); } + +void ConnectionListModel::save(size_t index, const ConnectionConfig &cc) +{ + +} diff --git a/pglab/ConnectionListModel.h b/pglab/ConnectionListModel.h index 78ce96a..e9cde8d 100644 --- a/pglab/ConnectionListModel.h +++ b/pglab/ConnectionListModel.h @@ -34,13 +34,14 @@ public: virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; void save(); - void save(int index); + void save(size_t index); + void save(size_t index, const ConnectionConfig &cc); + static QString makeLongDescription(const ConnectionConfig &cfg); private: ConnectionList *m_connections; - static QString makeLongDescription(const ConnectionConfig &cfg); }; #endif // CONNECTIONLISTMODEL_H diff --git a/pglab/ConnectionManagerWindow.cpp b/pglab/ConnectionManagerWindow.cpp index 2883c40..42c2e03 100644 --- a/pglab/ConnectionManagerWindow.cpp +++ b/pglab/ConnectionManagerWindow.cpp @@ -7,6 +7,21 @@ #include #include "ConnectionListModel.h" + +#include +#include + +QString pskFileName() +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + QDir dir(path); + if (!dir.exists()) { + dir.mkpath("."); + } + path += "/psk.ini"; + return path; +} + ConnectionManagerWindow::ConnectionManagerWindow(MasterController *master, QWidget *parent) : QMainWindow(parent) , ui(new Ui::ConnectionManagerWindow) @@ -53,9 +68,13 @@ void ConnectionManagerWindow::on_currentChanged(const QModelIndex ¤t, { int currow = current.row(); auto clm = m_masterController->getConnectionListModel(); - clm->save(prevSelection); + if (prevSelection) + clm->save(*prevSelection); m_mapper->setCurrentIndex(currow); - prevSelection = currow; + if (currow >= 0) + prevSelection = static_cast(currow); + else + prevSelection.reset(); } void ConnectionManagerWindow::on_actionDelete_connection_triggered() @@ -82,7 +101,6 @@ void ConnectionManagerWindow::setupWidgetMappings() m_mapper->addMapping(ui->edtHost, 2); m_mapper->addMapping(ui->spinPort, 3); m_mapper->addMapping(ui->edtUser, 4); - m_mapper->addMapping(ui->edtPassword, 5); m_mapper->addMapping(ui->edtDbname, 6); m_mapper->toFirst(); } @@ -90,7 +108,13 @@ void ConnectionManagerWindow::setupWidgetMappings() void ConnectionManagerWindow::on_actionConnect_triggered() { auto ci = ui->listView->selectionModel()->currentIndex(); - m_masterController->openSqlWindowForConnection(ci.row()); + if (ci.isValid()) { + auto r = static_cast(ci.row()); + m_masterController->openSqlWindowForConnection(r); + } + else { + // TODO can we give unobtrusive message why it didn't work? + } } void ConnectionManagerWindow::on_actionQuit_application_triggered() @@ -117,68 +141,3 @@ void ConnectionManagerWindow::on_actionManage_server_triggered() } - -#include -//#include -//#include -//#include -//#include -#include - - -void ConnectionManagerWindow::on_testButton_clicked() -{ - std::string error = Botan::runtime_version_check(BOTAN_VERSION_MAJOR, - BOTAN_VERSION_MINOR, - BOTAN_VERSION_PATCH); - if (error.empty()) { -// Botan::AutoSeeded_RNG rng; -// Botan::secure_vector salt = -// //{ 0x3f, 0x0a, 0xb0, 0x11, 0x44, 0xfe, 0x9d, 0xf7, 0x85, 0xd3, 0x11, 0x38, 0xe2, 0xdf, 0x31, 0x42 }; -// rng.random_vec(16); -// // salt should be random and saved with encrypted data so it can be used when we decrypt - -// std::string password = "Hello kitty"; -// std::unique_ptr pbkdf(Botan::get_pbkdf("PBKDF2(SHA-256)")); -// Botan::OctetString aes256_key = pbkdf->derive_key(32, password, salt.data(), salt.size(), 10000); - -// std::string plaintext("Your great-grandfather gave this watch to your granddad for good luck. Unfortunately, Dane's luck wasn't as good as his old man's."); -// Botan::secure_vector pt(plaintext.data(),plaintext.data()+plaintext.length()); - -// std::unique_ptr enc(Botan::get_cipher_mode("AES-256/CBC/PKCS7", Botan::ENCRYPTION)); -// enc->set_key(aes256_key); - -// //generate fresh nonce (IV) -// //std::unique_ptr rng(new Botan::AutoSeeded_RNG); -// std::vector iv(enc->default_nonce_length()); -// rng.randomize(iv.data(), iv.size()); -// enc->start(iv); -// enc->finish(pt); -// //std::cout << std::endl << enc->name() << " with iv " << Botan::hex_encode(iv) << std::endl << Botan::hex_encode(pt); - - - //std::string s = aes256_key.as_string();// + "\n" + t.format_string(); - - std::string passphrase = "my passphrase"; - std::string plaintext("password1234"); - try { - Botan::AutoSeeded_RNG rng; - std::string encrypted = Botan::CryptoBox::encrypt((const uint8_t*)plaintext.data(), plaintext.length(), passphrase, rng); - - std::string decrypted = Botan::CryptoBox::decrypt(encrypted, passphrase); - - std::string s = encrypted + "\n" + decrypted; - QMessageBox::information(this, "pglab", - QString::fromUtf8(s.c_str()), QMessageBox::Yes); - } - catch (Botan::Decoding_Error &/*e*/) { - QMessageBox::information(this, "pglab", - tr("Failure to decrypt"), QMessageBox::Yes); - - } - } - else { - QMessageBox ::information(this, "pglab", - QString::fromUtf8(error.c_str()), QMessageBox::Yes); - } -} diff --git a/pglab/ConnectionManagerWindow.h b/pglab/ConnectionManagerWindow.h index 7bad733..0821f8e 100644 --- a/pglab/ConnectionManagerWindow.h +++ b/pglab/ConnectionManagerWindow.h @@ -2,6 +2,7 @@ #define CONNECTIONMANAGERWINDOW_H #include +#include namespace Ui { class ConnectionManagerWindow; @@ -30,14 +31,12 @@ private slots: void on_actionBackup_database_triggered(); void on_actionManage_server_triggered(); - void on_testButton_clicked(); - private: Ui::ConnectionManagerWindow *ui; QDataWidgetMapper *m_mapper = nullptr; MasterController *m_masterController; - int prevSelection = -1; + boost::optional prevSelection; void setupWidgetMappings(); }; diff --git a/pglab/ConnectionManagerWindow.ui b/pglab/ConnectionManagerWindow.ui index ea3fd3d..839e9db 100644 --- a/pglab/ConnectionManagerWindow.ui +++ b/pglab/ConnectionManagerWindow.ui @@ -75,30 +75,23 @@ - - - Password - - - - - - - QLineEdit::Password - - - - Database - + - + + + + SSL + + + + 2 @@ -136,53 +129,46 @@ - - - SSL - - - - Certificate - + - + Key - + - + Root cert. - + - + Revocation list - + - + PushButton @@ -201,7 +187,7 @@ 0 0 800 - 25 + 20 diff --git a/pglab/MasterController.cpp b/pglab/MasterController.cpp index 05b1319..79ab6dd 100644 --- a/pglab/MasterController.cpp +++ b/pglab/MasterController.cpp @@ -5,6 +5,7 @@ #include "MainWindow.h" #include "ServerWindow.h" #include "BackupDialog.h" +#include "PasswordPromptDialog.h" MasterController::MasterController(QObject *parent) : QObject(parent) @@ -33,39 +34,103 @@ void MasterController::showConnectionManager() m_connectionManagerWindow->show(); } -void MasterController::openSqlWindowForConnection(int connection_index) +void MasterController::openSqlWindowForConnection(size_t connection_index) { - auto cc = m_connectionListModel->get(connection_index); - m_connectionListModel->save(connection_index); - if (cc.valid()) { - auto w = new MainWindow(this, nullptr); - w->setAttribute( Qt::WA_DeleteOnClose ); - w->setConfig(cc.get()); - w->show(); + + auto res = m_connectionListModel->get(connection_index); + if (res.valid()) { + auto cc = res.get(); + + m_connectionListModel->save(connection_index, cc); + if (retrieveConnectionPassword(cc)) { + // TODO instead of directly openening the mainwindow + // do async connect and only open window when we have + // working connection + auto w = new MainWindow(this, nullptr); + w->setAttribute( Qt::WA_DeleteOnClose ); + w->setConfig(cc); + w->show(); + } } } void MasterController::openBackupDlgForConnection(int connection_index) { - auto cc = m_connectionListModel->get(connection_index); - m_connectionListModel->save(connection_index); - if (cc.valid()) { + auto res = m_connectionListModel->get(connection_index); + if (res.valid()) { + auto cc = res.get(); + retrieveConnectionPassword(cc); + m_connectionListModel->save(connection_index, cc); + auto w = new BackupDialog(nullptr); //new ServerWindow(this, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); - w->setConfig(cc.get()); + w->setConfig(cc); w->show(); } } void MasterController::openServerWindowForConnection(int connection_index) { - auto cc = m_connectionListModel->get(connection_index); - m_connectionListModel->save(connection_index); - if (cc.valid()) { + auto res = m_connectionListModel->get(connection_index); + if (res.valid()) { + auto cc = res.get(); + retrieveConnectionPassword(cc); + m_connectionListModel->save(connection_index, cc); + auto w = new ServerWindow(this, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); - w->setConfig(cc.get()); + w->setConfig(cc); w->show(); } } + + +bool MasterController::retrieveConnectionPassword(ConnectionConfig &cc) +{ + // Look at config + // - is password required, how do we know? + // - IF is password stored in pskdb + // - ask pskdb for password + // - ELSE + // - ask user for password + QString str = ConnectionListModel::makeLongDescription(cc); + auto dlg = std::make_unique(nullptr); + dlg->setConnectionDescription(str); + int exec_result = dlg->exec(); + + if (exec_result == QDialog::Accepted) { + cc.setPassword(dlg->password().toUtf8().data()); + // - IF user checked remember password + // - ask pskdb to store password + + return true; + } + return false; +} + + +bool MasterController::getPasswordFromPskdb(const std::string &password_id, std::string &password) +{ +// func: getPasswordFromPskdb +// IF pskdb locked +// prompt user for pskdb passphrase +// unlock pskdb +// get pwd + return false; +} + + +bool MasterController::storePasswordInPskdb(const std::string &password_id, const std::string password) +{ +// func: storePasswordInPskdb +// IF pskdb not setup +// notify user and ask for passphrase +// init pskdb +// ELSE +// IF pskdb locked +// ask for passphrase +// unlock +// store pwd + return false; +} diff --git a/pglab/MasterController.h b/pglab/MasterController.h index 562e9ee..4a10c9a 100644 --- a/pglab/MasterController.h +++ b/pglab/MasterController.h @@ -16,7 +16,7 @@ class ConnectionManagerWindow; class MasterController : public QObject { Q_OBJECT public: - explicit MasterController(QObject *parent = 0); + explicit MasterController(QObject *parent = nullptr); MasterController(const MasterController&) = delete; MasterController &operator=(const MasterController&) = delete; ~MasterController(); @@ -29,7 +29,7 @@ public: } void showConnectionManager(); - void openSqlWindowForConnection(int connection_index); + void openSqlWindowForConnection(size_t connection_index); void openServerWindowForConnection(int connection_index); void openBackupDlgForConnection(int connection_index); @@ -41,7 +41,15 @@ private: ConnectionList *m_connectionList = nullptr; ConnectionListModel *m_connectionListModel = nullptr; ConnectionManagerWindow *m_connectionManagerWindow = nullptr; - + + /** Retrieves the connection password from the user (directly or through the psk db) + * + */ + bool retrieveConnectionPassword(ConnectionConfig &cc); + + bool getPasswordFromPskdb(const std::string &password_id, std::string &password); + + bool storePasswordInPskdb(const std::string &password_id, const std::string password); }; #endif // MASTERCONTROLLER_H diff --git a/pglab/PassPhraseForm.cpp b/pglab/PassPhraseForm.cpp new file mode 100644 index 0000000..36ff2fa --- /dev/null +++ b/pglab/PassPhraseForm.cpp @@ -0,0 +1,45 @@ +#include "PassPhraseForm.h" +#include "ui_PassPhraseForm.h" + +PassPhraseForm::PassPhraseForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::PassPhraseForm) +{ + ui->setupUi(this); +} + +PassPhraseForm::~PassPhraseForm() +{ + delete ui; +} + +/* + +Password strength calculation: +seperate characters in couple of groups + +For the use of characters from each group a certain value is added to the base value +which is meant to signify the size of the set of characters the password is based on. + +Some analysis of relative positions might be required! Predictable placement of special charachters and uppercase/lowercase or numbers +should be penalized. + +These calculations should result in a search space size per character + +the base to the power of the length of the password gives the resulting strength +from this result we take the 10 log to get the magnitude of the value. + +a-z 1:3 2:7 3:13 4:26 +A-Z 1:3 2:7 3:13 4:26 +0-9 1:4 2:10 +`~!@#$%^&*()_-=+[{]};:'",<.>/?\| 1:4 2:8 3:16 4:32 +space +1 + +Straf punten +alleen speciaal karakter aan eind van string -8 +alleen hoofdletter aan begin van wachtwoord -6 + +la-~ZDv4E-O*y]C +bYGWlDyeKKbcZBjoWX + +*/ diff --git a/pglab/PassPhraseForm.h b/pglab/PassPhraseForm.h new file mode 100644 index 0000000..c0c0f8d --- /dev/null +++ b/pglab/PassPhraseForm.h @@ -0,0 +1,22 @@ +#ifndef PASSPHRASEFORM_H +#define PASSPHRASEFORM_H + +#include + +namespace Ui { +class PassPhraseForm; +} + +class PassPhraseForm : public QWidget +{ + Q_OBJECT + +public: + explicit PassPhraseForm(QWidget *parent = nullptr); + ~PassPhraseForm(); + +private: + Ui::PassPhraseForm *ui; +}; + +#endif // PASSPHRASEFORM_H diff --git a/pglab/PassPhraseForm.ui b/pglab/PassPhraseForm.ui new file mode 100644 index 0000000..89bd22f --- /dev/null +++ b/pglab/PassPhraseForm.ui @@ -0,0 +1,75 @@ + + + PassPhraseForm + + + + 0 + 0 + 397 + 228 + + + + Form + + + false + + + + + + 20 + + + 20 + + + + + Enter passphrase: + + + + + + + 32767 + + + QLineEdit::NoEcho + + + + + + + Repeat passphrase: + + + + + + + QLineEdit::Password + + + + + + + 67 + + + + + + + + + + + + + diff --git a/pglab/PasswordPromptDialog.cpp b/pglab/PasswordPromptDialog.cpp new file mode 100644 index 0000000..0b11759 --- /dev/null +++ b/pglab/PasswordPromptDialog.cpp @@ -0,0 +1,70 @@ +#include "PasswordPromptDialog.h" +#include +#include +#include +#include +#include +#include + +PasswordPromptDialog::PasswordPromptDialog(QWidget *parent) + : QDialog(parent) +{ + m_connectionLabel = new QLabel(this); + auto dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + + m_passwordLabel = new QLabel(this); + m_passwordInput = new QLineEdit(this); + m_passwordInput->setEchoMode(QLineEdit::Password); + + m_saveCheck = new QCheckBox(this); + + + auto mainLayout = new QGridLayout; + int row = 0; + mainLayout->addWidget(m_connectionLabel, row, 0, 1, 2); + ++row; + mainLayout->addWidget(m_passwordLabel, row, 0); + mainLayout->addWidget(m_passwordInput, row, 1); + ++row; + mainLayout->addWidget(m_saveCheck, row, 1); + ++row; + mainLayout->addWidget(dialog_buttons, row, 0, 1 ,2); + setLayout(mainLayout); + + m_passwordInput->setFocus(); + retranslateUi(); + + // QMetaObject::connectSlotsByName(BackupDialog); + connect(dialog_buttons, &QDialogButtonBox::accepted, this, &PasswordPromptDialog::accept); + connect(dialog_buttons, &QDialogButtonBox::rejected, this, &PasswordPromptDialog::reject); +} + +void PasswordPromptDialog::retranslateUi() +{ + const char * context = "PasswordPromptDialog"; + setWindowTitle(QApplication::translate(context, "Connection password", nullptr)); + m_passwordLabel->setText(QApplication::translate(context, "Password", nullptr)); + m_passwordInput->setPlaceholderText(QApplication::translate(context, "Enter password", nullptr)); + m_saveCheck->setText(QApplication::translate(context, "Save password", nullptr)); +} + +void PasswordPromptDialog::setConnectionDescription(const QString &description) +{ + m_connectionLabel->setText(QString(tr("Please provide password for connection %1")).arg(description)); + +} + +QString PasswordPromptDialog::password() const +{ + return m_passwordInput->text(); +} + +//void PasswordPromptDialog::accept() +//{ + +//} + +//void PasswordPromptDialog::reject() +//{ + +//} diff --git a/pglab/PasswordPromptDialog.h b/pglab/PasswordPromptDialog.h new file mode 100644 index 0000000..f394a9e --- /dev/null +++ b/pglab/PasswordPromptDialog.h @@ -0,0 +1,32 @@ +#ifndef PASSWORDPROMPTDIALOG_H +#define PASSWORDPROMPTDIALOG_H + +#include + +class QCheckBox; +class QLabel; +class QLineEdit; + +class PasswordPromptDialog : public QDialog +{ + Q_OBJECT +public: + explicit PasswordPromptDialog(QWidget *parent = nullptr); + + void setConnectionDescription(const QString &description); + + QString password() const; +private: + QLabel *m_connectionLabel = nullptr; + QLabel *m_passwordLabel = nullptr; + QLineEdit *m_passwordInput = nullptr; + QCheckBox *m_saveCheck = nullptr; + + void retranslateUi(); + +private slots: +// void accept(); +// void reject(); +}; + +#endif // PASSWORDPROMPTDIALOG_H diff --git a/pglab/TablesPage.cpp b/pglab/TablesPage.cpp index 81c7c41..a622e07 100644 --- a/pglab/TablesPage.cpp +++ b/pglab/TablesPage.cpp @@ -26,14 +26,10 @@ TablesPage::TablesPage(MainWindow *parent) { ui->setupUi(this); - // WARNING delegates should NOT be shared!!! - auto pglab_delegate = new PgLabItemDelegate(this); - auto icon_delegate = new IconColumnDelegate(this); - SetTableViewDefault(ui->tableListTable); m_tablesModel = new TablesTableModel(this); ui->tableListTable->setModel(m_tablesModel); - ui->tableListTable->setItemDelegate(pglab_delegate); + ui->tableListTable->setItemDelegate(new PgLabItemDelegate(this)); ui->tableListTable->setSortingEnabled(true); ui->tableListTable->sortByColumn(0, Qt::AscendingOrder); ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows); @@ -47,14 +43,14 @@ TablesPage::TablesPage(MainWindow *parent) SetTableViewDefault(ui->constraintsTable); m_constraintModel = new ConstraintModel(this); ui->constraintsTable->setModel(m_constraintModel); - ui->constraintsTable->setItemDelegateForColumn(0, icon_delegate); + ui->constraintsTable->setItemDelegateForColumn(0, new IconColumnDelegate(this)); // Indexes SetTableViewDefault(ui->indexesTable); m_indexModel = new IndexModel(this); ui->indexesTable->setModel(m_indexModel); - ui->indexesTable->setItemDelegate(pglab_delegate); - ui->indexesTable->setItemDelegateForColumn(0, icon_delegate); + ui->indexesTable->setItemDelegate(new PgLabItemDelegate(this)); + ui->indexesTable->setItemDelegateForColumn(0, new IconColumnDelegate(this)); // Set code editor fonts QFont code_font = UserConfiguration::instance()->codeFont(); diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 7313d8a..605fece 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -23,7 +23,7 @@ DEFINES += _WIN32_WINNT=0x0501 #LIBS += -LC:\VSproj\boost32\lib -LC:/PROG/LIB -lws2_32 -llibpq #debug { -LIBS += c:/prog/lib/botand_imp.lib +LIBS += c:/prog/lib/botan_imp.lib #} #release { @@ -83,7 +83,9 @@ PropertyProxyModel.cpp \ TriggerPage.cpp \ SqlCodePreview.cpp \ CustomFilterSortModel.cpp \ - PropertiesPage.cpp + PropertiesPage.cpp \ + PassPhraseForm.cpp \ + PasswordPromptDialog.cpp HEADERS += \ QueryResultModel.h \ @@ -137,7 +139,9 @@ CustomDataRole.h \ TriggerPage.h \ SqlCodePreview.h \ CustomFilterSortModel.h \ - PropertiesPage.h + PropertiesPage.h \ + PassPhraseForm.h \ + PasswordPromptDialog.h FORMS += mainwindow.ui \ ConnectionManagerWindow.ui \ @@ -151,7 +155,8 @@ FORMS += mainwindow.ui \ NamespaceFilterWidget.ui \ ApplicationWindow.ui \ CrudTab.ui \ - CodeGenerator.ui + CodeGenerator.ui \ + PassPhraseForm.ui RESOURCES += \ resources.qrc diff --git a/pglablib/ConnectionConfig.cpp b/pglablib/ConnectionConfig.cpp index d6fcb21..f6c21e8 100644 --- a/pglablib/ConnectionConfig.cpp +++ b/pglablib/ConnectionConfig.cpp @@ -57,6 +57,22 @@ ConnectionConfig::ConnectionConfig() : m_applicationName(QCoreApplication::applicationName().toUtf8().data()) {} + +void ConnectionConfig::setUuid(const QUuid &uuid) +{ + if (uuid != m_uuid) { + m_dirty = true; + m_uuid = uuid; + } +} + + +const QUuid &ConnectionConfig::uuid() const +{ + return m_uuid; +} + + void ConnectionConfig::setName(std::string desc) { if (m_name != desc) { diff --git a/pglablib/ConnectionConfig.h b/pglablib/ConnectionConfig.h index b451a6a..ce9191e 100644 --- a/pglablib/ConnectionConfig.h +++ b/pglablib/ConnectionConfig.h @@ -1,6 +1,7 @@ #ifndef CONNECTION_H #define CONNECTION_H +#include #include #include @@ -27,6 +28,9 @@ class ConnectionConfig { public: ConnectionConfig(); + void setUuid(const QUuid &uuid); + const QUuid &uuid() const; + void setName(std::string desc); const std::string& name() const; @@ -73,6 +77,7 @@ public: bool dirty() const; void clean(); private: + QUuid m_uuid; std::string m_name; std::string m_host; std::string m_hostaddr; diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro index f678cd8..34c3dba 100644 --- a/pglablib/pglablib.pro +++ b/pglablib/pglablib.pro @@ -4,7 +4,7 @@ # #------------------------------------------------- -QT += widgets +QT += widgets core TARGET = pglablib TEMPLATE = lib diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e69de29