pgLab/pglab/ConnectionList.cpp
eelke 2230a4bd61 Lot of password related changes all over the place.
Password is no longer saved with the connection list.
Password is not entered along with other connection credentials.
Password is now asked for when required.
Still working on saving the password and auto retrieving it from the password manager.
2018-11-04 11:44:40 +01:00

156 lines
4.2 KiB
C++

#include "ConnectionList.h"
#include "ScopeGuard.h"
#include "util.h"
#include "PasswordManager.h"
#include <QDir>
#include <QStandardPaths>
#include <QSettings>
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<int>(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 <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)
{
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<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.setPassword(qvarToStdStr(settings.value("password")));
cc.setDbname(qvarToStdStr(settings.value("dbname")));
cc.setSslMode(static_cast<SslMode>(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")));
}
} // 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<int>(idx);
auto l = f + static_cast<int>(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();
}
}