mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Encrypted Logs: part 2: all encryption to be implemented in EncryptedDb class
This commit is contained in:
parent
172f1181c5
commit
3cf224a34e
|
@ -26,6 +26,9 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
#include "misc/db/plaindb.h"
|
||||||
|
#include "misc/db/encrypteddb.h"
|
||||||
|
|
||||||
static HistoryKeeper *historyInstance = nullptr;
|
static HistoryKeeper *historyInstance = nullptr;
|
||||||
|
|
||||||
HistoryKeeper *HistoryKeeper::getInstance()
|
HistoryKeeper *HistoryKeeper::getInstance()
|
||||||
|
@ -33,36 +36,35 @@ HistoryKeeper *HistoryKeeper::getInstance()
|
||||||
if (historyInstance == nullptr)
|
if (historyInstance == nullptr)
|
||||||
{
|
{
|
||||||
QString path(":memory:");
|
QString path(":memory:");
|
||||||
bool encrypted = Settings::getInstance().getEncryptLogs();
|
GenericDdInterface *dbIntf;
|
||||||
|
|
||||||
if (Settings::getInstance().getEnableLogging())
|
if (Settings::getInstance().getEnableLogging())
|
||||||
{
|
{
|
||||||
path = QDir(Settings::getInstance().getSettingsDirPath()).filePath("qtox_history.sqlite");
|
bool encrypted = Settings::getInstance().getEncryptLogs();
|
||||||
// path = "/tmp/qtox_history.sqlite"; // just for testing purpose
|
|
||||||
|
if (encrypted)
|
||||||
|
{
|
||||||
|
QString key = "plainKey"; // FIXME: ask user about it
|
||||||
|
path = QDir(Settings::getInstance().getSettingsDirPath()).filePath("qtox_history.encrypted");
|
||||||
|
dbIntf = new EncryptedDb(path, key);
|
||||||
|
|
||||||
|
historyInstance = new HistoryKeeper(dbIntf);
|
||||||
|
return historyInstance;
|
||||||
|
} else {
|
||||||
|
path = QDir(Settings::getInstance().getSettingsDirPath()).filePath("qtox_history.sqlite");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
historyInstance = new HistoryKeeper(path, encrypted);
|
dbIntf = new PlainDb(path);
|
||||||
|
historyInstance = new HistoryKeeper(dbIntf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return historyInstance;
|
return historyInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryKeeper::HistoryKeeper(const QString &path, bool encr) :
|
HistoryKeeper::HistoryKeeper(GenericDdInterface *db_) :
|
||||||
isEncrypted(encr)
|
db(db_)
|
||||||
{
|
{
|
||||||
db = QSqlDatabase::addDatabase("QSQLITE");
|
|
||||||
if (isEncrypted)
|
|
||||||
db.setDatabaseName(":memory:");
|
|
||||||
else
|
|
||||||
db.setDatabaseName(path);
|
|
||||||
|
|
||||||
if (!db.open())
|
|
||||||
{
|
|
||||||
qWarning() << QString("Can't open file: %1, history will not be saved!").arg(path);
|
|
||||||
db.setDatabaseName(":memory:");
|
|
||||||
db.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
DB format
|
DB format
|
||||||
chats:
|
chats:
|
||||||
|
@ -85,10 +87,10 @@ HistoryKeeper::HistoryKeeper(const QString &path, bool encr) :
|
||||||
message
|
message
|
||||||
*/
|
*/
|
||||||
|
|
||||||
db.exec(QString("CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, ") +
|
db->exec(QString("CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER NOT NULL, ") +
|
||||||
QString("profile_id INTEGER NOT NULL, chat_id INTEGER NOT NULL, sender INTERGER NOT NULL, message TEXT NOT NULL);"));
|
QString("profile_id INTEGER NOT NULL, chat_id INTEGER NOT NULL, sender INTERGER NOT NULL, message TEXT NOT NULL);"));
|
||||||
db.exec(QString("CREATE TABLE IF NOT EXISTS aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT UNIQUE NOT NULL);"));
|
db->exec(QString("CREATE TABLE IF NOT EXISTS aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT UNIQUE NOT NULL);"));
|
||||||
db.exec(QString("CREATE TABLE IF NOT EXISTS chats (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE NOT NULL, ctype INTEGER NOT NULL);"));
|
db->exec(QString("CREATE TABLE IF NOT EXISTS chats (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE NOT NULL, ctype INTEGER NOT NULL);"));
|
||||||
|
|
||||||
updateChatsID();
|
updateChatsID();
|
||||||
updateAliases();
|
updateAliases();
|
||||||
|
@ -96,7 +98,7 @@ HistoryKeeper::HistoryKeeper(const QString &path, bool encr) :
|
||||||
|
|
||||||
HistoryKeeper::~HistoryKeeper()
|
HistoryKeeper::~HistoryKeeper()
|
||||||
{
|
{
|
||||||
db.close();
|
delete db;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryKeeper::addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt)
|
void HistoryKeeper::addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt)
|
||||||
|
@ -105,9 +107,9 @@ void HistoryKeeper::addChatEntry(const QString& chat, const QString& message, co
|
||||||
int sender_id = getAliasID(sender);
|
int sender_id = getAliasID(sender);
|
||||||
int profile_id = getCurrentProfileID();
|
int profile_id = getCurrentProfileID();
|
||||||
|
|
||||||
db.exec(QString("INSERT INTO history (profile_id, timestamp, chat_id, sender, message)") +
|
db->exec(QString("INSERT INTO history (profile_id, timestamp, chat_id, sender, message)") +
|
||||||
QString("VALUES (%1, %2, %3, %4, '%5');")
|
QString("VALUES (%1, %2, %3, %4, '%5');")
|
||||||
.arg(profile_id).arg(dt.toMSecsSinceEpoch()).arg(chat_id).arg(sender_id).arg(wrapMessage(message)));
|
.arg(profile_id).arg(dt.toMSecsSinceEpoch()).arg(chat_id).arg(sender_id).arg(wrapMessage(message)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<HistoryKeeper::HistMessage> HistoryKeeper::getChatHistory(HistoryKeeper::ChatType ct, const QString &profile,
|
QList<HistoryKeeper::HistMessage> HistoryKeeper::getChatHistory(HistoryKeeper::ChatType ct, const QString &profile,
|
||||||
|
@ -125,9 +127,9 @@ QList<HistoryKeeper::HistMessage> HistoryKeeper::getChatHistory(HistoryKeeper::C
|
||||||
QSqlQuery dbAnswer;
|
QSqlQuery dbAnswer;
|
||||||
if (ct == ctSingle)
|
if (ct == ctSingle)
|
||||||
{
|
{
|
||||||
dbAnswer = db.exec(QString("SELECT timestamp, user_id, message FROM history INNER JOIN aliases ON history.sender = aliases.id ") +
|
dbAnswer = db->exec(QString("SELECT timestamp, user_id, message FROM history INNER JOIN aliases ON history.sender = aliases.id ") +
|
||||||
QString("AND timestamp BETWEEN %1 AND %2 AND chat_id = %3 AND profile_id = %4;")
|
QString("AND timestamp BETWEEN %1 AND %2 AND chat_id = %3 AND profile_id = %4;")
|
||||||
.arg(time64_from).arg(time64_to).arg(chat_id).arg(profile_id));
|
.arg(time64_from).arg(time64_to).arg(chat_id).arg(profile_id));
|
||||||
} else {
|
} else {
|
||||||
// no groupchats yet
|
// no groupchats yet
|
||||||
}
|
}
|
||||||
|
@ -161,7 +163,7 @@ QString HistoryKeeper::unWrapMessage(const QString &str)
|
||||||
|
|
||||||
void HistoryKeeper::updateChatsID()
|
void HistoryKeeper::updateChatsID()
|
||||||
{
|
{
|
||||||
auto dbAnswer = db.exec(QString("SELECT * FROM chats;"));
|
auto dbAnswer = db->exec(QString("SELECT * FROM chats;"));
|
||||||
|
|
||||||
chats.clear();
|
chats.clear();
|
||||||
while (dbAnswer.next())
|
while (dbAnswer.next())
|
||||||
|
@ -176,7 +178,7 @@ void HistoryKeeper::updateChatsID()
|
||||||
|
|
||||||
void HistoryKeeper::updateAliases()
|
void HistoryKeeper::updateAliases()
|
||||||
{
|
{
|
||||||
auto dbAnswer = db.exec(QString("SELECT * FROM aliases;"));
|
auto dbAnswer = db->exec(QString("SELECT * FROM aliases;"));
|
||||||
|
|
||||||
aliases.clear();
|
aliases.clear();
|
||||||
while (dbAnswer.next())
|
while (dbAnswer.next())
|
||||||
|
@ -194,7 +196,7 @@ QPair<int, HistoryKeeper::ChatType> HistoryKeeper::getChatID(const QString &id_s
|
||||||
if (it != chats.end())
|
if (it != chats.end())
|
||||||
return it.value();
|
return it.value();
|
||||||
|
|
||||||
db.exec(QString("INSERT INTO chats (name, ctype) VALUES ('%1', '%2');").arg(id_str).arg(ct));
|
db->exec(QString("INSERT INTO chats (name, ctype) VALUES ('%1', '%2');").arg(id_str).arg(ct));
|
||||||
updateChatsID();
|
updateChatsID();
|
||||||
|
|
||||||
return getChatID(id_str, ct);
|
return getChatID(id_str, ct);
|
||||||
|
@ -206,7 +208,7 @@ int HistoryKeeper::getAliasID(const QString &id_str)
|
||||||
if (it != aliases.end())
|
if (it != aliases.end())
|
||||||
return it.value();
|
return it.value();
|
||||||
|
|
||||||
db.exec(QString("INSERT INTO aliases (user_id) VALUES ('%1');").arg(id_str));
|
db->exec(QString("INSERT INTO aliases (user_id) VALUES ('%1');").arg(id_str));
|
||||||
updateAliases();
|
updateAliases();
|
||||||
|
|
||||||
return getAliasID(id_str);
|
return getAliasID(id_str);
|
||||||
|
@ -230,34 +232,6 @@ void HistoryKeeper::addGroupChatEntry(const QString &chat, const QString &messag
|
||||||
// no groupchats yet
|
// no groupchats yet
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryKeeper::syncToDisk()
|
|
||||||
{
|
|
||||||
if (!isEncrypted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QTemporaryFile tmpDump;
|
|
||||||
if (tmpDump.open())
|
|
||||||
{
|
|
||||||
QString fname = tmpDump.fileName();
|
|
||||||
if (!dumpDBtoFile(fname))
|
|
||||||
{
|
|
||||||
// warning
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// encryption here
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// warning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HistoryKeeper::dumpDBtoFile(const QString &fname)
|
|
||||||
{
|
|
||||||
Q_UNUSED(fname)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int HistoryKeeper::getCurrentProfileID()
|
int HistoryKeeper::getCurrentProfileID()
|
||||||
{
|
{
|
||||||
// for many profiles
|
// for many profiles
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QSqlDatabase>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
|
class GenericDdInterface;
|
||||||
|
|
||||||
class HistoryKeeper
|
class HistoryKeeper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -42,12 +43,11 @@ public:
|
||||||
void addGroupChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt);
|
void addGroupChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt);
|
||||||
QList<HistMessage> getChatHistory(ChatType ct, const QString &profile, const QString &chat,
|
QList<HistMessage> getChatHistory(ChatType ct, const QString &profile, const QString &chat,
|
||||||
const QDateTime &time_from, const QDateTime &time_to);
|
const QDateTime &time_from, const QDateTime &time_to);
|
||||||
void syncToDisk();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
HistoryKeeper(const QString &path, bool encr = false);
|
HistoryKeeper(GenericDdInterface *db_);
|
||||||
HistoryKeeper(HistoryKeeper &settings) = delete;
|
HistoryKeeper(HistoryKeeper &hk) = delete;
|
||||||
HistoryKeeper& operator=(const HistoryKeeper&) = delete;
|
HistoryKeeper& operator=(const HistoryKeeper&) = delete;
|
||||||
|
|
||||||
void updateChatsID();
|
void updateChatsID();
|
||||||
|
@ -57,11 +57,10 @@ private:
|
||||||
int getCurrentProfileID();
|
int getCurrentProfileID();
|
||||||
QString wrapMessage(const QString &str);
|
QString wrapMessage(const QString &str);
|
||||||
QString unWrapMessage(const QString &str);
|
QString unWrapMessage(const QString &str);
|
||||||
bool dumpDBtoFile(const QString &fname);
|
|
||||||
|
|
||||||
ChatType convertToChatType(int);
|
ChatType convertToChatType(int);
|
||||||
|
|
||||||
QSqlDatabase db;
|
GenericDdInterface *db;
|
||||||
QMap<QString, int> aliases;
|
QMap<QString, int> aliases;
|
||||||
QMap<QString, QPair<int, ChatType>> chats;
|
QMap<QString, QPair<int, ChatType>> chats;
|
||||||
bool isEncrypted;
|
bool isEncrypted;
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
#include "encrypteddb.h"
|
#include "encrypteddb.h"
|
||||||
#include "src/misc/settings.h"
|
#include "src/misc/settings.h"
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
EncryptedDb::EncryptedDb(const QString &fname, const QString &key) :
|
EncryptedDb::EncryptedDb(const QString &fname, const QString &key) :
|
||||||
key(key), encrFile(fname), PlainDb(":memory:")
|
PlainDb(":memory:"), key(key), encrFile(fname)
|
||||||
{
|
{
|
||||||
QList<QString> sqlCommands = decryptFile();
|
QList<QString> sqlCommands = decryptFile();
|
||||||
for (const QString &cmd : sqlCommands)
|
for (const QString &cmd : sqlCommands)
|
||||||
{
|
{
|
||||||
PlainDb::exec(true, cmd);
|
PlainDb::exec(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,13 +35,13 @@ EncryptedDb::~EncryptedDb()
|
||||||
// save to file if necessary
|
// save to file if necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlQuery EncryptedDb::exec(bool keep, const QString &query)
|
QSqlQuery EncryptedDb::exec(const QString &query)
|
||||||
{
|
{
|
||||||
QSqlQuery ret = PlainDb::exec(keep, query);
|
QSqlQuery retQSqlQuery = PlainDb::exec(query);
|
||||||
if (keep)
|
if (query.startsWith("INSERT", Qt::CaseInsensitive))
|
||||||
appendToEncrypted(query);
|
appendToEncrypted(query);
|
||||||
|
|
||||||
return ret;
|
return retQSqlQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EncryptedDb::save()
|
bool EncryptedDb::save()
|
||||||
|
@ -56,5 +56,5 @@ QList<QString> EncryptedDb::decryptFile()
|
||||||
|
|
||||||
void EncryptedDb::appendToEncrypted(const QString &sql)
|
void EncryptedDb::appendToEncrypted(const QString &sql)
|
||||||
{
|
{
|
||||||
Q_UNUSED(sql)
|
qDebug() << sql;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "plaindb.h"
|
#include "plaindb.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
class EncryptedDb : public PlainDb
|
class EncryptedDb : public PlainDb
|
||||||
{
|
{
|
||||||
|
@ -27,18 +28,17 @@ public:
|
||||||
EncryptedDb(const QString& fname, const QString &key);
|
EncryptedDb(const QString& fname, const QString &key);
|
||||||
virtual ~EncryptedDb();
|
virtual ~EncryptedDb();
|
||||||
|
|
||||||
virtual QSqlQuery exec(bool keep, const QString &query);
|
virtual QSqlQuery exec(const QString &query);
|
||||||
virtual bool save();
|
virtual bool save();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getFileName(){return encrFile;}
|
|
||||||
QString getKey(){return key;}
|
QString getKey(){return key;}
|
||||||
|
|
||||||
QList<QString> decryptFile();
|
QList<QString> decryptFile();
|
||||||
void appendToEncrypted(const QString &sql);
|
void appendToEncrypted(const QString &sql);
|
||||||
|
|
||||||
QString key;
|
QString key;
|
||||||
QString encrFile;
|
QFile encrFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENCRYPTEDDB_H
|
#endif // ENCRYPTEDDB_H
|
||||||
|
|
|
@ -25,7 +25,7 @@ class GenericDdInterface
|
||||||
public:
|
public:
|
||||||
virtual ~GenericDdInterface();
|
virtual ~GenericDdInterface();
|
||||||
|
|
||||||
virtual QSqlQuery exec(bool keep, const QString &query) = 0;
|
virtual QSqlQuery exec(const QString &query) = 0;
|
||||||
virtual bool save() = 0;
|
virtual bool save() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,8 @@ PlainDb::~PlainDb()
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSqlQuery PlainDb::exec(bool keep, const QString &query)
|
QSqlQuery PlainDb::exec(const QString &query)
|
||||||
{
|
{
|
||||||
Q_UNUSED(keep)
|
|
||||||
return db.exec(query);
|
return db.exec(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
PlainDb(const QString &db_name);
|
PlainDb(const QString &db_name);
|
||||||
virtual ~PlainDb();
|
virtual ~PlainDb();
|
||||||
|
|
||||||
virtual QSqlQuery exec(bool keep, const QString &query);
|
virtual QSqlQuery exec(const QString &query);
|
||||||
virtual bool save();
|
virtual bool save();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user