mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
history: encrypted <-> plain convertion
This commit is contained in:
parent
1d24eb14b4
commit
000eb8977d
@ -68,11 +68,14 @@ HistoryKeeper *HistoryKeeper::getInstance()
|
|||||||
return historyInstance;
|
return historyInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryKeeper::checkPassword()
|
bool HistoryKeeper::checkPassword(int encrypted)
|
||||||
{
|
{
|
||||||
if (Settings::getInstance().getEnableLogging())
|
if (!Settings::getInstance().getEnableLogging() && (encrypted == -1))
|
||||||
if (Settings::getInstance().getEncryptLogs())
|
return true;
|
||||||
return EncryptedDb::check(getHistoryPath());
|
|
||||||
|
if ((encrypted == 1) || (encrypted == -1 && Settings::getInstance().getEncryptLogs()))
|
||||||
|
return EncryptedDb::check(getHistoryPath(Settings::getInstance().getCurrentProfile(), encrypted));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +130,7 @@ HistoryKeeper::HistoryKeeper(GenericDdInterface *db_) :
|
|||||||
messageID = 0;
|
messageID = 0;
|
||||||
QSqlQuery sqlAnswer = db->exec("select seq from sqlite_sequence where name=\"history\";");
|
QSqlQuery sqlAnswer = db->exec("select seq from sqlite_sequence where name=\"history\";");
|
||||||
if (sqlAnswer.first())
|
if (sqlAnswer.first())
|
||||||
messageID = sqlAnswer.value(0).toInt();
|
messageID = sqlAnswer.value(0).toLongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryKeeper::~HistoryKeeper()
|
HistoryKeeper::~HistoryKeeper()
|
||||||
@ -141,16 +144,13 @@ void HistoryKeeper::reencrypt(QString newpw)
|
|||||||
// if newpw.isEmpty(), then use the other core password
|
// if newpw.isEmpty(), then use the other core password
|
||||||
}
|
}
|
||||||
|
|
||||||
int HistoryKeeper::addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent)
|
qint64 HistoryKeeper::addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent)
|
||||||
{
|
{
|
||||||
int chat_id = getChatID(chat, ctSingle).first;
|
QList<QString> cmds = generateAddChatEntryCmd(chat, message, sender, dt, isSent);
|
||||||
int sender_id = getAliasID(sender);
|
|
||||||
|
|
||||||
db->exec("BEGIN TRANSACTION;");
|
db->exec("BEGIN TRANSACTION;");
|
||||||
db->exec(QString("INSERT INTO history (timestamp, chat_id, sender, message)") +
|
for (auto &it : cmds)
|
||||||
QString("VALUES (%1, %2, %3, '%4');")
|
db->exec(it);
|
||||||
.arg(dt.toMSecsSinceEpoch()).arg(chat_id).arg(sender_id).arg(wrapMessage(message)));
|
|
||||||
db->exec(QString("INSERT INTO sent_status (status) VALUES (%1);").arg(isSent));
|
|
||||||
db->exec("COMMIT TRANSACTION;");
|
db->exec("COMMIT TRANSACTION;");
|
||||||
|
|
||||||
messageID++;
|
messageID++;
|
||||||
@ -189,12 +189,66 @@ QList<HistoryKeeper::HistMessage> HistoryKeeper::getChatHistory(HistoryKeeper::C
|
|||||||
|
|
||||||
QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt);
|
QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt);
|
||||||
|
|
||||||
res.push_back({id, sender,message,time,isSent});
|
res.push_back(HistMessage(id, "", sender, message, time, isSent));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<HistoryKeeper::HistMessage> HistoryKeeper::exportMessages()
|
||||||
|
{
|
||||||
|
QSqlQuery dbAnswer;
|
||||||
|
dbAnswer = db->exec(QString("SELECT history.id, timestamp, user_id, message, status, name FROM history LEFT JOIN sent_status ON history.id = sent_status.id ") +
|
||||||
|
QString("INNER JOIN aliases ON history.sender = aliases.id INNER JOIN chats ON history.chat_id = chats.id;"));
|
||||||
|
|
||||||
|
QList<HistMessage> res;
|
||||||
|
|
||||||
|
while (dbAnswer.next())
|
||||||
|
{
|
||||||
|
qint64 id = dbAnswer.value(0).toLongLong();
|
||||||
|
qint64 timeInt = dbAnswer.value(1).toLongLong();
|
||||||
|
QString sender = dbAnswer.value(2).toString();
|
||||||
|
QString message = unWrapMessage(dbAnswer.value(3).toString());
|
||||||
|
bool isSent = true;
|
||||||
|
if (!dbAnswer.value(4).isNull())
|
||||||
|
isSent = dbAnswer.value(4).toBool();
|
||||||
|
QString chat = dbAnswer.value(5).toString();
|
||||||
|
QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt);
|
||||||
|
|
||||||
|
res.push_back(HistMessage(id, chat, sender, message, time, isSent));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryKeeper::importMessages(const QList<HistoryKeeper::HistMessage> &lst)
|
||||||
|
{
|
||||||
|
db->exec("BEGIN TRANSACTION;");
|
||||||
|
for (const HistMessage &msg : lst)
|
||||||
|
{
|
||||||
|
QList<QString> cmds = generateAddChatEntryCmd(msg.chat, msg.message, msg.sender, msg.timestamp, msg.isSent);
|
||||||
|
for (auto &it : cmds)
|
||||||
|
db->exec(it);
|
||||||
|
|
||||||
|
messageID++;
|
||||||
|
}
|
||||||
|
db->exec("COMMIT TRANSACTION;");
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> HistoryKeeper::generateAddChatEntryCmd(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent)
|
||||||
|
{
|
||||||
|
QList<QString> cmds;
|
||||||
|
|
||||||
|
int chat_id = getChatID(chat, ctSingle).first;
|
||||||
|
int sender_id = getAliasID(sender);
|
||||||
|
|
||||||
|
cmds.push_back(QString("INSERT INTO history (timestamp, chat_id, sender, message) VALUES (%1, %2, %3, '%4');")
|
||||||
|
.arg(dt.toMSecsSinceEpoch()).arg(chat_id).arg(sender_id).arg(wrapMessage(message)));
|
||||||
|
cmds.push_back(QString("INSERT INTO sent_status (status) VALUES (%1);").arg(isSent));
|
||||||
|
|
||||||
|
return cmds;
|
||||||
|
}
|
||||||
|
|
||||||
QString HistoryKeeper::wrapMessage(const QString &str)
|
QString HistoryKeeper::wrapMessage(const QString &str)
|
||||||
{
|
{
|
||||||
QString wrappedMessage(str);
|
QString wrappedMessage(str);
|
||||||
@ -271,7 +325,7 @@ void HistoryKeeper::resetInstance()
|
|||||||
historyInstance = nullptr;
|
historyInstance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HistoryKeeper::addGroupChatEntry(const QString &chat, const QString &message, const QString &sender, const QDateTime &dt)
|
qint64 HistoryKeeper::addGroupChatEntry(const QString &chat, const QString &message, const QString &sender, const QDateTime &dt)
|
||||||
{
|
{
|
||||||
Q_UNUSED(chat)
|
Q_UNUSED(chat)
|
||||||
Q_UNUSED(message)
|
Q_UNUSED(message)
|
||||||
@ -349,3 +403,13 @@ bool HistoryKeeper::isFileExist()
|
|||||||
|
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HistoryKeeper::removeHistory(int encrypted)
|
||||||
|
{
|
||||||
|
Q_UNUSED(encrypted);
|
||||||
|
resetInstance();
|
||||||
|
|
||||||
|
QString path = getHistoryPath();
|
||||||
|
QFile DbFile(path);
|
||||||
|
return DbFile.remove();
|
||||||
|
}
|
||||||
|
@ -31,7 +31,11 @@ public:
|
|||||||
|
|
||||||
struct HistMessage
|
struct HistMessage
|
||||||
{
|
{
|
||||||
|
HistMessage(qint64 id, QString chat, QString sender, QString message, QDateTime timestamp, bool isSent) :
|
||||||
|
id(id), chat(chat), sender(sender), message(message), timestamp(timestamp), isSent(isSent) {}
|
||||||
|
|
||||||
qint64 id;
|
qint64 id;
|
||||||
|
QString chat;
|
||||||
QString sender;
|
QString sender;
|
||||||
QString message;
|
QString message;
|
||||||
QDateTime timestamp;
|
QDateTime timestamp;
|
||||||
@ -44,16 +48,20 @@ public:
|
|||||||
static void resetInstance();
|
static void resetInstance();
|
||||||
|
|
||||||
static QString getHistoryPath(QString currentProfile = QString(), int encrypted = -1); // -1 defaults to checking settings, 0 or 1 to specify
|
static QString getHistoryPath(QString currentProfile = QString(), int encrypted = -1); // -1 defaults to checking settings, 0 or 1 to specify
|
||||||
static bool checkPassword();
|
static bool checkPassword(int encrypted = -1);
|
||||||
static bool isFileExist();
|
static bool isFileExist();
|
||||||
static void renameHistory(QString from, QString to);
|
static void renameHistory(QString from, QString to);
|
||||||
|
static bool removeHistory(int encrypted = -1);
|
||||||
|
|
||||||
int addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent);
|
qint64 addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent);
|
||||||
int addGroupChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt);
|
qint64 addGroupChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt);
|
||||||
QList<HistMessage> getChatHistory(ChatType ct, const QString &chat, const QDateTime &time_from, const QDateTime &time_to);
|
QList<HistMessage> getChatHistory(ChatType ct, const QString &chat, const QDateTime &time_from, const QDateTime &time_to);
|
||||||
void markAsSent(int m_id);
|
void markAsSent(int m_id);
|
||||||
void reencrypt(QString newpw);
|
void reencrypt(QString newpw);
|
||||||
|
|
||||||
|
QList<HistMessage> exportMessages();
|
||||||
|
void importMessages(const QList<HistoryKeeper::HistMessage> &lst);
|
||||||
|
|
||||||
void setSyncType(Db::syncType sType);
|
void setSyncType(Db::syncType sType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,13 +75,14 @@ private:
|
|||||||
int getAliasID(const QString &id_str);
|
int getAliasID(const QString &id_str);
|
||||||
QString wrapMessage(const QString &str);
|
QString wrapMessage(const QString &str);
|
||||||
QString unWrapMessage(const QString &str);
|
QString unWrapMessage(const QString &str);
|
||||||
|
QList<QString> generateAddChatEntryCmd(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent);
|
||||||
|
|
||||||
ChatType convertToChatType(int);
|
ChatType convertToChatType(int);
|
||||||
|
|
||||||
GenericDdInterface *db;
|
GenericDdInterface *db;
|
||||||
QMap<QString, int> aliases;
|
QMap<QString, int> aliases;
|
||||||
QMap<QString, QPair<int, ChatType>> chats;
|
QMap<QString, QPair<int, ChatType>> chats;
|
||||||
int messageID;
|
qint64 messageID;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HISTORYKEEPER_H
|
#endif // HISTORYKEEPER_H
|
||||||
|
@ -33,12 +33,11 @@ EncryptedDb::EncryptedDb(const QString &fname, QList<QString> initList) :
|
|||||||
QByteArray fileContent;
|
QByteArray fileContent;
|
||||||
if (pullFileContent(fileName, buffer))
|
if (pullFileContent(fileName, buffer))
|
||||||
{
|
{
|
||||||
chunkPosition = encrFile.size() / encryptedChunkSize;
|
|
||||||
|
|
||||||
qDebug() << "writing old data";
|
qDebug() << "writing old data";
|
||||||
encrFile.setFileName(fileName);
|
encrFile.setFileName(fileName);
|
||||||
encrFile.open(QIODevice::ReadOnly);
|
encrFile.open(QIODevice::ReadOnly);
|
||||||
fileContent = encrFile.readAll();
|
fileContent = encrFile.readAll();
|
||||||
|
chunkPosition = encrFile.size() / encryptedChunkSize;
|
||||||
encrFile.close();
|
encrFile.close();
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "corrupted history log file will be wiped!";
|
qWarning() << "corrupted history log file will be wiped!";
|
||||||
@ -131,6 +130,7 @@ void EncryptedDb::appendToEncrypted(const QString &sql)
|
|||||||
if (encr.size() > 0)
|
if (encr.size() > 0)
|
||||||
{
|
{
|
||||||
encrFile.write(encr);
|
encrFile.write(encr);
|
||||||
|
encrFile.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = buffer.right(buffer.size() - plainChunkSize);
|
buffer = buffer.right(buffer.size() - plainChunkSize);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "src/widget/form/checkcontinue.h"
|
#include "src/widget/form/checkcontinue.h"
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
PrivacyForm::PrivacyForm() :
|
PrivacyForm::PrivacyForm() :
|
||||||
GenericForm(tr("Privacy"), QPixmap(":/img/settings/privacy.png"))
|
GenericForm(tr("Privacy"), QPixmap(":/img/settings/privacy.png"))
|
||||||
@ -79,7 +80,7 @@ bool PrivacyForm::setChatLogsPassword()
|
|||||||
QString newpw = dialog->getPassword();
|
QString newpw = dialog->getPassword();
|
||||||
delete dialog;
|
delete dialog;
|
||||||
|
|
||||||
if (!HistoryKeeper::checkPassword())
|
if (!HistoryKeeper::checkPassword(true))
|
||||||
if (checkContinue(tr("Old encrypted chat logs", "title"),
|
if (checkContinue(tr("Old encrypted chat logs", "title"),
|
||||||
tr("Would you like to re-encrypt your old chat logs?\nOtherwise they will be deleted.", "body")))
|
tr("Would you like to re-encrypt your old chat logs?\nOtherwise they will be deleted.", "body")))
|
||||||
{
|
{
|
||||||
@ -106,6 +107,7 @@ bool PrivacyForm::setChatLogsPassword()
|
|||||||
void PrivacyForm::onEncryptLogsUpdated()
|
void PrivacyForm::onEncryptLogsUpdated()
|
||||||
{
|
{
|
||||||
Core* core = Core::getInstance();
|
Core* core = Core::getInstance();
|
||||||
|
QList<HistoryKeeper::HistMessage> oldMessages;
|
||||||
|
|
||||||
if (bodyUI->cbEncryptHistory->isChecked())
|
if (bodyUI->cbEncryptHistory->isChecked())
|
||||||
{
|
{
|
||||||
@ -113,10 +115,19 @@ void PrivacyForm::onEncryptLogsUpdated()
|
|||||||
{
|
{
|
||||||
if (setChatLogsPassword())
|
if (setChatLogsPassword())
|
||||||
{
|
{
|
||||||
|
oldMessages = HistoryKeeper::getInstance()->exportMessages();
|
||||||
|
qDebug() << "Loaded messages:" << oldMessages.size();
|
||||||
|
bool delRet = HistoryKeeper::removeHistory();
|
||||||
|
if (!delRet)
|
||||||
|
qWarning() << "HistoryKeeper::removeHistory() returned FALSE";
|
||||||
|
HistoryKeeper::resetInstance(); // HistoryKeeper::removeHistory() invokes HistoryKeeper::removeHistory() but logic may be changed
|
||||||
|
|
||||||
Settings::getInstance().setEncryptLogs(true);
|
Settings::getInstance().setEncryptLogs(true);
|
||||||
bodyUI->cbEncryptHistory->setChecked(true);
|
bodyUI->cbEncryptHistory->setChecked(true);
|
||||||
// not logically necessary, but more consistent (esp. if the logic changes)
|
// not logically necessary, but more consistent (esp. if the logic changes)
|
||||||
bodyUI->changeLogsPwButton->setEnabled(true);
|
bodyUI->changeLogsPwButton->setEnabled(true);
|
||||||
|
|
||||||
|
HistoryKeeper::getInstance()->importMessages(oldMessages);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,10 +136,20 @@ void PrivacyForm::onEncryptLogsUpdated()
|
|||||||
{
|
{
|
||||||
if (checkContinue(tr("Old encrypted chat logs", "title"), tr("Would you like to un-encrypt your chat logs?\nOtherwise they will be deleted.")))
|
if (checkContinue(tr("Old encrypted chat logs", "title"), tr("Would you like to un-encrypt your chat logs?\nOtherwise they will be deleted.")))
|
||||||
{
|
{
|
||||||
// TODO: how to unencrypt current encrypted logs
|
oldMessages = HistoryKeeper::getInstance()->exportMessages();
|
||||||
|
qDebug() << "Loaded messages:" << oldMessages.size();
|
||||||
|
bool delRet = HistoryKeeper::removeHistory();
|
||||||
|
if (!delRet)
|
||||||
|
qWarning() << "HistoryKeeper::removeHistory() returned FALSE";
|
||||||
|
HistoryKeeper::resetInstance(); // HistoryKeeper::removeHistory() invokes HistoryKeeper::removeHistory() but logic may be changed
|
||||||
|
|
||||||
|
Settings::getInstance().setEncryptLogs(false);
|
||||||
|
HistoryKeeper::getInstance()->importMessages(oldMessages);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
HistoryKeeper::resetInstance();
|
HistoryKeeper::resetInstance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core->clearPassword(Core::ptHistory);
|
core->clearPassword(Core::ptHistory);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user