[PM-13396] Add support for legacy error response model in getToken (#4112)

This commit is contained in:
Patrick Honkonen 2024-10-21 09:23:49 -04:00 committed by GitHub
parent 4fc01c77d1
commit be0ebb9b3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 4 deletions

View file

@ -96,9 +96,17 @@ sealed class GetTokenResponseJson {
@Serializable @Serializable
data class Invalid( data class Invalid(
@SerialName("ErrorModel") @SerialName("ErrorModel")
val errorModel: ErrorModel, val errorModel: ErrorModel?,
@SerialName("errorModel")
val legacyErrorModel: LegacyErrorModel?,
) : GetTokenResponseJson() { ) : GetTokenResponseJson() {
/**
* The error message returned from the server, or null.
*/
val errorMessage: String?
get() = errorModel?.errorMessage ?: legacyErrorModel?.errorMessage
/** /**
* The error body of an invalid request containing a message. * The error body of an invalid request containing a message.
*/ */
@ -107,6 +115,18 @@ sealed class GetTokenResponseJson {
@SerialName("Message") @SerialName("Message")
val errorMessage: String, val errorMessage: String,
) )
/**
* The legacy error body of an invalid request containing a message.
*
* This model is used to support older versions of the error response model that used
* lower-case keys.
*/
@Serializable
data class LegacyErrorModel(
@SerialName("message")
val errorMessage: String,
)
} }
/** /**

View file

@ -45,7 +45,6 @@ import com.x8bit.bitwarden.data.auth.repository.model.AuthState
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.auth.repository.model.KnownDeviceResult import com.x8bit.bitwarden.data.auth.repository.model.KnownDeviceResult
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.model.NewSsoUserResult import com.x8bit.bitwarden.data.auth.repository.model.NewSsoUserResult
@ -99,6 +98,7 @@ import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager
import com.x8bit.bitwarden.data.platform.manager.PushManager import com.x8bit.bitwarden.data.platform.manager.PushManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
import com.x8bit.bitwarden.data.platform.manager.util.getActivePolicies import com.x8bit.bitwarden.data.platform.manager.util.getActivePolicies
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
@ -1503,7 +1503,7 @@ class AuthRepositoryImpl(
) )
is GetTokenResponseJson.Invalid -> LoginResult.Error( is GetTokenResponseJson.Invalid -> LoginResult.Error(
errorMessage = loginResponse.errorModel.errorMessage, errorMessage = loginResponse.errorMessage,
) )
} }
}, },

View file

@ -273,6 +273,22 @@ class IdentityServiceTest : BaseServiceTest() {
assertEquals(INVALID_LOGIN.asSuccess(), result) assertEquals(INVALID_LOGIN.asSuccess(), result)
} }
@Test
fun `getToken when response is a 400 with a legacy error body should return Invalid`() =
runTest {
server.enqueue(MockResponse().setResponseCode(400).setBody(LEGACY_INVALID_LOGIN_JSON))
val result = identityService.getToken(
email = EMAIL,
authModel = IdentityTokenAuthModel.MasterPassword(
username = EMAIL,
password = PASSWORD_HASH,
),
captchaToken = null,
uniqueAppId = UNIQUE_APP_ID,
)
assertEquals(LEGACY_INVALID_LOGIN.asSuccess(), result)
}
@Test @Test
fun `prevalidateSso when response is success should return PrevalidateSsoResponseJson`() = fun `prevalidateSso when response is success should return PrevalidateSsoResponseJson`() =
runTest { runTest {
@ -613,6 +629,14 @@ private const val INVALID_LOGIN_JSON = """
} }
""" """
private const val LEGACY_INVALID_LOGIN_JSON = """
{
"errorModel": {
"message": "Legacy-123"
}
}
"""
private const val TOO_MANY_REQUEST_ERROR_JSON = """ private const val TOO_MANY_REQUEST_ERROR_JSON = """
{ {
"Object": "error", "Object": "error",
@ -645,6 +669,14 @@ private val INVALID_LOGIN = GetTokenResponseJson.Invalid(
errorModel = GetTokenResponseJson.Invalid.ErrorModel( errorModel = GetTokenResponseJson.Invalid.ErrorModel(
errorMessage = "123", errorMessage = "123",
), ),
legacyErrorModel = null,
)
private val LEGACY_INVALID_LOGIN = GetTokenResponseJson.Invalid(
errorModel = null,
legacyErrorModel = GetTokenResponseJson.Invalid.LegacyErrorModel(
errorMessage = "Legacy-123",
),
) )
private val SEND_VERIFICATION_EMAIL_REQUEST = SendVerificationEmailRequestJson( private val SEND_VERIFICATION_EMAIL_REQUEST = SendVerificationEmailRequestJson(

View file

@ -65,7 +65,6 @@ import com.x8bit.bitwarden.data.auth.repository.model.AuthState
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult import com.x8bit.bitwarden.data.auth.repository.model.DeleteAccountResult
import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult import com.x8bit.bitwarden.data.auth.repository.model.EmailTokenResult
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.auth.repository.model.KnownDeviceResult import com.x8bit.bitwarden.data.auth.repository.model.KnownDeviceResult
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.model.NewSsoUserResult import com.x8bit.bitwarden.data.auth.repository.model.NewSsoUserResult
@ -106,6 +105,7 @@ import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager
import com.x8bit.bitwarden.data.platform.manager.PushManager import com.x8bit.bitwarden.data.platform.manager.PushManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
import com.x8bit.bitwarden.data.platform.manager.model.NotificationLogoutData import com.x8bit.bitwarden.data.platform.manager.model.NotificationLogoutData
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
@ -1522,6 +1522,7 @@ class AuthRepositoryTest {
errorModel = GetTokenResponseJson.Invalid.ErrorModel( errorModel = GetTokenResponseJson.Invalid.ErrorModel(
errorMessage = "mock_error_message", errorMessage = "mock_error_message",
), ),
legacyErrorModel = null,
) )
.asSuccess() .asSuccess()
@ -2314,6 +2315,7 @@ class AuthRepositoryTest {
errorModel = GetTokenResponseJson.Invalid.ErrorModel( errorModel = GetTokenResponseJson.Invalid.ErrorModel(
errorMessage = "mock_error_message", errorMessage = "mock_error_message",
), ),
legacyErrorModel = null,
) )
.asSuccess() .asSuccess()
@ -2782,6 +2784,7 @@ class AuthRepositoryTest {
errorModel = GetTokenResponseJson.Invalid.ErrorModel( errorModel = GetTokenResponseJson.Invalid.ErrorModel(
errorMessage = "mock_error_message", errorMessage = "mock_error_message",
), ),
legacyErrorModel = null,
) )
.asSuccess() .asSuccess()