From ea4825b8b84a8d82bd93ee949aed8ac5c61457ac Mon Sep 17 00:00:00 2001 From: David Perez Date: Tue, 19 Dec 2023 12:29:34 -0600 Subject: [PATCH] Delete the users vault data on logout (#418) --- .../data/auth/repository/AuthRepositoryImpl.kt | 3 +++ .../data/vault/repository/VaultRepository.kt | 6 ++++++ .../data/vault/repository/VaultRepositoryImpl.kt | 6 ++++++ .../data/auth/repository/AuthRepositoryTest.kt | 6 +++++- .../data/vault/repository/VaultRepositoryTest.kt | 12 ++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt index 831898f769..4a31a4e739 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt @@ -267,6 +267,9 @@ class AuthRepositoryImpl constructor( authDiskSource.userState = null } + // Delete all the vault data + vaultRepository.deleteVaultData(userId) + // Lock the vault for the logged out user vaultRepository.lockVaultIfNecessary(userId) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepository.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepository.kt index 2fb912f452..783d181a3e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepository.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepository.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.StateFlow /** * Responsible for managing vault data inside the network layer. */ +@Suppress("TooManyFunctions") interface VaultRepository { /** @@ -53,6 +54,11 @@ interface VaultRepository { */ fun clearUnlockedData() + /** + * Completely remove any persisted data from the vault. + */ + fun deleteVaultData(userId: String) + /** * Attempt to sync the vault data. */ diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt index baeffa1e5c..53d8c6854b 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt @@ -143,6 +143,12 @@ class VaultRepositoryImpl( sendDataMutableStateFlow.update { DataState.Loading } } + override fun deleteVaultData(userId: String) { + scope.launch { + vaultDiskSource.deleteVaultData(userId) + } + } + override fun sync() { if (!syncJob.isCompleted || willSyncAfterUnlock) return val userId = activeUserId ?: return diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt index 2ec51a2c7c..fd426d35ea 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt @@ -74,8 +74,9 @@ class AuthRepositoryTest { private val identityService: IdentityService = mockk() private val haveIBeenPwnedService: HaveIBeenPwnedService = mockk() private val mutableVaultStateFlow = MutableStateFlow(VAULT_STATE) - private val vaultRepository: VaultRepository = mockk() { + private val vaultRepository: VaultRepository = mockk { every { vaultStateFlow } returns mutableVaultStateFlow + every { deleteVaultData(any()) } just runs every { lockVaultIfNecessary(any()) } just runs every { clearUnlockedData() } just runs } @@ -999,6 +1000,7 @@ class AuthRepositoryTest { userId = USER_ID_1, organizationKeys = null, ) + verify { vaultRepository.deleteVaultData(userId = USER_ID_1) } verify { vaultRepository.clearUnlockedData() } verify { vaultRepository.lockVaultIfNecessary(userId = USER_ID_1) } } @@ -1081,6 +1083,7 @@ class AuthRepositoryTest { userId = USER_ID_1, organizationKeys = null, ) + verify { vaultRepository.deleteVaultData(userId = USER_ID_1) } verify { vaultRepository.clearUnlockedData() } verify { vaultRepository.lockVaultIfNecessary(userId = USER_ID_1) } } @@ -1131,6 +1134,7 @@ class AuthRepositoryTest { userId = USER_ID_2, organizationKeys = null, ) + verify { vaultRepository.deleteVaultData(userId = USER_ID_2) } verify(exactly = 0) { vaultRepository.clearUnlockedData() } verify { vaultRepository.lockVaultIfNecessary(userId = USER_ID_2) } } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt index 53d43c97a0..ad647a5417 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt @@ -243,6 +243,18 @@ class VaultRepositoryTest { } } + @Test + fun `deleteVaultData should call deleteVaultData on VaultDiskSource`() { + val userId = "userId-1234" + coEvery { vaultDiskSource.deleteVaultData(userId) } just runs + + vaultRepository.deleteVaultData(userId = userId) + + coVerify(exactly = 1) { + vaultDiskSource.deleteVaultData(userId) + } + } + @Suppress("MaxLineLength") @Test fun `sync with syncService Success should unlock the vault for orgs if necessary and update AuthDiskSource and DataStateFlows`() =