From 45fd9d9f1bc4ff5103323746f3cedf2f7287d3cc Mon Sep 17 00:00:00 2001 From: Brian Yencho Date: Sat, 6 Jan 2024 16:24:29 -0600 Subject: [PATCH] Fix Organizations model and persistence format (#512) --- .../datasource/disk/AuthDiskSourceImpl.kt | 13 +++- .../network/model/SyncResponseJson.kt | 63 ------------------- .../datasource/disk/AuthDiskSourceTest.kt | 6 +- .../network/model/SyncResponseProfileUtil.kt | 15 ----- .../network/service/SyncServiceTest.kt | 31 --------- 5 files changed, 15 insertions(+), 113 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceImpl.kt index 54e006b450..28632b028a 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceImpl.kt @@ -99,7 +99,12 @@ class AuthDiskSourceImpl( userId: String, ): List? = getString(key = "${ORGANIZATIONS_KEY}_$userId") - ?.let { json.decodeFromString(it) } + ?.let { + // The organizations are stored as a map + val organizationMap: Map = + json.decodeFromString(it) + organizationMap.values.toList() + } override fun getOrganizationsFlow( userId: String, @@ -113,7 +118,11 @@ class AuthDiskSourceImpl( ) { putString( key = "${ORGANIZATIONS_KEY}_$userId", - value = organizations?.let { json.encodeToString(it) }, + value = organizations?.let { nonNullOrganizations -> + // The organizations are stored as a map + val organizationsMap = nonNullOrganizations.associateBy { it.id } + json.encodeToString(organizationsMap) + }, ) getMutableOrganizationsFlow(userId = userId).tryEmit(organizations) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt index 557e04f233..2152fe38b3 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt @@ -205,14 +205,9 @@ data class SyncResponseJson( * @property seats The number of seats in the organization (nullable). * @property isEnabled If the organization is enabled. * @property providerType They type of provider for the organization (nullable). - * @property isResetPasswordEnrolled If reset password has been - * enrolled for the organization. - * @property shouldUseSecretsManager If the organization should use the secrets manager. * @property maxCollections The max collections of the organization (nullable). * @property isSelfHost If the organization is self hosted. - * @property shouldUseKeyConnector If the organization should use a key connector. * @property permissions The permissions of the organization. - * @property hasPublicAndPrivateKeys If the organization has public and private keys. * @property providerId The provider ID of the organization (nullable). * @property id The ID of the organization. * @property shouldUseGroups If the organization should use groups. @@ -222,29 +217,17 @@ data class SyncResponseJson( * @property shouldUsersGetPremium If users of the organization get premium. * @property maxStorageGb The max storage in Gb of the organization (nullable). * @property identifier The identifier of the organization (nullable). - * @property shouldUseSso If the organization should use single sign on. - * @property shouldUseCustomPermissions If the organization should use custom permissions. - * @property isFamilySponsorshipAvailable If the organization has - * family sponsorship available. - * @property shouldUseResetPassword If the organization should use reset password. - * @property planProductType The plan product type of the organization. - * @property accessSecretsManager If the organization can access secrets manager. * @property use2fa If the organization uses 2FA. * @property familySponsorshipToDelete If the organization has a * family sponsorship to delete (nullable). * @property userId The user id (nullable). - * @property shouldUseActivateAutofillPolicy If the organization should - * use auto fill policy. * @property shouldUseEvents If the organization should use events. * @property familySponsorshipFriendlyName If the family sponsorship is a friendly name. - * @property isKeyConnectorEnabled If the key connector is enabled. * @property shouldUseTotp If he organization should use TOTP. * @property familySponsorshipLastSyncDate The last date the family sponsorship * was synced (nullable). - * @property shouldUseScim If the organization should use scim. * @property name The name of the organization (nullable). * @property shouldUseApi If the organization should use API. - * @property isSsoBound If the organization is sso bound. * @property familySponsorshipValidUntil The family sponsorship valid until * of the organization (nullable). * @property status The status of the organization. @@ -269,27 +252,15 @@ data class SyncResponseJson( @SerialName("providerType") val providerType: Int?, - @SerialName("resetPasswordEnrolled") - val isResetPasswordEnrolled: Boolean, - - @SerialName("useSecretsManager") - val shouldUseSecretsManager: Boolean, - @SerialName("maxCollections") val maxCollections: Int?, @SerialName("selfHost") val isSelfHost: Boolean, - @SerialName("useKeyConnector") - val shouldUseKeyConnector: Boolean, - @SerialName("permissions") val permissions: Permissions, - @SerialName("hasPublicAndPrivateKeys") - val hasPublicAndPrivateKeys: Boolean, - @SerialName("providerId") val providerId: String?, @@ -317,24 +288,6 @@ data class SyncResponseJson( @SerialName("identifier") val identifier: String?, - @SerialName("useSso") - val shouldUseSso: Boolean, - - @SerialName("useCustomPermissions") - val shouldUseCustomPermissions: Boolean, - - @SerialName("familySponsorshipAvailable") - val isFamilySponsorshipAvailable: Boolean, - - @SerialName("useResetPassword") - val shouldUseResetPassword: Boolean, - - @SerialName("planProductType") - val planProductType: Int, - - @SerialName("accessSecretsManager") - val accessSecretsManager: Boolean, - @SerialName("use2fa") val use2fa: Boolean, @@ -344,18 +297,12 @@ data class SyncResponseJson( @SerialName("userId") val userId: String?, - @SerialName("useActivateAutofillPolicy") - val shouldUseActivateAutofillPolicy: Boolean, - @SerialName("useEvents") val shouldUseEvents: Boolean, @SerialName("familySponsorshipFriendlyName") val familySponsorshipFriendlyName: String?, - @SerialName("keyConnectorEnabled") - val isKeyConnectorEnabled: Boolean, - @SerialName("useTotp") val shouldUseTotp: Boolean, @@ -363,18 +310,12 @@ data class SyncResponseJson( @Contextual val familySponsorshipLastSyncDate: ZonedDateTime?, - @SerialName("useScim") - val shouldUseScim: Boolean, - @SerialName("name") val name: String?, @SerialName("useApi") val shouldUseApi: Boolean, - @SerialName("ssoBound") - val isSsoBound: Boolean, - @SerialName("familySponsorshipValidUntil") @Contextual val familySponsorshipValidUntil: ZonedDateTime?, @@ -437,7 +378,6 @@ data class SyncResponseJson( * @property shouldManageSso If sso should be managed. * @property shouldDeleteAssignedCollections If assigned collection should be deleted. * @property shouldManageUsers If users should be managed. - * @property shouldManageScim If scim should be managed. * @property shouldAccessImportExport If import/export should be accessed. * @property shouldEditAnyCollection If any collection should be edited. * @property shouldAccessEventLogs If event logs should be accessed. @@ -470,9 +410,6 @@ data class SyncResponseJson( @SerialName("manageUsers") val shouldManageUsers: Boolean, - @SerialName("manageScim") - val shouldManageScim: Boolean, - @SerialName("accessImportExport") val shouldAccessImportExport: Boolean, diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt index cc2161351a..39a557f798 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt @@ -257,11 +257,12 @@ class AuthDiskSourceTest { createMockOrganization(0), createMockOrganization(1), ) + val mockOrganizationsMap = mockOrganizations.associateBy { it.id } fakeSharedPreferences .edit() .putString( "${organizationsBaseKey}_$mockUserId", - json.encodeToString(mockOrganizations), + json.encodeToString(mockOrganizationsMap), ) .apply() val actual = authDiskSource.getOrganizations(userId = mockUserId) @@ -300,6 +301,7 @@ class AuthDiskSourceTest { createMockOrganization(0), createMockOrganization(1), ) + val mockOrganizationsMap = mockOrganizations.associateBy { it.id } authDiskSource.storeOrganizations( userId = mockUserId, organizations = mockOrganizations, @@ -309,7 +311,7 @@ class AuthDiskSourceTest { null, ) assertEquals( - json.encodeToJsonElement(mockOrganizations), + json.encodeToJsonElement(mockOrganizationsMap), json.parseToJsonElement(requireNotNull(actual)), ) } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseProfileUtil.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseProfileUtil.kt index 82c014f094..5d4f25000b 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseProfileUtil.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseProfileUtil.kt @@ -38,13 +38,9 @@ fun createMockOrganization(number: Int): SyncResponseJson.Profile.Organization = seats = 1, isEnabled = false, providerType = 1, - isResetPasswordEnrolled = false, - shouldUseSecretsManager = false, maxCollections = 1, isSelfHost = false, - shouldUseKeyConnector = false, permissions = createMockPermissions(), - hasPublicAndPrivateKeys = false, providerId = "mockProviderId-$number", id = "mockId-$number", shouldUseGroups = false, @@ -54,25 +50,15 @@ fun createMockOrganization(number: Int): SyncResponseJson.Profile.Organization = shouldUsersGetPremium = false, maxStorageGb = 1, identifier = "mockIdentifier-$number", - shouldUseSso = false, - shouldUseCustomPermissions = false, - isFamilySponsorshipAvailable = false, - shouldUseResetPassword = false, - planProductType = 1, - accessSecretsManager = false, use2fa = false, familySponsorshipToDelete = false, userId = "mockUserId-$number", - shouldUseActivateAutofillPolicy = false, shouldUseEvents = false, familySponsorshipFriendlyName = "mockFamilySponsorshipFriendlyName-$number", - isKeyConnectorEnabled = false, shouldUseTotp = false, familySponsorshipLastSyncDate = ZonedDateTime.parse("2023-10-27T12:00:00Z"), - shouldUseScim = false, name = "mockName-$number", shouldUseApi = false, - isSsoBound = false, familySponsorshipValidUntil = ZonedDateTime.parse("2023-10-27T12:00:00Z"), status = 1, ) @@ -97,7 +83,6 @@ fun createMockPermissions(): SyncResponseJson.Profile.Permissions = shouldManageSso = false, shouldDeleteAssignedCollections = false, shouldManageUsers = false, - shouldManageScim = false, shouldAccessImportExport = false, shouldEditAnyCollection = false, shouldAccessEventLogs = false, diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/service/SyncServiceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/service/SyncServiceTest.kt index 910be6ddf6..00f1ba9114 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/service/SyncServiceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/service/SyncServiceTest.kt @@ -50,11 +50,8 @@ private const val SYNC_SUCCESS_JSON = """ "seats": 1, "enabled": false, "providerType": 1, - "resetPasswordEnrolled": false, - "useSecretsManager": false, "maxCollections": 1, "selfHost": false, - "useKeyConnector": false, "permissions": { "manageGroups": false, "manageResetPassword": false, @@ -64,14 +61,12 @@ private const val SYNC_SUCCESS_JSON = """ "manageSso": false, "deleteAssignedCollections": false, "manageUsers": false, - "manageScim": false, "accessImportExport": false, "editAnyCollection": false, "accessEventLogs": false, "createNewCollections": false, "editAssignedCollections": false }, - "hasPublicAndPrivateKeys": false, "providerId": "mockProviderId-1", "id": "mockId-1", "useGroups": false, @@ -81,25 +76,15 @@ private const val SYNC_SUCCESS_JSON = """ "usersGetPremium": false, "maxStorageGb": 1, "identifier": "mockIdentifier-1", - "useSso": false, - "useCustomPermissions": false, - "familySponsorshipAvailable": false, - "useResetPassword": false, - "planProductType": 1, - "accessSecretsManager": false, "use2fa": false, "familySponsorshipToDelete": false, "userId": "mockUserId-1", - "useActivateAutofillPolicy": false, "useEvents": false, "familySponsorshipFriendlyName": "mockFamilySponsorshipFriendlyName-1", - "keyConnectorEnabled": false, "useTotp": false, "familySponsorshipLastSyncDate": "2023-10-27T12:00:00.00Z", - "useScim": false, "name": "mockName-1", "useApi": false, - "ssoBound": false, "familySponsorshipValidUntil": "2023-10-27T12:00:00.00Z", "status": 1 } @@ -116,7 +101,6 @@ private const val SYNC_SUCCESS_JSON = """ "manageSso": false, "deleteAssignedCollections": false, "manageUsers": false, - "manageScim": false, "accessImportExport": false, "editAnyCollection": false, "accessEventLogs": false, @@ -140,11 +124,8 @@ private const val SYNC_SUCCESS_JSON = """ "seats": 1, "enabled": false, "providerType": 1, - "resetPasswordEnrolled": false, - "useSecretsManager": false, "maxCollections": 1, "selfHost": false, - "useKeyConnector": false, "permissions": { "manageGroups": false, "manageResetPassword": false, @@ -154,14 +135,12 @@ private const val SYNC_SUCCESS_JSON = """ "manageSso": false, "deleteAssignedCollections": false, "manageUsers": false, - "manageScim": false, "accessImportExport": false, "editAnyCollection": false, "accessEventLogs": false, "createNewCollections": false, "editAssignedCollections": false }, - "hasPublicAndPrivateKeys": false, "providerId": "mockProviderId-1", "id": "mockId-1", "useGroups": false, @@ -171,25 +150,15 @@ private const val SYNC_SUCCESS_JSON = """ "usersGetPremium": false, "maxStorageGb": 1, "identifier": "mockIdentifier-1", - "useSso": false, - "useCustomPermissions": false, - "familySponsorshipAvailable": false, - "useResetPassword": false, - "planProductType": 1, - "accessSecretsManager": false, "use2fa": false, "familySponsorshipToDelete": false, "userId": "mockUserId-1", - "useActivateAutofillPolicy": false, "useEvents": false, "familySponsorshipFriendlyName": "mockFamilySponsorshipFriendlyName-1", - "keyConnectorEnabled": false, "useTotp": false, "familySponsorshipLastSyncDate": "2023-10-27T12:00:00.00Z", - "useScim": false, "name": "mockName-1", "useApi": false, - "ssoBound": false, "familySponsorshipValidUntil": "2023-10-27T12:00:00.00Z", "status": 1 }