Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform deeper domain comparison for saving/updating autofill passwords #5570

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,12 @@ interface AutofillFeature {
*/
@Toggle.DefaultValue(false)
fun partialFormSaves(): Toggle

/**
* Kill switch for toggling how deep a domain comparison to do when saving/updating credentials.
* We want to limit times we save duplicates, and we can do that with a deeper comparison of domains to decide if we already have a matching cred.
* By deeper, this means comparing using E-TLD+1
*/
@Toggle.DefaultValue(true)
fun deepDomainComparisonsOnExistingCredentialsChecks(): Toggle
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.duckduckgo.autofill.impl

import com.duckduckgo.autofill.api.AutofillFeature
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType.Password
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType.Username
Expand Down Expand Up @@ -56,6 +57,7 @@ class SecureStoreBackedAutofillStore @Inject constructor(
private val dispatcherProvider: DispatcherProvider = DefaultDispatcherProvider(),
private val autofillUrlMatcher: AutofillUrlMatcher,
private val syncCredentialsListener: SyncCredentialsListener,
private val autofillFeature: AutofillFeature,
passwordStoreEventListenersPlugins: PluginPoint<PasswordStoreEventListener>,
) : InternalAutofillStore, AutofillDeclineStore {

Expand Down Expand Up @@ -153,15 +155,24 @@ class SecureStoreBackedAutofillStore @Inject constructor(
credentials: LoginCredentials,
updateType: CredentialUpdateType,
): LoginCredentials? {
val url = autofillUrlMatcher.cleanRawUrl(rawUrl)
Timber.v("Updating credentials. Update type: %s. for %s", updateType, rawUrl)

val url = getUrlToCompare(rawUrl)
if (url == null) {
Timber.w("Cannot update credentials as URL to lookup is null")
return null
}

val filter = when (updateType) {
Username -> filterMatchingPassword(credentials)
Password -> filterMatchingUsername(credentials)
else -> return null
}

val matchingCredentials = secureStorage.websiteLoginDetailsWithCredentialsForDomain(url).firstOrNull()?.filter(filter)
val matchingCredentials = secureStorage.websiteLoginDetailsWithCredentialsForDomain(url)
.firstOrNull()
?.filter(filter)

if (matchingCredentials.isNullOrEmpty()) {
Timber.w("Cannot update credentials as no credentials were found for %s", url)
return null
Expand Down Expand Up @@ -238,8 +249,9 @@ class SecureStoreBackedAutofillStore @Inject constructor(
username: String?,
password: String?,
): ContainsCredentialsResult {
val url = autofillUrlMatcher.cleanRawUrl(rawUrl)
val credentials = secureStorage.websiteLoginDetailsWithCredentialsForDomain(url).firstOrNull() ?: return NoMatch
val urlToCompare = getUrlToCompare(rawUrl) ?: return NoMatch

val credentials = secureStorage.websiteLoginDetailsWithCredentialsForDomain(urlToCompare).firstOrNull() ?: return NoMatch

var exactMatchFound = false
var usernameMatchFound = false
Expand Down Expand Up @@ -278,6 +290,14 @@ class SecureStoreBackedAutofillStore @Inject constructor(
return matchType
}

private fun getUrlToCompare(rawUrl: String): String? {
return if (autofillFeature.deepDomainComparisonsOnExistingCredentialsChecks().isEnabled()) {
autofillUrlMatcher.extractUrlPartsForAutofill(rawUrl).eTldPlus1
} else {
autofillUrlMatcher.cleanRawUrl(rawUrl)
}
}

private fun LoginCredentials.prepareForBulkInsertion(): WebsiteLoginDetailsWithCredentials {
val loginDetails = WebsiteLoginDetails(
id = id,
Expand Down
Loading
Loading