[PM-20186] Migrate AuthRequestsService to the network module (#5039)

This commit is contained in:
Patrick Honkonen
2025-04-14 14:28:55 -04:00
committed by GitHub
parent 87ef0e2961
commit f087b6aac7
7 changed files with 8 additions and 8 deletions

View File

@@ -0,0 +1,31 @@
package com.bitwarden.network.service
import com.bitwarden.network.model.AuthRequestsResponseJson
/**
* Provides an API for interacting with login approval / authentication requests.
*/
interface AuthRequestsService {
/**
* Gets the list of auth requests for the current user.
*/
suspend fun getAuthRequests(): Result<AuthRequestsResponseJson>
/**
* Retrieves an existing auth request to see if a device has approved it.
*/
suspend fun getAuthRequest(
requestId: String,
): Result<AuthRequestsResponseJson.AuthRequest>
/**
* Updates an approval request.
*/
suspend fun updateAuthRequest(
requestId: String,
key: String,
masterPasswordHash: String?,
deviceId: String,
isApproved: Boolean,
): Result<AuthRequestsResponseJson.AuthRequest>
}

View File

@@ -0,0 +1,41 @@
package com.bitwarden.network.service
import com.bitwarden.network.api.AuthenticatedAuthRequestsApi
import com.bitwarden.network.model.AuthRequestUpdateRequestJson
import com.bitwarden.network.model.AuthRequestsResponseJson
import com.bitwarden.network.util.toResult
class AuthRequestsServiceImpl(
private val authenticatedAuthRequestsApi: AuthenticatedAuthRequestsApi,
) : AuthRequestsService {
override suspend fun getAuthRequests(): Result<AuthRequestsResponseJson> =
authenticatedAuthRequestsApi
.getAuthRequests()
.toResult()
override suspend fun getAuthRequest(
requestId: String,
): Result<AuthRequestsResponseJson.AuthRequest> =
authenticatedAuthRequestsApi
.getAuthRequest(requestId = requestId)
.toResult()
override suspend fun updateAuthRequest(
requestId: String,
key: String,
masterPasswordHash: String?,
deviceId: String,
isApproved: Boolean,
): Result<AuthRequestsResponseJson.AuthRequest> =
authenticatedAuthRequestsApi
.updateAuthRequest(
userId = requestId,
body = AuthRequestUpdateRequestJson(
key = key,
masterPasswordHash = masterPasswordHash,
deviceId = deviceId,
isApproved = isApproved,
),
)
.toResult()
}

View File

@@ -0,0 +1,123 @@
package com.bitwarden.network.service
import com.bitwarden.core.data.util.asSuccess
import com.bitwarden.network.api.AuthenticatedAuthRequestsApi
import com.bitwarden.network.base.BaseServiceTest
import com.bitwarden.network.model.AuthRequestsResponseJson
import kotlinx.coroutines.test.runTest
import okhttp3.mockwebserver.MockResponse
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import retrofit2.create
import java.time.ZonedDateTime
class AuthRequestsServiceTest : BaseServiceTest() {
private val authRequestsApi: AuthenticatedAuthRequestsApi = retrofit.create()
private val service = AuthRequestsServiceImpl(
authenticatedAuthRequestsApi = authRequestsApi,
)
@Test
fun `getAuthRequests when request response is Failure should return Failure`() = runTest {
val response = MockResponse().setResponseCode(400)
server.enqueue(response)
val actual = service.getAuthRequests()
assertTrue(actual.isFailure)
}
@Test
fun `getAuthRequests when request response is Success should return Success`() = runTest {
val json = """
{
"data": [
{
"id": "1",
"publicKey": "2",
"requestDeviceType": "Android",
"requestIpAddress": "1.0.0.1",
"creationDate": "2024-09-13T01:00:00.00Z",
"requestApproved": true,
"origin": "www.bitwarden.com"
}
]
}
"""
val response = MockResponse().setBody(json).setResponseCode(200)
server.enqueue(response)
val actual = service.getAuthRequests()
assertTrue(actual.isSuccess)
}
@Test
fun `updateAuthRequest when request response is Failure should return Failure`() = runTest {
val response = MockResponse().setResponseCode(400)
server.enqueue(response)
val actual = service.updateAuthRequest(
requestId = "userId",
deviceId = "deviceId",
key = "secureKey",
masterPasswordHash = null,
isApproved = true,
)
assertTrue(actual.isFailure)
}
@Test
fun `updateAuthRequest when request response is Success should return Success`() = runTest {
val response = MockResponse().setBody(AUTH_REQUEST_RESPONSE_JSON).setResponseCode(200)
server.enqueue(response)
val actual = service.updateAuthRequest(
requestId = "userId",
deviceId = "deviceId",
key = "secureKey",
masterPasswordHash = "verySecureHash",
isApproved = true,
)
assertEquals(AUTH_REQUEST_RESPONSE.asSuccess(), actual)
}
@Test
fun `getAuthRequest when request response is Failure should return Failure`() = runTest {
val response = MockResponse().setResponseCode(400)
server.enqueue(response)
val actual = service.getAuthRequest(requestId = "1")
assertTrue(actual.isFailure)
}
@Test
fun `getAuthRequest when request response is Success should return Success`() = runTest {
val response = MockResponse().setBody(AUTH_REQUEST_RESPONSE_JSON).setResponseCode(200)
server.enqueue(response)
val actual = service.getAuthRequest(requestId = "1")
assertEquals(AUTH_REQUEST_RESPONSE.asSuccess(), actual)
}
}
private const val AUTH_REQUEST_RESPONSE_JSON = """
{
"id": "1",
"publicKey": "2",
"requestDeviceType": "Android",
"requestIpAddress": "1.0.0.1",
"key": "key",
"masterPasswordHash": "verySecureHash",
"creationDate": "2024-09-13T01:00:00.00Z",
"requestApproved": true,
"origin": "www.bitwarden.com"
}
"""
private val AUTH_REQUEST_RESPONSE = AuthRequestsResponseJson.AuthRequest(
id = "1",
publicKey = "2",
platform = "Android",
ipAddress = "1.0.0.1",
key = "key",
masterPasswordHash = "verySecureHash",
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
responseDate = null,
requestApproved = true,
originUrl = "www.bitwarden.com",
)