Page MenuHomePhabricator

D10502.diff
No OneTemporary

D10502.diff

diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt
--- a/native/android/app/CMakeLists.txt
+++ b/native/android/app/CMakeLists.txt
@@ -130,6 +130,7 @@
"../../native_rust_library/RustAESCrypto.cpp"
"../../native_rust_library/RustCSAMetadataEmitter.cpp"
"../../native_rust_library/RustSecureStore.cpp"
+ "../../native_rust_library/RustBackupExecutor.cpp"
)
file(GLOB CRYPTO_NATIVE_CODE "../../cpp/CommonCpp/CryptoTools/*.cpp")
file(GLOB DB_NATIVE_CODE "../../cpp/CommonCpp/DatabaseManagers/*.cpp")
diff --git a/native/android/app/src/cpp/PlatformSpecificTools.cpp b/native/android/app/src/cpp/PlatformSpecificTools.cpp
--- a/native/android/app/src/cpp/PlatformSpecificTools.cpp
+++ b/native/android/app/src/cpp/PlatformSpecificTools.cpp
@@ -31,6 +31,27 @@
cls->getStaticMethod<JString()>("getNotificationsCryptoAccountPath");
return method(cls)->toStdString();
}
+
+ static std::string getBackupDirectoryPath() {
+ static const auto cls = javaClassStatic();
+ static auto method =
+ cls->getStaticMethod<JString()>("getBackupDirectoryPath");
+ return method(cls)->toStdString();
+ }
+
+ static std::string
+ getBackupFilePath(std::string backupID, bool isAttachments) {
+ static const auto cls = javaClassStatic();
+ static auto method =
+ cls->getStaticMethod<JString(std::string, bool)>("getBackupFilePath");
+ return method(cls, backupID, isAttachments)->toStdString();
+ }
+
+ static void removeBackupDirectory() {
+ static const auto cls = javaClassStatic();
+ static auto method = cls->getStaticMethod<void()>("removeBackupDirectory");
+ method(cls);
+ }
};
namespace comm {
@@ -55,4 +76,28 @@
return path;
}
+std::string PlatformSpecificTools::getBackupDirectoryPath() {
+ std::string path;
+ NativeAndroidAccessProvider::runTask([&path]() {
+ path = PlatformSpecificToolsJavaClass::getBackupDirectoryPath();
+ });
+ return path;
+}
+
+std::string PlatformSpecificTools::getBackupFilePath(
+ std::string backupID,
+ bool isAttachments) {
+ std::string path;
+ NativeAndroidAccessProvider::runTask([&path, backupID, isAttachments]() {
+ path = PlatformSpecificToolsJavaClass::getBackupFilePath(
+ backupID, isAttachments);
+ });
+ return path;
+}
+
+void PlatformSpecificTools::removeBackupDirectory() {
+ NativeAndroidAccessProvider::runTask(
+ []() { PlatformSpecificToolsJavaClass::removeBackupDirectory(); });
+}
+
} // namespace comm
diff --git a/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java b/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
--- a/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
+++ b/native/android/app/src/main/java/app/comm/android/fbjni/PlatformSpecificTools.java
@@ -3,9 +3,12 @@
import android.content.Context;
import android.util.Log;
import app.comm.android.MainApplication;
+import java.io.File;
+import java.lang.SecurityException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+
public class PlatformSpecificTools {
static SecureRandom secureRandom = new SecureRandom();
@@ -26,4 +29,73 @@
.getFileStreamPath("comm_notifications_crypto_account")
.getPath();
}
+
+ public static String getBackupDirectoryPath() {
+ Context mainApplicationContext =
+ MainApplication.getMainApplicationContext();
+ if (mainApplicationContext == null) {
+ throw new RuntimeException(
+ "Failed to resolve backup path - main application context not initialized.");
+ }
+
+ String filesDirPath = mainApplicationContext.getFilesDir().getPath();
+ String backupDirPath = String.join(File.separator, filesDirPath, "backup");
+
+ try {
+ File backupDirectory = new File(backupDirPath);
+ if (!backupDirectory.exists() && !backupDirectory.mkdirs()) {
+ throw new RuntimeException("Failed to create backup directory.");
+ }
+ return backupDirPath;
+ } catch (SecurityException | NullPointerException e) {
+ throw new RuntimeException(
+ "Failed to check if backup directory exists or to attempt its creation. Details: " +
+ e.getMessage());
+ }
+ }
+
+ public static String
+ getBackupFilePath(String backupID, boolean isAttachments) {
+ String backupDirPath = PlatformSpecificTools.getBackupDirectoryPath();
+
+ String filename;
+ if (isAttachments) {
+ filename = String.join("_", "backup", backupID, "attachments");
+ } else {
+ filename = String.join("_", "backup", backupID);
+ }
+ return String.join(File.separator, backupDirPath, filename);
+ }
+
+ public static void removeBackupDirectory() {
+ String backupDirPath = PlatformSpecificTools.getBackupDirectoryPath();
+ try {
+ File backupDirectory = new File(backupDirPath);
+ if (!backupDirectory.exists()) {
+ return;
+ }
+
+ File[] files = backupDirectory.listFiles();
+ if (files == null && !backupDirectory.delete()) {
+ throw new RuntimeException("Failed to remove backup directory.");
+ } else if (files == null) {
+ return;
+ }
+
+ // Backup directory structure is supposed to be flat.
+ for (File file : files) {
+ if (!file.delete()) {
+ throw new RuntimeException(
+ "Failed to remove backup file at path: " + file.getPath());
+ }
+ }
+
+ if (!backupDirectory.delete()) {
+ throw new RuntimeException("Failed to remove backup directory.");
+ }
+ } catch (NullPointerException | SecurityException e) {
+ throw new RuntimeException(
+ "Failed to remove backup directory. Details: " + e.getMessage());
+ }
+ }
}
diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseManager.cpp
@@ -2,6 +2,7 @@
#include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h"
#include "../Tools/CommSecureStore.h"
#include "Logger.h"
+#include "PlatformSpecificTools.h"
#include "SQLiteQueryExecutor.h"
namespace comm {
@@ -34,6 +35,7 @@
CommSecureStore::set(CommSecureStore::deviceID, "");
CommSecureStore::set(CommSecureStore::commServicesAccessToken, "");
SQLiteQueryExecutor::clearSensitiveData();
+ PlatformSpecificTools::removeBackupDirectory();
NotificationsCryptoModule::clearSensitiveData();
DatabaseManager::setDatabaseStatusAsWorkable();
}
diff --git a/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h b/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
--- a/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
+++ b/native/cpp/CommonCpp/Tools/PlatformSpecificTools.h
@@ -9,6 +9,10 @@
static void generateSecureRandomBytes(crypto::OlmBuffer &buffer, size_t size);
static std::string getDeviceOS();
static std::string getNotificationsCryptoAccountPath();
+ static std::string getBackupDirectoryPath();
+ static std::string
+ getBackupFilePath(std::string backupID, bool isAttachments);
+ static void removeBackupDirectory();
};
} // namespace comm
diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj
--- a/native/ios/Comm.xcodeproj/project.pbxproj
+++ b/native/ios/Comm.xcodeproj/project.pbxproj
@@ -81,6 +81,7 @@
CBCA09062A8E0E7400F75B3E /* StaffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */; };
CBCA09072A8E0E7D00F75B3E /* StaffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */; };
CBDEC69B28ED867000C17588 /* GlobalDBSingleton.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */; };
+ CBFBEEBA2B4ED90600729F1D /* RustBackupExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */; };
CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBFE58282885852B003B94C9 /* ThreadOperations.cpp */; };
D7DB6E0F85B2DBE15B01EC21 /* libPods-Comm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */; };
DFD5E77C2B05181400C32B6A /* RustSecureStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD5E77B2B05181400C32B6A /* RustSecureStore.cpp */; };
@@ -277,6 +278,8 @@
CBCF57AB2B05096F00EC4BC0 /* AESCryptoModuleObjCCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AESCryptoModuleObjCCompat.h; path = Comm/CommAESCryptoUtils/AESCryptoModuleObjCCompat.h; sourceTree = "<group>"; };
CBDEC69928ED859600C17588 /* GlobalDBSingleton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalDBSingleton.h; sourceTree = "<group>"; };
CBDEC69A28ED867000C17588 /* GlobalDBSingleton.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = GlobalDBSingleton.mm; path = Comm/GlobalDBSingleton.mm; sourceTree = "<group>"; };
+ CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RustBackupExecutor.cpp; sourceTree = "<group>"; };
+ CBFBEEB92B4ED90600729F1D /* RustBackupExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustBackupExecutor.h; sourceTree = "<group>"; };
CBFE58272885852B003B94C9 /* ThreadOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadOperations.h; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.h; sourceTree = "<group>"; };
CBFE58282885852B003B94C9 /* ThreadOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadOperations.cpp; path = PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp; sourceTree = "<group>"; };
DFD5E77A2B05181400C32B6A /* RustSecureStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RustSecureStore.h; sourceTree = "<group>"; };
@@ -593,6 +596,8 @@
8B99AF6B28D50D4800EB5ADB /* native_rust_library */ = {
isa = PBXGroup;
children = (
+ CBFBEEB82B4ED90600729F1D /* RustBackupExecutor.cpp */,
+ CBFBEEB92B4ED90600729F1D /* RustBackupExecutor.h */,
CB74AB1E2B2B0C0900CBB494 /* RustCSAMetadataEmitter.cpp */,
CB74AB1F2B2B0C0900CBB494 /* RustCSAMetadataEmitter.h */,
DFD5E7842B052B1400C32B6A /* RustAESCrypto.cpp */,
@@ -1094,6 +1099,7 @@
CBFE58292885852B003B94C9 /* ThreadOperations.cpp in Sources */,
CB74AB1C2B2AFF6E00CBB494 /* CommServicesAuthMetadataEmitter.mm in Sources */,
8E3994552B039A7C00D5E950 /* UserStore.cpp in Sources */,
+ CBFBEEBA2B4ED90600729F1D /* RustBackupExecutor.cpp in Sources */,
7FBB2A7829E945C2002C6493 /* CommUtilsModule.cpp in Sources */,
CB38B48228771C7A00171182 /* NonBlockingLock.mm in Sources */,
718DE99E2653D41C00365824 /* WorkerThread.cpp in Sources */,
diff --git a/native/ios/Comm/PlatformSpecificTools.mm b/native/ios/Comm/PlatformSpecificTools.mm
--- a/native/ios/Comm/PlatformSpecificTools.mm
+++ b/native/ios/Comm/PlatformSpecificTools.mm
@@ -37,4 +37,74 @@
.path UTF8String]);
}
+NSURL *getBackupDirAsURL() {
+ NSError *err = nil;
+ NSURL *documentsUrl =
+ [NSFileManager.defaultManager URLForDirectory:NSDocumentDirectory
+ inDomain:NSUserDomainMask
+ appropriateForURL:nil
+ create:false
+ error:&err];
+ if (err) {
+ NSLog(@"Error: %@", err);
+ throw std::runtime_error(
+ "Failed to resolve backup path - could not find documentsUrl. "
+ "Details: " +
+ std::string([err.localizedDescription UTF8String]));
+ }
+
+ NSURL *backupDir = [documentsUrl URLByAppendingPathComponent:@"backup"];
+ NSError *backupDirCreateError = nil;
+ if (![NSFileManager.defaultManager fileExistsAtPath:backupDir.path]) {
+ [NSFileManager.defaultManager createDirectoryAtURL:backupDir
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&backupDirCreateError];
+ }
+ if (backupDirCreateError) {
+ throw std::runtime_error(
+ "Failed to create backup directory. Details: " +
+ std::string([backupDirCreateError.localizedDescription UTF8String]));
+ }
+ return backupDir;
+}
+
+std::string PlatformSpecificTools::getBackupDirectoryPath() {
+ return [getBackupDirAsURL().path UTF8String];
+}
+
+std::string PlatformSpecificTools::getBackupFilePath(
+ std::string backupID,
+ bool isAttachments) {
+
+ NSURL *backupDir = getBackupDirAsURL();
+ NSString *backupIDObjC = [NSString stringWithCString:backupID.c_str()
+ encoding:NSUTF8StringEncoding];
+ NSString *filename;
+ if (isAttachments) {
+ filename = [@[ @"backup", backupIDObjC, @"attachments" ]
+ componentsJoinedByString:@"_"];
+ } else {
+ filename = [@[ @"backup", backupIDObjC ] componentsJoinedByString:@"_"];
+ }
+ return [[backupDir URLByAppendingPathComponent:filename].path UTF8String];
+}
+
+void PlatformSpecificTools::removeBackupDirectory() {
+ NSURL *backupDir = getBackupDirAsURL();
+ if (![NSFileManager.defaultManager fileExistsAtPath:backupDir.path]) {
+ return;
+ }
+
+ NSError *backupDirRemovalError = nil;
+ [NSFileManager.defaultManager removeItemAtURL:backupDir
+ error:&backupDirRemovalError];
+
+ if (backupDirRemovalError) {
+ throw std::runtime_error(
+ "Failed to remove backup directory. Details: " +
+ std::string([backupDirRemovalError.localizedDescription UTF8String]));
+ }
+}
+
}; // namespace comm
diff --git a/native/native_rust_library/RustBackupExecutor.h b/native/native_rust_library/RustBackupExecutor.h
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustBackupExecutor.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "cxx.h"
+
+namespace comm {
+
+rust::String getBackupDirectoryPath();
+rust::String getBackupFilePath(rust::String backupID, bool isAttachments);
+
+} // namespace comm
diff --git a/native/native_rust_library/RustBackupExecutor.cpp b/native/native_rust_library/RustBackupExecutor.cpp
new file mode 100644
--- /dev/null
+++ b/native/native_rust_library/RustBackupExecutor.cpp
@@ -0,0 +1,16 @@
+#include "RustBackupExecutor.h"
+#include "../cpp/CommonCpp/Tools/PlatformSpecificTools.h"
+
+#include <string>
+
+namespace comm {
+
+rust::String getBackupDirectoryPath() {
+ return rust::String(PlatformSpecificTools::getBackupDirectoryPath());
+}
+
+rust::String getBackupFilePath(rust::String backupID, bool isAttachments) {
+ return rust::String(PlatformSpecificTools::getBackupFilePath(
+ std::string(backupID), isAttachments));
+}
+} // namespace comm
diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs
--- a/native/native_rust_library/src/lib.rs
+++ b/native/native_rust_library/src/lib.rs
@@ -244,6 +244,23 @@
#[cxx_name = "secureStoreGet"]
fn secure_store_get(key: &str) -> Result<String>;
}
+
+ // C++ Backup creation
+ #[namespace = "comm"]
+ unsafe extern "C++" {
+ include!("RustBackupExecutor.h");
+
+ #[allow(unused)]
+ #[cxx_name = "getBackupDirectoryPath"]
+ fn get_backup_directory_path() -> Result<String>;
+
+ #[allow(unused)]
+ #[cxx_name = "getBackupFilePath"]
+ fn get_backup_file_path(
+ backup_id: String,
+ is_attachments: bool,
+ ) -> Result<String>;
+ }
}
fn handle_string_result_as_callback<E>(

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 1, 1:37 PM (20 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2605131
Default Alt Text
D10502.diff (15 KB)

Event Timeline