mirror of
https://github.com/bitwarden/android.git
synced 2026-06-08 23:16:33 -05:00
Save Organizations data to disk when syncing (#429)
This commit is contained in:
committed by
Álison Fernandes
parent
f2842446c9
commit
fe20e2703c
@@ -1,6 +1,7 @@
|
||||
package com.x8bit.bitwarden.data.auth.datasource.disk
|
||||
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
@@ -63,4 +64,22 @@ interface AuthDiskSource {
|
||||
userId: String,
|
||||
organizationKeys: Map<String, String>?,
|
||||
)
|
||||
|
||||
/**
|
||||
* Gets the organization data for the given [userId].
|
||||
*/
|
||||
fun getOrganizations(userId: String): List<SyncResponseJson.Profile.Organization>?
|
||||
|
||||
/**
|
||||
* Emits updates that track [getOrganizations]. This will replay the last known value, if any.
|
||||
*/
|
||||
fun getOrganizationsFlow(userId: String): Flow<List<SyncResponseJson.Profile.Organization>?>
|
||||
|
||||
/**
|
||||
* Stores the organization data for the given [userId].
|
||||
*/
|
||||
fun storeOrganizations(
|
||||
userId: String,
|
||||
organizations: List<SyncResponseJson.Profile.Organization>?,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.SharedPreferences
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.BaseDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.BaseDiskSource.Companion.BASE_KEY
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.onSubscription
|
||||
@@ -16,6 +17,7 @@ private const val REMEMBERED_EMAIL_ADDRESS_KEY = "$BASE_KEY:rememberedEmail"
|
||||
private const val STATE_KEY = "$BASE_KEY:state"
|
||||
private const val MASTER_KEY_ENCRYPTION_USER_KEY = "$BASE_KEY:masterKeyEncryptedUserKey"
|
||||
private const val MASTER_KEY_ENCRYPTION_PRIVATE_KEY = "$BASE_KEY:encPrivateKey"
|
||||
private const val ORGANIZATIONS_KEY = "$BASE_KEY:organizations"
|
||||
private const val ORGANIZATION_KEYS_KEY = "$BASE_KEY:encOrgKeys"
|
||||
|
||||
/**
|
||||
@@ -26,6 +28,12 @@ class AuthDiskSourceImpl(
|
||||
private val json: Json,
|
||||
) : BaseDiskSource(sharedPreferences = sharedPreferences),
|
||||
AuthDiskSource {
|
||||
private val mutableOrganizationsFlow =
|
||||
MutableSharedFlow<List<SyncResponseJson.Profile.Organization>?>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
|
||||
override val uniqueAppId: String
|
||||
get() = getString(key = UNIQUE_APP_ID_KEY) ?: generateAndStoreUniqueAppId()
|
||||
|
||||
@@ -91,6 +99,29 @@ class AuthDiskSourceImpl(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getOrganizations(
|
||||
userId: String,
|
||||
): List<SyncResponseJson.Profile.Organization>? =
|
||||
getString(key = "${ORGANIZATIONS_KEY}_$userId")
|
||||
?.let { json.decodeFromString(it) }
|
||||
|
||||
override fun getOrganizationsFlow(
|
||||
userId: String,
|
||||
): Flow<List<SyncResponseJson.Profile.Organization>?> =
|
||||
mutableOrganizationsFlow
|
||||
.onSubscription { emit(getOrganizations(userId = userId)) }
|
||||
|
||||
override fun storeOrganizations(
|
||||
userId: String,
|
||||
organizations: List<SyncResponseJson.Profile.Organization>?,
|
||||
) {
|
||||
putString(
|
||||
key = "${ORGANIZATIONS_KEY}_$userId",
|
||||
value = organizations?.let { json.encodeToString(it) },
|
||||
)
|
||||
mutableOrganizationsFlow.tryEmit(organizations)
|
||||
}
|
||||
|
||||
private fun generateAndStoreUniqueAppId(): String =
|
||||
UUID
|
||||
.randomUUID()
|
||||
|
||||
@@ -245,6 +245,7 @@ class AuthRepositoryImpl constructor(
|
||||
storeUserKey(userId = userId, userKey = null)
|
||||
storePrivateKey(userId = userId, privateKey = null)
|
||||
storeOrganizationKeys(userId = userId, organizationKeys = null)
|
||||
storeOrganizations(userId = userId, organizations = null)
|
||||
}
|
||||
|
||||
// Check if there is a new active user
|
||||
|
||||
@@ -191,7 +191,7 @@ class VaultRepositoryImpl(
|
||||
)
|
||||
|
||||
unlockVaultForOrganizationsIfNecessary(syncResponse = syncResponse)
|
||||
storeKeys(syncResponse = syncResponse)
|
||||
storeProfileData(syncResponse = syncResponse)
|
||||
vaultDiskSource.replaceVaultData(userId = userId, vault = syncResponse)
|
||||
decryptSendsAndUpdateSendDataState(sendList = syncResponse.sends)
|
||||
},
|
||||
@@ -403,7 +403,7 @@ class VaultRepositoryImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun storeKeys(
|
||||
private fun storeProfileData(
|
||||
syncResponse: SyncResponseJson,
|
||||
) {
|
||||
val profile = syncResponse.profile
|
||||
@@ -426,6 +426,10 @@ class VaultRepositoryImpl(
|
||||
.filter { it.key != null }
|
||||
.associate { it.id to requireNotNull(it.key) },
|
||||
)
|
||||
storeOrganizations(
|
||||
userId = profile.id,
|
||||
organizations = syncResponse.profile.organizations,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user