mirror of
https://github.com/bitwarden/android.git
synced 2026-06-07 14:57:41 -05:00
BIT-1246, BIT-1250: Show correct permission-related errors when editing (#482)
This commit is contained in:
committed by
Álison Fernandes
parent
8476e55b5a
commit
1e996fcbbe
@@ -9,6 +9,7 @@ import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.serialization.json.Json
|
||||
import retrofit2.create
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -23,8 +24,10 @@ object VaultNetworkModule {
|
||||
@Singleton
|
||||
fun provideCiphersService(
|
||||
retrofits: Retrofits,
|
||||
json: Json,
|
||||
): CiphersService = CiphersServiceImpl(
|
||||
ciphersApi = retrofits.authenticatedApiRetrofit.create(),
|
||||
json = json,
|
||||
)
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Models the response from the update cipher request.
|
||||
*/
|
||||
sealed class UpdateCipherResponseJson {
|
||||
/**
|
||||
* The request completed successfully and returned the updated [cipher].
|
||||
*/
|
||||
data class Success(
|
||||
val cipher: SyncResponseJson.Cipher,
|
||||
) : UpdateCipherResponseJson()
|
||||
|
||||
/**
|
||||
* Represents the json body of an invalid update request.
|
||||
*
|
||||
* @param message A general, user-displayable error message.
|
||||
* @param validationErrors a map where each value is a list of error messages for each key.
|
||||
* The values in the array should be used for display to the user, since the keys tend to come
|
||||
* back as nonsense. (eg: empty string key)
|
||||
*/
|
||||
@Serializable
|
||||
data class Invalid(
|
||||
@SerialName("message")
|
||||
val message: String?,
|
||||
|
||||
@SerialName("validationErrors")
|
||||
val validationErrors: Map<String, List<String>>?,
|
||||
) : UpdateCipherResponseJson()
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.vault.datasource.network.service
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherResponseJson
|
||||
|
||||
/**
|
||||
* Provides an API for querying ciphers endpoints.
|
||||
@@ -18,5 +19,5 @@ interface CiphersService {
|
||||
suspend fun updateCipher(
|
||||
cipherId: String,
|
||||
body: CipherJsonRequest,
|
||||
): Result<SyncResponseJson.Cipher>
|
||||
): Result<UpdateCipherResponseJson>
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.network.service
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.toBitwardenError
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.util.parseErrorBodyOrNull
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.CiphersApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherResponseJson
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class CiphersServiceImpl constructor(
|
||||
private val ciphersApi: CiphersApi,
|
||||
private val json: Json,
|
||||
) : CiphersService {
|
||||
override suspend fun createCipher(body: CipherJsonRequest): Result<SyncResponseJson.Cipher> =
|
||||
ciphersApi.createCipher(body = body)
|
||||
@@ -13,9 +18,20 @@ class CiphersServiceImpl constructor(
|
||||
override suspend fun updateCipher(
|
||||
cipherId: String,
|
||||
body: CipherJsonRequest,
|
||||
): Result<SyncResponseJson.Cipher> =
|
||||
ciphersApi.updateCipher(
|
||||
cipherId = cipherId,
|
||||
body = body,
|
||||
)
|
||||
): Result<UpdateCipherResponseJson> =
|
||||
ciphersApi
|
||||
.updateCipher(
|
||||
cipherId = cipherId,
|
||||
body = body,
|
||||
)
|
||||
.map { UpdateCipherResponseJson.Success(cipher = it) }
|
||||
.recoverCatching { throwable ->
|
||||
throwable
|
||||
.toBitwardenError()
|
||||
.parseErrorBodyOrNull<UpdateCipherResponseJson.Invalid>(
|
||||
code = 400,
|
||||
json = json,
|
||||
)
|
||||
?: throw throwable
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
@@ -387,10 +388,18 @@ class VaultRepositoryImpl(
|
||||
)
|
||||
}
|
||||
.fold(
|
||||
onFailure = { UpdateCipherResult.Error },
|
||||
onSuccess = {
|
||||
sync()
|
||||
UpdateCipherResult.Success
|
||||
onFailure = { UpdateCipherResult.Error(errorMessage = null) },
|
||||
onSuccess = { response ->
|
||||
when (response) {
|
||||
is UpdateCipherResponseJson.Invalid -> {
|
||||
UpdateCipherResult.Error(errorMessage = response.message)
|
||||
}
|
||||
|
||||
is UpdateCipherResponseJson.Success -> {
|
||||
sync()
|
||||
UpdateCipherResult.Success
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ sealed class UpdateCipherResult {
|
||||
data object Success : UpdateCipherResult()
|
||||
|
||||
/**
|
||||
* Generic error while updating cipher.
|
||||
* Generic error while updating cipher. The optional [errorMessage] may be displayed directly in
|
||||
* the UI when present.
|
||||
*/
|
||||
data object Error : UpdateCipherResult()
|
||||
data class Error(val errorMessage: String?) : UpdateCipherResult()
|
||||
}
|
||||
|
||||
@@ -690,10 +690,18 @@ class VaultAddEditViewModel @Inject constructor(
|
||||
action: VaultAddEditAction.Internal.UpdateCipherResultReceive,
|
||||
) {
|
||||
mutableStateFlow.update { it.copy(dialog = null) }
|
||||
when (action.updateCipherResult) {
|
||||
when (val result = action.updateCipherResult) {
|
||||
is UpdateCipherResult.Error -> {
|
||||
// TODO Display error dialog BIT-501
|
||||
sendEvent(VaultAddEditEvent.ShowToast(message = "Save Item Failure".asText()))
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialog = VaultAddEditState.DialogState.Error(
|
||||
message = result
|
||||
.errorMessage
|
||||
?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is UpdateCipherResult.Success -> {
|
||||
|
||||
Reference in New Issue
Block a user