mirror of
https://github.com/bitwarden/android.git
synced 2024-11-21 08:55:48 +03:00
BITAU-69 Check for OS version in AuthenticatorBridgeManager (#4019)
This commit is contained in:
parent
20383f06a8
commit
32f2bfb29f
4 changed files with 58 additions and 11 deletions
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
@ -18,6 +19,7 @@ import com.bitwarden.authenticatorbridge.provider.AuthenticatorBridgeCallbackPro
|
|||
import com.bitwarden.authenticatorbridge.provider.StubAuthenticatorBridgeCallbackProvider
|
||||
import com.bitwarden.authenticatorbridge.provider.SymmetricKeyStorageProvider
|
||||
import com.bitwarden.authenticatorbridge.util.decrypt
|
||||
import com.bitwarden.authenticatorbridge.util.isBuildVersionBelow
|
||||
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
@ -58,10 +60,10 @@ internal class AuthenticatorBridgeManagerImpl(
|
|||
*/
|
||||
private val mutableSharedAccountsStateFlow: MutableStateFlow<AccountSyncState> =
|
||||
MutableStateFlow(
|
||||
if (isBitwardenAppInstalled()) {
|
||||
AccountSyncState.Loading
|
||||
} else {
|
||||
AccountSyncState.AppNotInstalled
|
||||
when {
|
||||
isBuildVersionBelow(Build.VERSION_CODES.S) -> AccountSyncState.OsVersionNotSupported
|
||||
!isBitwardenAppInstalled() -> AccountSyncState.AppNotInstalled
|
||||
else -> AccountSyncState.Loading
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -102,6 +104,10 @@ internal class AuthenticatorBridgeManagerImpl(
|
|||
}
|
||||
|
||||
private fun bindService() {
|
||||
if (isBuildVersionBelow(Build.VERSION_CODES.S)) {
|
||||
mutableSharedAccountsStateFlow.value = AccountSyncState.OsVersionNotSupported
|
||||
return
|
||||
}
|
||||
if (!isBitwardenAppInstalled()) {
|
||||
mutableSharedAccountsStateFlow.value = AccountSyncState.AppNotInstalled
|
||||
return
|
||||
|
|
|
@ -27,6 +27,11 @@ sealed class AccountSyncState {
|
|||
*/
|
||||
data object Loading : AccountSyncState()
|
||||
|
||||
/**
|
||||
* OS version can't support account syncing.
|
||||
*/
|
||||
data object OsVersionNotSupported: AccountSyncState()
|
||||
|
||||
/**
|
||||
* Accounts successfully synced.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.bitwarden.authenticatorbridge.util
|
||||
|
||||
import android.os.Build
|
||||
|
||||
/**
|
||||
* Returns true if the current OS build version is below the provided [version].
|
||||
*
|
||||
* @see Build.VERSION_CODES
|
||||
*/
|
||||
fun isBuildVersionBelow(version: Int): Boolean = version > Build.VERSION.SDK_INT
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.os.Build
|
||||
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService
|
||||
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback
|
||||
import com.bitwarden.authenticatorbridge.manager.model.AccountSyncState
|
||||
|
@ -15,6 +16,7 @@ import com.bitwarden.authenticatorbridge.util.FakeSymmetricKeyStorageProvider
|
|||
import com.bitwarden.authenticatorbridge.util.TestAuthenticatorBridgeCallbackProvider
|
||||
import com.bitwarden.authenticatorbridge.util.decrypt
|
||||
import com.bitwarden.authenticatorbridge.util.generateSecretKey
|
||||
import com.bitwarden.authenticatorbridge.util.isBuildVersionBelow
|
||||
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
||||
import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData
|
||||
import io.mockk.every
|
||||
|
@ -45,23 +47,27 @@ class AuthenticatorBridgeManagerTest {
|
|||
private val fakeSymmetricKeyStorageProvider = FakeSymmetricKeyStorageProvider()
|
||||
private val testAuthenticatorBridgeCallbackProvider = TestAuthenticatorBridgeCallbackProvider()
|
||||
|
||||
private val manager: AuthenticatorBridgeManagerImpl = AuthenticatorBridgeManagerImpl(
|
||||
context = context,
|
||||
connectionType = AuthenticatorBridgeConnectionType.DEV,
|
||||
symmetricKeyStorageProvider = fakeSymmetricKeyStorageProvider,
|
||||
callbackProvider = testAuthenticatorBridgeCallbackProvider,
|
||||
processLifecycleOwner = fakeLifecycleOwner,
|
||||
)
|
||||
private lateinit var manager: AuthenticatorBridgeManagerImpl
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(::isBuildVersionBelow)
|
||||
every { isBuildVersionBelow(Build.VERSION_CODES.S) } returns false
|
||||
mockkConstructor(Intent::class)
|
||||
mockkStatic(IAuthenticatorBridgeService.Stub::class)
|
||||
mockkStatic(EncryptedSharedAccountData::decrypt)
|
||||
manager = AuthenticatorBridgeManagerImpl(
|
||||
context = context,
|
||||
connectionType = AuthenticatorBridgeConnectionType.DEV,
|
||||
symmetricKeyStorageProvider = fakeSymmetricKeyStorageProvider,
|
||||
callbackProvider = testAuthenticatorBridgeCallbackProvider,
|
||||
processLifecycleOwner = fakeLifecycleOwner,
|
||||
)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
mockkStatic(::isBuildVersionBelow)
|
||||
unmockkConstructor(Intent::class)
|
||||
unmockkStatic(IAuthenticatorBridgeService.Stub::class)
|
||||
unmockkStatic(EncryptedSharedAccountData::decrypt)
|
||||
|
@ -87,6 +93,26 @@ class AuthenticatorBridgeManagerTest {
|
|||
assertEquals(AccountSyncState.AppNotInstalled, manager.accountSyncStateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial AccountSyncState should be OsVersionNotSupported when OS level is below S`() {
|
||||
every { isBuildVersionBelow(Build.VERSION_CODES.S) } returns true
|
||||
val manager = AuthenticatorBridgeManagerImpl(
|
||||
context = context,
|
||||
connectionType = AuthenticatorBridgeConnectionType.DEV,
|
||||
symmetricKeyStorageProvider = fakeSymmetricKeyStorageProvider,
|
||||
callbackProvider = testAuthenticatorBridgeCallbackProvider,
|
||||
processLifecycleOwner = fakeLifecycleOwner,
|
||||
)
|
||||
assertEquals(AccountSyncState.OsVersionNotSupported, manager.accountSyncStateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onStart when OS level is below S should set state to OsVersionNotSupported`() {
|
||||
every { isBuildVersionBelow(Build.VERSION_CODES.S) } returns true
|
||||
fakeLifecycleOwner.lifecycle.dispatchOnStart()
|
||||
assertEquals(AccountSyncState.OsVersionNotSupported, manager.accountSyncStateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onStart when bindService fails should set state to error`() {
|
||||
val mockIntent: Intent = mockk()
|
||||
|
|
Loading…
Reference in a new issue