Fix saving of cookies
authorHannah von Reth <vonreth@kde.org>
Fri, 24 Jan 2020 16:57:34 +0000 (17:57 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:59:06 +0000 (10:59 +0100)
Fixes: #7700
src/gui/accountmanager.cpp
src/libsync/cookiejar.cpp
src/libsync/cookiejar.h
test/CMakeLists.txt
test/testcookies.cpp [new file with mode: 0644]

index 577320447ec5743fad791de87714fbe68e6b737d..85f475cac818975ccdfc4d05c69c3df501aaea1f 100644 (file)
@@ -258,7 +258,10 @@ void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool s
         auto *jar = qobject_cast<CookieJar *>(acc->_am->cookieJar());
         if (jar) {
             qCInfo(lcAccountManager) << "Saving cookies." << acc->cookieJarPath();
-            jar->save(acc->cookieJarPath());
+            if (!jar->save(acc->cookieJarPath()))
+            {
+                qCWarning(lcAccountManager) << "Failed to save cookies to" << acc->cookieJarPath();
+            }
         }
     }
 }
index ded4eaeedbb8d94e29f4d2120b3ebe8eb290db6d..7e6158f845c53d938d0b38c4fa34e0deb7cf2dd9 100644 (file)
@@ -21,6 +21,7 @@
 #include <QLoggingCategory>
 #include <QNetworkCookie>
 #include <QDataStream>
+#include <QDir>
 
 namespace OCC {
 
@@ -95,27 +96,45 @@ void CookieJar::clearSessionCookies()
     setAllCookies(removeExpired(allCookies()));
 }
 
-void CookieJar::save(const QString &fileName)
+bool CookieJar::save(const QString &fileName)
 {
-    QFile file;
-    file.setFileName(fileName);
+    const QFileInfo info(fileName);
+    if (!info.dir().exists())
+    {
+        info.dir().mkpath(".");
+    }
+
     qCDebug(lcCookieJar) << fileName;
-    file.open(QIODevice::WriteOnly);
+    QFile file(fileName);
+    if (!file.open(QIODevice::WriteOnly))
+    {
+        return false;
+    }
     QDataStream stream(&file);
     stream << removeExpired(allCookies());
     file.close();
+    return true;
 }
 
-void CookieJar::restore(const QString &fileName)
+bool CookieJar::restore(const QString &fileName)
 {
-    QFile file;
-    file.setFileName(fileName);
-    file.open(QIODevice::ReadOnly);
+    const QFileInfo info(fileName);
+    if (!info.exists())
+    {
+        return false;
+    }
+
+    QFile file(fileName);
+    if (!file.open(QIODevice::ReadOnly))
+    {
+        return false;
+    }
     QDataStream stream(&file);
     QList<QNetworkCookie> list;
     stream >> list;
     setAllCookies(removeExpired(list));
     file.close();
+    return true;
 }
 
 QList<QNetworkCookie> CookieJar::removeExpired(const QList<QNetworkCookie> &cookies)
index 245b546b93d64846852895cca217af4c434e4d92..ecdd69971c597003ff3fdb0bf74d0fbc32f58770 100644 (file)
@@ -39,8 +39,8 @@ public:
     using QNetworkCookieJar::setAllCookies;
     using QNetworkCookieJar::allCookies;
 
-    void save(const QString &fileName);
-    void restore(const QString &fileName);
+    bool save(const QString &fileName);
+    bool restore(const QString &fileName);
 
 signals:
     void newCookiesForUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
index 682f42fcc2dfde96e412fa76a278b42d7e2e5a27..dc4100e97c03c20c62e97ae8540cb4241257727c 100644 (file)
@@ -37,6 +37,7 @@ nextcloud_add_test(OwnSql "")
 nextcloud_add_test(SyncJournalDB "")
 nextcloud_add_test(SyncFileItem "")
 nextcloud_add_test(ConcatUrl "")
+nextcloud_add_test(Cookies "")
 nextcloud_add_test(XmlParse "")
 nextcloud_add_test(ChecksumValidator "")
 
diff --git a/test/testcookies.cpp b/test/testcookies.cpp
new file mode 100644 (file)
index 0000000..a5053ab
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+   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 <QtTest>
+
+#include "libsync/cookiejar.h"
+
+using namespace OCC;
+
+class TestCookies : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void testCookies()
+    {
+        QTemporaryDir tmp;
+        const QString nonexistingPath = tmp.filePath("someNonexistingDir/test.db");
+        QNetworkCookie cookieA = QNetworkCookie("foo", "bar");
+        // tomorrow rounded
+        cookieA.setExpirationDate(QDateTime(QDateTime::currentDateTimeUtc().addDays(1).date()));
+        const QList<QNetworkCookie> cookies = {cookieA, QNetworkCookie("foo2", "bar")};
+        CookieJar jar;
+        jar.setAllCookies(cookies);
+        QCOMPARE(cookies, jar.allCookies());
+        QVERIFY(jar.save(tmp.filePath("test.db")));
+        // ensure we are able to create a cookie jar in a non exisitning folder (mkdir)
+        QVERIFY(jar.save(nonexistingPath));
+
+        CookieJar jar2;
+        QVERIFY(jar2.restore(nonexistingPath));
+        // here we should have  only cookieA as the second one was a session cookie
+        QCOMPARE(QList<QNetworkCookie>{cookieA}, jar2.allCookies());
+
+    }
+
+};
+
+QTEST_APPLESS_MAIN(TestCookies)
+#include "testcookies.moc"