mirror of
https://github.com/android-password-store/Android-Password-Store.git
synced 2025-09-05 15:45:42 +02:00
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:
parent
041cf00510
commit
b16620b55c
|
@ -5,8 +5,6 @@
|
||||||
package com.zeapo.pwdstore
|
package com.zeapo.pwdstore
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.annotation.VisibleForTesting
|
|
||||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.UnsupportedEncodingException
|
import java.io.UnsupportedEncodingException
|
||||||
|
|
||||||
|
@ -100,7 +98,7 @@ class PasswordEntry(private val content: String) {
|
||||||
if (line.startsWith("otpauth://totp/")) {
|
if (line.startsWith("otpauth://totp/")) {
|
||||||
return Uri.parse(line).getQueryParameter("secret")
|
return Uri.parse(line).getQueryParameter("secret")
|
||||||
}
|
}
|
||||||
if (line.toLowerCase().startsWith("totp:")) {
|
if (line.startsWith("totp:", ignoreCase = true)) {
|
||||||
return line.split(": *".toRegex(), 2).toTypedArray()[1]
|
return line.split(": *".toRegex(), 2).toTypedArray()[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +163,6 @@ class PasswordEntry(private val content: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@VisibleForTesting(otherwise = PRIVATE)
|
|
||||||
val USERNAME_FIELDS = arrayOf(
|
val USERNAME_FIELDS = arrayOf(
|
||||||
"login:",
|
"login:",
|
||||||
"username:",
|
"username:",
|
||||||
|
|
|
@ -28,6 +28,7 @@ import androidx.core.content.edit
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.preference.CheckBoxPreference
|
import androidx.preference.CheckBoxPreference
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
@ -114,21 +115,22 @@ class UserPreference : AppCompatActivity() {
|
||||||
|
|
||||||
// Autofill preferences
|
// Autofill preferences
|
||||||
autoFillEnablePreference = findPreference("autofill_enable")
|
autoFillEnablePreference = findPreference("autofill_enable")
|
||||||
val autoFillAppsPreference = findPreference<Preference>("autofill_apps")!!
|
val oreoAutofillDirectoryStructurePreference = findPreference<ListPreference>("oreo_autofill_directory_structure")
|
||||||
val autoFillDefaultPreference = findPreference<CheckBoxPreference>("autofill_default")!!
|
val oreoAutofillDefaultUsername = findPreference<EditTextPreference>("oreo_autofill_default_username")
|
||||||
val autoFillAlwaysShowDialogPreference =
|
val autoFillAppsPreference = findPreference<Preference>("autofill_apps")
|
||||||
findPreference<CheckBoxPreference>("autofill_always")!!
|
val autoFillDefaultPreference = findPreference<CheckBoxPreference>("autofill_default")
|
||||||
val autoFillShowFullNamePreference =
|
val autoFillAlwaysShowDialogPreference = findPreference<CheckBoxPreference>("autofill_always")
|
||||||
findPreference<CheckBoxPreference>("autofill_full_path")!!
|
val autoFillShowFullNamePreference = findPreference<CheckBoxPreference>("autofill_full_path")
|
||||||
autofillDependencies = listOf(
|
autofillDependencies = listOfNotNull(
|
||||||
autoFillAppsPreference,
|
autoFillAppsPreference,
|
||||||
autoFillDefaultPreference,
|
autoFillDefaultPreference,
|
||||||
autoFillAlwaysShowDialogPreference,
|
autoFillAlwaysShowDialogPreference,
|
||||||
autoFillShowFullNamePreference
|
autoFillShowFullNamePreference
|
||||||
)
|
)
|
||||||
val oreoAutofillDirectoryStructurePreference =
|
oreoAutofillDependencies = listOfNotNull(
|
||||||
findPreference<ListPreference>("oreo_autofill_directory_structure")!!
|
oreoAutofillDirectoryStructurePreference,
|
||||||
oreoAutofillDependencies = listOf(oreoAutofillDirectoryStructurePreference)
|
oreoAutofillDefaultUsername
|
||||||
|
)
|
||||||
|
|
||||||
// Misc preferences
|
// Misc preferences
|
||||||
val appVersionPreference = findPreference<Preference>("app_version")
|
val appVersionPreference = findPreference<Preference>("app_version")
|
||||||
|
@ -258,7 +260,7 @@ class UserPreference : AppCompatActivity() {
|
||||||
selectExternalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
selectExternalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
||||||
externalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
externalGitRepositoryPreference?.onPreferenceChangeListener = resetRepo
|
||||||
|
|
||||||
autoFillAppsPreference.onPreferenceClickListener = ClickListener {
|
autoFillAppsPreference?.onPreferenceClickListener = ClickListener {
|
||||||
val intent = Intent(callingActivity, AutofillPreferenceActivity::class.java)
|
val intent = Intent(callingActivity, AutofillPreferenceActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
true
|
true
|
||||||
|
|
|
@ -16,6 +16,7 @@ import android.view.autofill.AutofillId
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.preference.PreferenceManager
|
||||||
import com.github.ajalt.timberkt.Timber.tag
|
import com.github.ajalt.timberkt.Timber.tag
|
||||||
import com.github.ajalt.timberkt.e
|
import com.github.ajalt.timberkt.e
|
||||||
import com.zeapo.pwdstore.PasswordEntry
|
import com.zeapo.pwdstore.PasswordEntry
|
||||||
|
@ -35,6 +36,12 @@ private fun ByteArray.base64(): String {
|
||||||
return Base64.encodeToString(this, Base64.NO_WRAP)
|
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 {
|
private fun stableHash(array: Collection<ByteArray>): String {
|
||||||
val hashes = array.map { it.sha256().base64() }
|
val hashes = array.map { it.sha256().base64() }
|
||||||
return hashes.sorted().joinToString(separator = ";")
|
return hashes.sorted().joinToString(separator = ";")
|
||||||
|
@ -82,12 +89,15 @@ val AssistStructure.ViewNode.webOrigin: String?
|
||||||
data class Credentials(val username: String?, val password: String) {
|
data class Credentials(val username: String?, val password: String) {
|
||||||
companion object {
|
companion object {
|
||||||
fun fromStoreEntry(
|
fun fromStoreEntry(
|
||||||
|
context: Context,
|
||||||
file: File,
|
file: File,
|
||||||
entry: PasswordEntry,
|
entry: PasswordEntry,
|
||||||
directoryStructure: DirectoryStructure
|
directoryStructure: DirectoryStructure
|
||||||
): Credentials {
|
): Credentials {
|
||||||
// Always give priority to a username stored in the encrypted extras
|
// 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)
|
return Credentials(username, entry.password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ class AutofillDecryptActivity : Activity(), CoroutineScope {
|
||||||
val entry = withContext(Dispatchers.IO) {
|
val entry = withContext(Dispatchers.IO) {
|
||||||
PasswordEntry(decryptedOutput)
|
PasswordEntry(decryptedOutput)
|
||||||
}
|
}
|
||||||
Credentials.fromStoreEntry(file, entry, directoryStructure)
|
Credentials.fromStoreEntry(this, file, entry, directoryStructure)
|
||||||
} catch (e: UnsupportedEncodingException) {
|
} catch (e: UnsupportedEncodingException) {
|
||||||
e(e) { "Failed to parse password entry" }
|
e(e) { "Failed to parse password entry" }
|
||||||
null
|
null
|
||||||
|
|
|
@ -370,4 +370,6 @@
|
||||||
<string name="snackbar_action_grant">Grant</string>
|
<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_summary">Enable debug logging (requires app restart)</string>
|
||||||
<string name="pref_debug_logging_title">Debug logging</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>
|
</resources>
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
app:key="oreo_autofill_directory_structure"
|
app:key="oreo_autofill_directory_structure"
|
||||||
app:title="@string/oreo_autofill_preference_directory_structure"
|
app:title="@string/oreo_autofill_preference_directory_structure"
|
||||||
app:useSimpleSummaryProvider="true" />
|
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
|
<Preference
|
||||||
app:key="autofill_apps"
|
app:key="autofill_apps"
|
||||||
app:title="@string/pref_autofill_apps_title" />
|
app:title="@string/pref_autofill_apps_title" />
|
||||||
|
|
Loading…
Reference in a new issue