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