From bc5bf155a2b328cbb169dc64049605036fc01748 Mon Sep 17 00:00:00 2001 From: Kamal Bramwell <kamal@elixxir.io> Date: Fri, 2 Dec 2022 09:08:30 -0500 Subject: [PATCH] Added Crust backup/restore data source --- .../messenger/backup/cloud/crust/Crust.kt | 88 +++++++++++++++++++ .../backup/cloud/crust/CrustDataSource.kt | 31 +++++++ .../backup/data/BackupLocationRepository.kt | 10 ++- .../messenger/backup/data/BackupSource.kt | 2 +- .../backup/data/backup/BackupMediator.kt | 1 + .../backup/BackupPreferencesRepository.kt | 1 + .../repository/PreferencesRepository.kt | 7 ++ 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/Crust.kt create mode 100644 app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/CrustDataSource.kt diff --git a/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/Crust.kt b/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/Crust.kt new file mode 100644 index 00000000..ebfd9cda --- /dev/null +++ b/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/Crust.kt @@ -0,0 +1,88 @@ +package io.xxlabs.messenger.backup.cloud.crust + +import io.xxlabs.messenger.R +import io.xxlabs.messenger.backup.bindings.AccountArchive +import io.xxlabs.messenger.backup.bindings.BackupService +import io.xxlabs.messenger.backup.cloud.CloudStorage +import io.xxlabs.messenger.backup.data.backup.BackupPreferencesRepository +import io.xxlabs.messenger.backup.data.restore.RestoreEnvironment +import io.xxlabs.messenger.backup.model.BackupLocation +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * Encapsulates Crust storage API. + */ +class Crust private constructor( + private val backupService: BackupService, + private val preferences: BackupPreferencesRepository, + private val crustApi: CrustDataSource +) : CloudStorage(backupService) { + + private var cachedBackupData: AccountArchive? = null + + override val location: BackupLocation = BackupLocationData( + R.drawable.ic_sftp, + "Crust", + ::signInRequired, + ::authBackgroundsApp, + ::signOut, + ::isEnabled + ) { + null + } + + private fun signInRequired(): Boolean = false + + private fun authBackgroundsApp() = false + + private fun signOut() {} + + override fun onAuthResultSuccess() { + scope.launch { + fetchData() + withContext(Dispatchers.Main) { + _authResultCallback?.onSuccess() + } + } + } + + private suspend fun fetchData() { + cachedBackupData = crustApi.recoverBackup("").getOrNull()?.let { + AccountArchive(it) + } + } + + override suspend fun onRestore(environment: RestoreEnvironment) { + updateProgress(25) + cachedBackupData?.restoreUsing(environment) + } + + override fun isEnabled(): Boolean { + return preferences.isCrustEnabled + } + + override fun backupNow() { + if (isEnabled()) backup() + } + + private fun backup() { + scope.launch { + updateProgress() + crustApi.uploadBackup(backupService.backupFilePath) + updateProgress(25) + } + } + + companion object { + @Volatile + private var instance: Crust? = null + + fun getInstance( + backupService: BackupService, + preferences: BackupPreferencesRepository, + crustApi: CrustDataSource + ): Crust = instance ?: Crust(backupService, preferences, crustApi) + } +} \ No newline at end of file diff --git a/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/CrustDataSource.kt b/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/CrustDataSource.kt new file mode 100644 index 00000000..2ffbad53 --- /dev/null +++ b/app/src/main/java/io/xxlabs/messenger/backup/cloud/crust/CrustDataSource.kt @@ -0,0 +1,31 @@ +package io.xxlabs.messenger.backup.cloud.crust + +import bindings.Bindings +import bindings.UserDiscovery + +interface CrustDataSource { + suspend fun uploadBackup(path: String): ByteArray + suspend fun recoverBackup(username: String): Result<ByteArray> +} + +class BindingsCrustMediator( + var udManager: UserDiscovery? = null, + var receptionRsaPrivateKey: ByteArray = byteArrayOf() +) : CrustDataSource { + + + override suspend fun uploadBackup(path: String): ByteArray { + return udManager?.let { + Bindings.uploadBackup(path, udManager, receptionRsaPrivateKey) + } ?: byteArrayOf() + } + + override suspend fun recoverBackup(username: String): Result<ByteArray> { + return try { + val backupData = Bindings.recoverBackup(username) + Result.success(backupData) + } catch (e: Exception) { + Result.failure(e) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/xxlabs/messenger/backup/data/BackupLocationRepository.kt b/app/src/main/java/io/xxlabs/messenger/backup/data/BackupLocationRepository.kt index f307ca2a..8cddcfce 100644 --- a/app/src/main/java/io/xxlabs/messenger/backup/data/BackupLocationRepository.kt +++ b/app/src/main/java/io/xxlabs/messenger/backup/data/BackupLocationRepository.kt @@ -1,6 +1,8 @@ package io.xxlabs.messenger.backup.data import io.xxlabs.messenger.backup.bindings.BackupService +import io.xxlabs.messenger.backup.cloud.crust.BindingsCrustMediator +import io.xxlabs.messenger.backup.cloud.crust.Crust import io.xxlabs.messenger.backup.cloud.drive.GoogleDrive import io.xxlabs.messenger.backup.cloud.dropbox.Dropbox import io.xxlabs.messenger.backup.cloud.sftp.transfer.Sftp @@ -12,14 +14,18 @@ abstract class BackupLocationRepository( backupService: BackupService, ) : AccountBackupDataSource { + private val crustApi = BindingsCrustMediator() + protected val googleDrive = GoogleDrive.getInstance(backupService, preferences) protected val dropbox = Dropbox.getInstance(backupService, preferences) protected val sftp = Sftp.getInstance(backupService, preferences) + protected val crust = Crust.getInstance(backupService, preferences, crustApi) override val locations: List<AccountBackup> = listOf( googleDrive, dropbox, - sftp + sftp, + crust ) override fun getBackupFrom(source: BackupSource): AccountBackup = @@ -27,6 +33,7 @@ abstract class BackupLocationRepository( BackupSource.DRIVE -> googleDrive BackupSource.DROPBOX -> dropbox BackupSource.SFTP -> sftp + BackupSource.CRUST -> crust } override fun getSourceFor(backup: AccountBackup): BackupSource? = @@ -34,6 +41,7 @@ abstract class BackupLocationRepository( is GoogleDrive -> BackupSource.DRIVE is Dropbox -> BackupSource.DROPBOX is Sftp -> BackupSource.SFTP + is Crust -> BackupSource.CRUST else -> null } } \ No newline at end of file diff --git a/app/src/main/java/io/xxlabs/messenger/backup/data/BackupSource.kt b/app/src/main/java/io/xxlabs/messenger/backup/data/BackupSource.kt index 8bf3bcdc..7cb9bf5f 100644 --- a/app/src/main/java/io/xxlabs/messenger/backup/data/BackupSource.kt +++ b/app/src/main/java/io/xxlabs/messenger/backup/data/BackupSource.kt @@ -2,4 +2,4 @@ package io.xxlabs.messenger.backup.data import java.io.Serializable -enum class BackupSource : Serializable { DRIVE, DROPBOX, SFTP } \ No newline at end of file +enum class BackupSource : Serializable { DRIVE, DROPBOX, SFTP, CRUST } \ No newline at end of file diff --git a/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupMediator.kt b/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupMediator.kt index 86099fbf..fa696e60 100644 --- a/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupMediator.kt +++ b/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupMediator.kt @@ -24,6 +24,7 @@ class BackupMediator @Inject constructor( googleDrive.location.name -> googleDrive dropbox.location.name -> dropbox sftp.location.name -> sftp + crust.location.name -> crust else -> null } diff --git a/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupPreferencesRepository.kt b/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupPreferencesRepository.kt index 23cfcaaf..e4325468 100644 --- a/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupPreferencesRepository.kt +++ b/app/src/main/java/io/xxlabs/messenger/backup/data/backup/BackupPreferencesRepository.kt @@ -5,6 +5,7 @@ interface BackupPreferencesRepository { var isGoogleDriveEnabled: Boolean var isDropboxEnabled: Boolean var isSftpEnabled: Boolean + var isCrustEnabled: Boolean var backupPassword: String? var autoBackup: Boolean var wiFiOnlyBackup: Boolean diff --git a/app/src/main/java/io/xxlabs/messenger/repository/PreferencesRepository.kt b/app/src/main/java/io/xxlabs/messenger/repository/PreferencesRepository.kt index e7b1b1a9..c25e36ab 100644 --- a/app/src/main/java/io/xxlabs/messenger/repository/PreferencesRepository.kt +++ b/app/src/main/java/io/xxlabs/messenger/repository/PreferencesRepository.kt @@ -245,6 +245,13 @@ class PreferencesRepository @Inject constructor( preferences.edit().putBoolean("sftp_enabled", value).apply() } + override var isCrustEnabled: Boolean = preferences.getBoolean("crust_enabled", false) + get() = preferences.getBoolean("crust_enabled", false) + set(value) { + field = value + preferences.edit().putBoolean("crust_enabled", value).apply() + } + override var backupPassword: String? = preferences.getString("backup_pw", null) get() = preferences.getString("backup_pw", null) set(value) { -- GitLab