/*
Copyright © 2015 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
qTox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with qTox. If not, see .
*/
#include "profile.h"
#include "profilelocker.h"
#include "src/persistence/settings.h"
#include "src/core/core.h"
#include "src/persistence/historykeeper.h"
#include "src/widget/gui.h"
#include "src/widget/widget.h"
#include "src/nexus.h"
#include
#include
#include
#include
#include
#include
#include
QVector Profile::profiles;
Profile::Profile(QString name, QString password, bool isNewProfile)
: name{name}, password{password},
newProfile{isNewProfile}, isRemoved{false}
{
Settings& s = Settings::getInstance();
s.setCurrentProfile(name);
s.save(false);
HistoryKeeper::resetInstance();
coreThread = new QThread();
coreThread->setObjectName("qTox Core");
core = new Core(coreThread, *this);
core->moveToThread(coreThread);
QObject::connect(coreThread, &QThread::started, core, &Core::start);
}
Profile* Profile::loadProfile(QString name, QString password)
{
if (ProfileLocker::hasLock())
{
qCritical() << "Tried to load profile "<isReady())
saveToxSave();
delete core;
delete coreThread;
ProfileLocker::assertLock();
assert(ProfileLocker::getCurLockName() == name);
ProfileLocker::unlock();
}
QVector Profile::getFilesByExt(QString extension)
{
QDir dir(Settings::getInstance().getSettingsDirPath());
QVector out;
dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
dir.setNameFilters(QStringList("*."+extension));
QFileInfoList list = dir.entryInfoList();
out.reserve(list.size());
for (QFileInfo file : list)
out += file.completeBaseName();
return out;
}
void Profile::scanProfiles()
{
profiles.clear();
QVector toxfiles = getFilesByExt("tox"), inifiles = getFilesByExt("ini");
for (QString toxfile : toxfiles)
{
if (!inifiles.contains(toxfile))
importProfile(toxfile);
profiles.append(toxfile);
}
}
void Profile::importProfile(QString name)
{
assert(!exists(name));
Settings::getInstance().createPersonal(name);
}
QVector Profile::getProfiles()
{
return profiles;
}
Core* Profile::getCore()
{
return core;
}
QString Profile::getName()
{
return name;
}
void Profile::startCore()
{
coreThread->start();
}
bool Profile::isNewProfile()
{
return newProfile;
}
QByteArray Profile::loadToxSave()
{
assert(!isRemoved);
/// TODO: Cache the data, invalidate it only when we save
QByteArray data;
QString path = Settings::getInstance().getSettingsDirPath() + name + ".tox";
QFile saveFile(path);
qint64 fileSize;
qDebug() << "Loading tox save "<(data.data()), salt);
core->setPassword(password, salt);
data = core->decryptData(data);
if (data.isEmpty())
qCritical() << "Failed to decrypt the tox save file";
}
else
{
if (!password.isEmpty())
qWarning() << "We have a password, but the tox save file is not encrypted";
}
fail:
saveFile.close();
return data;
}
void Profile::saveToxSave()
{
assert(core->isReady());
QByteArray data = core->getToxSaveData();
assert(data.size());
saveToxSave(data);
}
void Profile::saveToxSave(QByteArray data)
{
assert(!isRemoved);
ProfileLocker::assertLock();
assert(ProfileLocker::getCurLockName() == name);
QString path = Settings::getInstance().getSettingsDirPath() + name + ".tox";
qDebug() << "Saving tox save to "<setPassword(password);
data = core->encryptData(data);
if (data.isEmpty())
{
qCritical() << "Failed to encrypt, can't save!";
saveFile.cancelWriting();
return;
}
}
saveFile.write(data);
saveFile.commit();
newProfile = false;
}
bool Profile::exists(QString name)
{
QString path = Settings::getInstance().getSettingsDirPath() + name;
return QFile::exists(path+".tox") && QFile::exists(path+".ini");
}
bool Profile::isEncrypted()
{
return !password.isEmpty();
}
bool Profile::isEncrypted(QString name)
{
uint8_t data[encryptHeaderSize] = {0};
QString path = Settings::getInstance().getSettingsDirPath() + name + ".tox";
QFile saveFile(path);
if (!saveFile.open(QIODevice::ReadOnly))
{
qWarning() << "Couldn't open tox save "<isReady())
saveToxSave();
QMetaObject::invokeMethod(core, "reset");
}
void Profile::setPassword(QString newPassword)
{
QList oldMessages = HistoryKeeper::exportMessagesDeleteFile();
password = newPassword;
core->setPassword(password);
saveToxSave();
HistoryKeeper::getInstance()->importMessages(oldMessages);
Nexus::getDesktopGUI()->reloadHistory();
}