Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F112280
D189.1732288083.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D189.1732288083.diff
View Options
diff --git a/src/matrix-sdk.hpp b/src/matrix-sdk.hpp
--- a/src/matrix-sdk.hpp
+++ b/src/matrix-sdk.hpp
@@ -12,6 +12,7 @@
#include <QString>
#include <memory>
+#include <filesystem>
#include <lager/extra/qt.hpp>
@@ -38,6 +39,8 @@
struct MatrixSdkPrivate;
+std::filesystem::path sessionDirForUserAndDeviceId(std::filesystem::path userDataDir, std::string userId, std::string deviceId);
+
class MatrixSdk : public QObject
{
Q_OBJECT
diff --git a/src/matrix-sdk.cpp b/src/matrix-sdk.cpp
--- a/src/matrix-sdk.cpp
+++ b/src/matrix-sdk.cpp
@@ -80,6 +80,14 @@
void resume() { throw std::runtime_error{"not implemented!"}; }
};
+std::filesystem::path sessionDirForUserAndDeviceId(std::filesystem::path userDataDir, std::string userId, std::string deviceId)
+{
+ auto encodedUserId = encodeBase64(userId, Base64Opts::urlSafe);
+ auto sessionDir = userDataDir / "sessions"
+ / encodedUserId / deviceId;
+ return sessionDir;
+}
+
struct MatrixSdkPrivate
{
MatrixSdkPrivate(MatrixSdk *q, bool testing, std::unique_ptr<KazvSessionLockGuard> lockGuard);
@@ -169,11 +177,10 @@
using StdPath = std::filesystem::path;
auto userDataDir = StdPath(this->userDataDir);
- auto encodedUserId = encodeBase64(userId, Base64Opts::urlSafe);
- auto sessionDir = userDataDir / "sessions"
- / encodedUserId / deviceId;
+ auto sessionDir = sessionDirForUserAndDeviceId(userDataDir, userId, deviceId);
auto storeFile = sessionDir / "store";
+ auto storeFileNew = sessionDir / "store.new";
auto metadataFile = sessionDir / "metadata";
@@ -195,18 +202,29 @@
}
}
- {
- auto storeStream = std::ofstream(storeFile);
+ try {
+ auto storeStream = std::ofstream(storeFileNew);
if (! storeStream) {
- qDebug() << "Unable to open storeFile";
+ qCWarning(kazvLog) << "Unable to open storeFile";
return;
}
using OAr = boost::archive::text_oarchive;
auto archive = OAr{storeStream};
c.serializeTo(archive);
- qDebug() << "Serialization done";
+ } catch (const std::exception &e) {
+ qCWarning(kazvLog) << "Cannot write to store file: " << e.what();
+ return;
}
+ err.clear();
+ std::filesystem::rename(storeFileNew, storeFile, err);
+ if (err) {
+ qCWarning(kazvLog) << "Cannot move storeFile into place: " << QString::fromStdString(err.message());
+ return;
+ }
+ qDebug() << "Serialization done";
+
+
// store metadata
{
KConfig metadata(QString::fromStdString(metadataFile.string()));
@@ -530,9 +548,8 @@
auto parts = sessionName.split(u'/');
if (parts.size() == 2) {
auto userId = parts[0].toStdString();
- auto sessionId = parts[1].toStdString();
- auto encodedUserId = encodeBase64(userId, Base64Opts::urlSafe);
- auto sessionDir = userDataDir / "sessions" / encodedUserId / sessionId;
+ auto deviceId = parts[1].toStdString();
+ auto sessionDir = sessionDirForUserAndDeviceId(userDataDir, userId, deviceId);
try {
lockGuard = std::make_unique<KazvSessionLockGuard>(sessionDir);
} catch (const std::runtime_error &e) {
@@ -552,16 +569,14 @@
auto parts = sessionName.split(u'/');
if (parts.size() == 2) {
auto userId = parts[0].toStdString();
- auto sessionId = parts[1].toStdString();
- auto encodedUserId = encodeBase64(userId, Base64Opts::urlSafe);
- qCDebug(kazvLog) << "trying new path";
- auto sessionDir = userDataDir / "sessions" / encodedUserId / sessionId;
+ auto deviceId = parts[1].toStdString();
+ auto sessionDir = sessionDirForUserAndDeviceId(userDataDir, userId, deviceId);
if (std::filesystem::exists(sessionDir)) {
qCDebug(kazvLog) << "new path works";
return std::filesystem::remove_all(sessionDir);
}
qCDebug(kazvLog) << "trying legacy path";
- auto legacySessionDir = userDataDir / "sessions" / userId / sessionId;
+ auto legacySessionDir = userDataDir / "sessions" / userId / deviceId;
if (std::filesystem::exists(legacySessionDir)) {
qCDebug(kazvLog) << "legacy path works";
return std::filesystem::remove_all(legacySessionDir);
diff --git a/src/tests/matrix-sdk-sessions-test.hpp b/src/tests/matrix-sdk-sessions-test.hpp
--- a/src/tests/matrix-sdk-sessions-test.hpp
+++ b/src/tests/matrix-sdk-sessions-test.hpp
@@ -44,4 +44,5 @@
void testListLegacySessions();
void testLoadSession();
void testSessionLock();
+ void testSaveSessionFailure();
};
diff --git a/src/tests/matrix-sdk-sessions-test.cpp b/src/tests/matrix-sdk-sessions-test.cpp
--- a/src/tests/matrix-sdk-sessions-test.cpp
+++ b/src/tests/matrix-sdk-sessions-test.cpp
@@ -136,6 +136,60 @@
#endif
}
+void MatrixSdkSessionsTest::testSaveSessionFailure()
+{
+#if KAZV_IS_WINDOWS
+ QSKIP("Skipping because session the condition cannot be easily satisfied on Windows");
+#endif
+
+ auto userId = std::string("@mew:example.com");
+ auto deviceId = std::string("device1");
+ createSession(userId, deviceId);
+
+ auto sessionDir = sessionDirForUserAndDeviceId(Fs::path(m_userDataDir), userId, deviceId);
+ // there is store, metadata and lock under the sessionDir
+
+ std::error_code err;
+ // make the sessionDir readonly, so that new file cannot be created
+ Fs::permissions(
+ sessionDir,
+ Fs::perms::owner_read | Fs::perms::owner_exec,
+ Fs::perm_options::replace,
+ err);
+ QVERIFY(!err);
+ err.clear();
+
+ // a model that is slightly different from the original one
+ SdkModel model;
+ model.client.userId = userId;
+ model.client.deviceId = deviceId;
+ model.client.serverUrl = "https://example.com";
+
+ {
+ auto sdk = makeMatrixSdk(model, /* testing = */ false);
+ // this should fail
+ sdk->serializeToFile();
+ }
+ // Not ideal, but this is the only way to wait for
+ // MatrixSdkPravite to be destroyed.
+ QTest::qWait(100);
+
+ auto sdk = makeMatrixSdk();
+ auto res = sdk->loadSession(QString::fromStdString(userId + "/" + deviceId));
+ QCOMPARE(res, MatrixSdk::SessionLoadSuccess);
+ // verify that the original data is kept
+ QCOMPARE(sdk->serverUrl(), u""_s);
+
+ // before cleaning up, add write permissions back so the files can be removed
+ Fs::permissions(
+ sessionDir,
+ Fs::perms::owner_read | Fs::perms::owner_write | Fs::perms::owner_exec,
+ Fs::perm_options::replace,
+ err);
+ QVERIFY(!err);
+ err.clear();
+}
+
#ifndef MATRIX_SDK_SESSIONS_TEST_NO_MAIN
QTEST_MAIN(MatrixSdkSessionsTest)
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 22, 7:08 AM (19 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38890
Default Alt Text
D189.1732288083.diff (6 KB)
Attached To
Mode
D189: Use a temp file to save session
Attached
Detach File
Event Timeline
Log In to Comment