#include "ConnectionController.h" #include "MasterController.h" #include "ConnectionManagerWindow.h" #include "ConnectionListModel.h" #include "PasswordManager.h" #include "DatabaseWindow.h" #include "ServerWindow.h" #include "BackupDialog.h" #include "PasswordPromptDialog.h" #include "ConnectionConfigurationWidget.h" ConnectionController::ConnectionController(MasterController *parent) : QObject(parent) , m_masterController(parent) {} ConnectionController::~ConnectionController() { delete m_connectionManagerWindow; delete m_connectionListModel; } void ConnectionController::init() { //std::string dbfilename = QDir::toNativeSeparators(GetUserConfigDatabaseName()).toUtf8().data(); //m_userConfigDatabase = std::make_shared(dbfilename); m_passwordManager = std::make_shared(); m_connectionListModel = new ConnectionListModel(this); m_connectionListModel->load(); m_connectionManagerWindow = new ConnectionManagerWindow(m_masterController, nullptr); m_connectionManagerWindow->show(); } void ConnectionController::showConnectionManager() { m_connectionManagerWindow->show(); } void ConnectionController::openSqlWindowForConnection(int connection_index) { auto res = m_connectionListModel->get(connection_index); if (res.valid()) { auto cc = res.get(); if (retrieveConnectionPassword(cc)) { m_connectionListModel->save(cc); // TODO instead of directly openening the mainwindow // do async connect and only open window when we have // working connection auto w = new DatabaseWindow(m_masterController, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); w->setConfig(cc); w->showMaximized(); } } } void ConnectionController::openBackupDlgForConnection(int connection_index) { auto res = m_connectionListModel->get(connection_index); if (res.valid()) { auto cc = res.get(); if (retrieveConnectionPassword(cc)) { m_connectionListModel->save(cc); auto w = new BackupDialog(nullptr); //new ServerWindow(this, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); w->setConfig(cc); w->show(); } } } void ConnectionController::createConnection() { ConnectionConfig cc; cc.setUuid(QUuid::createUuid()); ConnectionConfigurationWidget::editExistingInWindow(this, cc); } void ConnectionController::editConnection(int connection_index) { auto res = m_connectionListModel->get(connection_index); if (res.valid()) { auto cc = res.get(); ConnectionConfigurationWidget::editExistingInWindow(this, cc); } } void ConnectionController::openServerWindowForConnection(int connection_index) { auto res = m_connectionListModel->get(connection_index); if (res.valid()) { auto cc = res.get(); if (retrieveConnectionPassword(cc)) { m_connectionListModel->save(cc); auto w = new ServerWindow(m_masterController, nullptr); w->setAttribute( Qt::WA_DeleteOnClose ); w->setConfig(cc); w->show(); } } } bool ConnectionController::retrieveConnectionPassword(ConnectionConfig &cc) { auto pw_state = cc.passwordState(); if (pw_state == PasswordState::NotNeeded) { return true; } else if (pw_state == PasswordState::SavedPasswordManager) { std::string pw; bool result = getPasswordFromPskdb(getPskId(cc), pw); if (result) { cc.setPassword(pw); return true; } } // Geen else hier want als voorgaande blok niet geretourneerd heeft moeten we wachtwoord // ook aan de gebruiker vragen zoals hier gebeurd. QString str = ConnectionListModel::makeLongDescription(cc); auto dlg = std::make_unique(PasswordPromptDialog::SaveOption, nullptr); dlg->setCaption(tr("Connection password prompt")); dlg->setDescription(QString(tr("Please provide password for connection %1")).arg(str)); int exec_result = dlg->exec(); if (exec_result == QDialog::Accepted) { std::string password = dlg->password().toUtf8().data(); cc.setPassword(password); if (dlg->saveChecked()) { storePasswordInPskdb(getPskId(cc), password); cc.setPasswordState(PasswordState::SavedPasswordManager); } return true; } return false; } bool ConnectionController::getPasswordFromPskdb(const std::string &password_id, std::string &password) { if (!UnlockPasswordManagerIfNeeded()) return false; return m_passwordManager->get(password_id, password); } bool ConnectionController::storePasswordInPskdb(const std::string &password_id, const std::string password) { if (!UnlockPasswordManagerIfNeeded()) return false; m_passwordManager->set(password_id, password); return true; } bool ConnectionController::UnlockPasswordManagerIfNeeded() { auto&& user_cfg_db = m_masterController->userConfigDatabase(); if (m_passwordManager->initialized(user_cfg_db)) { if (!m_passwordManager->locked()) return true; while (true) { // ask user for passphrase auto dlg = std::make_unique(nullptr, nullptr); dlg->setCaption(tr("Unlock password manager")); dlg->setDescription(tr("Enter password for password manager")); int exec_result = dlg->exec(); bool ok = (exec_result == QDialog::Accepted); if (!ok) { // leave this retry loop break; } // user gave OK, if succeeds return true otherwise loop a prompt for password again. if (m_passwordManager->openDatabase(user_cfg_db, dlg->password())) return true; } } else { // Ask user for passphrase + confirmation, clearly instruct this is first setup // create auto dlg = std::make_unique(PasswordPromptDialog::ConfirmPassword, nullptr); dlg->setCaption(tr("Password manager setup")); dlg->setDescription(tr("Enter a strong password for password manager initialization. A strong key will be " "derived from your password and it will be impossible to recover anything from the " "password manager without the password you enter here.")); int exec_result = dlg->exec(); if (exec_result == QDialog::Accepted) { QString passphrase = dlg->password(); if (m_passwordManager->createDatabase(user_cfg_db, passphrase)) return true; } } return false; } std::string ConnectionController::getPskId(const ConnectionConfig &cc) { std::string id = "dbpw/"; id += cc.uuid().toString().toUtf8().data(); return id; }