Make saving of the entered password work to.toStdString

Also when testing a preexisting connection config it will now decode a potential stored password.
This commit is contained in:
eelke 2021-07-04 19:33:06 +02:00
parent c00a0452d1
commit 87cfb84997
6 changed files with 117 additions and 70 deletions

View file

@ -24,10 +24,11 @@
#define SET_OBJECT_NAME(var) var->setObjectName(#var) #define SET_OBJECT_NAME(var) var->setObjectName(#var)
void ConnectionConfigurationWidget::editExistingInWindow(ConnectionController *ctrl, const ConnectionConfig &cfg) void ConnectionConfigurationWidget::editExistingInWindow(ConnectionController *connection_controller, const ConnectionConfig &cfg,
std::function<void(ConnectionConfigurationWidget&)> save_func)
{ {
try { try {
auto w = new ConnectionConfigurationWidget(ctrl->getConnectionTreeModel()); auto w = new ConnectionConfigurationWidget(connection_controller);
w->setData(cfg); w->setData(cfg);
auto btn_hbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal); auto btn_hbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
@ -41,12 +42,13 @@ void ConnectionConfigurationWidget::editExistingInWindow(ConnectionController *c
win->setLayout(vbox); win->setLayout(vbox);
win->setAttribute( Qt::WA_DeleteOnClose, true ); win->setAttribute( Qt::WA_DeleteOnClose, true );
QObject::connect(btn_hbox, &QDialogButtonBox::accepted, [ctrl, w, win] () { QObject::connect(btn_hbox, &QDialogButtonBox::accepted, [w, win, save_func] () {
auto cc = w->data(); // auto cc = w->data();
auto grp = w->group(); // auto grp = w->group();
ctrl->getConnectionTreeModel()->save(grp, cc); // connection_controller->getConnectionTreeModel()->save(grp, cc);
win->accept(); save_func(*w);
}); win->accept();
});
QObject::connect(btn_hbox, &QDialogButtonBox::rejected, [win] () QObject::connect(btn_hbox, &QDialogButtonBox::rejected, [win] ()
{ {
win->reject(); win->reject();
@ -59,13 +61,14 @@ void ConnectionConfigurationWidget::editExistingInWindow(ConnectionController *c
} }
} }
ConnectionConfigurationWidget::ConnectionConfigurationWidget(ConnectionTreeModel *connection_model, QWidget *parent) ConnectionConfigurationWidget::ConnectionConfigurationWidget(ConnectionController *connection_controller, QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_connectionModel(connection_model) , m_connectionController(connection_controller)
, m_connectionModel(connection_controller->getConnectionTreeModel())
{ {
lblGroup = new QLabel; lblGroup = new QLabel;
cmbbxGroup = new QComboBox; cmbbxGroup = new QComboBox;
cmbbxGroup->setModel(connection_model); cmbbxGroup->setModel(m_connectionModel);
cmbbxGroup->setModelColumn(0); cmbbxGroup->setModelColumn(0);
lblGroup->setBuddy(cmbbxGroup); lblGroup->setBuddy(cmbbxGroup);
@ -202,12 +205,16 @@ void ConnectionConfigurationWidget::setData(const ConnectionConfig &cfg)
edtHost->setText(cfg.host()); edtHost->setText(cfg.host());
spinPort->setValue(cfg.port()); spinPort->setValue(cfg.port());
edtUser->setText(cfg.user()); edtUser->setText(cfg.user());
edtPassword->setText("");
cmbDbname->setCurrentText(cfg.dbname()); cmbDbname->setCurrentText(cfg.dbname());
cmbbxSsl->setCurrentIndex(static_cast<int>(cfg.sslMode())); cmbbxSsl->setCurrentIndex(static_cast<int>(cfg.sslMode()));
edtCert->setText(cfg.sslCert()); edtCert->setText(cfg.sslCert());
edtKey->setText(cfg.sslKey()); edtKey->setText(cfg.sslKey());
edtRootCert->setText(cfg.sslRootCert()); edtRootCert->setText(cfg.sslRootCert());
edtCrl->setText(cfg.sslCrl()); edtCrl->setText(cfg.sslCrl());
encodedPassword = cfg.encodedPassword();
} }
ConnectionConfig ConnectionConfigurationWidget::data() const ConnectionConfig ConnectionConfigurationWidget::data() const
@ -225,6 +232,7 @@ ConnectionConfig ConnectionConfigurationWidget::data() const
cfg.setSslKey(edtKey->text()); cfg.setSslKey(edtKey->text());
cfg.setSslRootCert(edtRootCert->text()); cfg.setSslRootCert(edtRootCert->text());
cfg.setSslCrl(edtCrl->text()); cfg.setSslCrl(edtCrl->text());
cfg.setEncodedPassword(encodedPassword); // this could be old, it will be overriden later when there is a new password to save.
return cfg; return cfg;
} }
@ -233,9 +241,20 @@ QString ConnectionConfigurationWidget::group() const
return cmbbxGroup->currentText(); return cmbbxGroup->currentText();
} }
bool ConnectionConfigurationWidget::savePassword() const
{
return cbSavePassword->isChecked() && !edtPassword->text().isEmpty();
}
void ConnectionConfigurationWidget::testConnection() void ConnectionConfigurationWidget::testConnection()
{ {
QString password = edtPassword->text();
if (password.isEmpty() && !encodedPassword.isEmpty()) {
m_connectionController->decodeConnectionPassword(m_uuid, encodedPassword, password);
}
auto cc = data(); auto cc = data();
cc.setPassword(password);
QFuture<TestConnectionResult> result = QtConcurrent::run([cc] { return TestConnection(cc); }); QFuture<TestConnectionResult> result = QtConcurrent::run([cc] { return TestConnection(cc); });
TestWatcher.setFuture(result); TestWatcher.setFuture(result);
} }

View file

@ -25,23 +25,27 @@ class ConnectionConfigurationWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
static void editExistingInWindow(ConnectionController *ctrl, const ConnectionConfig &cfg); static void editExistingInWindow(ConnectionController *ctrl, const ConnectionConfig &cfg,
std::function<void(ConnectionConfigurationWidget&)> save_func);
explicit ConnectionConfigurationWidget(ConnectionTreeModel *connection_model, QWidget *parent = nullptr); explicit ConnectionConfigurationWidget(ConnectionController *connection_controller, QWidget *parent = nullptr);
void retranslateUi(); void retranslateUi();
void setData(const ConnectionConfig &cfg); void setData(const ConnectionConfig &cfg);
ConnectionConfig data() const; ConnectionConfig data() const;
QString group() const; QString group() const;
bool savePassword() const;
signals: signals:
public slots: public slots:
void testConnection(); void testConnection();
private: private:
ConnectionController *m_connectionController;
ConnectionTreeModel *m_connectionModel; ConnectionTreeModel *m_connectionModel;
QUuid m_uuid; QUuid m_uuid;
QByteArray encodedPassword;
QLabel *lblGroup; QLabel *lblGroup;
QComboBox *cmbbxGroup; QComboBox *cmbbxGroup;
@ -73,7 +77,9 @@ private:
QLabel *lblResult; QLabel *lblResult;
QFormLayout *formLayout; QFormLayout *formLayout;
QFutureWatcher<TestConnectionResult> TestWatcher; QFutureWatcher<TestConnectionResult> TestWatcher;
private slots: private slots:
void handleTestResult(); void handleTestResult();
}; };

View file

@ -83,14 +83,14 @@ void ConnectionController::createConnection()
{ {
ConnectionConfig cc; ConnectionConfig cc;
cc.setUuid(QUuid::createUuid()); cc.setUuid(QUuid::createUuid());
ConnectionConfigurationWidget::editExistingInWindow(this, cc); ConnectionConfigurationWidget::editExistingInWindow(this, cc, [this] (ConnectionConfigurationWidget &w) -> void { saveConnection(w); });
} }
void ConnectionController::editConnection(QModelIndex index) void ConnectionController::editConnection(QModelIndex index)
{ {
auto config = ConnectionTreeModel::getConfigFromModelIndex(index); auto config = ConnectionTreeModel::getConfigFromModelIndex(index);
if (config) { if (config) {
ConnectionConfigurationWidget::editExistingInWindow(this, *config); ConnectionConfigurationWidget::editExistingInWindow(this, *config, [this] (ConnectionConfigurationWidget &w) -> void { saveConnection(w); });
} }
} }
@ -100,10 +100,20 @@ void ConnectionController::editCopy(QModelIndex index)
if (config) { if (config) {
auto cc = *config; auto cc = *config;
cc.setUuid(QUuid::createUuid()); cc.setUuid(QUuid::createUuid());
ConnectionConfigurationWidget::editExistingInWindow(this, cc); ConnectionConfigurationWidget::editExistingInWindow(this, cc, [this] (ConnectionConfigurationWidget &w) -> void { saveConnection(w); });
} }
} }
void ConnectionController::saveConnection(ConnectionConfigurationWidget &w)
{
auto cc = w.data();
auto grp = w.group();
if (w.savePassword()) {
encryptPassword(cc);
}
m_connectionTreeModel->save(grp, cc);
}
void ConnectionController::addGroup() void ConnectionController::addGroup()
{ {
auto result = QInputDialog::getText(nullptr, tr("Add new connection group"), auto result = QInputDialog::getText(nullptr, tr("Add new connection group"),
@ -142,8 +152,8 @@ bool ConnectionController::retrieveConnectionPassword(ConnectionConfig &cc)
auto enc_pwd = cc.encodedPassword(); auto enc_pwd = cc.encodedPassword();
if (!enc_pwd.isEmpty()) { if (!enc_pwd.isEmpty()) {
std::string pw; std::string pw;
bool result = decodePassword(getPskId(cc), bool result = retrieveFromPasswordManager(getPskId(cc.uuid()),
std::string_view(enc_pwd.data(), enc_pwd.size()) , pw);// getPasswordFromPskdb(getPskId(cc), pw); std::string_view(enc_pwd.data(), enc_pwd.size()) , pw);
if (result) { if (result) {
cc.setPassword(QString::fromUtf8(pw.data(), pw.size())); cc.setPassword(QString::fromUtf8(pw.data(), pw.size()));
return true; return true;
@ -161,19 +171,14 @@ bool ConnectionController::retrieveConnectionPassword(ConnectionConfig &cc)
auto password = dlg->password(); auto password = dlg->password();
cc.setPassword(password); cc.setPassword(password);
if (dlg->saveChecked()) { if (dlg->saveChecked()) {
auto ba = password.toUtf8(); encryptPassword(cc);
std::string pw(ba.data(), static_cast<size_t>(ba.size()));
std::string encoded_pw;
if (encodePassword(getPskId(cc), pw, encoded_pw)) {
cc.setEncodedPassword({ encoded_pw.data(), static_cast<int>(encoded_pw.size()) });
}
} }
return true; return true;
} }
return false; return false;
} }
bool ConnectionController::decodePassword(const std::string &password_id, const std::string_view &enc_password, std::string &password) bool ConnectionController::retrieveFromPasswordManager(const std::string &password_id, const std::string_view &enc_password, std::string &password)
{ {
if (!UnlockPasswordManagerIfNeeded()) if (!UnlockPasswordManagerIfNeeded())
return false; return false;
@ -182,13 +187,27 @@ bool ConnectionController::decodePassword(const std::string &password_id, const
return true; return true;
} }
bool ConnectionController::encodePassword(const std::string &password_id, const std::string &password, std::string &enc_password) bool ConnectionController::encryptPassword(ConnectionConfig &cc)
{ {
if (!UnlockPasswordManagerIfNeeded()) if (!UnlockPasswordManagerIfNeeded())
return false; return false;
enc_password = m_passwordManager->encrypt(password_id, password); std::string password = cc.password().toStdString();
return true; std::string password_id = getPskId(cc.uuid());
std::string enc_password = m_passwordManager->encrypt(password_id, password);
cc.setEncodedPassword({ enc_password.data(), static_cast<int>(enc_password.size()) });
return true;
}
bool ConnectionController::decodeConnectionPassword(QUuid id, QByteArray encoded, QString &out_password)
{
std::string password_id = getPskId(id);
std::string enc(encoded.data(), encoded.size());
std::string password;
bool res = retrieveFromPasswordManager(password_id, enc, password);
if (res)
out_password = QString::fromStdString(password);
return res;
} }
bool ConnectionController::UnlockPasswordManagerIfNeeded() bool ConnectionController::UnlockPasswordManagerIfNeeded()
@ -236,13 +255,13 @@ bool ConnectionController::UnlockPasswordManagerIfNeeded()
return true; return true;
} }
} }
return false; return false;
} }
std::string ConnectionController::getPskId(const ConnectionConfig &cc) std::string ConnectionController::getPskId(QUuid connectionid)
{ {
std::string id = "dbpw/"; std::string id = "dbpw/";
id += cc.uuid().toString().toUtf8().data(); id += connectionid.toString().toUtf8().data();
return id; return id;
} }

View file

@ -6,6 +6,7 @@
class MasterController; class MasterController;
class ConnectionConfig; class ConnectionConfig;
class ConnectionConfigurationWidget;
class ConnectionList; class ConnectionList;
class ConnectionTreeModel; class ConnectionTreeModel;
class ConnectionManagerWindow; class ConnectionManagerWindow;
@ -40,6 +41,14 @@ public:
void removeGroup(QModelIndex index); void removeGroup(QModelIndex index);
std::shared_ptr<PasswordManager> passwordManager(); std::shared_ptr<PasswordManager> passwordManager();
/** Retrieves the connection password from the user (directly or through the psk db)
*
*/
bool retrieveConnectionPassword(ConnectionConfig &cc);
bool UnlockPasswordManagerIfNeeded();
bool decodeConnectionPassword(QUuid id, QByteArray encoded, QString &out_password);
private: private:
MasterController *m_masterController; MasterController *m_masterController;
ConnectionList *m_connectionList = nullptr; ConnectionList *m_connectionList = nullptr;
@ -52,21 +61,15 @@ private:
*/ */
std::shared_ptr<PasswordManager> m_passwordManager; std::shared_ptr<PasswordManager> m_passwordManager;
/** Retrieves the connection password from the user (directly or through the psk db) bool retrieveFromPasswordManager(const std::string &password_id, const std::string_view &enc_password, std::string &password);
* // bool updatePasswordManager(const std::string &password_id, const std::string &password, std::string &enc_password);
*/
bool retrieveConnectionPassword(ConnectionConfig &cc);
bool decodePassword(const std::string &password_id, const std::string_view &enc_password, std::string &password); /// Expects the plaintext password to be the password that needs encoding.
bool encodePassword(const std::string &password_id, const std::string &password, std::string &enc_password); bool encryptPassword(ConnectionConfig &cc);
/// static std::string getPskId(QUuid connectionid);
///
/// \return bool: succeeded, int: relock timeout
///
bool UnlockPasswordManagerIfNeeded();
static std::string getPskId(const ConnectionConfig &cc); void saveConnection(ConnectionConfigurationWidget &w);
private slots: private slots:
void relock(); void relock();
}; };

View file

@ -133,7 +133,7 @@ void ConnectionConfig::setUser(const QString& v)
{ {
if (m_user != v) { if (m_user != v) {
m_dirty = true; m_dirty = true;
m_user = std::move(v); m_user = v;
} }
} }
@ -147,7 +147,7 @@ void ConnectionConfig::setPassword(const QString& v)
{ {
if (m_password != v) { if (m_password != v) {
m_dirty = true; m_dirty = true;
m_password = std::move(v); m_password = v;
} }
} }
@ -160,7 +160,7 @@ void ConnectionConfig::setDbname(const QString& v)
{ {
if (m_dbname != v) { if (m_dbname != v) {
m_dirty = true; m_dirty = true;
m_dbname = std::move(v); m_dbname = v;
} }
} }
@ -298,15 +298,15 @@ void ConnectionConfig::setEncodedPassword(const QByteArray &encodedPassword)
m_encodedPassword = encodedPassword; m_encodedPassword = encodedPassword;
} }
void ConnectionConfig::write(QDataStream &out) const //void ConnectionConfig::write(QDataStream &out) const
{ //{
// out << //// out <<
} //}
void ConnectionConfig::read(QDataStream &in) //void ConnectionConfig::read(QDataStream &in)
{ //{
} //}
QString ConnectionConfig::escapeConnectionStringValue(const QString &value) QString ConnectionConfig::escapeConnectionStringValue(const QString &value)
{ {
@ -465,15 +465,15 @@ void ConnectionGroup::update(int idx, const ConnectionConfig &cc)
node->setParent(this); node->setParent(this);
} }
QDataStream &operator<<(QDataStream &out, const ConnectionConfig &cc) //QDataStream &operator<<(QDataStream &out, const ConnectionConfig &cc)
{ //{
cc.write(out); // cc.write(out);
return out; // return out;
} //}
QDataStream &operator>>(QDataStream &in, ConnectionConfig &cc) //QDataStream &operator>>(QDataStream &in, ConnectionConfig &cc)
{ //{
//in>>myObj.uId>>myObj.passwd>>myObj.statusType; // //in>>myObj.uId>>myObj.passwd>>myObj.statusType;
cc.read(in); // cc.read(in);
return in; // return in;
} //}

View file

@ -121,8 +121,8 @@ public:
QByteArray encodedPassword() const; QByteArray encodedPassword() const;
void setEncodedPassword(const QByteArray &encodedPassword); void setEncodedPassword(const QByteArray &encodedPassword);
void write(QDataStream &out) const; // void write(QDataStream &out) const;
void read(QDataStream &in); // void read(QDataStream &in);
/** Escapes a value for inclusion in a keyword value connection string. /** Escapes a value for inclusion in a keyword value connection string.
* *
@ -164,9 +164,9 @@ private:
Q_DECLARE_METATYPE(ConnectionConfig) Q_DECLARE_METATYPE(ConnectionConfig)
QDataStream &operator<<(QDataStream &out, const ConnectionConfig &cc); //QDataStream &operator<<(QDataStream &out, const ConnectionConfig &cc);
QDataStream &operator>>(QDataStream &in, ConnectionConfig &cc); //QDataStream &operator>>(QDataStream &in, ConnectionConfig &cc);
#endif // CONNECTION_H #endif // CONNECTION_H