Skip to content

Commit 5eb56ca

Browse files
authored
[PM-27119] Prevent import card data when ITEM_RESTRICT_TYPES policy is active (#6123)
1 parent b2d94fa commit 5eb56ca

File tree

8 files changed

+299
-25
lines changed

8 files changed

+299
-25
lines changed

app/src/main/kotlin/com/x8bit/bitwarden/data/platform/manager/util/PolicyManagerExtensions.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,9 @@ inline fun <reified T : PolicyInformation> getPolicyTypeJson(): PolicyTypeJson =
4343
)
4444
}
4545
}
46+
/**
47+
* Helper method for verifying if user has enabled the restrict item policy.
48+
*/
49+
fun PolicyManager.hasRestrictItemTypes(): Boolean =
50+
getActivePolicies(type = PolicyTypeJson.RESTRICT_ITEM_TYPES)
51+
.any { it.isEnabled }

app/src/main/kotlin/com/x8bit/bitwarden/data/vault/manager/CredentialExchangeImportManagerImpl.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import com.bitwarden.network.model.ImportCiphersJsonRequest
1212
import com.bitwarden.network.model.ImportCiphersResponseJson
1313
import com.bitwarden.network.service.CiphersService
1414
import com.bitwarden.network.util.base64UrlDecodeOrNull
15+
import com.bitwarden.vault.CipherType
16+
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
17+
import com.x8bit.bitwarden.data.platform.manager.util.hasRestrictItemTypes
1518
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
1619
import com.x8bit.bitwarden.data.vault.manager.model.ImportCxfPayloadResult
1720
import com.x8bit.bitwarden.data.vault.manager.model.SyncVaultDataResult
@@ -34,6 +37,7 @@ class CredentialExchangeImportManagerImpl(
3437
private val vaultSdkSource: VaultSdkSource,
3538
private val ciphersService: CiphersService,
3639
private val vaultSyncManager: VaultSyncManager,
40+
private val policyManager: PolicyManager,
3741
private val json: Json,
3842
) : CredentialExchangeImportManager {
3943

@@ -83,7 +87,9 @@ class CredentialExchangeImportManagerImpl(
8387
}
8488

8589
val accountsJson = try {
86-
json.encodeToString(exportResponse.accounts.firstOrNull())
90+
json.encodeToString(
91+
value = exportResponse.accounts.firstOrNull(),
92+
)
8793
} catch (_: SerializationException) {
8894
return ImportCxfPayloadResult.Error(
8995
ImportCredentialsInvalidJsonException("Unable to re-encode accounts."),
@@ -95,15 +101,22 @@ class CredentialExchangeImportManagerImpl(
95101
payload = accountsJson,
96102
)
97103
.flatMap { cipherList ->
98-
if (cipherList.isEmpty()) {
104+
// Filter out card ciphers if RESTRICT_ITEM_TYPES policy is active
105+
val filteredCipherList = if (policyManager.hasRestrictItemTypes()) {
106+
cipherList.filter { cipher -> cipher.type != CipherType.CARD }
107+
} else {
108+
cipherList
109+
}
110+
111+
if (filteredCipherList.isEmpty()) {
99112
// If no ciphers were returned, we can skip the remaining steps and return the
100113
// appropriate result.
101114
return ImportCxfPayloadResult.NoItems
102115
}
103116
ciphersService
104117
.importCiphers(
105118
request = ImportCiphersJsonRequest(
106-
ciphers = cipherList.map {
119+
ciphers = filteredCipherList.map {
107120
it.toEncryptedNetworkCipher(
108121
encryptedFor = userId,
109122
)
@@ -120,7 +133,7 @@ class CredentialExchangeImportManagerImpl(
120133

121134
ImportCiphersResponseJson.Success -> {
122135
ImportCxfPayloadResult
123-
.Success(itemCount = cipherList.size)
136+
.Success(itemCount = filteredCipherList.size)
124137
.asSuccess()
125138
}
126139
}

app/src/main/kotlin/com/x8bit/bitwarden/data/vault/manager/di/VaultManagerModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.x8bit.bitwarden.data.auth.manager.UserStateManager
1717
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
1818
import com.x8bit.bitwarden.data.platform.manager.AppStateManager
1919
import com.x8bit.bitwarden.data.platform.manager.DatabaseSchemeManager
20+
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
2021
import com.x8bit.bitwarden.data.platform.manager.PushManager
2122
import com.x8bit.bitwarden.data.platform.manager.ReviewPromptManager
2223
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
@@ -210,11 +211,13 @@ object VaultManagerModule {
210211
vaultSdkSource: VaultSdkSource,
211212
ciphersService: CiphersService,
212213
vaultSyncManager: VaultSyncManager,
214+
policyManager: PolicyManager,
213215
json: Json,
214216
): CredentialExchangeImportManager = CredentialExchangeImportManagerImpl(
215217
vaultSdkSource = vaultSdkSource,
216218
ciphersService = ciphersService,
217219
vaultSyncManager = vaultSyncManager,
220+
policyManager = policyManager,
218221
json = json,
219222
)
220223
}

app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/exportvault/ExportVaultViewModel.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.x8bit.bitwarden.data.auth.repository.model.VerifyOtpResult
2121
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
2222
import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
2323
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
24+
import com.x8bit.bitwarden.data.platform.manager.util.hasRestrictItemTypes
2425
import com.x8bit.bitwarden.data.vault.manager.FileManager
2526
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
2627
import com.x8bit.bitwarden.data.vault.repository.model.ExportVaultDataResult
@@ -464,10 +465,7 @@ class ExportVaultViewModel @Inject constructor(
464465
}
465466

466467
private fun getRestrictedItemTypes(): List<CipherType> {
467-
val hasActiveRestrictItemTypesPolicy = policyManager
468-
.getActivePolicies(type = PolicyTypeJson.RESTRICT_ITEM_TYPES)
469-
.isNotEmpty()
470-
return if (!hasActiveRestrictItemTypesPolicy) {
468+
return if (!policyManager.hasRestrictItemTypes()) {
471469
emptyList()
472470
} else {
473471
listOf(CipherType.CARD)

app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/importitems/ImportItemsViewModel.kt

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import com.bitwarden.ui.platform.resource.BitwardenString
1313
import com.bitwarden.ui.util.Text
1414
import com.bitwarden.ui.util.asPluralsText
1515
import com.bitwarden.ui.util.asText
16+
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
17+
import com.x8bit.bitwarden.data.platform.manager.util.hasRestrictItemTypes
1618
import com.x8bit.bitwarden.data.vault.manager.model.SyncVaultDataResult
1719
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
1820
import com.x8bit.bitwarden.data.vault.repository.model.ImportCredentialsResult
@@ -32,6 +34,7 @@ private const val KEY_STATE = "state"
3234
class ImportItemsViewModel @Inject constructor(
3335
savedStateHandle: SavedStateHandle,
3436
private val vaultRepository: VaultRepository,
37+
private val policyManager: PolicyManager,
3538
) : BaseViewModel<ImportItemsState, ImportItemsEvent, ImportItemsAction>(
3639
initialState = savedStateHandle[KEY_STATE] ?: ImportItemsState(),
3740
) {
@@ -117,24 +120,29 @@ class ImportItemsViewModel @Inject constructor(
117120
}
118121

119122
private fun handleImportFromAnotherAppClick() {
123+
val credentialTypes = buildList {
124+
add(CredentialTypes.CREDENTIAL_TYPE_BASIC_AUTH)
125+
add(CredentialTypes.CREDENTIAL_TYPE_PUBLIC_KEY)
126+
add(CredentialTypes.CREDENTIAL_TYPE_ADDRESS)
127+
add(CredentialTypes.CREDENTIAL_TYPE_API_KEY)
128+
// Only include credit card type if policy doesn't restrict it
129+
if (!policyManager.hasRestrictItemTypes()) {
130+
add(CredentialTypes.CREDENTIAL_TYPE_CREDIT_CARD)
131+
}
132+
add(CredentialTypes.CREDENTIAL_TYPE_CUSTOM_FIELDS)
133+
add(CredentialTypes.CREDENTIAL_TYPE_DRIVERS_LICENSE)
134+
add(CredentialTypes.CREDENTIAL_TYPE_IDENTITY_DOCUMENT)
135+
add(CredentialTypes.CREDENTIAL_TYPE_NOTE)
136+
add(CredentialTypes.CREDENTIAL_TYPE_PASSPORT)
137+
add(CredentialTypes.CREDENTIAL_TYPE_PERSON_NAME)
138+
add(CredentialTypes.CREDENTIAL_TYPE_SSH_KEY)
139+
add(CredentialTypes.CREDENTIAL_TYPE_TOTP)
140+
add(CredentialTypes.CREDENTIAL_TYPE_WIFI)
141+
}
142+
120143
sendEvent(
121144
ImportItemsEvent.ShowRegisteredImportSources(
122-
credentialTypes = listOf(
123-
CredentialTypes.CREDENTIAL_TYPE_BASIC_AUTH,
124-
CredentialTypes.CREDENTIAL_TYPE_PUBLIC_KEY,
125-
CredentialTypes.CREDENTIAL_TYPE_ADDRESS,
126-
CredentialTypes.CREDENTIAL_TYPE_API_KEY,
127-
CredentialTypes.CREDENTIAL_TYPE_CREDIT_CARD,
128-
CredentialTypes.CREDENTIAL_TYPE_CUSTOM_FIELDS,
129-
CredentialTypes.CREDENTIAL_TYPE_DRIVERS_LICENSE,
130-
CredentialTypes.CREDENTIAL_TYPE_IDENTITY_DOCUMENT,
131-
CredentialTypes.CREDENTIAL_TYPE_NOTE,
132-
CredentialTypes.CREDENTIAL_TYPE_PASSPORT,
133-
CredentialTypes.CREDENTIAL_TYPE_PERSON_NAME,
134-
CredentialTypes.CREDENTIAL_TYPE_SSH_KEY,
135-
CredentialTypes.CREDENTIAL_TYPE_TOTP,
136-
CredentialTypes.CREDENTIAL_TYPE_WIFI,
137-
),
145+
credentialTypes = credentialTypes,
138146
),
139147
)
140148
}

0 commit comments

Comments
 (0)