mirror of
https://github.com/bitwarden/android.git
synced 2026-04-28 20:08:27 -05:00
[PM-20191] Migrate OrganizationService to network module (#5049)
This commit is contained in:
@@ -12,8 +12,8 @@ import com.bitwarden.network.service.IdentityService
|
||||
import com.bitwarden.network.service.IdentityServiceImpl
|
||||
import com.bitwarden.network.service.NewAuthRequestService
|
||||
import com.bitwarden.network.service.NewAuthRequestServiceImpl
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationServiceImpl
|
||||
import com.bitwarden.network.service.OrganizationService
|
||||
import com.bitwarden.network.service.OrganizationServiceImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.retrofit.Retrofits
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.x8bit.bitwarden.data.auth.datasource.network.service
|
||||
|
||||
import com.bitwarden.network.model.OrganizationAutoEnrollStatusResponseJson
|
||||
import com.bitwarden.network.model.OrganizationDomainSsoDetailsResponseJson
|
||||
import com.bitwarden.network.model.OrganizationKeysResponseJson
|
||||
import com.bitwarden.network.model.VerifiedOrganizationDomainSsoDetailsResponse
|
||||
|
||||
/**
|
||||
* Provides an API for querying organization endpoints.
|
||||
*/
|
||||
interface OrganizationService {
|
||||
/**
|
||||
* Enrolls a user with the given [userId] in this organizations reset password functionality.
|
||||
*/
|
||||
suspend fun organizationResetPasswordEnroll(
|
||||
organizationId: String,
|
||||
userId: String,
|
||||
passwordHash: String?,
|
||||
resetPasswordKey: String,
|
||||
): Result<Unit>
|
||||
|
||||
/**
|
||||
* Request claimed organization domain information for an [email] needed for SSO requests.
|
||||
*/
|
||||
suspend fun getOrganizationDomainSsoDetails(
|
||||
email: String,
|
||||
): Result<OrganizationDomainSsoDetailsResponseJson>
|
||||
|
||||
/**
|
||||
* Gets info regarding whether this organization enforces reset password auto enrollment.
|
||||
*/
|
||||
suspend fun getOrganizationAutoEnrollStatus(
|
||||
organizationIdentifier: String,
|
||||
): Result<OrganizationAutoEnrollStatusResponseJson>
|
||||
|
||||
/**
|
||||
* Gets the public and private keys for this organization.
|
||||
*/
|
||||
suspend fun getOrganizationKeys(
|
||||
organizationId: String,
|
||||
): Result<OrganizationKeysResponseJson>
|
||||
|
||||
/**
|
||||
* Request organization verified domain details for an [email] needed for SSO
|
||||
* requests.
|
||||
*/
|
||||
suspend fun getVerifiedOrganizationDomainSsoDetails(
|
||||
email: String,
|
||||
): Result<VerifiedOrganizationDomainSsoDetailsResponse>
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package com.x8bit.bitwarden.data.auth.datasource.network.service
|
||||
|
||||
import com.bitwarden.network.api.AuthenticatedOrganizationApi
|
||||
import com.bitwarden.network.api.UnauthenticatedOrganizationApi
|
||||
import com.bitwarden.network.model.OrganizationAutoEnrollStatusResponseJson
|
||||
import com.bitwarden.network.model.OrganizationDomainSsoDetailsRequestJson
|
||||
import com.bitwarden.network.model.OrganizationDomainSsoDetailsResponseJson
|
||||
import com.bitwarden.network.model.OrganizationKeysResponseJson
|
||||
import com.bitwarden.network.model.OrganizationResetPasswordEnrollRequestJson
|
||||
import com.bitwarden.network.model.VerifiedOrganizationDomainSsoDetailsRequest
|
||||
import com.bitwarden.network.model.VerifiedOrganizationDomainSsoDetailsResponse
|
||||
import com.bitwarden.network.util.toResult
|
||||
|
||||
/**
|
||||
* Default implementation of [OrganizationService].
|
||||
*/
|
||||
class OrganizationServiceImpl(
|
||||
private val authenticatedOrganizationApi: AuthenticatedOrganizationApi,
|
||||
private val unauthenticatedOrganizationApi: UnauthenticatedOrganizationApi,
|
||||
) : OrganizationService {
|
||||
override suspend fun organizationResetPasswordEnroll(
|
||||
organizationId: String,
|
||||
userId: String,
|
||||
passwordHash: String?,
|
||||
resetPasswordKey: String,
|
||||
): Result<Unit> = authenticatedOrganizationApi
|
||||
.organizationResetPasswordEnroll(
|
||||
organizationId = organizationId,
|
||||
userId = userId,
|
||||
body = OrganizationResetPasswordEnrollRequestJson(
|
||||
passwordHash = passwordHash,
|
||||
resetPasswordKey = resetPasswordKey,
|
||||
),
|
||||
)
|
||||
.toResult()
|
||||
|
||||
override suspend fun getOrganizationDomainSsoDetails(
|
||||
email: String,
|
||||
): Result<OrganizationDomainSsoDetailsResponseJson> = unauthenticatedOrganizationApi
|
||||
.getClaimedDomainOrganizationDetails(
|
||||
body = OrganizationDomainSsoDetailsRequestJson(
|
||||
email = email,
|
||||
),
|
||||
)
|
||||
.toResult()
|
||||
|
||||
override suspend fun getOrganizationAutoEnrollStatus(
|
||||
organizationIdentifier: String,
|
||||
): Result<OrganizationAutoEnrollStatusResponseJson> = authenticatedOrganizationApi
|
||||
.getOrganizationAutoEnrollResponse(
|
||||
organizationIdentifier = organizationIdentifier,
|
||||
)
|
||||
.toResult()
|
||||
|
||||
override suspend fun getOrganizationKeys(
|
||||
organizationId: String,
|
||||
): Result<OrganizationKeysResponseJson> = authenticatedOrganizationApi
|
||||
.getOrganizationKeys(
|
||||
organizationId = organizationId,
|
||||
)
|
||||
.toResult()
|
||||
|
||||
override suspend fun getVerifiedOrganizationDomainSsoDetails(
|
||||
email: String,
|
||||
): Result<VerifiedOrganizationDomainSsoDetailsResponse> = unauthenticatedOrganizationApi
|
||||
.getVerifiedOrganizationDomainsByEmail(
|
||||
body = VerifiedOrganizationDomainSsoDetailsRequest(
|
||||
email = email,
|
||||
),
|
||||
)
|
||||
.toResult()
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import com.bitwarden.network.service.AccountsService
|
||||
import com.bitwarden.network.service.DevicesService
|
||||
import com.bitwarden.network.service.HaveIBeenPwnedService
|
||||
import com.bitwarden.network.service.IdentityService
|
||||
import com.bitwarden.network.service.OrganizationService
|
||||
import com.bitwarden.network.util.isSslHandShakeError
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
|
||||
@@ -45,7 +46,6 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.model.ForcePasswordResetRea
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeviceDataModel
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toInt
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.util.toKdfTypeJson
|
||||
|
||||
@@ -6,8 +6,8 @@ import com.bitwarden.network.service.AccountsService
|
||||
import com.bitwarden.network.service.DevicesService
|
||||
import com.bitwarden.network.service.HaveIBeenPwnedService
|
||||
import com.bitwarden.network.service.IdentityService
|
||||
import com.bitwarden.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManager
|
||||
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManager
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
package com.x8bit.bitwarden.data.auth.datasource.network.service
|
||||
|
||||
import com.bitwarden.core.data.util.asSuccess
|
||||
import com.bitwarden.network.api.AuthenticatedOrganizationApi
|
||||
import com.bitwarden.network.api.UnauthenticatedOrganizationApi
|
||||
import com.bitwarden.network.base.BaseServiceTest
|
||||
import com.bitwarden.network.model.OrganizationAutoEnrollStatusResponseJson
|
||||
import com.bitwarden.network.model.OrganizationDomainSsoDetailsResponseJson
|
||||
import com.bitwarden.network.model.OrganizationKeysResponseJson
|
||||
import com.bitwarden.network.model.VerifiedOrganizationDomainSsoDetailsResponse
|
||||
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 OrganizationServiceTest : BaseServiceTest() {
|
||||
private val authenticatedOrganizationApi: AuthenticatedOrganizationApi = retrofit.create()
|
||||
private val unauthenticatedOrganizationApi: UnauthenticatedOrganizationApi = retrofit.create()
|
||||
|
||||
private val organizationService = OrganizationServiceImpl(
|
||||
authenticatedOrganizationApi = authenticatedOrganizationApi,
|
||||
unauthenticatedOrganizationApi = unauthenticatedOrganizationApi,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `organizationResetPasswordEnroll when response is success should return Unit as success`() =
|
||||
runTest {
|
||||
server.enqueue(MockResponse().setResponseCode(200))
|
||||
val result = organizationService.organizationResetPasswordEnroll(
|
||||
organizationId = "orgId",
|
||||
userId = "userId",
|
||||
passwordHash = "passwordHash",
|
||||
resetPasswordKey = "resetPasswordKey",
|
||||
)
|
||||
assertEquals(Unit.asSuccess(), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `organizationResetPasswordEnroll when response is an error should return an error`() =
|
||||
runTest {
|
||||
server.enqueue(MockResponse().setResponseCode(400))
|
||||
val result = organizationService.organizationResetPasswordEnroll(
|
||||
organizationId = "orgId",
|
||||
userId = "userId",
|
||||
passwordHash = "passwordHash",
|
||||
resetPasswordKey = "resetPasswordKey",
|
||||
)
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getOrganizationDomainSsoDetails when response is success should return PrevalidateSsoResponseJson`() =
|
||||
runTest {
|
||||
val email = "test@gmail.com"
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody(ORGANIZATION_DOMAIN_SSO_DETAILS_JSON),
|
||||
)
|
||||
val result = organizationService.getOrganizationDomainSsoDetails(email)
|
||||
assertEquals(ORGANIZATION_DOMAIN_SSO_BODY.asSuccess(), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrganizationDomainSsoDetails when response is an error should return an error`() =
|
||||
runTest {
|
||||
val email = "test@gmail.com"
|
||||
server.enqueue(MockResponse().setResponseCode(400))
|
||||
val result = organizationService.getOrganizationDomainSsoDetails(email)
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrganizationAutoEnrollStatus when response is success should return valid response`() =
|
||||
runTest {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody(ORGANIZATION_AUTO_ENROLL_STATUS_JSON),
|
||||
)
|
||||
val result = organizationService.getOrganizationAutoEnrollStatus("orgId")
|
||||
assertEquals(ORGANIZATION_AUTO_ENROLL_STATUS_RESPONSE.asSuccess(), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrganizationAutoEnrollStatus when response is an error should return an error`() =
|
||||
runTest {
|
||||
server.enqueue(MockResponse().setResponseCode(400))
|
||||
val result = organizationService.getOrganizationAutoEnrollStatus("orgId")
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrganizationKeys when response is success should return valid response`() = runTest {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody(ORGANIZATION_KEYS_JSON),
|
||||
)
|
||||
val result = organizationService.getOrganizationKeys("orgId")
|
||||
assertEquals(ORGANIZATION_KEYS_RESPONSE.asSuccess(), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getOrganizationKeys when response is an error should return an error`() = runTest {
|
||||
server.enqueue(MockResponse().setResponseCode(400))
|
||||
val result = organizationService.getOrganizationKeys("orgId")
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getVerifiedOrganizationDomainSsoDetails when response is success should return valid response`() =
|
||||
runTest {
|
||||
server.enqueue(
|
||||
MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setBody(ORGANIZATION_VERIFIED_DOMAIN_SSO_DETAILS_JSON),
|
||||
)
|
||||
val result =
|
||||
organizationService.getVerifiedOrganizationDomainSsoDetails("example@bitwarden.com")
|
||||
assertEquals(ORGANIZATION_VERIFIED_DOMAIN_SSO_DETAILS_RESPONSE.asSuccess(), result)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `getVerifiedOrganizationDomainSsoDetails when response is an error should return an error`() =
|
||||
runTest {
|
||||
server.enqueue(MockResponse().setResponseCode(400))
|
||||
val result =
|
||||
organizationService.getVerifiedOrganizationDomainSsoDetails("example@bitwarden.com")
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
}
|
||||
|
||||
private const val ORGANIZATION_AUTO_ENROLL_STATUS_JSON = """
|
||||
{
|
||||
"id": "orgId",
|
||||
"resetPasswordEnabled": true
|
||||
}
|
||||
"""
|
||||
|
||||
private val ORGANIZATION_AUTO_ENROLL_STATUS_RESPONSE = OrganizationAutoEnrollStatusResponseJson(
|
||||
organizationId = "orgId",
|
||||
isResetPasswordEnabled = true,
|
||||
)
|
||||
|
||||
private const val ORGANIZATION_DOMAIN_SSO_DETAILS_JSON = """
|
||||
{
|
||||
"ssoAvailable": true,
|
||||
"domainName": "bitwarden.com",
|
||||
"organizationIdentifier": "Test Org",
|
||||
"ssoRequired": false,
|
||||
"verifiedDate": "2024-09-13T00:00:00.000Z"
|
||||
}
|
||||
"""
|
||||
|
||||
private val ORGANIZATION_DOMAIN_SSO_BODY = OrganizationDomainSsoDetailsResponseJson(
|
||||
isSsoAvailable = true,
|
||||
organizationIdentifier = "Test Org",
|
||||
verifiedDate = ZonedDateTime.parse("2024-09-13T00:00:00.000Z"),
|
||||
)
|
||||
|
||||
private const val ORGANIZATION_KEYS_JSON = """
|
||||
{
|
||||
"privateKey": "privateKey",
|
||||
"publicKey": "publicKey"
|
||||
}
|
||||
"""
|
||||
|
||||
private val ORGANIZATION_KEYS_RESPONSE = OrganizationKeysResponseJson(
|
||||
privateKey = "privateKey",
|
||||
publicKey = "publicKey",
|
||||
)
|
||||
|
||||
private const val ORGANIZATION_VERIFIED_DOMAIN_SSO_DETAILS_JSON = """
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"organizationIdentifier": "Test Identifier",
|
||||
"organizationName": "Bitwarden",
|
||||
"domainName": "bitwarden.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
private val ORGANIZATION_VERIFIED_DOMAIN_SSO_DETAILS_RESPONSE =
|
||||
VerifiedOrganizationDomainSsoDetailsResponse(
|
||||
verifiedOrganizationDomainSsoDetails = listOf(
|
||||
VerifiedOrganizationDomainSsoDetailsResponse.VerifiedOrganizationDomainSsoDetail(
|
||||
organizationIdentifier = "Test Identifier",
|
||||
organizationName = "Bitwarden",
|
||||
domainName = "bitwarden.com",
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -56,6 +56,7 @@ import com.bitwarden.network.service.AccountsService
|
||||
import com.bitwarden.network.service.DevicesService
|
||||
import com.bitwarden.network.service.HaveIBeenPwnedService
|
||||
import com.bitwarden.network.service.IdentityService
|
||||
import com.bitwarden.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
@@ -64,7 +65,6 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.PendingAuthRequestJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.OrganizationService
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength.LEVEL_0
|
||||
import com.x8bit.bitwarden.data.auth.datasource.sdk.model.PasswordStrength.LEVEL_1
|
||||
|
||||
Reference in New Issue
Block a user