Replace the generic Result class in the auth repo with specific result classes (#301)

This commit is contained in:
David Perez
2024-06-20 17:08:07 +01:00
committed by Álison Fernandes
parent c9c313230f
commit 798fdf3e19
9 changed files with 163 additions and 65 deletions
@@ -1,8 +1,9 @@
package com.x8bit.bitwarden.data.auth.repository
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
import com.x8bit.bitwarden.data.auth.repository.model.AuthState
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.model.PasswordStrengthResult
import com.x8bit.bitwarden.data.auth.repository.model.RegisterResult
import com.x8bit.bitwarden.data.auth.repository.model.UserState
import com.x8bit.bitwarden.data.auth.repository.util.CaptchaCallbackTokenResult
@@ -38,7 +39,7 @@ interface AuthRepository : AuthenticatorProvider {
/**
* Attempt to delete the current account and logout them out upon success.
*/
suspend fun deleteAccount(password: String): Result<Unit>
suspend fun deleteAccount(password: String): DeleteAccountResult
/**
* Attempt to login with the given email and password. Updated access token will be reflected
@@ -74,5 +75,5 @@ interface AuthRepository : AuthenticatorProvider {
/**
* Get the password strength for the given [email] and [password] combo.
*/
suspend fun getPasswordStrength(email: String, password: String): Result<PasswordStrength>
suspend fun getPasswordStrength(email: String, password: String): PasswordStrengthResult
}
@@ -15,7 +15,9 @@ import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toKdfTypeJson
import com.x8bit.bitwarden.data.auth.repository.model.AuthState
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.model.PasswordStrengthResult
import com.x8bit.bitwarden.data.auth.repository.model.RegisterResult
import com.x8bit.bitwarden.data.auth.repository.model.UserState
import com.x8bit.bitwarden.data.auth.repository.util.CaptchaCallbackTokenResult
@@ -27,7 +29,6 @@ import com.x8bit.bitwarden.data.auth.util.toSdkParams
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.util.asFailure
import com.x8bit.bitwarden.data.platform.util.asSuccess
import com.x8bit.bitwarden.data.platform.util.flatMap
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import kotlinx.coroutines.CoroutineScope
@@ -107,9 +108,9 @@ class AuthRepositoryImpl constructor(
authDiskSource.rememberedEmailAddress = value
}
override suspend fun deleteAccount(password: String): Result<Unit> {
override suspend fun deleteAccount(password: String): DeleteAccountResult {
val profile = authDiskSource.userState?.activeAccount?.profile
?: return IllegalStateException("Not logged in.").asFailure()
?: return DeleteAccountResult.Error
return authSdkSource
.hashPassword(
email = profile.email,
@@ -118,6 +119,10 @@ class AuthRepositoryImpl constructor(
)
.flatMap { hashedPassword -> accountsService.deleteAccount(hashedPassword) }
.onSuccess { logout() }
.fold(
onFailure = { DeleteAccountResult.Error },
onSuccess = { DeleteAccountResult.Success },
)
}
override suspend fun login(
@@ -322,17 +327,18 @@ class AuthRepositoryImpl constructor(
override suspend fun getPasswordStrength(
email: String,
password: String,
): Result<PasswordStrength> {
): PasswordStrengthResult {
// TODO: Replace with SDK call (BIT-964)
// Ex: return authSdkSource.passwordStrength(email, password)
val length = password.length
return when {
length <= 3 -> PasswordStrength.LEVEL_0
length <= 6 -> PasswordStrength.LEVEL_1
length <= 9 -> PasswordStrength.LEVEL_2
length <= 11 -> PasswordStrength.LEVEL_3
else -> PasswordStrength.LEVEL_4
}
.asSuccess()
return PasswordStrengthResult.Success(
passwordStrength = when {
length <= 3 -> PasswordStrength.LEVEL_0
length <= 6 -> PasswordStrength.LEVEL_1
length <= 9 -> PasswordStrength.LEVEL_2
length <= 11 -> PasswordStrength.LEVEL_3
else -> PasswordStrength.LEVEL_4
},
)
}
}
@@ -0,0 +1,16 @@
package com.x8bit.bitwarden.data.auth.repository.model
/**
* Models result of deleting an account.
*/
sealed class DeleteAccountResult {
/**
* Delete succeeded.
*/
data object Success : DeleteAccountResult()
/**
* There was an error deleting the account.
*/
data object Error : DeleteAccountResult()
}
@@ -0,0 +1,20 @@
package com.x8bit.bitwarden.data.auth.repository.model
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
/**
* Models result of determining the strength of a password.
*/
sealed class PasswordStrengthResult {
/**
* The contains the password strength.
*/
data class Success(
val passwordStrength: PasswordStrength,
) : PasswordStrengthResult()
/**
* There was an error determining the password strength.
*/
data object Error : PasswordStrengthResult()
}
@@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.model.PasswordStrengthResult
import com.x8bit.bitwarden.data.auth.repository.model.RegisterResult
import com.x8bit.bitwarden.data.auth.repository.util.CaptchaCallbackTokenResult
import com.x8bit.bitwarden.data.auth.repository.util.generateUriForCaptcha
@@ -111,18 +112,24 @@ class CreateAccountViewModel @Inject constructor(
}
private fun handlePasswordStrengthResult(action: ReceivePasswordStrengthResult) {
action.result.onSuccess {
val updatedState = when (it) {
PasswordStrength.LEVEL_0 -> PasswordStrengthState.WEAK_1
PasswordStrength.LEVEL_1 -> PasswordStrengthState.WEAK_2
PasswordStrength.LEVEL_2 -> PasswordStrengthState.WEAK_3
PasswordStrength.LEVEL_3 -> PasswordStrengthState.GOOD
PasswordStrength.LEVEL_4 -> PasswordStrengthState.STRONG
when (val result = action.result) {
is PasswordStrengthResult.Success -> {
val updatedState = when (result.passwordStrength) {
PasswordStrength.LEVEL_0 -> PasswordStrengthState.WEAK_1
PasswordStrength.LEVEL_1 -> PasswordStrengthState.WEAK_2
PasswordStrength.LEVEL_2 -> PasswordStrengthState.WEAK_3
PasswordStrength.LEVEL_3 -> PasswordStrengthState.GOOD
PasswordStrength.LEVEL_4 -> PasswordStrengthState.STRONG
}
mutableStateFlow.update { oldState ->
oldState.copy(
passwordStrengthState = updatedState,
)
}
}
mutableStateFlow.update { oldState ->
oldState.copy(
passwordStrengthState = updatedState,
)
PasswordStrengthResult.Error -> {
// TODO: Assess possible error conditions (BIT-964)
}
}
}
@@ -510,7 +517,7 @@ sealed class CreateAccountAction {
* Indicates a password strength result has been received.
*/
data class ReceivePasswordStrengthResult(
val result: Result<PasswordStrength>,
val result: PasswordStrengthResult,
) : Internal()
}
}
@@ -5,6 +5,7 @@ import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.Text
import com.x8bit.bitwarden.ui.platform.base.util.asText
@@ -74,12 +75,13 @@ class DeleteAccountViewModel @Inject constructor(
private fun handleDeleteAccountComplete(
action: DeleteAccountAction.Internal.DeleteAccountComplete,
) {
action.result.fold(
onSuccess = {
when (action.result) {
DeleteAccountResult.Success -> {
mutableStateFlow.update { it.copy(dialog = null) }
// TODO: Display a dialog confirming account deletion (BIT-1184)
},
onFailure = {
}
DeleteAccountResult.Error -> {
mutableStateFlow.update {
it.copy(
dialog = DeleteAccountState.DeleteAccountDialog.Error(
@@ -87,8 +89,8 @@ class DeleteAccountViewModel @Inject constructor(
),
)
}
},
)
}
}
}
}
@@ -171,7 +173,7 @@ sealed class DeleteAccountAction {
* Indicates that the delete account request has completed.
*/
data class DeleteAccountComplete(
val result: Result<Unit>,
val result: DeleteAccountResult,
) : Internal()
}
}