Flatpak migration and account security

Flatpak:
- Rewrite chat message deprecated logs : no more ensuring that this file must exists
- If a message history file exists in the application folder, let the SDK migrate data and remove the file
- Copy recursively all data from Flatpak installation, if files doesn't exist
- Split 2 migrations : old GTK and Flatpak
This commit is contained in:
Julien Wadel 2020-06-11 10:19:07 +02:00
parent 0ac9f08b9f
commit 72b5293594
8 changed files with 76 additions and 24 deletions

View file

@ -240,7 +240,7 @@ string Paths::getLogsDirPath () {
}
string Paths::getMessageHistoryFilePath () {
return getWritableFilePath(getAppMessageHistoryFilePath());
return getReadableFilePath(getAppMessageHistoryFilePath());// No need to ensure that the file exists as this DB is deprecated
}
string Paths::getPackageDataDirPath () {
@ -300,10 +300,19 @@ static void migrateConfigurationFile (const QString &oldPath, const QString &new
qWarning() << "Failed migration of" << oldPath << "to" << newPath;
}
}
void Paths::migrate () {
void migrateFlatpakVersionFiles(){
#ifdef Q_OS_LINUX
// Copy all files
QString flatpakPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.var/app/com.belledonnecommunications.linphone/data/linphone";
if( QDir().exists(flatpakPath)){
qInfo() << "Migrating data from Flatpak.";
Utils::copyDir(flatpakPath, QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
}
#endif
}
void migrateGTKVersionFiles(){
QString newPath = getAppConfigFilePath();
QString oldBaseDir = QSysInfo::productType() == QLatin1String("windows")
QString oldBaseDir = QSysInfo::productType() == QLatin1String("windows")
? QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
: QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
QString oldPath = oldBaseDir + "/.linphonerc";
@ -329,3 +338,7 @@ void Paths::migrate () {
if (!filePathExists(newPath) && filePathExists(oldPath))
migrateFile(oldPath, newPath);
}
void Paths::migrate () {
migrateFlatpakVersionFiles(); // First, check Flatpak version as it is the earlier version
migrateGTKVersionFiles();// Then check old version for migration
}

View file

@ -22,6 +22,7 @@
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "utils/LinphoneUtils.hpp"
#include "utils/Utils.hpp"
@ -55,9 +56,9 @@ private:
linphone::AccountCreator::Status status,
const string &
) override {
if (status == linphone::AccountCreator::Status::AccountCreated)
if (status == linphone::AccountCreator::Status::AccountCreated){
emit mAssistant->createStatusChanged(QString(""));
else {
}else {
if (status == linphone::AccountCreator::Status::RequestFailed)
emit mAssistant->createStatusChanged(tr("requestFailed"));
else if (status == linphone::AccountCreator::Status::ServerError)
@ -74,6 +75,7 @@ private:
) override {
if (status == linphone::AccountCreator::Status::AccountExist || status == linphone::AccountCreator::Status::AccountExistWithAlias) {
createProxyConfig(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->loginStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
@ -94,7 +96,7 @@ private:
) {
if (creator->getEmail().empty())
createProxyConfig(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
@ -111,6 +113,7 @@ private:
) override {
if (status == linphone::AccountCreator::Status::AccountActivated) {
createProxyConfig(creator);
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->activateStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)
@ -126,6 +129,7 @@ private:
const string &
) override {
if (status == linphone::AccountCreator::Status::RequestOk) {
CoreManager::getInstance()->getSipAddressesModel()->reset();
emit mAssistant->recoverStatusChanged(QString(""));
} else {
if (status == linphone::AccountCreator::Status::RequestFailed)

View file

@ -23,6 +23,7 @@
#include <QSysInfo>
#include <QtConcurrent>
#include <QTimer>
#include <QFile>
#include "config.h"
@ -210,7 +211,10 @@ void CoreManager::cleanLogs () const {
void CoreManager::setDatabasesPaths () {
SET_DATABASE_PATH(Friends, Paths::getFriendsListFilePath());
SET_DATABASE_PATH(CallLogs, Paths::getCallHistoryFilePath());
SET_DATABASE_PATH(Chat, Paths::getMessageHistoryFilePath());
if(QFile::exists(Utils::coreStringToAppString(Paths::getMessageHistoryFilePath()))){
SET_DATABASE_PATH(Chat, Paths::getMessageHistoryFilePath());// Setting the message database let SDK to migrate data
QFile::remove(Utils::coreStringToAppString(Paths::getMessageHistoryFilePath()));
}
}
#undef SET_DATABASE_PATH

View file

@ -74,7 +74,13 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
}
// -----------------------------------------------------------------------------
void SipAddressesModel::reset(){
mPeerAddressToSipAddressEntry.clear();
mRefs.clear();
resetInternalData();
initSipAddresses();
emit sipAddressReset();
}
int SipAddressesModel::rowCount (const QModelIndex &) const {
return mRefs.count();
}
@ -433,7 +439,6 @@ void SipAddressesModel::handleIsComposingChanged (const shared_ptr<linphone::Cha
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
}
// -----------------------------------------------------------------------------
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, ContactModel *contact) {
@ -548,6 +553,7 @@ void SipAddressesModel::initSipAddresses () {
}
void SipAddressesModel::initSipAddressesFromChat () {
for (const auto &chatRoom : CoreManager::getInstance()->getCore()->getChatRooms()) {
list<shared_ptr<linphone::ChatMessage>> history(chatRoom->getHistory(1));
if (history.empty())
@ -571,19 +577,18 @@ void SipAddressesModel::initSipAddressesFromCalls () {
for (const auto &callLog : CoreManager::getInstance()->getCore()->getCallLogs()) {
const QString peerAddress(Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()));
const QString localAddress(Utils::coreStringToAppString(callLog->getLocalAddress()->asStringUriOnly()));
switch (callLog->getStatus()) {
case linphone::Call::Status::Aborted:
case linphone::Call::Status::EarlyAborted:
return; // Ignore aborted calls.
case linphone::Call::Status::AcceptedElsewhere:
case linphone::Call::Status::DeclinedElsewhere:
return; // Ignore accepted calls on other device.
case linphone::Call::Status::Success:
case linphone::Call::Status::Declined:
case linphone::Call::Status::Aborted:
case linphone::Call::Status::EarlyAborted:
return; // Ignore aborted calls.
case linphone::Call::Status::AcceptedElsewhere:
case linphone::Call::Status::DeclinedElsewhere:
return; // Ignore accepted calls on other device.
case linphone::Call::Status::Success:
case linphone::Call::Status::Declined:
case linphone::Call::Status::Missed:
break;
case linphone::Call::Status::Missed:
break;
}
ConferenceId conferenceId{ peerAddress, localAddress };
@ -593,8 +598,8 @@ void SipAddressesModel::initSipAddressesFromCalls () {
// The duration can be wrong if status is not success.
QDateTime timestamp(callLog->getStatus() == linphone::Call::Status::Success
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000));
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000));
auto &localToConferenceEntry = getSipAddressEntry(peerAddress)->localAddressToConferenceEntry;
auto it = localToConferenceEntry.find(localAddress);

View file

@ -52,6 +52,8 @@ public:
};
SipAddressesModel (QObject *parent = Q_NULLPTR);
void reset();
int rowCount (const QModelIndex &index = QModelIndex()) const override;
@ -78,6 +80,8 @@ public:
Q_INVOKABLE static QString cleanSipAddress (const QString &sipAddress);
// ---------------------------------------------------------------------------
signals:
void sipAddressReset();// The model has been reset
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
@ -143,7 +147,6 @@ private:
it = mPeerAddressToSipAddressEntry.insert(peerAddress, { peerAddress, nullptr, Presence::Offline, {} });
return &(*it);
}
QHash<QString, SipAddressEntry> mPeerAddressToSipAddressEntry;
QList<const SipAddressEntry *> mRefs;

View file

@ -33,6 +33,9 @@ TimelineModel::TimelineModel (QObject *parent) : QSortFilterProxyModel(parent) {
QObject::connect(accountSettingsModel, &AccountSettingsModel::accountSettingsUpdated, this, [this]() {
handleLocalAddressChanged(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddressAsStringUriOnly());
});
QObject::connect(coreManager->getSipAddressesModel(), &SipAddressesModel::sipAddressReset, this, [this]() {
invalidate();// Invalidate and reload GUI if the model has been reset
});
mLocalAddress = accountSettingsModel->getUsedSipAddressAsStringUriOnly();
setSourceModel(coreManager->getSipAddressesModel());

View file

@ -20,6 +20,8 @@
#include <QFileInfo>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include "Utils.hpp"
@ -355,3 +357,20 @@ QString Utils::getCountryName(const QLocale::Country& p_country)
countryName = QLocale::countryToString(p_country);
return countryName;
}
// Copy a folder recursively without erasing old file
void Utils::copyDir(QString from, QString to) {
QDir dir;
dir.setPath(from);
from += QDir::separator();
to += QDir::separator();
foreach (QString copyFile, dir.entryList(QDir::Files)) {// Copy each files
QString toFile = to + copyFile;
if (!QFile::exists(toFile))
QFile::copy(from+copyFile, toFile);
}
foreach (QString nextDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {// Copy folder
QString toDir = to + nextDir;
QDir().mkpath(toDir);// no need to check if dir exists
copyDir(from + nextDir, toDir);//Go up
}
}

View file

@ -98,6 +98,7 @@ namespace Utils {
return connection;
}
QString getCountryName(const QLocale::Country& country);
void copyDir(QString from, QString to);// Copy a folder recursively without erasing old file
}
#endif // UTILS_H_