mirror of
https://github.com/bitwarden/android.git
synced 2024-11-24 10:25:57 +03:00
PM-11299: Update the userState to properly parse the hasManageResetPasswordPermission flag (#3820)
This commit is contained in:
parent
162da64567
commit
b7330392cc
16 changed files with 74 additions and 11 deletions
|
@ -7,12 +7,15 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.OrganizationType
|
|||
*
|
||||
* @property id The ID of the organization.
|
||||
* @property name The name of the organization (if applicable).
|
||||
* @property shouldManageResetPassword Indicates that this user has the permission to manage their
|
||||
* own password.
|
||||
* @property shouldUseKeyConnector Indicates that the organization uses a key connector.
|
||||
* @property role The user's role in the organization.
|
||||
*/
|
||||
data class Organization(
|
||||
val id: String,
|
||||
val name: String?,
|
||||
val shouldManageResetPassword: Boolean,
|
||||
val shouldUseKeyConnector: Boolean,
|
||||
val role: OrganizationType,
|
||||
)
|
||||
|
|
|
@ -16,6 +16,7 @@ fun SyncResponseJson.Profile.Organization.toOrganization(): Organization =
|
|||
name = this.name,
|
||||
shouldUseKeyConnector = this.shouldUseKeyConnector,
|
||||
role = this.type,
|
||||
shouldManageResetPassword = this.permissions.shouldManageResetPassword,
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.x8bit.bitwarden.data.auth.repository.model.UserOrganizations
|
|||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.VaultUnlockType
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.toEnvironmentUrlsOrDefault
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.OrganizationType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockData
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.statusFor
|
||||
|
@ -101,7 +102,7 @@ fun UserStateJson.toUserStateJsonWithPassword(): UserStateJson {
|
|||
/**
|
||||
* Converts the given [UserStateJson] to a [UserState] using the given [vaultState].
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LongMethod")
|
||||
fun UserStateJson.toUserState(
|
||||
vaultState: List<VaultUnlockData>,
|
||||
userAccountTokens: List<UserAccountTokens>,
|
||||
|
@ -125,8 +126,17 @@ fun UserStateJson.toUserState(
|
|||
val decryptionOptions = profile.userDecryptionOptions
|
||||
val trustedDeviceOptions = decryptionOptions?.trustedDeviceUserDecryptionOptions
|
||||
val keyConnectorOptions = decryptionOptions?.keyConnectorUserDecryptionOptions
|
||||
val organizations = userOrganizationsList
|
||||
.find { it.userId == userId }
|
||||
?.organizations
|
||||
.orEmpty()
|
||||
val hasManageResetPasswordPermission = organizations.any {
|
||||
it.role == OrganizationType.OWNER ||
|
||||
it.role == OrganizationType.ADMIN ||
|
||||
it.shouldManageResetPassword
|
||||
}
|
||||
val needsMasterPassword = decryptionOptions?.hasMasterPassword == false &&
|
||||
trustedDeviceOptions?.hasManageResetPasswordPermission != false &&
|
||||
hasManageResetPasswordPermission &&
|
||||
keyConnectorOptions == null
|
||||
val trustedDevice = trustedDeviceOptions?.let {
|
||||
UserState.TrustedDevice(
|
||||
|
@ -152,10 +162,7 @@ fun UserStateJson.toUserState(
|
|||
?.isLoggedIn == true,
|
||||
isVaultUnlocked = vaultUnlocked,
|
||||
needsPasswordReset = needsPasswordReset,
|
||||
organizations = userOrganizationsList
|
||||
.find { it.userId == userId }
|
||||
?.organizations
|
||||
.orEmpty(),
|
||||
organizations = organizations,
|
||||
isBiometricsEnabled = isBiometricsEnabledProvider(userId),
|
||||
vaultUnlockType = vaultUnlockTypeProvider(userId),
|
||||
needsMasterPassword = needsMasterPassword,
|
||||
|
|
|
@ -4277,6 +4277,9 @@ class AuthRepositoryTest {
|
|||
mockk<SyncResponseJson.Profile.Organization> {
|
||||
every { id } returns "orgId"
|
||||
every { name } returns "orgName"
|
||||
every { permissions } returns mockk {
|
||||
every { shouldManageResetPassword } returns false
|
||||
}
|
||||
every { shouldUseKeyConnector } returns true
|
||||
every { type } returns OrganizationType.USER
|
||||
every { keyConnectorUrl } returns null
|
||||
|
@ -4299,6 +4302,9 @@ class AuthRepositoryTest {
|
|||
mockk<SyncResponseJson.Profile.Organization> {
|
||||
every { id } returns "orgId"
|
||||
every { name } returns "orgName"
|
||||
every { permissions } returns mockk {
|
||||
every { shouldManageResetPassword } returns false
|
||||
}
|
||||
every { shouldUseKeyConnector } returns true
|
||||
every { type } returns OrganizationType.USER
|
||||
every { keyConnectorUrl } returns url
|
||||
|
@ -4332,6 +4338,9 @@ class AuthRepositoryTest {
|
|||
mockk<SyncResponseJson.Profile.Organization> {
|
||||
every { id } returns "orgId"
|
||||
every { name } returns "orgName"
|
||||
every { permissions } returns mockk {
|
||||
every { shouldManageResetPassword } returns false
|
||||
}
|
||||
every { shouldUseKeyConnector } returns true
|
||||
every { type } returns OrganizationType.USER
|
||||
every { keyConnectorUrl } returns url
|
||||
|
|
|
@ -189,6 +189,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-1",
|
||||
name = "mockName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -200,6 +201,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-2",
|
||||
name = "mockName-2",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -211,6 +213,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-3",
|
||||
name = "mockName-3",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -357,6 +360,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-1",
|
||||
name = "mockName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -387,6 +391,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-1",
|
||||
name = "mockName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -398,6 +403,7 @@ class AuthDiskSourceExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-2",
|
||||
name = "mockName-2",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -20,6 +20,7 @@ class SyncResponseJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-1",
|
||||
name = "mockName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -34,19 +35,22 @@ class SyncResponseJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "mockId-1",
|
||||
name = "mockName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = true,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "mockId-2",
|
||||
name = "mockName-2",
|
||||
shouldManageResetPassword = true,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.USER,
|
||||
),
|
||||
),
|
||||
listOf(
|
||||
createMockOrganization(number = 1).copy(shouldUseKeyConnector = true),
|
||||
createMockOrganization(number = 2).copy(type = OrganizationType.USER),
|
||||
createMockOrganization(number = 2, shouldManageResetPassword = true)
|
||||
.copy(type = OrganizationType.USER),
|
||||
)
|
||||
.toOrganizations(),
|
||||
)
|
||||
|
|
|
@ -342,6 +342,7 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -403,6 +404,7 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -444,6 +446,7 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -501,6 +504,7 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -543,13 +547,14 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
),
|
||||
isBiometricsEnabled = false,
|
||||
vaultUnlockType = VaultUnlockType.MASTER_PASSWORD,
|
||||
needsMasterPassword = false,
|
||||
needsMasterPassword = true,
|
||||
trustedDevice = UserState.TrustedDevice(
|
||||
isDeviceTrusted = true,
|
||||
hasAdminApproval = false,
|
||||
|
@ -608,6 +613,7 @@ class UserStateJsonExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -34,6 +34,7 @@ fun createMockOrganization(
|
|||
number: Int,
|
||||
isEnabled: Boolean = false,
|
||||
shouldUsePolicies: Boolean = false,
|
||||
shouldManageResetPassword: Boolean = false,
|
||||
): SyncResponseJson.Profile.Organization =
|
||||
SyncResponseJson.Profile.Organization(
|
||||
shouldUsePolicies = shouldUsePolicies,
|
||||
|
@ -45,7 +46,7 @@ fun createMockOrganization(
|
|||
providerType = 1,
|
||||
maxCollections = 1,
|
||||
isSelfHost = false,
|
||||
permissions = createMockPermissions(),
|
||||
permissions = createMockPermissions(shouldManageResetPassword = shouldManageResetPassword),
|
||||
providerId = "mockProviderId-$number",
|
||||
id = "mockId-$number",
|
||||
shouldUseGroups = false,
|
||||
|
@ -78,10 +79,12 @@ fun createMockOrganizationKeys(number: Int): Map<String, String> =
|
|||
/**
|
||||
* Create a mock [SyncResponseJson.Profile.Permissions].
|
||||
*/
|
||||
fun createMockPermissions(): SyncResponseJson.Profile.Permissions =
|
||||
fun createMockPermissions(
|
||||
shouldManageResetPassword: Boolean = false,
|
||||
): SyncResponseJson.Profile.Permissions =
|
||||
SyncResponseJson.Profile.Permissions(
|
||||
shouldManageGroups = false,
|
||||
shouldManageResetPassword = false,
|
||||
shouldManageResetPassword = shouldManageResetPassword,
|
||||
shouldAccessReports = false,
|
||||
shouldManagePolicies = false,
|
||||
shouldDeleteAnyCollection = false,
|
||||
|
|
|
@ -156,6 +156,7 @@ private val DEFAULT_ACCOUNT = UserState.Account(
|
|||
Organization(
|
||||
id = "orgId",
|
||||
name = ORGANIZATION_NAME,
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = true,
|
||||
role = OrganizationType.USER,
|
||||
),
|
||||
|
|
|
@ -341,6 +341,7 @@ class RootNavViewModelTest : BaseViewModelTest() {
|
|||
Organization(
|
||||
id = "orgId",
|
||||
name = "orgName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = true,
|
||||
role = OrganizationType.USER,
|
||||
),
|
||||
|
|
|
@ -3879,6 +3879,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -435,6 +435,7 @@ class CipherViewExtensionsTest {
|
|||
Organization(
|
||||
id = "mockOrganizationId-1",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -491,18 +491,21 @@ private val DEFAULT_USER_STATE = UserState(
|
|||
Organization(
|
||||
id = "mockOrganizationId-1",
|
||||
name = "mockOrganizationName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "mockOrganizationId-2",
|
||||
name = "mockOrganizationName-2",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "mockOrganizationId-3",
|
||||
name = "mockOrganizationName-3",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -103,18 +103,21 @@ private fun createMockUserState(hasOrganizations: Boolean = true): UserState =
|
|||
Organization(
|
||||
id = "mockOrganizationId-1",
|
||||
name = "mockOrganizationName-1",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "mockOrganizationId-2",
|
||||
name = "mockOrganizationName-2",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "mockOrganizationId-3",
|
||||
name = "mockOrganizationName-3",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -188,6 +188,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
Organization(
|
||||
id = "organiationId",
|
||||
name = "Test Organization",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -271,6 +272,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "Test Organization",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -478,6 +480,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
Organization(
|
||||
id = "testOrganizationId",
|
||||
name = "Test Organization",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
|
@ -77,6 +77,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -101,6 +102,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -129,6 +131,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -157,6 +160,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -200,6 +204,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -241,6 +246,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -286,6 +292,7 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId",
|
||||
name = "organizationName",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -360,11 +367,13 @@ class UserStateExtensionsTest {
|
|||
id = "organizationId-B",
|
||||
name = "Organization B",
|
||||
shouldUseKeyConnector = false,
|
||||
shouldManageResetPassword = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "organizationId-A",
|
||||
name = "Organization A",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
@ -413,12 +422,14 @@ class UserStateExtensionsTest {
|
|||
Organization(
|
||||
id = "organizationId-B",
|
||||
name = "Organization B",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
Organization(
|
||||
id = "organizationId-A",
|
||||
name = "Organization A",
|
||||
shouldManageResetPassword = false,
|
||||
shouldUseKeyConnector = false,
|
||||
role = OrganizationType.ADMIN,
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue