1
0
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:
apprb 2014-12-04 21:22:17 +06:00
parent 1d24eb14b4
commit 000eb8977d
No known key found for this signature in database
GPG Key ID: B001911B5B22FB9B
4 changed files with 116 additions and 22 deletions

View File

@ -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();
}

View File

@ -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

View File

@ -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);

View File

@ -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);