[PM-25057] Refactor card restriction logic in AutofillCipherProvider (#5788)

This commit is contained in:
Patrick Honkonen
2025-08-26 14:47:18 -04:00
committed by GitHub
parent d2d89b5a0f
commit aab8198457
2 changed files with 41 additions and 3 deletions

View File

@@ -71,7 +71,9 @@ class AutofillCipherProviderImpl(
// Must not require a reprompt.
it.reprompt == CipherRepromptType.NONE &&
// Must not be restricted by organization.
it.organizationId !in organizationIdsWithCardTypeRestrictions
!it.isExcludedByOrgCardRestrictions(
organizationIdsWithCardTypeRestrictions,
)
}
?.let { nonNullCipherListView ->
nonNullCipherListView.id?.let { cipherId ->
@@ -154,4 +156,25 @@ class AutofillCipherProviderImpl(
is GetCipherResult.Success -> result.cipherView
}
/**
* Checks if this [CipherListView] item should be excluded from autofill due to
* organization-based card type restrictions.
*
* It's considered restricted if:
* 1. There are organizations with card type restrictions AND this item is a personal vault item
* (organizationId is null).
* 2. OR this item belongs to an organization that has card type restrictions.
*/
private fun CipherListView.isExcludedByOrgCardRestrictions(
restrictingOrgIds: List<String>,
): Boolean {
if (restrictingOrgIds.isEmpty()) {
return false
}
// If personal vault (no orgId), restricted if any org has restrictions.
return organizationId == null ||
// If part of an org, restricted if that org is in the restricting list.
organizationId in restrictingOrgIds
}
}

View File

@@ -279,7 +279,13 @@ class AutofillCipherProviderTest {
every { deletedDate } returns null
every { type } returns CipherListViewType.Card(cardListView)
every { reprompt } returns CipherRepromptType.NONE
every { organizationId } returns ORGANIZATION_ID
every { organizationId } returns ORGANIZATION_ID_WITH_CARD_TYPE_RESTRICTIONS
}
val personalVaultCardCipherView: CipherListView = mockk {
every { deletedDate } returns null
every { type } returns CipherListViewType.Card(cardListView)
every { reprompt } returns CipherRepromptType.NONE
every { organizationId } returns null
}
val decryptCipherListViewsResult = DecryptCipherListResult(
successes = listOf(
@@ -287,6 +293,7 @@ class AutofillCipherProviderTest {
deletedCardCipherView,
repromptCardCipherView,
restrictedCardCipherView,
personalVaultCardCipherView,
loginCipherListViewWithTotp,
loginCipherListViewWithoutTotp,
),
@@ -295,7 +302,12 @@ class AutofillCipherProviderTest {
every {
policyManager.getActivePolicies(PolicyTypeJson.RESTRICT_ITEM_TYPES)
} returns listOf(createMockPolicy(number = 1, organizationId = ORGANIZATION_ID))
} returns listOf(
createMockPolicy(
number = 1,
organizationId = ORGANIZATION_ID_WITH_CARD_TYPE_RESTRICTIONS,
),
)
coEvery {
vaultRepository.getCipher(CARD_CIPHER_ID)
} returns GetCipherResult.Success(
@@ -314,6 +326,7 @@ class AutofillCipherProviderTest {
val expected = listOf(
CARD_AUTOFILL_CIPHER,
)
every { cardCipherListView.organizationId } returns ORGANIZATION_ID
every { cardCipherListView.subtitle } returns CARD_SUBTITLE
// Test & Verify
@@ -563,6 +576,8 @@ class AutofillCipherProviderTest {
private const val ACTIVE_USER_ID = "activeUserId"
private const val ORGANIZATION_ID = "organizationId"
private const val ORGANIZATION_ID_WITH_CARD_TYPE_RESTRICTIONS =
"organizationIdWithCardTypeRestrictions"
private const val CARD_CARDHOLDER_NAME = "John Doe"
private const val CARD_CODE = "123"
private const val CARD_EXP_MONTH = "January"