mirror of
https://github.com/bitwarden/android.git
synced 2026-04-29 20:38:41 -05:00
PM-24688: Use the realtime elapse time to determine vault lock timeouts (#5684)
This commit is contained in:
@@ -3,6 +3,8 @@ package com.x8bit.bitwarden.data.platform.manager.di
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManagerImpl
|
||||||
import com.bitwarden.core.data.manager.toast.ToastManager
|
import com.bitwarden.core.data.manager.toast.ToastManager
|
||||||
import com.bitwarden.core.data.manager.toast.ToastManagerImpl
|
import com.bitwarden.core.data.manager.toast.ToastManagerImpl
|
||||||
import com.bitwarden.data.manager.DispatcherManager
|
import com.bitwarden.data.manager.DispatcherManager
|
||||||
@@ -198,6 +200,10 @@ object PlatformManagerModule {
|
|||||||
toastManager = toastManager,
|
toastManager = toastManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideRealtimeManager(): RealtimeManager = RealtimeManagerImpl()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideToastManager(
|
fun provideToastManager(
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import android.content.IntentFilter
|
|||||||
import com.bitwarden.core.InitOrgCryptoRequest
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoMethod
|
import com.bitwarden.core.InitUserCryptoMethod
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
||||||
import com.bitwarden.core.data.util.asSuccess
|
import com.bitwarden.core.data.util.asSuccess
|
||||||
import com.bitwarden.core.data.util.concurrentMapOf
|
import com.bitwarden.core.data.util.concurrentMapOf
|
||||||
@@ -77,6 +78,7 @@ private const val MAXIMUM_INVALID_UNLOCK_ATTEMPTS = 5
|
|||||||
@Suppress("TooManyFunctions", "LongParameterList")
|
@Suppress("TooManyFunctions", "LongParameterList")
|
||||||
class VaultLockManagerImpl(
|
class VaultLockManagerImpl(
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
|
private val realtimeManager: RealtimeManager,
|
||||||
private val authDiskSource: AuthDiskSource,
|
private val authDiskSource: AuthDiskSource,
|
||||||
private val authSdkSource: AuthSdkSource,
|
private val authSdkSource: AuthSdkSource,
|
||||||
private val vaultSdkSource: VaultSdkSource,
|
private val vaultSdkSource: VaultSdkSource,
|
||||||
@@ -613,7 +615,7 @@ class VaultLockManagerImpl(
|
|||||||
handleTimeoutAction(userId = userId, vaultTimeoutAction = vaultTimeoutAction)
|
handleTimeoutAction(userId = userId, vaultTimeoutAction = vaultTimeoutAction)
|
||||||
},
|
},
|
||||||
vaultTimeoutAction = vaultTimeoutAction,
|
vaultTimeoutAction = vaultTimeoutAction,
|
||||||
startTimeMs = clock.millis(),
|
startTimeMs = realtimeManager.elapsedRealtimeMs,
|
||||||
durationMs = delayMs,
|
durationMs = delayMs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -674,11 +676,12 @@ class VaultLockManagerImpl(
|
|||||||
private inner class ScreenStateBroadcastReceiver : BroadcastReceiver() {
|
private inner class ScreenStateBroadcastReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
userIdTimerJobMap.map { (userId, data) ->
|
userIdTimerJobMap.map { (userId, data) ->
|
||||||
|
val durationSoFarMs = (realtimeManager.elapsedRealtimeMs - data.startTimeMs)
|
||||||
|
.coerceAtLeast(minimumValue = 0L)
|
||||||
handleTimeoutActionWithDelay(
|
handleTimeoutActionWithDelay(
|
||||||
userId = userId,
|
userId = userId,
|
||||||
vaultTimeoutAction = data.vaultTimeoutAction,
|
vaultTimeoutAction = data.vaultTimeoutAction,
|
||||||
delayMs = data.durationMs - (clock.millis() - data.startTimeMs)
|
delayMs = data.durationMs - durationSoFarMs,
|
||||||
.coerceAtLeast(minimumValue = 0L),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.x8bit.bitwarden.data.vault.manager.di
|
package com.x8bit.bitwarden.data.vault.manager.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
import com.bitwarden.data.manager.DispatcherManager
|
import com.bitwarden.data.manager.DispatcherManager
|
||||||
import com.bitwarden.network.service.CiphersService
|
import com.bitwarden.network.service.CiphersService
|
||||||
import com.bitwarden.network.service.DownloadService
|
import com.bitwarden.network.service.DownloadService
|
||||||
@@ -73,6 +74,7 @@ object VaultManagerModule {
|
|||||||
fun provideVaultLockManager(
|
fun provideVaultLockManager(
|
||||||
@ApplicationContext context: Context,
|
@ApplicationContext context: Context,
|
||||||
clock: Clock,
|
clock: Clock,
|
||||||
|
realtimeManager: RealtimeManager,
|
||||||
authDiskSource: AuthDiskSource,
|
authDiskSource: AuthDiskSource,
|
||||||
authSdkSource: AuthSdkSource,
|
authSdkSource: AuthSdkSource,
|
||||||
vaultSdkSource: VaultSdkSource,
|
vaultSdkSource: VaultSdkSource,
|
||||||
@@ -85,6 +87,7 @@ object VaultManagerModule {
|
|||||||
VaultLockManagerImpl(
|
VaultLockManagerImpl(
|
||||||
context = context,
|
context = context,
|
||||||
clock = clock,
|
clock = clock,
|
||||||
|
realtimeManager = realtimeManager,
|
||||||
authDiskSource = authDiskSource,
|
authDiskSource = authDiskSource,
|
||||||
authSdkSource = authSdkSource,
|
authSdkSource = authSdkSource,
|
||||||
vaultSdkSource = vaultSdkSource,
|
vaultSdkSource = vaultSdkSource,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import app.cash.turbine.test
|
|||||||
import com.bitwarden.core.InitOrgCryptoRequest
|
import com.bitwarden.core.InitOrgCryptoRequest
|
||||||
import com.bitwarden.core.InitUserCryptoMethod
|
import com.bitwarden.core.InitUserCryptoMethod
|
||||||
import com.bitwarden.core.InitUserCryptoRequest
|
import com.bitwarden.core.InitUserCryptoRequest
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
import com.bitwarden.core.data.util.asFailure
|
import com.bitwarden.core.data.util.asFailure
|
||||||
import com.bitwarden.core.data.util.asSuccess
|
import com.bitwarden.core.data.util.asSuccess
|
||||||
import com.bitwarden.crypto.HashPurpose
|
import com.bitwarden.crypto.HashPurpose
|
||||||
@@ -100,10 +101,14 @@ class VaultLockManagerTest {
|
|||||||
}
|
}
|
||||||
private val testDispatcher = UnconfinedTestDispatcher()
|
private val testDispatcher = UnconfinedTestDispatcher()
|
||||||
private val fakeDispatcherManager = FakeDispatcherManager(unconfined = testDispatcher)
|
private val fakeDispatcherManager = FakeDispatcherManager(unconfined = testDispatcher)
|
||||||
|
private val realtimeManager: RealtimeManager = mockk {
|
||||||
|
every { elapsedRealtimeMs } returns FIXED_CLOCK.millis()
|
||||||
|
}
|
||||||
|
|
||||||
private val vaultLockManager: VaultLockManager = VaultLockManagerImpl(
|
private val vaultLockManager: VaultLockManager = VaultLockManagerImpl(
|
||||||
context = context,
|
context = context,
|
||||||
clock = FIXED_CLOCK,
|
clock = FIXED_CLOCK,
|
||||||
|
realtimeManager = realtimeManager,
|
||||||
authDiskSource = fakeAuthDiskSource,
|
authDiskSource = fakeAuthDiskSource,
|
||||||
authSdkSource = authSdkSource,
|
authSdkSource = authSdkSource,
|
||||||
vaultSdkSource = vaultSdkSource,
|
vaultSdkSource = vaultSdkSource,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.bitwarden.authenticator.data.auth.repository
|
package com.bitwarden.authenticator.data.auth.repository
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import com.bitwarden.authenticator.data.auth.datasource.disk.AuthDiskSource
|
import com.bitwarden.authenticator.data.auth.datasource.disk.AuthDiskSource
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,7 +9,7 @@ import javax.inject.Inject
|
|||||||
*/
|
*/
|
||||||
class AuthRepositoryImpl @Inject constructor(
|
class AuthRepositoryImpl @Inject constructor(
|
||||||
private val authDiskSource: AuthDiskSource,
|
private val authDiskSource: AuthDiskSource,
|
||||||
private val elapsedRealtimeMillisProvider: () -> Long = { SystemClock.elapsedRealtime() },
|
private val realtimeManager: RealtimeManager,
|
||||||
) : AuthRepository {
|
) : AuthRepository {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,7 +17,7 @@ class AuthRepositoryImpl @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
override fun updateLastActiveTime() {
|
override fun updateLastActiveTime() {
|
||||||
authDiskSource.storeLastActiveTimeMillis(
|
authDiskSource.storeLastActiveTimeMillis(
|
||||||
lastActiveTimeMillis = elapsedRealtimeMillisProvider(),
|
lastActiveTimeMillis = realtimeManager.elapsedRealtimeMs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.bitwarden.authenticator.data.auth.repository.di
|
|||||||
import com.bitwarden.authenticator.data.auth.datasource.disk.AuthDiskSource
|
import com.bitwarden.authenticator.data.auth.datasource.disk.AuthDiskSource
|
||||||
import com.bitwarden.authenticator.data.auth.repository.AuthRepository
|
import com.bitwarden.authenticator.data.auth.repository.AuthRepository
|
||||||
import com.bitwarden.authenticator.data.auth.repository.AuthRepositoryImpl
|
import com.bitwarden.authenticator.data.auth.repository.AuthRepositoryImpl
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
@@ -18,7 +19,9 @@ object AuthRepositoryModule {
|
|||||||
@Provides
|
@Provides
|
||||||
fun provideAuthRepository(
|
fun provideAuthRepository(
|
||||||
authDiskSource: AuthDiskSource,
|
authDiskSource: AuthDiskSource,
|
||||||
|
realtimeManager: RealtimeManager,
|
||||||
): AuthRepository = AuthRepositoryImpl(
|
): AuthRepository = AuthRepositoryImpl(
|
||||||
authDiskSource = authDiskSource,
|
authDiskSource = authDiskSource,
|
||||||
|
realtimeManager = realtimeManager,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import com.bitwarden.authenticator.data.platform.manager.imports.ImportManager
|
|||||||
import com.bitwarden.authenticator.data.platform.manager.imports.ImportManagerImpl
|
import com.bitwarden.authenticator.data.platform.manager.imports.ImportManagerImpl
|
||||||
import com.bitwarden.authenticator.data.platform.repository.DebugMenuRepository
|
import com.bitwarden.authenticator.data.platform.repository.DebugMenuRepository
|
||||||
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
|
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManager
|
||||||
|
import com.bitwarden.core.data.manager.realtime.RealtimeManagerImpl
|
||||||
import com.bitwarden.core.data.manager.toast.ToastManager
|
import com.bitwarden.core.data.manager.toast.ToastManager
|
||||||
import com.bitwarden.core.data.manager.toast.ToastManagerImpl
|
import com.bitwarden.core.data.manager.toast.ToastManagerImpl
|
||||||
import com.bitwarden.data.manager.DispatcherManager
|
import com.bitwarden.data.manager.DispatcherManager
|
||||||
@@ -49,6 +51,10 @@ object PlatformManagerModule {
|
|||||||
toastManager = toastManager,
|
toastManager = toastManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideRealtimeManager(): RealtimeManager = RealtimeManagerImpl()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideToastManager(
|
fun provideToastManager(
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.bitwarden.core.data.manager.realtime
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An manager interface for accessing the system realtime clock.
|
||||||
|
*/
|
||||||
|
interface RealtimeManager {
|
||||||
|
/**
|
||||||
|
* Returns milliseconds since the device has booted up, this includes time spent in sleep.
|
||||||
|
*/
|
||||||
|
val elapsedRealtimeMs: Long
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bitwarden.core.data.manager.realtime
|
||||||
|
|
||||||
|
import android.os.SystemClock
|
||||||
|
import com.bitwarden.annotation.OmitFromCoverage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation of the [RealtimeManager].
|
||||||
|
*/
|
||||||
|
@OmitFromCoverage
|
||||||
|
class RealtimeManagerImpl : RealtimeManager {
|
||||||
|
override val elapsedRealtimeMs: Long get() = SystemClock.elapsedRealtime()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user