From b16620b55c60181a0ae9b19ab880a47f4f958159 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Tue, 12 May 2020 01:43:03 +0530 Subject: Add setting for fallback username (#772) * PasswordEntry: remove useless annotations Turns out VisibleForTesting only applies for documentation purposes. Boo >:( Signed-off-by: Harsh Shandilya * PasswordEntry: silence locale warning Signed-off-by: Harsh Shandilya * Add setting for fallback username Fixes #763 Signed-off-by: Harsh Shandilya --- .../main/java/com/zeapo/pwdstore/PasswordEntry.kt | 5 +---- .../main/java/com/zeapo/pwdstore/UserPreference.kt | 24 ++++++++++++---------- .../zeapo/pwdstore/autofill/oreo/AutofillHelper.kt | 12 ++++++++++- .../autofill/oreo/ui/AutofillDecryptActivity.kt | 2 +- app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/preference.xml | 4 ++++ 6 files changed, 32 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt index b7670742..32f671be 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt @@ -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:", diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt index 5bca7315..10665e38 100644 --- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt +++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.kt @@ -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("autofill_apps")!! - val autoFillDefaultPreference = findPreference("autofill_default")!! - val autoFillAlwaysShowDialogPreference = - findPreference("autofill_always")!! - val autoFillShowFullNamePreference = - findPreference("autofill_full_path")!! - autofillDependencies = listOf( + val oreoAutofillDirectoryStructurePreference = findPreference("oreo_autofill_directory_structure") + val oreoAutofillDefaultUsername = findPreference("oreo_autofill_default_username") + val autoFillAppsPreference = findPreference("autofill_apps") + val autoFillDefaultPreference = findPreference("autofill_default") + val autoFillAlwaysShowDialogPreference = findPreference("autofill_always") + val autoFillShowFullNamePreference = findPreference("autofill_full_path") + autofillDependencies = listOfNotNull( autoFillAppsPreference, autoFillDefaultPreference, autoFillAlwaysShowDialogPreference, autoFillShowFullNamePreference ) - val oreoAutofillDirectoryStructurePreference = - findPreference("oreo_autofill_directory_structure")!! - oreoAutofillDependencies = listOf(oreoAutofillDirectoryStructurePreference) + oreoAutofillDependencies = listOfNotNull( + oreoAutofillDirectoryStructurePreference, + oreoAutofillDefaultUsername + ) // Misc preferences val appVersionPreference = findPreference("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 diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt index 59077ac8..101f96a0 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillHelper.kt @@ -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): 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) } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt index c57ffdcc..4c806dff 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillDecryptActivity.kt @@ -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 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index db8491e8..f6bb751d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -370,4 +370,6 @@ Grant Enable debug logging (requires app restart) Debug logging + If Autofill is unable to determine a username from your password file or directory structure, it will use the value specified here + Default username diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index e59e1c8c..af55295c 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -13,6 +13,10 @@ app:key="oreo_autofill_directory_structure" app:title="@string/oreo_autofill_preference_directory_structure" app:useSimpleSummaryProvider="true" /> + -- cgit v1.2.3