Allow custom public suffixes for Autofill (#841)

Adds a preference that allows the user to specify domains that are then
treated as additional public suffixes for the purposes of Autofill.
This commit is contained in:
Fabian Henneke 2020-06-09 13:45:23 +02:00 committed by GitHub
parent 02b7f5559d
commit 2fa03e3fa0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 3 deletions

View file

@ -116,6 +116,7 @@ class UserPreference : AppCompatActivity() {
autoFillEnablePreference = findPreference("autofill_enable")
val oreoAutofillDirectoryStructurePreference = findPreference<ListPreference>("oreo_autofill_directory_structure")
val oreoAutofillDefaultUsername = findPreference<EditTextPreference>("oreo_autofill_default_username")
val oreoAutofillCustomPublixSuffixes = findPreference<EditTextPreference>("oreo_autofill_custom_public_suffixes")
val autoFillAppsPreference = findPreference<Preference>("autofill_apps")
val autoFillDefaultPreference = findPreference<CheckBoxPreference>("autofill_default")
val autoFillAlwaysShowDialogPreference = findPreference<CheckBoxPreference>("autofill_always")
@ -128,8 +129,15 @@ class UserPreference : AppCompatActivity() {
)
oreoAutofillDependencies = listOfNotNull(
oreoAutofillDirectoryStructurePreference,
oreoAutofillDefaultUsername
oreoAutofillDefaultUsername,
oreoAutofillCustomPublixSuffixes
)
oreoAutofillCustomPublixSuffixes?.apply {
setOnBindEditTextListener {
it.isSingleLine = false
it.setHint(R.string.preference_custom_public_suffixes_hint)
}
}
// Misc preferences
val appVersionPreference = findPreference<Preference>("app_version")

View file

@ -6,6 +6,7 @@ package com.zeapo.pwdstore.autofill.oreo
import android.content.Context
import android.util.Patterns
import androidx.preference.PreferenceManager
import kotlinx.coroutines.runBlocking
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
@ -44,7 +45,43 @@ fun getPublicSuffixPlusOne(context: Context, domain: String) = runBlocking {
) {
domain
} else {
PublicSuffixListCache.getOrCachePublicSuffixList(context).getPublicSuffixPlusOne(domain)
.await() ?: domain
getCanonicalSuffix(context, domain)
}
}
/**
* Returns:
* - [domain], if [domain] equals [suffix];
* - null, if [domain] does not have [suffix] as a domain suffix or only with an empty prefix;
* - the direct subdomain of [suffix] of which [domain] is a subdomain.
*/
fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
if (domain == suffix)
return domain
val prefix = domain.removeSuffix(".$suffix")
if (prefix == domain || prefix.isEmpty())
return null
val lastPrefixPart = prefix.takeLastWhile { it != '.' }
return "$lastPrefixPart.$suffix"
}
fun getCustomSuffixes(context: Context): Sequence<String> {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString("oreo_autofill_custom_public_suffixes", "")!!
.splitToSequence('\n')
.filter { it.isNotBlank() && it.first() != '.' && it.last() != '.' }
}
suspend fun getCanonicalSuffix(context: Context, domain: String): String {
val publicSuffixList = PublicSuffixListCache.getOrCachePublicSuffixList(context)
val publicSuffixPlusOne = publicSuffixList.getPublicSuffixPlusOne(domain).await()
?: return domain
var longestSuffix = publicSuffixPlusOne
for (customSuffix in getCustomSuffixes(context)) {
val suffixPlusUpToOne = getSuffixPlusUpToOne(domain, customSuffix) ?: continue
// A shorter suffix is automatically a substring.
if (suffixPlusUpToOne.length > longestSuffix.length)
longestSuffix = suffixPlusUpToOne
}
return longestSuffix
}

View file

@ -373,4 +373,7 @@
<string name="preference_default_username_title">Default username</string>
<string name="git_operation_remember_password">Remember password</string>
<string name="git_operation_hint_password">Password</string>
<string name="preference_custom_public_suffixes_title">Custom domains</string>
<string name="preference_custom_public_suffixes_summary">Autofill will distinguish subdomains of these domains</string>
<string name="preference_custom_public_suffixes_hint">company.com\npersonal.com</string>
</resources>

View file

@ -21,6 +21,10 @@
app:key="oreo_autofill_default_username"
app:summary="@string/preference_default_username_summary"
app:title="@string/preference_default_username_title" />
<EditTextPreference
app:key="oreo_autofill_custom_public_suffixes"
app:summary="@string/preference_custom_public_suffixes_summary"
app:title="@string/preference_custom_public_suffixes_title" />
<Preference
app:key="autofill_apps"
app:title="@string/pref_autofill_apps_title" />