Safely store passwords #79
21 changed files with 508 additions and 195 deletions
|
|
@ -16,7 +16,7 @@ class BackupDialog : public QDialog
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BackupDialog(QWidget *parent = 0);
|
explicit BackupDialog(QWidget *parent = nullptr);
|
||||||
~BackupDialog();
|
~BackupDialog();
|
||||||
|
|
||||||
void ConnectTo(QProcess *process);
|
void ConnectTo(QProcess *process);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "ConnectionList.h"
|
#include "ConnectionList.h"
|
||||||
#include "ScopeGuard.h"
|
#include "ScopeGuard.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "PasswordManager.h"
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
@ -19,31 +20,38 @@ namespace {
|
||||||
settings.setValue("hostaddr", stdStrToQ(cc.hostAddr()));
|
settings.setValue("hostaddr", stdStrToQ(cc.hostAddr()));
|
||||||
settings.setValue("port", cc.port());
|
settings.setValue("port", cc.port());
|
||||||
settings.setValue("user", stdStrToQ(cc.user()));
|
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("dbname", stdStrToQ(cc.dbname()));
|
||||||
settings.setValue("sslmode", (int)cc.sslMode());
|
settings.setValue("sslmode", static_cast<int>(cc.sslMode()));
|
||||||
settings.setValue("sslcert", stdStrToQ(cc.sslCert()));
|
settings.setValue("sslcert", stdStrToQ(cc.sslCert()));
|
||||||
settings.setValue("sslkey", stdStrToQ(cc.sslKey()));
|
settings.setValue("sslkey", stdStrToQ(cc.sslKey()));
|
||||||
settings.setValue("sslrootcert", stdStrToQ(cc.sslRootCert()));
|
settings.setValue("sslrootcert", stdStrToQ(cc.sslRootCert()));
|
||||||
settings.setValue("sslcrl", stdStrToQ(cc.sslCrl()));
|
settings.setValue("sslcrl", stdStrToQ(cc.sslCrl()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename S, typename T>
|
||||||
|
bool in_range(T value)
|
||||||
|
{
|
||||||
|
return value >= std::numeric_limits<S>::min() && value <= std::numeric_limits<S>::max();
|
||||||
|
}
|
||||||
|
|
||||||
void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc)
|
void LoadConnectionConfig(QSettings &settings, ConnectionConfig &cc)
|
||||||
{
|
{
|
||||||
cc.setName(qvarToStdStr(settings.value("name")));
|
cc.setName(qvarToStdStr(settings.value("name")));
|
||||||
cc.setHost(qvarToStdStr(settings.value("host")));
|
cc.setHost(qvarToStdStr(settings.value("host")));
|
||||||
cc.setHostAddr(qvarToStdStr(settings.value("hostaddr")));
|
cc.setHostAddr(qvarToStdStr(settings.value("hostaddr")));
|
||||||
cc.setPort(settings.value("port", 5432).toInt());
|
int p = settings.value("port", 5432).toInt();
|
||||||
|
if (!in_range<uint16_t>(p)) {
|
||||||
|
p = 0; // let the user re-enter a valid value
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.setPort(static_cast<uint16_t>(p));
|
||||||
cc.setUser(qvarToStdStr(settings.value("user")));
|
cc.setUser(qvarToStdStr(settings.value("user")));
|
||||||
// std::string encpw = qvarToStdStr(settings.value("encryptedpw"));
|
|
||||||
// if (encpw.empty()) {
|
//cc.setPassword(qvarToStdStr(settings.value("password")));
|
||||||
cc.setPassword(qvarToStdStr(settings.value("password")));
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// cc.setEncryptedPassword(encpw);
|
|
||||||
// }
|
|
||||||
cc.setDbname(qvarToStdStr(settings.value("dbname")));
|
cc.setDbname(qvarToStdStr(settings.value("dbname")));
|
||||||
cc.setSslMode((SslMode)settings.value("sslmode").toInt());
|
cc.setSslMode(static_cast<SslMode>(settings.value("sslmode").toInt()));
|
||||||
cc.setSslCert(qvarToStdStr(settings.value("sslcert")));
|
cc.setSslCert(qvarToStdStr(settings.value("sslcert")));
|
||||||
cc.setSslKey(qvarToStdStr(settings.value("sslkey")));
|
cc.setSslKey(qvarToStdStr(settings.value("sslkey")));
|
||||||
cc.setSslRootCert(qvarToStdStr(settings.value("sslrootcert")));
|
cc.setSslRootCert(qvarToStdStr(settings.value("sslrootcert")));
|
||||||
|
|
@ -69,19 +77,20 @@ QString ConnectionList::iniFileName()
|
||||||
|
|
||||||
ConnectionList::ConnectionList()
|
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;
|
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 f = m_connections.begin() + static_cast<int>(idx);
|
||||||
auto l = f + count;
|
auto l = f + static_cast<int>(count);
|
||||||
deleteFromIni(f, l);
|
deleteFromIni(f, l);
|
||||||
m_connections.erase(f, l);
|
m_connections.erase(f, l);
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +100,7 @@ void ConnectionList::deleteFromIni(t_Connections::iterator begin, t_Connections:
|
||||||
QString file_name = iniFileName();
|
QString file_name = iniFileName();
|
||||||
QSettings settings(file_name, QSettings::IniFormat);
|
QSettings settings(file_name, QSettings::IniFormat);
|
||||||
for (auto i = begin; i != end; ++i) {
|
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(); };
|
SCOPE_EXIT { settings.endGroup(); };
|
||||||
|
|
||||||
ConnectionConfig cc;
|
ConnectionConfig cc;
|
||||||
|
cc.setUuid(uuid);
|
||||||
LoadConnectionConfig(settings, cc);
|
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();
|
QString file_name = iniFileName();
|
||||||
QSettings settings(file_name, QSettings::IniFormat);
|
QSettings settings(file_name, QSettings::IniFormat);
|
||||||
for (auto& e : m_connections) {
|
for (auto& e : m_connections) {
|
||||||
settings.beginGroup(e.m_uuid.toString());
|
settings.beginGroup(e.uuid().toString());
|
||||||
SCOPE_EXIT { settings.endGroup(); };
|
SCOPE_EXIT { settings.endGroup(); };
|
||||||
|
|
||||||
SaveConnectionConfig(settings, e.m_config);
|
SaveConnectionConfig(settings, e);
|
||||||
e.m_config.clean();
|
e.clean();
|
||||||
}
|
}
|
||||||
settings.sync();
|
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.at(index);
|
||||||
auto& e = m_connections[index];
|
if (e.dirty()) {
|
||||||
if (e.m_config.dirty()) {
|
QString file_name = iniFileName();
|
||||||
QString file_name = iniFileName();
|
QSettings settings(file_name, QSettings::IniFormat);
|
||||||
QSettings settings(file_name, QSettings::IniFormat);
|
settings.beginGroup(e.uuid().toString());
|
||||||
settings.beginGroup(e.m_uuid.toString());
|
SaveConnectionConfig(settings, e);
|
||||||
SaveConnectionConfig(settings, e.m_config);
|
e.clean();
|
||||||
e.m_config.clean();
|
settings.sync();
|
||||||
settings.sync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,47 +8,42 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Expected.h"
|
#include "Expected.h"
|
||||||
|
|
||||||
|
|
||||||
class ConnectionList {
|
class ConnectionList {
|
||||||
private:
|
|
||||||
static QString iniFileName();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ConnectionList();
|
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 load();
|
||||||
void save();
|
void save();
|
||||||
void save(int index);
|
void save(size_t index);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class LijstElem {
|
// class LijstElem {
|
||||||
public:
|
// public:
|
||||||
QUuid m_uuid;
|
// QUuid m_uuid; ///< Unique identifier, used as a key for storing password in psk db.
|
||||||
ConnectionConfig m_config;
|
// ConnectionConfig m_config;
|
||||||
|
|
||||||
LijstElem(const QUuid id, const ConnectionConfig &cfg)
|
// LijstElem(const QUuid id, const ConnectionConfig &cfg)
|
||||||
: m_uuid(id), m_config(cfg)
|
// : m_uuid(id), m_config(cfg)
|
||||||
{}
|
// {}
|
||||||
};
|
// };
|
||||||
|
|
||||||
using t_Connections = std::vector<LijstElem>;
|
using t_Connections = std::vector<ConnectionConfig>;
|
||||||
t_Connections m_connections;
|
t_Connections m_connections;
|
||||||
|
|
||||||
void deleteFromIni(t_Connections::iterator begin, t_Connections::iterator end);
|
void deleteFromIni(t_Connections::iterator begin, t_Connections::iterator end);
|
||||||
|
|
||||||
|
static QString iniFileName();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONNECTIONLIST_H
|
#endif // CONNECTIONLIST_H
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,27 @@ Expected<ConnectionConfig> ConnectionListModel::get(int row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
size_t as_size_t(T t);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
size_t as_size_t(int t)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(t >= 0);
|
||||||
|
return static_cast<size_t>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
size_t as_size_t(long t)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(t >= 0);
|
||||||
|
return static_cast<size_t>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//void ConnectionListModel::del(const int idx)
|
//void ConnectionListModel::del(const int idx)
|
||||||
bool ConnectionListModel::removeRows(int row, int count, const QModelIndex &parent)
|
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);
|
beginRemoveRows(parent, row, row + count -1);
|
||||||
SCOPE_EXIT { endRemoveRows(); };
|
SCOPE_EXIT { endRemoveRows(); };
|
||||||
|
|
||||||
m_connections->remove(row, count);
|
m_connections->remove(as_size_t(row), as_size_t(count));
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -176,7 +197,12 @@ void ConnectionListModel::save()
|
||||||
m_connections->save();
|
m_connections->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionListModel::save(int index)
|
void ConnectionListModel::save(size_t index)
|
||||||
{
|
{
|
||||||
m_connections->save(index);
|
m_connections->save(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionListModel::save(size_t index, const ConnectionConfig &cc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,14 @@ public:
|
||||||
virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||||
|
|
||||||
void save();
|
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:
|
private:
|
||||||
|
|
||||||
ConnectionList *m_connections;
|
ConnectionList *m_connections;
|
||||||
|
|
||||||
|
|
||||||
static QString makeLongDescription(const ConnectionConfig &cfg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONNECTIONLISTMODEL_H
|
#endif // CONNECTIONLISTMODEL_H
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,21 @@
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include "ConnectionListModel.h"
|
#include "ConnectionListModel.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
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)
|
ConnectionManagerWindow::ConnectionManagerWindow(MasterController *master, QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent)
|
||||||
, ui(new Ui::ConnectionManagerWindow)
|
, ui(new Ui::ConnectionManagerWindow)
|
||||||
|
|
@ -53,9 +68,13 @@ void ConnectionManagerWindow::on_currentChanged(const QModelIndex ¤t,
|
||||||
{
|
{
|
||||||
int currow = current.row();
|
int currow = current.row();
|
||||||
auto clm = m_masterController->getConnectionListModel();
|
auto clm = m_masterController->getConnectionListModel();
|
||||||
clm->save(prevSelection);
|
if (prevSelection)
|
||||||
|
clm->save(*prevSelection);
|
||||||
m_mapper->setCurrentIndex(currow);
|
m_mapper->setCurrentIndex(currow);
|
||||||
prevSelection = currow;
|
if (currow >= 0)
|
||||||
|
prevSelection = static_cast<size_t>(currow);
|
||||||
|
else
|
||||||
|
prevSelection.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionManagerWindow::on_actionDelete_connection_triggered()
|
void ConnectionManagerWindow::on_actionDelete_connection_triggered()
|
||||||
|
|
@ -82,7 +101,6 @@ void ConnectionManagerWindow::setupWidgetMappings()
|
||||||
m_mapper->addMapping(ui->edtHost, 2);
|
m_mapper->addMapping(ui->edtHost, 2);
|
||||||
m_mapper->addMapping(ui->spinPort, 3);
|
m_mapper->addMapping(ui->spinPort, 3);
|
||||||
m_mapper->addMapping(ui->edtUser, 4);
|
m_mapper->addMapping(ui->edtUser, 4);
|
||||||
m_mapper->addMapping(ui->edtPassword, 5);
|
|
||||||
m_mapper->addMapping(ui->edtDbname, 6);
|
m_mapper->addMapping(ui->edtDbname, 6);
|
||||||
m_mapper->toFirst();
|
m_mapper->toFirst();
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +108,13 @@ void ConnectionManagerWindow::setupWidgetMappings()
|
||||||
void ConnectionManagerWindow::on_actionConnect_triggered()
|
void ConnectionManagerWindow::on_actionConnect_triggered()
|
||||||
{
|
{
|
||||||
auto ci = ui->listView->selectionModel()->currentIndex();
|
auto ci = ui->listView->selectionModel()->currentIndex();
|
||||||
m_masterController->openSqlWindowForConnection(ci.row());
|
if (ci.isValid()) {
|
||||||
|
auto r = static_cast<size_t>(ci.row());
|
||||||
|
m_masterController->openSqlWindowForConnection(r);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO can we give unobtrusive message why it didn't work?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionManagerWindow::on_actionQuit_application_triggered()
|
void ConnectionManagerWindow::on_actionQuit_application_triggered()
|
||||||
|
|
@ -117,68 +141,3 @@ void ConnectionManagerWindow::on_actionManage_server_triggered()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <botan/botan.h>
|
|
||||||
//#include <botan/base64.h>
|
|
||||||
//#include <botan/pbkdf.h>
|
|
||||||
//#include <botan/block_cipher.h>
|
|
||||||
//#include <botan/hex.h>
|
|
||||||
#include <botan/cryptobox.h>
|
|
||||||
|
|
||||||
|
|
||||||
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<Botan::byte> 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<Botan::PBKDF> 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<uint8_t> pt(plaintext.data(),plaintext.data()+plaintext.length());
|
|
||||||
|
|
||||||
// std::unique_ptr<Botan::Cipher_Mode> enc(Botan::get_cipher_mode("AES-256/CBC/PKCS7", Botan::ENCRYPTION));
|
|
||||||
// enc->set_key(aes256_key);
|
|
||||||
|
|
||||||
// //generate fresh nonce (IV)
|
|
||||||
// //std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);
|
|
||||||
// std::vector<uint8_t> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define CONNECTIONMANAGERWINDOW_H
|
#define CONNECTIONMANAGERWINDOW_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConnectionManagerWindow;
|
class ConnectionManagerWindow;
|
||||||
|
|
@ -30,14 +31,12 @@ private slots:
|
||||||
void on_actionBackup_database_triggered();
|
void on_actionBackup_database_triggered();
|
||||||
void on_actionManage_server_triggered();
|
void on_actionManage_server_triggered();
|
||||||
|
|
||||||
void on_testButton_clicked();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ConnectionManagerWindow *ui;
|
Ui::ConnectionManagerWindow *ui;
|
||||||
QDataWidgetMapper *m_mapper = nullptr;
|
QDataWidgetMapper *m_mapper = nullptr;
|
||||||
MasterController *m_masterController;
|
MasterController *m_masterController;
|
||||||
|
|
||||||
int prevSelection = -1;
|
boost::optional<size_t> prevSelection;
|
||||||
|
|
||||||
void setupWidgetMappings();
|
void setupWidgetMappings();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -75,30 +75,23 @@
|
||||||
<widget class="QLineEdit" name="edtUser"/>
|
<widget class="QLineEdit" name="edtUser"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Password</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLineEdit" name="edtPassword">
|
|
||||||
<property name="echoMode">
|
|
||||||
<enum>QLineEdit::Password</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Database</string>
|
<string>Database</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLineEdit" name="edtDbname"/>
|
<widget class="QLineEdit" name="edtDbname"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>SSL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
<widget class="QComboBox" name="cmbbxSsl">
|
<widget class="QComboBox" name="cmbbxSsl">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
|
|
@ -136,53 +129,46 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>SSL</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
<widget class="QLabel" name="label_8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Certificate</string>
|
<string>Certificate</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QLineEdit" name="edtCert"/>
|
<widget class="QLineEdit" name="edtCert"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="7" column="0">
|
||||||
<widget class="QLabel" name="label_9">
|
<widget class="QLabel" name="label_9">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Key</string>
|
<string>Key</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="QLineEdit" name="edtKey"/>
|
<widget class="QLineEdit" name="edtKey"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_10">
|
<widget class="QLabel" name="label_10">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Root cert.</string>
|
<string>Root cert.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QLineEdit" name="edtRootCert"/>
|
<widget class="QLineEdit" name="edtRootCert"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QLabel" name="label_11">
|
<widget class="QLabel" name="label_11">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Revocation list</string>
|
<string>Revocation list</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QLineEdit" name="edtCrl"/>
|
<widget class="QLineEdit" name="edtCrl"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QPushButton" name="testButton">
|
<widget class="QPushButton" name="testButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>PushButton</string>
|
<string>PushButton</string>
|
||||||
|
|
@ -201,7 +187,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>800</width>
|
||||||
<height>25</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "ServerWindow.h"
|
#include "ServerWindow.h"
|
||||||
#include "BackupDialog.h"
|
#include "BackupDialog.h"
|
||||||
|
#include "PasswordPromptDialog.h"
|
||||||
|
|
||||||
|
|
||||||
MasterController::MasterController(QObject *parent) : QObject(parent)
|
MasterController::MasterController(QObject *parent) : QObject(parent)
|
||||||
|
|
@ -33,39 +34,103 @@ void MasterController::showConnectionManager()
|
||||||
m_connectionManagerWindow->show();
|
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);
|
auto res = m_connectionListModel->get(connection_index);
|
||||||
if (cc.valid()) {
|
if (res.valid()) {
|
||||||
auto w = new MainWindow(this, nullptr);
|
auto cc = res.get();
|
||||||
w->setAttribute( Qt::WA_DeleteOnClose );
|
|
||||||
w->setConfig(cc.get());
|
m_connectionListModel->save(connection_index, cc);
|
||||||
w->show();
|
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)
|
void MasterController::openBackupDlgForConnection(int connection_index)
|
||||||
{
|
{
|
||||||
auto cc = m_connectionListModel->get(connection_index);
|
auto res = m_connectionListModel->get(connection_index);
|
||||||
m_connectionListModel->save(connection_index);
|
if (res.valid()) {
|
||||||
if (cc.valid()) {
|
auto cc = res.get();
|
||||||
|
retrieveConnectionPassword(cc);
|
||||||
|
m_connectionListModel->save(connection_index, cc);
|
||||||
|
|
||||||
auto w = new BackupDialog(nullptr); //new ServerWindow(this, nullptr);
|
auto w = new BackupDialog(nullptr); //new ServerWindow(this, nullptr);
|
||||||
w->setAttribute( Qt::WA_DeleteOnClose );
|
w->setAttribute( Qt::WA_DeleteOnClose );
|
||||||
w->setConfig(cc.get());
|
w->setConfig(cc);
|
||||||
w->show();
|
w->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MasterController::openServerWindowForConnection(int connection_index)
|
void MasterController::openServerWindowForConnection(int connection_index)
|
||||||
{
|
{
|
||||||
auto cc = m_connectionListModel->get(connection_index);
|
auto res = m_connectionListModel->get(connection_index);
|
||||||
m_connectionListModel->save(connection_index);
|
if (res.valid()) {
|
||||||
if (cc.valid()) {
|
auto cc = res.get();
|
||||||
|
retrieveConnectionPassword(cc);
|
||||||
|
m_connectionListModel->save(connection_index, cc);
|
||||||
|
|
||||||
auto w = new ServerWindow(this, nullptr);
|
auto w = new ServerWindow(this, nullptr);
|
||||||
w->setAttribute( Qt::WA_DeleteOnClose );
|
w->setAttribute( Qt::WA_DeleteOnClose );
|
||||||
w->setConfig(cc.get());
|
w->setConfig(cc);
|
||||||
w->show();
|
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<PasswordPromptDialog>(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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class ConnectionManagerWindow;
|
||||||
class MasterController : public QObject {
|
class MasterController : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit MasterController(QObject *parent = 0);
|
explicit MasterController(QObject *parent = nullptr);
|
||||||
MasterController(const MasterController&) = delete;
|
MasterController(const MasterController&) = delete;
|
||||||
MasterController &operator=(const MasterController&) = delete;
|
MasterController &operator=(const MasterController&) = delete;
|
||||||
~MasterController();
|
~MasterController();
|
||||||
|
|
@ -29,7 +29,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void showConnectionManager();
|
void showConnectionManager();
|
||||||
void openSqlWindowForConnection(int connection_index);
|
void openSqlWindowForConnection(size_t connection_index);
|
||||||
void openServerWindowForConnection(int connection_index);
|
void openServerWindowForConnection(int connection_index);
|
||||||
void openBackupDlgForConnection(int connection_index);
|
void openBackupDlgForConnection(int connection_index);
|
||||||
|
|
||||||
|
|
@ -41,7 +41,15 @@ private:
|
||||||
ConnectionList *m_connectionList = nullptr;
|
ConnectionList *m_connectionList = nullptr;
|
||||||
ConnectionListModel *m_connectionListModel = nullptr;
|
ConnectionListModel *m_connectionListModel = nullptr;
|
||||||
ConnectionManagerWindow *m_connectionManagerWindow = 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
|
#endif // MASTERCONTROLLER_H
|
||||||
|
|
|
||||||
45
pglab/PassPhraseForm.cpp
Normal file
45
pglab/PassPhraseForm.cpp
Normal file
|
|
@ -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
|
||||||
|
|
||||||
|
*/
|
||||||
22
pglab/PassPhraseForm.h
Normal file
22
pglab/PassPhraseForm.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef PASSPHRASEFORM_H
|
||||||
|
#define PASSPHRASEFORM_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PassPhraseForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PassPhraseForm : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PassPhraseForm(QWidget *parent = nullptr);
|
||||||
|
~PassPhraseForm();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::PassPhraseForm *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PASSPHRASEFORM_H
|
||||||
75
pglab/PassPhraseForm.ui
Normal file
75
pglab/PassPhraseForm.ui
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PassPhraseForm</class>
|
||||||
|
<widget class="QWidget" name="PassPhraseForm">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>397</width>
|
||||||
|
<height>228</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="verticalSpacing">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enter passphrase:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>32767</number>
|
||||||
|
</property>
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::NoEcho</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Repeat passphrase:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_2">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="value">
|
||||||
|
<number>67</number>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
70
pglab/PasswordPromptDialog.cpp
Normal file
70
pglab/PasswordPromptDialog.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "PasswordPromptDialog.h"
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
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()
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
32
pglab/PasswordPromptDialog.h
Normal file
32
pglab/PasswordPromptDialog.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef PASSWORDPROMPTDIALOG_H
|
||||||
|
#define PASSWORDPROMPTDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -26,14 +26,10 @@ TablesPage::TablesPage(MainWindow *parent)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// WARNING delegates should NOT be shared!!!
|
|
||||||
auto pglab_delegate = new PgLabItemDelegate(this);
|
|
||||||
auto icon_delegate = new IconColumnDelegate(this);
|
|
||||||
|
|
||||||
SetTableViewDefault(ui->tableListTable);
|
SetTableViewDefault(ui->tableListTable);
|
||||||
m_tablesModel = new TablesTableModel(this);
|
m_tablesModel = new TablesTableModel(this);
|
||||||
ui->tableListTable->setModel(m_tablesModel);
|
ui->tableListTable->setModel(m_tablesModel);
|
||||||
ui->tableListTable->setItemDelegate(pglab_delegate);
|
ui->tableListTable->setItemDelegate(new PgLabItemDelegate(this));
|
||||||
ui->tableListTable->setSortingEnabled(true);
|
ui->tableListTable->setSortingEnabled(true);
|
||||||
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder);
|
ui->tableListTable->sortByColumn(0, Qt::AscendingOrder);
|
||||||
ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
ui->tableListTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
|
@ -47,14 +43,14 @@ TablesPage::TablesPage(MainWindow *parent)
|
||||||
SetTableViewDefault(ui->constraintsTable);
|
SetTableViewDefault(ui->constraintsTable);
|
||||||
m_constraintModel = new ConstraintModel(this);
|
m_constraintModel = new ConstraintModel(this);
|
||||||
ui->constraintsTable->setModel(m_constraintModel);
|
ui->constraintsTable->setModel(m_constraintModel);
|
||||||
ui->constraintsTable->setItemDelegateForColumn(0, icon_delegate);
|
ui->constraintsTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
|
||||||
|
|
||||||
// Indexes
|
// Indexes
|
||||||
SetTableViewDefault(ui->indexesTable);
|
SetTableViewDefault(ui->indexesTable);
|
||||||
m_indexModel = new IndexModel(this);
|
m_indexModel = new IndexModel(this);
|
||||||
ui->indexesTable->setModel(m_indexModel);
|
ui->indexesTable->setModel(m_indexModel);
|
||||||
ui->indexesTable->setItemDelegate(pglab_delegate);
|
ui->indexesTable->setItemDelegate(new PgLabItemDelegate(this));
|
||||||
ui->indexesTable->setItemDelegateForColumn(0, icon_delegate);
|
ui->indexesTable->setItemDelegateForColumn(0, new IconColumnDelegate(this));
|
||||||
|
|
||||||
// Set code editor fonts
|
// Set code editor fonts
|
||||||
QFont code_font = UserConfiguration::instance()->codeFont();
|
QFont code_font = UserConfiguration::instance()->codeFont();
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ DEFINES += _WIN32_WINNT=0x0501
|
||||||
#LIBS += -LC:\VSproj\boost32\lib -LC:/PROG/LIB -lws2_32 -llibpq
|
#LIBS += -LC:\VSproj\boost32\lib -LC:/PROG/LIB -lws2_32 -llibpq
|
||||||
|
|
||||||
#debug {
|
#debug {
|
||||||
LIBS += c:/prog/lib/botand_imp.lib
|
LIBS += c:/prog/lib/botan_imp.lib
|
||||||
#}
|
#}
|
||||||
|
|
||||||
#release {
|
#release {
|
||||||
|
|
@ -83,7 +83,9 @@ PropertyProxyModel.cpp \
|
||||||
TriggerPage.cpp \
|
TriggerPage.cpp \
|
||||||
SqlCodePreview.cpp \
|
SqlCodePreview.cpp \
|
||||||
CustomFilterSortModel.cpp \
|
CustomFilterSortModel.cpp \
|
||||||
PropertiesPage.cpp
|
PropertiesPage.cpp \
|
||||||
|
PassPhraseForm.cpp \
|
||||||
|
PasswordPromptDialog.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
QueryResultModel.h \
|
QueryResultModel.h \
|
||||||
|
|
@ -137,7 +139,9 @@ CustomDataRole.h \
|
||||||
TriggerPage.h \
|
TriggerPage.h \
|
||||||
SqlCodePreview.h \
|
SqlCodePreview.h \
|
||||||
CustomFilterSortModel.h \
|
CustomFilterSortModel.h \
|
||||||
PropertiesPage.h
|
PropertiesPage.h \
|
||||||
|
PassPhraseForm.h \
|
||||||
|
PasswordPromptDialog.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
ConnectionManagerWindow.ui \
|
ConnectionManagerWindow.ui \
|
||||||
|
|
@ -151,7 +155,8 @@ FORMS += mainwindow.ui \
|
||||||
NamespaceFilterWidget.ui \
|
NamespaceFilterWidget.ui \
|
||||||
ApplicationWindow.ui \
|
ApplicationWindow.ui \
|
||||||
CrudTab.ui \
|
CrudTab.ui \
|
||||||
CodeGenerator.ui
|
CodeGenerator.ui \
|
||||||
|
PassPhraseForm.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,22 @@ ConnectionConfig::ConnectionConfig()
|
||||||
: m_applicationName(QCoreApplication::applicationName().toUtf8().data())
|
: 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)
|
void ConnectionConfig::setName(std::string desc)
|
||||||
{
|
{
|
||||||
if (m_name != desc) {
|
if (m_name != desc) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef CONNECTION_H
|
#ifndef CONNECTION_H
|
||||||
#define CONNECTION_H
|
#define CONNECTION_H
|
||||||
|
|
||||||
|
#include <QUuid>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -27,6 +28,9 @@ class ConnectionConfig {
|
||||||
public:
|
public:
|
||||||
ConnectionConfig();
|
ConnectionConfig();
|
||||||
|
|
||||||
|
void setUuid(const QUuid &uuid);
|
||||||
|
const QUuid &uuid() const;
|
||||||
|
|
||||||
void setName(std::string desc);
|
void setName(std::string desc);
|
||||||
const std::string& name() const;
|
const std::string& name() const;
|
||||||
|
|
||||||
|
|
@ -73,6 +77,7 @@ public:
|
||||||
bool dirty() const;
|
bool dirty() const;
|
||||||
void clean();
|
void clean();
|
||||||
private:
|
private:
|
||||||
|
QUuid m_uuid;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_host;
|
std::string m_host;
|
||||||
std::string m_hostaddr;
|
std::string m_hostaddr;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
QT += widgets
|
QT += widgets core
|
||||||
|
|
||||||
TARGET = pglablib
|
TARGET = pglablib
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
|
|
|
||||||
0
readme.md
Normal file
0
readme.md
Normal file
Loading…
Add table
Add a link
Reference in a new issue