mirror of
https://github.com/bitwarden/android.git
synced 2025-02-28 19:49:24 +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
authenticatorbridge/src
main/java/com/bitwarden/authenticatorbridge
test/java/com/bitwarden/authenticatorbridge/manager
|
@ -5,6 +5,7 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.content.pm.PackageManager.NameNotFoundException
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.lifecycle.DefaultLifecycleObserver
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
import androidx.lifecycle.LifecycleOwner
|
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.StubAuthenticatorBridgeCallbackProvider
|
||||||
import com.bitwarden.authenticatorbridge.provider.SymmetricKeyStorageProvider
|
import com.bitwarden.authenticatorbridge.provider.SymmetricKeyStorageProvider
|
||||||
import com.bitwarden.authenticatorbridge.util.decrypt
|
import com.bitwarden.authenticatorbridge.util.decrypt
|
||||||
|
import com.bitwarden.authenticatorbridge.util.isBuildVersionBelow
|
||||||
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
@ -58,10 +60,10 @@ internal class AuthenticatorBridgeManagerImpl(
|
||||||
*/
|
*/
|
||||||
private val mutableSharedAccountsStateFlow: MutableStateFlow<AccountSyncState> =
|
private val mutableSharedAccountsStateFlow: MutableStateFlow<AccountSyncState> =
|
||||||
MutableStateFlow(
|
MutableStateFlow(
|
||||||
if (isBitwardenAppInstalled()) {
|
when {
|
||||||
AccountSyncState.Loading
|
isBuildVersionBelow(Build.VERSION_CODES.S) -> AccountSyncState.OsVersionNotSupported
|
||||||
} else {
|
!isBitwardenAppInstalled() -> AccountSyncState.AppNotInstalled
|
||||||
AccountSyncState.AppNotInstalled
|
else -> AccountSyncState.Loading
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -102,6 +104,10 @@ internal class AuthenticatorBridgeManagerImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindService() {
|
private fun bindService() {
|
||||||
|
if (isBuildVersionBelow(Build.VERSION_CODES.S)) {
|
||||||
|
mutableSharedAccountsStateFlow.value = AccountSyncState.OsVersionNotSupported
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!isBitwardenAppInstalled()) {
|
if (!isBitwardenAppInstalled()) {
|
||||||
mutableSharedAccountsStateFlow.value = AccountSyncState.AppNotInstalled
|
mutableSharedAccountsStateFlow.value = AccountSyncState.AppNotInstalled
|
||||||
return
|
return
|
||||||
|
|
|
@ -27,6 +27,11 @@ sealed class AccountSyncState {
|
||||||
*/
|
*/
|
||||||
data object Loading : AccountSyncState()
|
data object Loading : AccountSyncState()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OS version can't support account syncing.
|
||||||
|
*/
|
||||||
|
data object OsVersionNotSupported: AccountSyncState()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accounts successfully synced.
|
* 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.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.content.pm.PackageManager.NameNotFoundException
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
|
import android.os.Build
|
||||||
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService
|
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService
|
||||||
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback
|
import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback
|
||||||
import com.bitwarden.authenticatorbridge.manager.model.AccountSyncState
|
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.TestAuthenticatorBridgeCallbackProvider
|
||||||
import com.bitwarden.authenticatorbridge.util.decrypt
|
import com.bitwarden.authenticatorbridge.util.decrypt
|
||||||
import com.bitwarden.authenticatorbridge.util.generateSecretKey
|
import com.bitwarden.authenticatorbridge.util.generateSecretKey
|
||||||
|
import com.bitwarden.authenticatorbridge.util.isBuildVersionBelow
|
||||||
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
import com.bitwarden.authenticatorbridge.util.toFingerprint
|
||||||
import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData
|
import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
@ -45,23 +47,27 @@ class AuthenticatorBridgeManagerTest {
|
||||||
private val fakeSymmetricKeyStorageProvider = FakeSymmetricKeyStorageProvider()
|
private val fakeSymmetricKeyStorageProvider = FakeSymmetricKeyStorageProvider()
|
||||||
private val testAuthenticatorBridgeCallbackProvider = TestAuthenticatorBridgeCallbackProvider()
|
private val testAuthenticatorBridgeCallbackProvider = TestAuthenticatorBridgeCallbackProvider()
|
||||||
|
|
||||||
private val manager: AuthenticatorBridgeManagerImpl = AuthenticatorBridgeManagerImpl(
|
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,
|
context = context,
|
||||||
connectionType = AuthenticatorBridgeConnectionType.DEV,
|
connectionType = AuthenticatorBridgeConnectionType.DEV,
|
||||||
symmetricKeyStorageProvider = fakeSymmetricKeyStorageProvider,
|
symmetricKeyStorageProvider = fakeSymmetricKeyStorageProvider,
|
||||||
callbackProvider = testAuthenticatorBridgeCallbackProvider,
|
callbackProvider = testAuthenticatorBridgeCallbackProvider,
|
||||||
processLifecycleOwner = fakeLifecycleOwner,
|
processLifecycleOwner = fakeLifecycleOwner,
|
||||||
)
|
)
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
fun setup() {
|
|
||||||
mockkConstructor(Intent::class)
|
|
||||||
mockkStatic(IAuthenticatorBridgeService.Stub::class)
|
|
||||||
mockkStatic(EncryptedSharedAccountData::decrypt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun teardown() {
|
fun teardown() {
|
||||||
|
mockkStatic(::isBuildVersionBelow)
|
||||||
unmockkConstructor(Intent::class)
|
unmockkConstructor(Intent::class)
|
||||||
unmockkStatic(IAuthenticatorBridgeService.Stub::class)
|
unmockkStatic(IAuthenticatorBridgeService.Stub::class)
|
||||||
unmockkStatic(EncryptedSharedAccountData::decrypt)
|
unmockkStatic(EncryptedSharedAccountData::decrypt)
|
||||||
|
@ -87,6 +93,26 @@ class AuthenticatorBridgeManagerTest {
|
||||||
assertEquals(AccountSyncState.AppNotInstalled, manager.accountSyncStateFlow.value)
|
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
|
@Test
|
||||||
fun `onStart when bindService fails should set state to error`() {
|
fun `onStart when bindService fails should set state to error`() {
|
||||||
val mockIntent: Intent = mockk()
|
val mockIntent: Intent = mockk()
|
||||||
|
|
Loading…
Add table
Reference in a new issue