#include "ConnectionList.h" #include "ScopeGuard.h" #include "util.h" #include "PasswordManager.h" #include #include #include namespace { /** Saves a connection configuration. Before calling this you may want to call beginGroup. */ void SaveConnectionConfig(QSettings &settings, const ConnectionConfig &cc) { settings.setValue("name", stdStrToQ(cc.name())); settings.setValue("host", stdStrToQ(cc.host())); 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("dbname", stdStrToQ(cc.dbname())); 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())); settings.setValue("passwordState", static_cast(cc.passwordState())); } 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"))); 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"))); //cc.setPassword(qvarToStdStr(settings.value("password"))); cc.setDbname(qvarToStdStr(settings.value("dbname"))); 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"))); cc.setSslCrl(qvarToStdStr(settings.value("sslcrl"))); PasswordState pwstate; QVariant v = settings.value("passwordState"); if (v.isNull()) pwstate = PasswordState::NotStored; else pwstate = static_cast(v.toInt()); cc.setPasswordState(pwstate); } } // end of unnamed namespace /// \todo should return an expected as creation of the folder can fail QString ConnectionList::iniFileName() { QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QDir dir(path); if (!dir.exists()) { dir.mkpath("."); } path += "/connections.ini"; return path; } ConnectionList::ConnectionList() { } size_t ConnectionList::createNew() { ConnectionConfig cc; cc.setUuid(QUuid::createUuid()); m_connections.push_back(cc); return m_connections.size()-1; } void ConnectionList::remove(size_t idx, size_t count) { auto f = m_connections.begin() + static_cast(idx); auto l = f + static_cast(count); deleteFromIni(f, l); m_connections.erase(f, l); } void ConnectionList::deleteFromIni(t_Connections::iterator begin, t_Connections::iterator end) { QString file_name = iniFileName(); QSettings settings(file_name, QSettings::IniFormat); for (auto i = begin; i != end; ++i) { settings.remove(i->uuid().toString()); } } void ConnectionList::load() { QString file_name = iniFileName(); QSettings settings(file_name, QSettings::IniFormat); auto groups = settings.childGroups(); for (auto grp : groups) { if (grp == "c_IniGroupSecurity") { // Read security settings } else { QUuid uuid(grp); if ( ! uuid.isNull() ) { settings.beginGroup(grp); SCOPE_EXIT { settings.endGroup(); }; ConnectionConfig cc; cc.setUuid(uuid); LoadConnectionConfig(settings, cc); m_connections.push_back(cc); } } } } void ConnectionList::save() { QString file_name = iniFileName(); QSettings settings(file_name, QSettings::IniFormat); for (auto& e : m_connections) { settings.beginGroup(e.uuid().toString()); SCOPE_EXIT { settings.endGroup(); }; SaveConnectionConfig(settings, e); e.clean(); } settings.sync(); } void ConnectionList::save(size_t index) { 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(); } }