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;
|
||||
}
|
||||
|
||||
bool HistoryKeeper::checkPassword()
|
||||
bool HistoryKeeper::checkPassword(int encrypted)
|
||||
{
|
||||
if (Settings::getInstance().getEnableLogging())
|
||||
if (Settings::getInstance().getEncryptLogs())
|
||||
return EncryptedDb::check(getHistoryPath());
|
||||
if (!Settings::getInstance().getEnableLogging() && (encrypted == -1))
|
||||
return true;
|
||||
|
||||
if ((encrypted == 1) || (encrypted == -1 && Settings::getInstance().getEncryptLogs()))
|
||||
return EncryptedDb::check(getHistoryPath(Settings::getInstance().getCurrentProfile(), encrypted));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -127,7 +130,7 @@ HistoryKeeper::HistoryKeeper(GenericDdInterface *db_) :
|
||||
messageID = 0;
|
||||
QSqlQuery sqlAnswer = db->exec("select seq from sqlite_sequence where name=\"history\";");
|
||||
if (sqlAnswer.first())
|
||||
messageID = sqlAnswer.value(0).toInt();
|
||||
messageID = sqlAnswer.value(0).toLongLong();
|
||||
}
|
||||
|
||||
HistoryKeeper::~HistoryKeeper()
|
||||
@ -141,16 +144,13 @@ void HistoryKeeper::reencrypt(QString newpw)
|
||||
// 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;
|
||||
int sender_id = getAliasID(sender);
|
||||
QList<QString> cmds = generateAddChatEntryCmd(chat, message, sender, dt, isSent);
|
||||
|
||||
db->exec("BEGIN TRANSACTION;");
|
||||
db->exec(QString("INSERT INTO history (timestamp, chat_id, sender, message)") +
|
||||
QString("VALUES (%1, %2, %3, '%4');")
|
||||
.arg(dt.toMSecsSinceEpoch()).arg(chat_id).arg(sender_id).arg(wrapMessage(message)));
|
||||
db->exec(QString("INSERT INTO sent_status (status) VALUES (%1);").arg(isSent));
|
||||
for (auto &it : cmds)
|
||||
db->exec(it);
|
||||
db->exec("COMMIT TRANSACTION;");
|
||||
|
||||
messageID++;
|
||||
@ -189,12 +189,66 @@ QList<HistoryKeeper::HistMessage> HistoryKeeper::getChatHistory(HistoryKeeper::C
|
||||
|
||||
QDateTime time = QDateTime::fromMSecsSinceEpoch(timeInt);
|
||||
|
||||
res.push_back({id, sender,message,time,isSent});
|
||||
res.push_back(HistMessage(id, "", sender, message, time, isSent));
|
||||
}
|
||||
|
||||
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 wrappedMessage(str);
|
||||
@ -271,7 +325,7 @@ void HistoryKeeper::resetInstance()
|
||||
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(message)
|
||||
@ -349,3 +403,13 @@ bool HistoryKeeper::isFileExist()
|
||||
|
||||
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
|
||||
{
|
||||
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;
|
||||
QString chat;
|
||||
QString sender;
|
||||
QString message;
|
||||
QDateTime timestamp;
|
||||
@ -44,16 +48,20 @@ public:
|
||||
static void resetInstance();
|
||||
|
||||
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 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);
|
||||
int addGroupChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt);
|
||||
qint64 addChatEntry(const QString& chat, const QString& message, const QString& sender, const QDateTime &dt, bool isSent);
|
||||
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);
|
||||
void markAsSent(int m_id);
|
||||
void reencrypt(QString newpw);
|
||||
|
||||
QList<HistMessage> exportMessages();
|
||||
void importMessages(const QList<HistoryKeeper::HistMessage> &lst);
|
||||
|
||||
void setSyncType(Db::syncType sType);
|
||||
|
||||
private:
|
||||
@ -67,13 +75,14 @@ private:
|
||||
int getAliasID(const QString &id_str);
|
||||
QString wrapMessage(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);
|
||||
|
||||
GenericDdInterface *db;
|
||||
QMap<QString, int> aliases;
|
||||
QMap<QString, QPair<int, ChatType>> chats;
|
||||
int messageID;
|
||||
qint64 messageID;
|
||||
};
|
||||
|
||||
#endif // HISTORYKEEPER_H
|
||||
|
@ -33,12 +33,11 @@ EncryptedDb::EncryptedDb(const QString &fname, QList<QString> initList) :
|
||||
QByteArray fileContent;
|
||||
if (pullFileContent(fileName, buffer))
|
||||
{
|
||||
chunkPosition = encrFile.size() / encryptedChunkSize;
|
||||
|
||||
qDebug() << "writing old data";
|
||||
encrFile.setFileName(fileName);
|
||||
encrFile.open(QIODevice::ReadOnly);
|
||||
fileContent = encrFile.readAll();
|
||||
chunkPosition = encrFile.size() / encryptedChunkSize;
|
||||
encrFile.close();
|
||||
} else {
|
||||
qWarning() << "corrupted history log file will be wiped!";
|
||||
@ -131,6 +130,7 @@ void EncryptedDb::appendToEncrypted(const QString &sql)
|
||||
if (encr.size() > 0)
|
||||
{
|
||||
encrFile.write(encr);
|
||||
encrFile.flush();
|
||||
}
|
||||
|
||||
buffer = buffer.right(buffer.size() - plainChunkSize);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "src/widget/form/checkcontinue.h"
|
||||
#include <QMessageBox>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
PrivacyForm::PrivacyForm() :
|
||||
GenericForm(tr("Privacy"), QPixmap(":/img/settings/privacy.png"))
|
||||
@ -79,7 +80,7 @@ bool PrivacyForm::setChatLogsPassword()
|
||||
QString newpw = dialog->getPassword();
|
||||
delete dialog;
|
||||
|
||||
if (!HistoryKeeper::checkPassword())
|
||||
if (!HistoryKeeper::checkPassword(true))
|
||||
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")))
|
||||
{
|
||||
@ -106,6 +107,7 @@ bool PrivacyForm::setChatLogsPassword()
|
||||
void PrivacyForm::onEncryptLogsUpdated()
|
||||
{
|
||||
Core* core = Core::getInstance();
|
||||
QList<HistoryKeeper::HistMessage> oldMessages;
|
||||
|
||||
if (bodyUI->cbEncryptHistory->isChecked())
|
||||
{
|
||||
@ -113,10 +115,19 @@ void PrivacyForm::onEncryptLogsUpdated()
|
||||
{
|
||||
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);
|
||||
bodyUI->cbEncryptHistory->setChecked(true);
|
||||
// not logically necessary, but more consistent (esp. if the logic changes)
|
||||
bodyUI->changeLogsPwButton->setEnabled(true);
|
||||
|
||||
HistoryKeeper::getInstance()->importMessages(oldMessages);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -125,11 +136,21 @@ 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.")))
|
||||
{
|
||||
// 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
|
||||
{
|
||||
HistoryKeeper::resetInstance();
|
||||
}
|
||||
}
|
||||
|
||||
core->clearPassword(Core::ptHistory);
|
||||
Settings::getInstance().setEncryptLogs(false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user