mirror of
https://github.com/bitwarden/android.git
synced 2026-08-01 18:53:39 -05:00
PM-41062: chore: Separate ephemeral and persistent pin envelopes (#7218)
This commit is contained in:
+51
-25
@@ -199,16 +199,11 @@ interface AuthDiskSource : AppIdProvider {
|
||||
* Retrieves a pin-protected user key for the given [userId].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use getPinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelope"),
|
||||
message = "Use getEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
fun getPinProtectedUserKey(userId: String): String?
|
||||
|
||||
/**
|
||||
* Retrieves a pin-protected user key envelope for the given [userId].
|
||||
*/
|
||||
fun getPinProtectedUserKeyEnvelope(userId: String): String?
|
||||
|
||||
/**
|
||||
* Stores a pin-protected user key for the given [userId].
|
||||
*
|
||||
@@ -216,8 +211,8 @@ interface AuthDiskSource : AppIdProvider {
|
||||
* [getPinProtectedUserKey] during the current app session.
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use storePinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("storePinProtectedUserKeyEnvelope"),
|
||||
message = "Use storeEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"storePersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
fun storePinProtectedUserKey(
|
||||
userId: String,
|
||||
@@ -225,31 +220,62 @@ interface AuthDiskSource : AppIdProvider {
|
||||
inMemoryOnly: Boolean = false,
|
||||
)
|
||||
|
||||
/**
|
||||
* Stores a pin-protected user key envelope for the given [userId].
|
||||
*
|
||||
* When [inMemoryOnly] is `true`, the value will only be available via a call to
|
||||
* [getPinProtectedUserKeyEnvelope] during the current app session.
|
||||
*/
|
||||
fun storePinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
inMemoryOnly: Boolean = false,
|
||||
)
|
||||
|
||||
/**
|
||||
* Retrieves a flow for the pin-protected user key for the given [userId].
|
||||
*/
|
||||
@Deprecated(
|
||||
message = "Use getPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelopeFlow"),
|
||||
message = "Use getEphemeralPinProtectedUserKeyEnvelopeFlow and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
)
|
||||
fun getPinProtectedUserKeyFlow(userId: String): Flow<String?>
|
||||
|
||||
/**
|
||||
* Retrieves a flow for the pin-protected user key envelope for the given [userId].
|
||||
* Retrieves the pin-protected user key envelope for the given [userId].
|
||||
*
|
||||
* This will return either the in-memory or persistent pin-protected user key, whichever is
|
||||
* available.
|
||||
*/
|
||||
fun getPinProtectedUserKeyEnvelopeFlow(userId: String): Flow<String?>
|
||||
fun getPinProtectedUserKeyEnvelope(userId: String): String?
|
||||
|
||||
/**
|
||||
* Retrieves the ephemeral pin-protected user key envelope for the given [userId].
|
||||
*
|
||||
* This will always ignore the persistent pin-protected user key.
|
||||
*/
|
||||
fun getEphemeralPinProtectedUserKeyEnvelope(userId: String): String?
|
||||
|
||||
/**
|
||||
* Retrieves the persistent pin-protected user key envelope for the given [userId].
|
||||
*
|
||||
* This will always ignore the ephemeral pin-protected user key.
|
||||
*/
|
||||
fun getPersistentPinProtectedUserKeyEnvelope(userId: String): String?
|
||||
|
||||
/**
|
||||
* Stores an ephemeral pin-protected user key envelope for the given [userId].
|
||||
*/
|
||||
fun storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
)
|
||||
|
||||
/**
|
||||
* Stores a persistent pin-protected user key envelope for the given [userId].
|
||||
*/
|
||||
fun storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
)
|
||||
|
||||
/**
|
||||
* Retrieves a flow for the ephemeral pin-protected user key envelope for the given [userId].
|
||||
*/
|
||||
fun getEphemeralPinProtectedUserKeyEnvelopeFlow(userId: String): Flow<String?>
|
||||
|
||||
/**
|
||||
* Retrieves a flow for the persistent pin-protected user key envelope for the given [userId].
|
||||
*/
|
||||
fun getPersistentPinProtectedUserKeyEnvelopeFlow(userId: String): Flow<String?>
|
||||
|
||||
/**
|
||||
* Gets a two-factor auth token using a user's [email].
|
||||
|
||||
+77
-42
@@ -74,8 +74,11 @@ class AuthDiskSourceImpl(
|
||||
),
|
||||
AuthDiskSource {
|
||||
|
||||
private val inMemoryPinProtectedUserKeys = mutableMapOf<String, String?>()
|
||||
private val inMemoryPinProtectedUserKeyEnvelopes = mutableMapOf<String, String?>()
|
||||
// Ephemeral in-memory values
|
||||
private val ephemeralPinProtectedUserKeys = mutableMapOf<String, String?>()
|
||||
private val ephemeralPinProtectedUserKeyEnvelopes = mutableMapOf<String, String?>()
|
||||
|
||||
// Shared flows for observing data changes
|
||||
private val mutableShouldUseKeyConnectorFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<Boolean?>>()
|
||||
private val mutableOrganizationsFlowMap =
|
||||
@@ -91,7 +94,9 @@ class AuthDiskSourceImpl(
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val mutablePinProtectedUserKeyFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val mutablePinProtectedUserKeyEnvelopeFlowMap =
|
||||
private val mutableEphemeralPinProtectedUserKeyEnvelopeFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val mutablePersistentPinProtectedUserKeyEnvelopeFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val mutableUserStateFlow = bufferedMutableSharedFlow<UserStateJson?>(replay = 1)
|
||||
|
||||
@@ -179,7 +184,14 @@ class AuthDiskSourceImpl(
|
||||
storeLastLockTimestamp(userId = userId, lastLockTimestamp = null)
|
||||
storeEncryptedPin(userId = userId, encryptedPin = null)
|
||||
storePinProtectedUserKey(userId = userId, pinProtectedUserKey = null)
|
||||
storePinProtectedUserKeyEnvelope(userId = userId, pinProtectedUserKeyEnvelope = null)
|
||||
storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
|
||||
// Certain values are never removed as required by the feature requirements:
|
||||
// * DeviceKey
|
||||
@@ -342,29 +354,23 @@ class AuthDiskSourceImpl(
|
||||
.onSubscription { emit(getUserBiometricUnlockKey(userId = userId)) }
|
||||
|
||||
@Deprecated(
|
||||
"Use getPinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelope"),
|
||||
"Use getEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
override fun getPinProtectedUserKey(userId: String): String? =
|
||||
inMemoryPinProtectedUserKeys[userId]
|
||||
ephemeralPinProtectedUserKeys[userId]
|
||||
?: getString(key = PIN_PROTECTED_USER_KEY_KEY.appendIdentifier(userId))
|
||||
|
||||
override fun getPinProtectedUserKeyEnvelope(userId: String): String? =
|
||||
inMemoryPinProtectedUserKeyEnvelopes[userId]
|
||||
?: getString(
|
||||
key = PIN_PROTECTED_USER_KEY_KEY_ENVELOPE.appendIdentifier(userId),
|
||||
)
|
||||
|
||||
@Deprecated(
|
||||
"Use storePinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("storePinProtectedUserKeyEnvelope"),
|
||||
"Use storeEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"storePersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
override fun storePinProtectedUserKey(
|
||||
userId: String,
|
||||
pinProtectedUserKey: String?,
|
||||
inMemoryOnly: Boolean,
|
||||
) {
|
||||
inMemoryPinProtectedUserKeys[userId] = pinProtectedUserKey
|
||||
ephemeralPinProtectedUserKeys[userId] = pinProtectedUserKey
|
||||
if (inMemoryOnly) return
|
||||
putString(
|
||||
key = PIN_PROTECTED_USER_KEY_KEY.appendIdentifier(userId),
|
||||
@@ -373,34 +379,57 @@ class AuthDiskSourceImpl(
|
||||
getMutablePinProtectedUserKeyFlow(userId).tryEmit(pinProtectedUserKey)
|
||||
}
|
||||
|
||||
override fun storePinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
inMemoryOnly: Boolean,
|
||||
) {
|
||||
inMemoryPinProtectedUserKeyEnvelopes[userId] = pinProtectedUserKeyEnvelope
|
||||
if (inMemoryOnly) {
|
||||
getMutablePinProtectedUserKeyEnvelopeFlow(userId).tryEmit(pinProtectedUserKeyEnvelope)
|
||||
return
|
||||
}
|
||||
putString(
|
||||
key = PIN_PROTECTED_USER_KEY_KEY_ENVELOPE.appendIdentifier(userId),
|
||||
value = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
getMutablePinProtectedUserKeyEnvelopeFlow(userId).tryEmit(pinProtectedUserKeyEnvelope)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Use getPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelopeFlow"),
|
||||
"Use getEphemeralPinProtectedUserKeyEnvelopeFlow and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
)
|
||||
override fun getPinProtectedUserKeyFlow(userId: String): Flow<String?> =
|
||||
getMutablePinProtectedUserKeyFlow(userId)
|
||||
.onSubscription { emit(getPinProtectedUserKey(userId = userId)) }
|
||||
|
||||
override fun getPinProtectedUserKeyEnvelopeFlow(userId: String): Flow<String?> =
|
||||
getMutablePinProtectedUserKeyEnvelopeFlow(userId)
|
||||
.onSubscription { emit(getPinProtectedUserKeyEnvelope(userId = userId)) }
|
||||
override fun getPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = getEphemeralPinProtectedUserKeyEnvelope(userId = userId)
|
||||
?: getPersistentPinProtectedUserKeyEnvelope(userId = userId)
|
||||
|
||||
override fun getEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = ephemeralPinProtectedUserKeyEnvelopes[userId]
|
||||
|
||||
override fun getPersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = getString(key = PIN_PROTECTED_USER_KEY_KEY_ENVELOPE.appendIdentifier(userId))
|
||||
|
||||
override fun storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
) {
|
||||
ephemeralPinProtectedUserKeyEnvelopes[userId] = pinProtectedUserKeyEnvelope
|
||||
getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.tryEmit(pinProtectedUserKeyEnvelope)
|
||||
}
|
||||
|
||||
override fun storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
) {
|
||||
putString(
|
||||
key = PIN_PROTECTED_USER_KEY_KEY_ENVELOPE.appendIdentifier(userId),
|
||||
value = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
getMutablePersistentPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.tryEmit(pinProtectedUserKeyEnvelope)
|
||||
}
|
||||
|
||||
override fun getEphemeralPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): Flow<String?> = getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.onSubscription { emit(getEphemeralPinProtectedUserKeyEnvelope(userId = userId)) }
|
||||
|
||||
override fun getPersistentPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): Flow<String?> = getMutablePersistentPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.onSubscription { emit(getPersistentPinProtectedUserKeyEnvelope(userId = userId)) }
|
||||
|
||||
override fun getTwoFactorToken(email: String): String? =
|
||||
getString(key = TWO_FACTOR_TOKEN_KEY.appendIdentifier(email))
|
||||
@@ -635,11 +664,17 @@ class AuthDiskSourceImpl(
|
||||
bufferedMutableSharedFlow(replay = 1)
|
||||
}
|
||||
|
||||
private fun getMutablePinProtectedUserKeyEnvelopeFlow(
|
||||
private fun getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): MutableSharedFlow<String?> = mutablePinProtectedUserKeyEnvelopeFlowMap.getOrPut(userId) {
|
||||
bufferedMutableSharedFlow(replay = 1)
|
||||
}
|
||||
): MutableSharedFlow<String?> = mutableEphemeralPinProtectedUserKeyEnvelopeFlowMap.getOrPut(
|
||||
key = userId,
|
||||
) { bufferedMutableSharedFlow(replay = 1) }
|
||||
|
||||
private fun getMutablePersistentPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): MutableSharedFlow<String?> = mutablePersistentPinProtectedUserKeyEnvelopeFlowMap.getOrPut(
|
||||
key = userId,
|
||||
) { bufferedMutableSharedFlow(replay = 1) }
|
||||
|
||||
private fun migrateAccountTokens() {
|
||||
userState
|
||||
|
||||
@@ -82,9 +82,10 @@ class UserLogoutManagerImpl(
|
||||
val vaultTimeoutAction = settingsDiskSource.getVaultTimeoutAction(userId = userId)
|
||||
val encryptedPin = authDiskSource.getEncryptedPin(userId = userId)
|
||||
val pinProtectedUserKey = authDiskSource.getPinProtectedUserKey(userId = userId)
|
||||
val pinProtectedUserKeyEnvelope = authDiskSource.getPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
)
|
||||
val ephemeralPinProtectedUserKeyEnvelope = authDiskSource
|
||||
.getEphemeralPinProtectedUserKeyEnvelope(userId = userId)
|
||||
val persistentPinProtectedUserKeyEnvelope = authDiskSource
|
||||
.getPersistentPinProtectedUserKeyEnvelope(userId = userId)
|
||||
|
||||
clearData(userId = userId)
|
||||
mutableLogoutEventFlow.tryEmit(LogoutEvent(loggedOutUserId = userId))
|
||||
@@ -103,9 +104,13 @@ class UserLogoutManagerImpl(
|
||||
authDiskSource.apply {
|
||||
storeEncryptedPin(userId = userId, encryptedPin = encryptedPin)
|
||||
storePinProtectedUserKey(userId = userId, pinProtectedUserKey = pinProtectedUserKey)
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
pinProtectedUserKeyEnvelope = ephemeralPinProtectedUserKeyEnvelope,
|
||||
)
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = persistentPinProtectedUserKeyEnvelope,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+28
-24
@@ -294,13 +294,15 @@ class SettingsRepositoryImpl(
|
||||
override val isUnlockWithPinEnabledFlow: Flow<Boolean>
|
||||
get() = activeUserId
|
||||
?.let { userId ->
|
||||
authDiskSource
|
||||
.getPinProtectedUserKeyFlow(userId)
|
||||
.combine(
|
||||
authDiskSource.getPinProtectedUserKeyEnvelopeFlow(userId),
|
||||
) { pinProtectedUserKey, pinProtectedUserKeyEnvelope ->
|
||||
pinProtectedUserKey != null || pinProtectedUserKeyEnvelope != null
|
||||
}
|
||||
combine(
|
||||
authDiskSource.getPinProtectedUserKeyFlow(userId = userId),
|
||||
authDiskSource.getEphemeralPinProtectedUserKeyEnvelopeFlow(userId = userId),
|
||||
authDiskSource.getPersistentPinProtectedUserKeyEnvelopeFlow(userId = userId),
|
||||
) { pinUserKey, ephemeralPinUserKeyEnvelope, persistentPinUserKeyEnvelope ->
|
||||
pinUserKey != null ||
|
||||
ephemeralPinUserKeyEnvelope != null ||
|
||||
persistentPinUserKeyEnvelope != null
|
||||
}
|
||||
}
|
||||
?: flowOf(false)
|
||||
|
||||
@@ -627,17 +629,21 @@ class SettingsRepositoryImpl(
|
||||
userId = userId,
|
||||
encryptedPin = enrollPinResponse.userKeyEncryptedPin,
|
||||
)
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope =
|
||||
enrollPinResponse.pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = shouldRequireMasterPasswordOnRestart,
|
||||
)
|
||||
if (shouldRequireMasterPasswordOnRestart) {
|
||||
storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = enrollPinResponse
|
||||
.pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
} else {
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = enrollPinResponse
|
||||
.pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
}
|
||||
// Remove any legacy pin protected user keys.
|
||||
storePinProtectedUserKey(
|
||||
userId = userId,
|
||||
pinProtectedUserKey = null,
|
||||
)
|
||||
storePinProtectedUserKey(userId = userId, pinProtectedUserKey = null)
|
||||
}
|
||||
},
|
||||
onFailure = {
|
||||
@@ -652,18 +658,16 @@ class SettingsRepositoryImpl(
|
||||
override fun clearUnlockPin() {
|
||||
val userId = activeUserId ?: return
|
||||
authDiskSource.apply {
|
||||
storeEncryptedPin(
|
||||
userId = userId,
|
||||
encryptedPin = null,
|
||||
)
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
storeEncryptedPin(userId = userId, encryptedPin = null)
|
||||
storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
authDiskSource.storePinProtectedUserKey(
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKey = null,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
storePinProtectedUserKey(userId = userId, pinProtectedUserKey = null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-6
@@ -67,7 +67,7 @@ internal class PinProtectedUserKeyManagerImpl(
|
||||
userId = userId,
|
||||
encryptedPin = null,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
inMemoryOnly = false,
|
||||
inMemoryOnly = inMemoryOnly,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -78,11 +78,17 @@ internal class PinProtectedUserKeyManagerImpl(
|
||||
inMemoryOnly: Boolean,
|
||||
) {
|
||||
authDiskSource.storeEncryptedPin(userId = userId, encryptedPin = encryptedPin)
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = inMemoryOnly,
|
||||
)
|
||||
if (inMemoryOnly) {
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
} else {
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
}
|
||||
// This property is deprecated and we should be migrated to the PinProtectedUserKeyEnvelope.
|
||||
// Because of this, we always clear this value and it should always be cleared at the disk
|
||||
// level, not the in-memory level.
|
||||
|
||||
+15
-10
@@ -283,9 +283,13 @@ class AuthDiskSourceTest {
|
||||
userId = userId,
|
||||
pinProtectedUserKey = "pinProtectedUserKey",
|
||||
)
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
pinProtectedUserKeyEnvelope = "ephemeralPinProtectedUserKeyEnvelope",
|
||||
)
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = "persistentPinProtectedUserKeyEnvelope",
|
||||
)
|
||||
authDiskSource.storeInvalidUnlockAttempts(
|
||||
userId = userId,
|
||||
@@ -358,6 +362,8 @@ class AuthDiskSourceTest {
|
||||
assertNull(authDiskSource.getEncryptedPin(userId = userId))
|
||||
assertNull(authDiskSource.getPinProtectedUserKey(userId = userId))
|
||||
assertNull(authDiskSource.getPinProtectedUserKeyEnvelope(userId = userId))
|
||||
assertNull(authDiskSource.getEphemeralPinProtectedUserKeyEnvelope(userId = userId))
|
||||
assertNull(authDiskSource.getPersistentPinProtectedUserKeyEnvelope(userId = userId))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -813,13 +819,13 @@ class AuthDiskSourceTest {
|
||||
|
||||
@Test
|
||||
@Suppress("MaxLineLength")
|
||||
fun `storePinProtectedUserKeyEnvelope should update result flow from getPinProtectedUserKeyEnvelopeFlow`() =
|
||||
fun `storePersistentPinProtectedUserKeyEnvelope should update result flow from getPersistentPinProtectedUserKeyEnvelopeFlow`() =
|
||||
runTest {
|
||||
val topSecretKey = "topsecret"
|
||||
val mockUserId = "mockUserId"
|
||||
authDiskSource.getPinProtectedUserKeyEnvelopeFlow(mockUserId).test {
|
||||
authDiskSource.getPersistentPinProtectedUserKeyEnvelopeFlow(mockUserId).test {
|
||||
assertNull(awaitItem())
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = mockUserId,
|
||||
pinProtectedUserKeyEnvelope = topSecretKey,
|
||||
)
|
||||
@@ -829,17 +835,16 @@ class AuthDiskSourceTest {
|
||||
|
||||
@Test
|
||||
@Suppress("MaxLineLength")
|
||||
fun `storePinProtectedUserKeyEnvelope with inMemoryOnly true emits flow and stores only in memory`() =
|
||||
fun `storeEphemeralPinProtectedUserKeyEnvelope emits flow and stores only in memory`() =
|
||||
runTest {
|
||||
val userId = "mockUserId"
|
||||
val envelope = "topSecretEnvelope"
|
||||
|
||||
authDiskSource.getPinProtectedUserKeyEnvelopeFlow(userId).test {
|
||||
authDiskSource.getEphemeralPinProtectedUserKeyEnvelopeFlow(userId).test {
|
||||
assertNull(awaitItem())
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = envelope,
|
||||
inMemoryOnly = true,
|
||||
)
|
||||
assertEquals(envelope, awaitItem())
|
||||
assertEquals(envelope, authDiskSource.getPinProtectedUserKeyEnvelope(userId))
|
||||
@@ -878,7 +883,7 @@ class AuthDiskSourceTest {
|
||||
"bwPreferencesStorage:pinKeyEncryptedUserKeyEnvelope"
|
||||
val mockUserId = "mockUserId"
|
||||
val mockPinProtectedUserKeyEnvelope = "mockPinProtectedUserKeyEnvelope"
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = mockUserId,
|
||||
pinProtectedUserKeyEnvelope = mockPinProtectedUserKeyEnvelope,
|
||||
)
|
||||
|
||||
+84
-36
@@ -65,8 +65,11 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
private val storedLastLockTimestampState = mutableMapOf<String, Instant?>()
|
||||
private val storedAccountCryptographicState =
|
||||
mutableMapOf<String, WrappedAccountCryptographicState?>()
|
||||
private val storedPinProtectedUserKeyEnvelopes = mutableMapOf<String, Pair<String?, Boolean>>()
|
||||
private val mutablePinProtectedUserKeyEnvelopesFlowMap =
|
||||
private val storedEphemeralPinProtectedUserKeyEnvelopes = mutableMapOf<String, String?>()
|
||||
private val storedPersistentPinProtectedUserKeyEnvelopes = mutableMapOf<String, String?>()
|
||||
private val mutableEphemeralPinProtectedUserKeyEnvelopesFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
private val mutablePersistentPinProtectedUserKeyEnvelopesFlowMap =
|
||||
mutableMapOf<String, MutableSharedFlow<String?>>()
|
||||
|
||||
override var userState: UserStateJson? = null
|
||||
@@ -90,7 +93,8 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
storedBiometricInitVectors.remove(userId)
|
||||
storedBiometricKeys.remove(userId)
|
||||
storedOrganizationKeys.remove(userId)
|
||||
storedPinProtectedUserKeyEnvelopes.remove(userId)
|
||||
storedEphemeralPinProtectedUserKeyEnvelopes.remove(userId)
|
||||
storedPersistentPinProtectedUserKeyEnvelopes.remove(userId)
|
||||
storedEncryptedPins.remove(userId)
|
||||
storedPinProtectedUserKeys.remove(userId)
|
||||
|
||||
@@ -98,13 +102,8 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
mutableOrganizationsFlowMap.remove(userId)
|
||||
mutablePoliciesFlowMap.remove(userId)
|
||||
mutableAccountTokensFlowMap.remove(userId)
|
||||
mutablePinProtectedUserKeyEnvelopesFlowMap.remove(userId)
|
||||
}
|
||||
|
||||
private fun getMutablePinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): MutableSharedFlow<String?> = mutablePinProtectedUserKeyEnvelopesFlowMap.getOrPut(userId) {
|
||||
bufferedMutableSharedFlow(replay = 1)
|
||||
mutableEphemeralPinProtectedUserKeyEnvelopesFlowMap.remove(userId)
|
||||
mutablePersistentPinProtectedUserKeyEnvelopesFlowMap.remove(userId)
|
||||
}
|
||||
|
||||
override fun getShouldUseKeyConnectorFlow(
|
||||
@@ -175,15 +174,15 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Use getPinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelope"),
|
||||
"Use getEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
override fun getPinProtectedUserKey(userId: String): String? =
|
||||
storedPinProtectedUserKeys[userId]?.first
|
||||
|
||||
@Deprecated(
|
||||
"Use storePinProtectedUserKeyEnvelope instead.",
|
||||
replaceWith = ReplaceWith("storePinProtectedUserKeyEnvelope"),
|
||||
"Use storeEphemeralPinProtectedUserKeyEnvelope and " +
|
||||
"storePersistentPinProtectedUserKeyEnvelope instead.",
|
||||
)
|
||||
override fun storePinProtectedUserKey(
|
||||
userId: String,
|
||||
@@ -195,8 +194,8 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
"Use getPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
replaceWith = ReplaceWith("getPinProtectedUserKeyEnvelopeFlow"),
|
||||
"Use getEphemeralPinProtectedUserKeyEnvelopeFlow and " +
|
||||
"getPersistentPinProtectedUserKeyEnvelopeFlow instead.",
|
||||
)
|
||||
override fun getPinProtectedUserKeyFlow(userId: String): Flow<String?> =
|
||||
getMutablePinProtectedUserKeyFlow(userId)
|
||||
@@ -347,40 +346,63 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
storedLastLockTimestampState[userId] = lastLockTimestamp
|
||||
}
|
||||
|
||||
override fun getPinProtectedUserKeyEnvelope(userId: String): String? =
|
||||
storedPinProtectedUserKeyEnvelopes[userId]?.first
|
||||
override fun getPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = getEphemeralPinProtectedUserKeyEnvelope(userId = userId)
|
||||
?: getPersistentPinProtectedUserKeyEnvelope(userId = userId)
|
||||
|
||||
override fun storePinProtectedUserKeyEnvelope(
|
||||
override fun getEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = storedEphemeralPinProtectedUserKeyEnvelopes[userId]
|
||||
|
||||
override fun getPersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
): String? = storedPersistentPinProtectedUserKeyEnvelopes[userId]
|
||||
|
||||
override fun storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
inMemoryOnly: Boolean,
|
||||
) {
|
||||
storedPinProtectedUserKeyEnvelopes[userId] = pinProtectedUserKeyEnvelope to inMemoryOnly
|
||||
getMutablePinProtectedUserKeyEnvelopeFlow(userId).tryEmit(pinProtectedUserKeyEnvelope)
|
||||
storedEphemeralPinProtectedUserKeyEnvelopes[userId] = pinProtectedUserKeyEnvelope
|
||||
getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.tryEmit(pinProtectedUserKeyEnvelope)
|
||||
}
|
||||
|
||||
override fun getPinProtectedUserKeyEnvelopeFlow(userId: String): Flow<String?> =
|
||||
getMutablePinProtectedUserKeyEnvelopeFlow(userId)
|
||||
.onSubscription {
|
||||
emit(getPinProtectedUserKeyEnvelope(userId))
|
||||
}
|
||||
override fun storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
) {
|
||||
storedPersistentPinProtectedUserKeyEnvelopes[userId] = pinProtectedUserKeyEnvelope
|
||||
getMutablePersistentPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.tryEmit(pinProtectedUserKeyEnvelope)
|
||||
}
|
||||
|
||||
override fun getEphemeralPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): Flow<String?> = getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.onSubscription { emit(getEphemeralPinProtectedUserKeyEnvelope(userId = userId)) }
|
||||
|
||||
override fun getPersistentPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): Flow<String?> = getMutablePersistentPinProtectedUserKeyEnvelopeFlow(userId = userId)
|
||||
.onSubscription { emit(getPersistentPinProtectedUserKeyEnvelope(userId = userId)) }
|
||||
|
||||
/**
|
||||
* Assert the the [isTdeLoginComplete] was stored successfully using the [userId].
|
||||
* Assert the [isTdeLoginComplete] was stored successfully using the [userId].
|
||||
*/
|
||||
fun assertIsTdeLoginComplete(userId: String, isTdeLoginComplete: Boolean?) {
|
||||
assertEquals(isTdeLoginComplete, storedIsTdeLoginComplete[userId])
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the the [shouldTrustDevice] was stored successfully using the [userId].
|
||||
* Assert the [shouldTrustDevice] was stored successfully using the [userId].
|
||||
*/
|
||||
fun assertShouldTrustDevice(userId: String, shouldTrustDevice: Boolean?) {
|
||||
assertEquals(shouldTrustDevice, storedShouldTrustDevice[userId])
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the the [shouldUseKeyConnector] was stored successfully using the [userId].
|
||||
* Assert the [shouldUseKeyConnector] was stored successfully using the [userId].
|
||||
*/
|
||||
fun assertShouldUseKeyConnector(userId: String, shouldUseKeyConnector: Boolean?) {
|
||||
assertEquals(shouldUseKeyConnector, storedShouldUseKeyConnector[userId])
|
||||
@@ -450,21 +472,35 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the [pinProtectedUserKeyEnvelope] was stored successfully using the [userId].
|
||||
* Assert that the ephemeral [pinProtectedUserKeyEnvelope] was stored successfully using the
|
||||
* [userId].
|
||||
*/
|
||||
fun assertPinProtectedUserKeyEnvelope(
|
||||
fun assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
inMemoryOnly: Boolean = false,
|
||||
) {
|
||||
assertEquals(
|
||||
pinProtectedUserKeyEnvelope to inMemoryOnly,
|
||||
storedPinProtectedUserKeyEnvelopes[userId],
|
||||
pinProtectedUserKeyEnvelope,
|
||||
storedEphemeralPinProtectedUserKeyEnvelopes[userId],
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the the [organizationKeys] was stored successfully using the [userId].
|
||||
* Assert that the persistent [pinProtectedUserKeyEnvelope] was stored successfully using the
|
||||
* [userId].
|
||||
*/
|
||||
fun assertPersistentPinProtectedUserKeyEnvelope(
|
||||
userId: String,
|
||||
pinProtectedUserKeyEnvelope: String?,
|
||||
) {
|
||||
assertEquals(
|
||||
pinProtectedUserKeyEnvelope,
|
||||
storedPersistentPinProtectedUserKeyEnvelopes[userId],
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the [organizationKeys] was stored successfully using the [userId].
|
||||
*/
|
||||
fun assertOrganizationKeys(userId: String, organizationKeys: Map<String, String>?) {
|
||||
assertEquals(organizationKeys, storedOrganizationKeys[userId])
|
||||
@@ -587,5 +623,17 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||
bufferedMutableSharedFlow(replay = 1)
|
||||
}
|
||||
|
||||
private fun getMutableEphemeralPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): MutableSharedFlow<String?> = mutableEphemeralPinProtectedUserKeyEnvelopesFlowMap.getOrPut(
|
||||
key = userId,
|
||||
) { bufferedMutableSharedFlow(replay = 1) }
|
||||
|
||||
private fun getMutablePersistentPinProtectedUserKeyEnvelopeFlow(
|
||||
userId: String,
|
||||
): MutableSharedFlow<String?> = mutablePersistentPinProtectedUserKeyEnvelopesFlowMap.getOrPut(
|
||||
key = userId,
|
||||
) { bufferedMutableSharedFlow(replay = 1) }
|
||||
|
||||
//endregion Private helper functions
|
||||
}
|
||||
|
||||
@@ -152,10 +152,19 @@ class UserLogoutManagerTest {
|
||||
settingsDiskSource.getVaultTimeoutAction(userId = userId)
|
||||
} returns vaultTimeoutAction
|
||||
every {
|
||||
authDiskSource.getPinProtectedUserKeyEnvelope(userId = userId)
|
||||
authDiskSource.getEphemeralPinProtectedUserKeyEnvelope(userId = userId)
|
||||
} returns pinProtectedUserKeyEnvelope
|
||||
every {
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.getPersistentPinProtectedUserKeyEnvelope(userId = userId)
|
||||
} returns pinProtectedUserKeyEnvelope
|
||||
every {
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
} just runs
|
||||
every {
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
@@ -193,7 +202,11 @@ class UserLogoutManagerTest {
|
||||
userId = userId,
|
||||
vaultTimeoutAction = vaultTimeoutAction,
|
||||
)
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
@@ -221,10 +234,19 @@ class UserLogoutManagerTest {
|
||||
settingsDiskSource.getVaultTimeoutAction(userId = userId)
|
||||
} returns vaultTimeoutAction
|
||||
every {
|
||||
authDiskSource.getPinProtectedUserKeyEnvelope(userId = userId)
|
||||
authDiskSource.getEphemeralPinProtectedUserKeyEnvelope(userId = userId)
|
||||
} returns pinProtectedUserKeyEnvelope
|
||||
every {
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.getPersistentPinProtectedUserKeyEnvelope(userId = userId)
|
||||
} returns pinProtectedUserKeyEnvelope
|
||||
every {
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
} just runs
|
||||
every {
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
@@ -252,7 +274,11 @@ class UserLogoutManagerTest {
|
||||
userId = userId,
|
||||
vaultTimeoutAction = vaultTimeoutAction,
|
||||
)
|
||||
authDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
authDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
authDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
)
|
||||
|
||||
@@ -100,11 +100,11 @@ class UserStateManagerTest {
|
||||
)
|
||||
|
||||
fakeAuthDiskSource.apply {
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID_1,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUseKey",
|
||||
)
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID_2,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUseKey",
|
||||
)
|
||||
@@ -147,11 +147,11 @@ class UserStateManagerTest {
|
||||
)
|
||||
|
||||
fakeAuthDiskSource.apply {
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID_1,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID_2,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
|
||||
@@ -6707,7 +6707,7 @@ class AuthRepositoryTest {
|
||||
val pinProtectedUserKey = "pinProtectedUserKey"
|
||||
val error = Throwable("Fail!")
|
||||
fakeAuthDiskSource.userState = SINGLE_USER_STATE_1
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = SINGLE_USER_STATE_1.activeUserId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKey,
|
||||
)
|
||||
@@ -6741,7 +6741,7 @@ class AuthRepositoryTest {
|
||||
val pin = "PIN"
|
||||
val pinProtectedUserKey = "pinProtectedUserKey"
|
||||
fakeAuthDiskSource.userState = SINGLE_USER_STATE_1
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = SINGLE_USER_STATE_1.activeUserId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKey,
|
||||
)
|
||||
@@ -6775,7 +6775,7 @@ class AuthRepositoryTest {
|
||||
val pin = "PIN"
|
||||
val pinProtectedUserKey = "pinProtectedUserKey"
|
||||
fakeAuthDiskSource.userState = SINGLE_USER_STATE_1
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = SINGLE_USER_STATE_1.activeUserId,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKey,
|
||||
)
|
||||
|
||||
+13
-7
@@ -210,7 +210,7 @@ class SettingsRepositoryTest {
|
||||
|
||||
// Updating the Vault settings values and calling setDefaultsIfNecessary again has no
|
||||
// effect on the currently stored values since we have a way to unlock the vault.
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedKey",
|
||||
)
|
||||
@@ -1050,10 +1050,9 @@ class SettingsRepositoryTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
assertPinProtectedUserKeyEnvelope(
|
||||
assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = true,
|
||||
)
|
||||
}
|
||||
coVerify {
|
||||
@@ -1092,10 +1091,9 @@ class SettingsRepositoryTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
assertPinProtectedUserKeyEnvelope(
|
||||
assertPersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = false,
|
||||
)
|
||||
}
|
||||
coVerify {
|
||||
@@ -1115,7 +1113,11 @@ class SettingsRepositoryTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = "encryptedPin",
|
||||
)
|
||||
storePinProtectedUserKeyEnvelope(
|
||||
storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
)
|
||||
storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
)
|
||||
@@ -1128,7 +1130,11 @@ class SettingsRepositoryTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = null,
|
||||
)
|
||||
assertPinProtectedUserKeyEnvelope(
|
||||
assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
assertPersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
|
||||
+29
-16
@@ -41,7 +41,7 @@ class PinProtectedUserKeyManagerTest {
|
||||
fun `deriveTemporaryPinProtectedUserKeyIfNecessary with encrypted key and existing pinProtectedUserKeyEnvelope does nothing`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = "encryptedPin")
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
)
|
||||
@@ -67,7 +67,7 @@ class PinProtectedUserKeyManagerTest {
|
||||
userKeyEncryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = encryptedPin)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -92,10 +92,9 @@ class PinProtectedUserKeyManagerTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = true,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKey(
|
||||
userId = USER_ID,
|
||||
@@ -106,12 +105,12 @@ class PinProtectedUserKeyManagerTest {
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `deriveTemporaryPinProtectedUserKeyIfNecessary with enrollment failure should clear all pin data`() =
|
||||
fun `deriveTemporaryPinProtectedUserKeyIfNecessary with enrollment failure should clear ephemeral pin data`() =
|
||||
runTest {
|
||||
val encryptedPin = "encryptedPin"
|
||||
val error = Throwable("Fail!")
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = encryptedPin)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -136,10 +135,9 @@ class PinProtectedUserKeyManagerTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = null,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
inMemoryOnly = false,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKey(
|
||||
userId = USER_ID,
|
||||
@@ -162,10 +160,27 @@ class PinProtectedUserKeyManagerTest {
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `migratePinProtectedUserKeyIfNeeded with encrypted key and existing pinProtectedUserKeyEnvelope does nothing`() =
|
||||
fun `migratePinProtectedUserKeyIfNeeded with encrypted key and existing PersistentPinProtectedUserKeyEnvelope does nothing`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = "encryptedPin")
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
)
|
||||
|
||||
pinProtectedUserKeyManager.migratePinProtectedUserKeyIfNeeded(userId = USER_ID)
|
||||
|
||||
coVerify(exactly = 0) {
|
||||
vaultSdkSource.enrollPinWithEncryptedPin(userId = any(), encryptedPin = any())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `migratePinProtectedUserKeyIfNeeded with encrypted key and existing ephemeralPinProtectedUserKeyEnvelope does nothing`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = "encryptedPin")
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = "pinProtectedUserKeyEnvelope",
|
||||
)
|
||||
@@ -189,7 +204,7 @@ class PinProtectedUserKeyManagerTest {
|
||||
userKeyEncryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = encryptedPin)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -216,10 +231,9 @@ class PinProtectedUserKeyManagerTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = userKeyEncryptedPin,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.assertEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = pinProtectedUserKeyEnvelope,
|
||||
inMemoryOnly = true,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKey(
|
||||
userId = USER_ID,
|
||||
@@ -236,7 +250,7 @@ class PinProtectedUserKeyManagerTest {
|
||||
val pinProtectedUserKey = "pinProtectedUserKey"
|
||||
val error = Throwable("Fail!")
|
||||
fakeAuthDiskSource.storeEncryptedPin(userId = USER_ID, encryptedPin = encryptedPin)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -263,10 +277,9 @@ class PinProtectedUserKeyManagerTest {
|
||||
userId = USER_ID,
|
||||
encryptedPin = null,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.assertPersistentPinProtectedUserKeyEnvelope(
|
||||
userId = USER_ID,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
inMemoryOnly = false,
|
||||
)
|
||||
fakeAuthDiskSource.assertPinProtectedUserKey(
|
||||
userId = USER_ID,
|
||||
|
||||
+16
-4
@@ -675,7 +675,11 @@ class VaultRepositoryTest {
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKey = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -699,7 +703,11 @@ class VaultRepositoryTest {
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = "mockId-1",
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -754,7 +762,11 @@ class VaultRepositoryTest {
|
||||
val mockVaultUnlockResult = VaultUnlockResult.Success
|
||||
prepareStateForUnlocking(unlockResult = mockVaultUnlockResult)
|
||||
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storeEphemeralPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = null,
|
||||
)
|
||||
@@ -1585,7 +1597,7 @@ class VaultRepositoryTest {
|
||||
userId = userId,
|
||||
pinProtectedUserKey = "mockKey-1",
|
||||
)
|
||||
fakeAuthDiskSource.storePinProtectedUserKeyEnvelope(
|
||||
fakeAuthDiskSource.storePersistentPinProtectedUserKeyEnvelope(
|
||||
userId = userId,
|
||||
pinProtectedUserKeyEnvelope = "mockKey-1",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user