BIT-1506: block autofill for block listed URIs (#855)

This commit is contained in:
Lucas Kivi 2024-01-29 18:57:06 -06:00 committed by Álison Fernandes
parent c7580c87bd
commit 88da5b2007
2 changed files with 77 additions and 5 deletions

View file

@ -15,6 +15,16 @@ import com.x8bit.bitwarden.data.autofill.util.toAutofillView
import com.x8bit.bitwarden.data.autofill.util.website
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
/**
* A list of URIs that should never be autofilled.
*/
private val BLOCK_LISTED_URIS: List<String> = listOf(
"androidapp://android",
"androidapp://com.android.settings",
"androidapp://com.x8bit.bitwarden",
"androidapp://com.oneplus.applocker",
)
/**
* The default [AutofillParser] implementation for the app. This is a tool for parsing autofill data
* from the OS into domain models.
@ -65,15 +75,19 @@ class AutofillParserImpl(
.map { it.autofillViews }
.flatten()
// Find the focused view (or indicate there is no fulfillment to be performed.)
val focusedView = autofillViews
.firstOrNull { it.data.isFocused }
?: return AutofillRequest.Unfillable
// Find the focused view.
val focusedView = autofillViews.firstOrNull { it.data.isFocused }
val uri = traversalDataList.buildUriOrNull(
assistStructure = assistStructure,
)
val blockListedURIs = settingsRepository.blockedAutofillUris + BLOCK_LISTED_URIS
if (focusedView == null || blockListedURIs.contains(uri)) {
// The view is unfillable if there are no focused views or the URI is block listed.
return AutofillRequest.Unfillable
}
// Choose the first focused partition of data for fulfillment.
val partition = when (focusedView) {
is AutofillView.Card -> {

View file

@ -63,6 +63,7 @@ class AutofillParserTests {
private val inlinePresentationSpecs: List<InlinePresentationSpec> = mockk()
private val settingsRepository: SettingsRepository = mockk {
every { isInlineAutofillEnabled } answers { mockIsInlineAutofillEnabled }
every { blockedAutofillUris } returns emptyList()
}
private var mockIsInlineAutofillEnabled = true
@ -483,6 +484,57 @@ class AutofillParserTests {
}
}
@Test
fun `parse should skip block listed URIs Login when a Login view is focused`() {
// Setup all tests
setupAssistStructureWithAllAutofillViewTypes()
val cardAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
data = AutofillView.Data(
autofillId = cardAutofillId,
isFocused = true,
),
)
val loginAutofillView: AutofillView.Login = AutofillView.Login.Username(
data = AutofillView.Data(
autofillId = loginAutofillId,
isFocused = true,
),
)
val remoteBlockList = listOf(
"blockListedUri.com",
"blockListedAgainUri.com",
)
every { cardViewNode.toAutofillView() } returns cardAutofillView
every { loginViewNode.toAutofillView() } returns loginAutofillView
every { settingsRepository.blockedAutofillUris } returns remoteBlockList
// A function for asserting that a block listed URI results in an unfillable request.
fun testBlockListedUri(blockListedUri: String) {
// Setup
every {
any<List<ViewNodeTraversalData>>().buildUriOrNull(assistStructure)
} returns blockListedUri
// Test
val actual = parser.parse(
autofillAppInfo = autofillAppInfo,
fillRequest = fillRequest,
)
// Verify
assertEquals(AutofillRequest.Unfillable, actual)
}
// Test all block listed URIs
BLOCK_LISTED_URIS.forEach(::testBlockListedUri)
remoteBlockList.forEach(::testBlockListedUri)
// Verify all tests
verify(exactly = BLOCK_LISTED_URIS.size + remoteBlockList.size) {
any<List<ViewNodeTraversalData>>().buildUriOrNull(assistStructure)
}
}
/**
* Setup [assistStructure] to return window nodes with each [AutofillView] type (card and login)
* so we can test how different window node configurations produce different partitions.
@ -494,7 +546,13 @@ class AutofillParserTests {
}
}
private val BLOCK_LISTED_URIS: List<String> = listOf(
"androidapp://android",
"androidapp://com.android.settings",
"androidapp://com.x8bit.bitwarden",
"androidapp://com.oneplus.applocker",
)
private const val ID_PACKAGE: String = "com.x8bit.bitwarden"
private const val MAX_INLINE_SUGGESTION_COUNT: Int = 42
private const val URI: String = "androidapp://com.x8bit.bitwarden"
private const val URI: String = "androidapp://com.google"
private const val WEBSITE: String = "https://www.google.com"