Add setting for fallback username (#772)

* PasswordEntry: remove useless annotations

Turns out VisibleForTesting only applies for documentation purposes. Boo >:(

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* PasswordEntry: silence locale warning

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>

* Add setting for fallback username

Fixes #763

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-05-12 01:43:03 +05:30 committed by GitHub
parent 041cf00510
commit b16620b55c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 17 deletions

View file

@ -5,8 +5,6 @@
package com.zeapo.pwdstore
import android.net.Uri
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.PRIVATE
import java.io.ByteArrayOutputStream
import java.io.UnsupportedEncodingException
@ -100,7 +98,7 @@ class PasswordEntry(private val content: String) {
if (line.startsWith("otpauth://totp/")) {
return Uri.parse(line).getQueryParameter("secret")
}
if (line.toLowerCase().startsWith("totp:")) {
if (line.startsWith("totp:", ignoreCase = true)) {
return line.split(": *".toRegex(), 2).toTypedArray()[1]
}
}
@ -165,7 +163,6 @@ class PasswordEntry(private val content: String) {
}
companion object {
@VisibleForTesting(otherwise = PRIVATE)
val USERNAME_FIELDS = arrayOf(
"login:",
"username:",

View file

@ -28,6 +28,7 @@ import androidx.core.content.edit
import androidx.core.content.getSystemService
import androidx.documentfile.provider.DocumentFile
import androidx.preference.CheckBoxPreference
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
@ -114,21 +115,22 @@ class UserPreference : AppCompatActivity() {
// Autofill preferences
autoFillEnablePreference = findPreference("autofill_enable")
val autoFillAppsPreference = findPreference<Preference>("autofill_apps")!!
val autoFillDefaultPreference = findPreference<CheckBoxPreference>("autofill_default")!!
val autoFillAlwaysShowDialogPreference =
findPreference<CheckBoxPreference>("autofill_always")!!
val autoFillShowFullNamePreference =
findPreference<CheckBoxPreference>("autofill_full_path")!!
autofillDependencies = listOf(
val oreoAutofillDirectoryStructurePreference = findPreference<ListPreference>("oreo_autofill_directory_structure")
val oreoAutofillDefaultUsername = findPreference<EditTextPreference>("oreo_autofill_default_username")
val autoFillAppsPreference = findPreference<Preference>("autofill_apps")
val autoFillDefaultPreference = findPreference<CheckBoxPreference>("autofill_default")
val autoFillAlwaysShowDialogPreference = findPreference<CheckBoxPreference>("autofill_always")
val autoFillShowFullNamePreference = findPreference<CheckBoxPreference>("autofill_full_path")
autofillDependencies = listOfNotNull(
autoFillAppsPreference,
autoFillDefaultPreference,
autoFillAlwaysShowDialogPreference,
autoFillShowFullNamePreference
)
val oreoAutofillDirectoryStructurePreference =
findPreference<ListPreference>("oreo_autofill_directory_structure")!!
oreoAutofillDependencies = listOf(oreoAutofillDirectoryStructurePreference)
oreoAutofillDependencies = listOfNotNull(
oreoAutofillDirectoryStructurePreference,
oreoAutofillDefaultUsername
)
// Misc preferences
val appVersionPreference = findPreference<Preference>("app_version")
@ -258,7 +260,7 @@ class UserPreference : AppCompatActivity() {
selectExternalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
externalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
autoFillAppsPreference.onPreferenceClickListener = ClickListener {
autoFillAppsPreference?.onPreferenceClickListener = ClickListener {
val intent = Intent(callingActivity, AutofillPreferenceActivity::class.java)
startActivity(intent)
true

View file

@ -16,6 +16,7 @@ import android.view.autofill.AutofillId
import android.widget.RemoteViews
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.preference.PreferenceManager
import com.github.ajalt.timberkt.Timber.tag
import com.github.ajalt.timberkt.e
import com.zeapo.pwdstore.PasswordEntry
@ -35,6 +36,12 @@ private fun ByteArray.base64(): String {
return Base64.encodeToString(this, Base64.NO_WRAP)
}
private fun Context.getDefaultUsername(): String? {
return PreferenceManager
.getDefaultSharedPreferences(this)
.getString("oreo_autofill_default_username", null)
}
private fun stableHash(array: Collection<ByteArray>): String {
val hashes = array.map { it.sha256().base64() }
return hashes.sorted().joinToString(separator = ";")
@ -82,12 +89,15 @@ val AssistStructure.ViewNode.webOrigin: String?
data class Credentials(val username: String?, val password: String) {
companion object {
fun fromStoreEntry(
context: Context,
file: File,
entry: PasswordEntry,
directoryStructure: DirectoryStructure
): Credentials {
// Always give priority to a username stored in the encrypted extras
val username = entry.username ?: directoryStructure.getUsernameFor(file)
val username = entry.username
?: directoryStructure.getUsernameFor(file)
?: context.getDefaultUsername()
return Credentials(username, entry.password)
}
}

View file

@ -180,7 +180,7 @@ class AutofillDecryptActivity : Activity(), CoroutineScope {
val entry = withContext(Dispatchers.IO) {
PasswordEntry(decryptedOutput)
}
Credentials.fromStoreEntry(file, entry, directoryStructure)
Credentials.fromStoreEntry(this, file, entry, directoryStructure)
} catch (e: UnsupportedEncodingException) {
e(e) { "Failed to parse password entry" }
null

View file

@ -370,4 +370,6 @@
<string name="snackbar_action_grant">Grant</string>
<string name="pref_debug_logging_summary">Enable debug logging (requires app restart)</string>
<string name="pref_debug_logging_title">Debug logging</string>
<string name="preference_default_username_summary">If Autofill is unable to determine a username from your password file or directory structure, it will use the value specified here</string>
<string name="preference_default_username_title">Default username</string>
</resources>

View file

@ -13,6 +13,10 @@
app:key="oreo_autofill_directory_structure"
app:title="@string/oreo_autofill_preference_directory_structure"
app:useSimpleSummaryProvider="true" />
<EditTextPreference
app:key="oreo_autofill_default_username"
app:summary="@string/preference_default_username_summary"
app:title="@string/preference_default_username_title" />
<Preference
app:key="autofill_apps"
app:title="@string/pref_autofill_apps_title" />