From edf545171455665dcc8e278f748db328d4120af4 Mon Sep 17 00:00:00 2001 From: Ilya Chelyadin Date: Fri, 18 Oct 2024 21:23:21 +0300 Subject: [PATCH 1/3] logs and cookies moved to state path Signed-off-by: Ilya Chelyadin --- src/gui/accountmanager.cpp | 1 + src/gui/syncrunfilelog.cpp | 2 +- src/gui/updater/ocupdater.cpp | 2 +- src/libsync/account.cpp | 13 ++++++++++++- src/libsync/account.h | 1 + src/libsync/configfile.cpp | 2 +- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/gui/accountmanager.cpp b/src/gui/accountmanager.cpp index f89085664ceda..47bfb0317d75b 100644 --- a/src/gui/accountmanager.cpp +++ b/src/gui/accountmanager.cpp @@ -130,6 +130,7 @@ AccountManager::AccountsRestoreResult AccountManager::restore(const bool alsoRes const auto jar = qobject_cast(acc->_networkAccessManager->cookieJar()); Q_ASSERT(jar); if (jar) { + acc->tryMigrateCookieJar(); jar->restore(acc->cookieJarPath()); } addAccountState(accState); diff --git a/src/gui/syncrunfilelog.cpp b/src/gui/syncrunfilelog.cpp index 4150d1f92615b..d60f2825970f6 100644 --- a/src/gui/syncrunfilelog.cpp +++ b/src/gui/syncrunfilelog.cpp @@ -32,7 +32,7 @@ void SyncRunFileLog::start(const QString &folderPath) { const qint64 logfileMaxSize = 10 * 1024 * 1024; // 10MiB - const QString logpath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + const QString logpath = QStandardPaths::writableLocation(QStandardPaths::StateLocation); if(!QDir(logpath).exists()) { QDir().mkdir(logpath); } diff --git a/src/gui/updater/ocupdater.cpp b/src/gui/updater/ocupdater.cpp index 5ea60813011ae..037601c28f46c 100644 --- a/src/gui/updater/ocupdater.cpp +++ b/src/gui/updater/ocupdater.cpp @@ -220,7 +220,7 @@ void OCUpdater::slotStartInstaller() return QDir::toNativeSeparators(path); }; - QString msiLogFile = cfg.configPath() + "msi.log"; + QString msiLogFile = cfg.logDir() + "msi.log"; QString command = QStringLiteral("&{msiexec /i '%1' /L*V '%2'| Out-Null ; &'%3'}") .arg(preparePathForPowershell(updateFile)) .arg(preparePathForPowershell(msiLogFile)) diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index fbfc415bddb45..86f2a30a1c3fd 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -388,9 +388,20 @@ void Account::lendCookieJarTo(QNetworkAccessManager *guest) jar->setParent(oldParent); // takes it back } +void Account::tryMigrateCookieJar() +{ + QString oldCookieJarPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/cookies" + id() + ".db"; + if (QFile::exists(oldCookieJarPath)) + { + qDebug() << "Migrating cookie jar from "<< oldCookieJarPath << "to " << cookieJarPath(); + if (!QFile::rename(oldCookieJarPath, cookieJarPath())) + qWarning() << "Failed to migrate cookie jar"; + } +} + QString Account::cookieJarPath() { - return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/cookies" + id() + ".db"; + return QStandardPaths::writableLocation(QStandardPaths::StateLocation) + "/cookies" + id() + ".db"; } void Account::resetNetworkAccessManager() diff --git a/src/libsync/account.h b/src/libsync/account.h index eddb77c90510a..50a9913158337 100644 --- a/src/libsync/account.h +++ b/src/libsync/account.h @@ -313,6 +313,7 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject void clearCookieJar(); void lendCookieJarTo(QNetworkAccessManager *guest); + void tryMigrateCookieJar(); QString cookieJarPath(); void resetNetworkAccessManager(); diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index b1cb4268d1059..405b9d900b5fe 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -1124,7 +1124,7 @@ void ConfigFile::setAutomaticLogDir(bool enabled) QString ConfigFile::logDir() const { - const auto defaultLogDir = QString(configPath() + QStringLiteral("/logs")); + const auto defaultLogDir = QString(QStandardPaths::writableLocation(QStandardPaths::StateLocation) + QStringLiteral("/logs")); QSettings settings(configFile(), QSettings::IniFormat); return settings.value(QLatin1String(logDirC), defaultLogDir).toString(); } From 70a04ed834c06c5e3b7862d16db2532e3d1ac2d5 Mon Sep 17 00:00:00 2001 From: Ilya Chelyadin Date: Thu, 3 Apr 2025 12:06:43 +0300 Subject: [PATCH 2/3] Abort cookie jar migraion if it exists on new path Signed-off-by: Ilya Chelyadin --- src/libsync/account.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index 20f2ca4725a62..5c8c8412b89c0 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -393,6 +393,11 @@ void Account::tryMigrateCookieJar() QString oldCookieJarPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/cookies" + id() + ".db"; if (QFile::exists(oldCookieJarPath)) { + if (QFile::exists(cookieJarPath())) + { + qWarning() << "Both old cookie jar and new cookie jar exists. Abort migration"; + return; + } qDebug() << "Migrating cookie jar from "<< oldCookieJarPath << "to " << cookieJarPath(); if (!QFile::rename(oldCookieJarPath, cookieJarPath())) qWarning() << "Failed to migrate cookie jar"; From aeb4ec9aa671c82767efa5ac75b0c8b703c75b91 Mon Sep 17 00:00:00 2001 From: Ilya Chelyadin Date: Thu, 3 Apr 2025 13:25:21 +0300 Subject: [PATCH 3/3] Added test for cookie jar migration Signed-off-by: Ilya Chelyadin --- test/CMakeLists.txt | 1 + test/testcookiejarmigration.cpp | 85 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 test/testcookiejarmigration.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2c66540f1c5ee..7dff5a1db21f1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -94,6 +94,7 @@ nextcloud_add_test(FileTagModel) nextcloud_add_test(SyncConflictsModel) nextcloud_add_test(DateFieldBackend) nextcloud_add_test(ClientStatusReporting) +nextcloud_add_test(CookieJarMigration) nextcloud_add_test(FolderStatusModel) diff --git a/test/testcookiejarmigration.cpp b/test/testcookiejarmigration.cpp new file mode 100644 index 0000000000000..4d072be7afc2e --- /dev/null +++ b/test/testcookiejarmigration.cpp @@ -0,0 +1,85 @@ +/* + This software is in the public domain, furnished "as is", without technical + support, and with no warranty, express or implied, as to its usefulness for + any purpose. +*/ + +#include + +#include "account.h" +#include "accountmanager.h" +#include "logger.h" + +using namespace OCC; + +class TestCookieJarMigration : public QObject +{ + Q_OBJECT + AccountPtr _account; + QString oldCookieJarPath; + +private slots: + void initTestCase() + { + OCC::Logger::instance()->setLogFlush(true); + OCC::Logger::instance()->setLogDebug(true); + + QStandardPaths::setTestModeEnabled(true); + // Create directories used in test, since Qt doesn't create its automatically + QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::StateLocation)); + QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + + _account = Account::create(); + AccountManager::instance()->addAccount(_account); + oldCookieJarPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/cookies" + _account->id() + ".db"; + } + void testNoAction() + { + QFile jarFile(_account->cookieJarPath()); + jarFile.open(QFile::WriteOnly); + jarFile.write("1", 1); // Write one byte to file + jarFile.close(); + _account->tryMigrateCookieJar(); + + QVERIFY(!QFile::exists(oldCookieJarPath)); // Check that old file doesn't exits + QCOMPARE(QFileInfo(_account->cookieJarPath()).size(), 1); // Check that this byte present in new file + QFile::remove(_account->cookieJarPath()); // Cleanup + } + void testSimpleMigration() + { + QFile oldJarFile(oldCookieJarPath); + oldJarFile.open(QFile::WriteOnly); + oldJarFile.write("1", 1); // Write one byte to file + oldJarFile.close(); + + _account->tryMigrateCookieJar(); + QVERIFY(!QFile::exists(oldCookieJarPath)); // Check that old file is deleted + + QCOMPARE(QFileInfo(_account->cookieJarPath()).size(), 1); // Check that this byte present in new file + QFile::remove(_account->cookieJarPath()); // Cleanup + } + void testNotOverwrite() + { + QFile oldJarFile(oldCookieJarPath); + oldJarFile.open(QFile::WriteOnly); + oldJarFile.write("1", 1); // Write one byte to file + oldJarFile.close(); + + QFile newJarFile(_account->cookieJarPath()); + oldJarFile.open(QFile::WriteOnly); + oldJarFile.write("123", 3); // Write three bytes to file + oldJarFile.close(); + + + _account->tryMigrateCookieJar(); + + QCOMPARE(QFileInfo(_account->cookieJarPath()).size(), 3); // Check that these bytes still present + + // Cleanup + QFile::remove(_account->cookieJarPath()); + QFile::remove(oldCookieJarPath); + } +}; + +QTEST_APPLESS_MAIN(TestCookieJarMigration) +#include "testcookiejarmigration.moc"