mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
BIT-1506: block autofill for block listed URIs (#855)
This commit is contained in:
parent
c7580c87bd
commit
88da5b2007
2 changed files with 77 additions and 5 deletions
|
@ -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 -> {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue