Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: create backup module [WPB-10575] #3117

Merged
merged 1 commit into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions backup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Cross-platform Backup

This module implements the Wire Cross-platform Backup solution.
Its purpose is to create a common implementation to be used by iOS, Web, and Android.

## Capabilities

> [!TIP]
> The backup blob/file will be referred in this document as **backup artifact**, or simply
> **artifact**.
> The clients (iOS, Web, and Android) will be referred as **callers**.

### Creation of backup artifact

The library should be able to transform data like messages, conversations, users into an artifact,
_i.e._ create a backup file.

### Restoration of original data

It should also be able to revert this process, _i.e._ read a backup artifact and understand all of
its contents, allowing the caller to get access to the original data.

### Optional Encryption

The artifact may _(or may not)_ be Encrypted. Clients using this library can provide an optional
passphrase to encrypt and decrypt the artifact.

### Optional UserID verification

When creating an artifact, callers need to provide a qualified user ID. This qualified user ID will
be stored within the artifact.
When restoring the original data, the library _can_ compare the user ID in the artifact with a user
ID provided by the caller. This may not be wanted in all features, _e.g._ in case of chat history
sharing across different users.

### Peak into artifact

Clients can ask the library if a piece of data is an actual cross-platform artifact.
The library should respond yes/no, and provide more details in case of a positive answer: is it
encrypted? Was it created by the same user that is restoring the artifact?

--------

# Development

Using Kotlin Multiplatform, it should at least be available for iOS, JS (with TypeScript types),
Android, and JVM.

### Building

Before we can automate the deployment of this library, we can manually generate and send library
artifacts (not backup artifacts) using the following Gradle tasks:

- iOS: `./gradlew :backup:assembleBackupDebugXCFramework`
- Web: `./gradlew :backup:jsBrowserDevelopmentLibraryDistribution`

**Output:** the results will be in `backup/build` directory. iOS needs the whole `backup.xcframework` directory, Web/JS needs the whole directory that contains `package.json`
115 changes: 115 additions & 0 deletions backup/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
plugins {
id(libs.plugins.android.library.get().pluginId)
id(libs.plugins.kotlin.multiplatform.get().pluginId)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
id(libs.plugins.kalium.library.get().pluginId)
}

kaliumLibrary {
multiplatform { enableJs.set(true) }
}

@Suppress("UnusedPrivateProperty")
kotlin {
val xcf = XCFramework()
val appleTargets = listOf(iosX64(), iosArm64(), iosSimulatorArm64(), macosArm64(), macosX64())
appleTargets.forEach {
it.binaries.framework {
baseName = "backup"
xcf.add(this)
}
}
js {
browser()
binaries.library()
generateTypeScriptDefinitions()
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(project(":data"))
implementation(project(":protobuf"))
implementation(libs.pbandk.runtime.common)

implementation(libs.coroutines.core)
implementation(libs.ktxDateTime)
implementation(libs.ktxSerialization)

implementation(libs.okio.core)

// Libsodium
implementation(libs.libsodiumBindingsMP)
}
}
val commonTest by getting {
dependencies {
implementation(libs.coroutines.test)
implementation(libs.okio.test)
}
}

val nonJsMain by creating {
dependsOn(commonMain)
}
val nonJsTest by creating {
dependsOn(commonTest)
}
val androidMain by getting {
dependsOn(nonJsMain)
}
val jvmMain by getting {
dependsOn(nonJsMain)
}

val iosX64Main by getting {
dependsOn(nonJsMain)
dependencies {
implementation(libs.pbandk.runtime.iosX64)
}
}
val iosArm64Main by getting {
dependsOn(nonJsMain)
dependencies {
implementation(libs.pbandk.runtime.iosArm64)
}
}
val iosSimulatorArm64Main by getting {
dependsOn(nonJsMain)
dependencies {
implementation(libs.pbandk.runtime.iosSimulatorArm64)
}
}
val macosX64Main by getting {
dependsOn(nonJsMain)
dependencies {
implementation(libs.pbandk.runtime.macX64)
}
}
val macosArm64Main by getting {
dependsOn(nonJsMain)
dependencies {
implementation(libs.pbandk.runtime.macArm64)
}
}
}
}
7 changes: 3 additions & 4 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ plugins {
}

kaliumLibrary {
multiplatform {
enableJs.set(false)
}
multiplatform { }
}

@Suppress("UnusedPrivateProperty")
kotlin {
sourceSets {
@Suppress("UnusedPrivateProperty")
val commonMain by getting {
dependencies {
implementation(project(":network-model"))
Expand Down
2 changes: 1 addition & 1 deletion network-model/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ plugins {

kaliumLibrary {
multiplatform {
enableJs.set(false)
enableJs.set(true)
}
}

Expand Down
Loading