From 441b4d3b682824cf20200287c80ccc61f5e0bdef Mon Sep 17 00:00:00 2001 From: Fabian Henneke Date: Wed, 15 Apr 2020 17:20:26 +0200 Subject: Add support for "work/example.org.gpg" folder layout --- .../zeapo/pwdstore/SearchableRepositoryViewModel.kt | 2 +- .../zeapo/pwdstore/autofill/oreo/AutofillHelper.kt | 6 +++++- .../pwdstore/autofill/oreo/AutofillPreferences.kt | 21 ++++++++++++++++----- .../autofill/oreo/ui/AutofillSaveActivity.kt | 2 +- app/src/main/res/values/arrays.xml | 6 ++++-- 5 files changed, 27 insertions(+), 10 deletions(-) (limited to 'app') diff --git a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt index 47170717..1604cb66 100644 --- a/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt +++ b/app/src/main/java/com/zeapo/pwdstore/SearchableRepositoryViewModel.kt @@ -97,7 +97,7 @@ private fun PasswordItem.Companion.makeComparator( .then(compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getIdentifierFor(it.file) }) - .then(compareBy(CaseInsensitiveComparator) { + .then(compareBy(nullsLast(CaseInsensitiveComparator)) { directoryStructure.getUsernameFor(it.file) }) } 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 e3d48302..47822e0f 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 @@ -19,6 +19,7 @@ import com.github.ajalt.timberkt.Timber.tag import com.github.ajalt.timberkt.e import com.zeapo.pwdstore.PasswordEntry import com.zeapo.pwdstore.R +import com.zeapo.pwdstore.utils.PasswordRepository import java.io.File import java.security.MessageDigest @@ -100,7 +101,10 @@ private fun makeRemoteView( fun makeFillMatchRemoteView(context: Context, file: File, formOrigin: FormOrigin): RemoteViews { val title = formOrigin.getPrettyIdentifier(context, untrusted = false) - val summary = AutofillPreferences.directoryStructure(context).getUsernameFor(file) + val directoryStructure = AutofillPreferences.directoryStructure(context) + val relativeFile = file.relativeTo(PasswordRepository.getRepositoryDirectory(context)) + val summary = directoryStructure.getUsernameFor(relativeFile) + ?: directoryStructure.getPathToIdentifierFor(relativeFile) ?: "" val iconRes = R.drawable.ic_person_black_24dp return makeRemoteView(context, title, summary, iconRes) } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt index 39e1dbb5..a08fc424 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/AutofillPreferences.kt @@ -16,6 +16,7 @@ private val Context.defaultSharedPreferences: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences(this) enum class DirectoryStructure(val value: String) { + EncryptedUsername("encrypted_username"), FileBased("file"), DirectoryBased("directory"); @@ -24,11 +25,13 @@ enum class DirectoryStructure(val value: String) { * [DirectoryStructure]. * * Examples: + * - * --> null (EncryptedUsername) * - work/example.org/john@doe.org.gpg --> john@doe.org (FileBased) * - work/example.org/john@doe.org/password.gpg --> john@doe.org (DirectoryBased) * - Temporary PIN.gpg --> Temporary PIN (DirectoryBased, fallback) */ - fun getUsernameFor(file: File): String = when (this) { + fun getUsernameFor(file: File): String? = when (this) { + EncryptedUsername -> null FileBased -> file.nameWithoutExtension DirectoryBased -> file.parentFile?.name ?: file.nameWithoutExtension } @@ -41,12 +44,14 @@ enum class DirectoryStructure(val value: String) { * [DirectoryStructure.getAccountPartFor] will always return a non-null result. * * Examples: + * - work/example.org.gpg --> example.org (EncryptedUsername) * - work/example.org/john@doe.org.gpg --> example.org (FileBased) * - example.org.gpg --> example.org (FileBased, fallback) * - work/example.org/john@doe.org/password.gpg --> example.org (DirectoryBased) * - Temporary PIN.gpg --> null (DirectoryBased) */ fun getIdentifierFor(file: File): String? = when (this) { + EncryptedUsername -> file.nameWithoutExtension FileBased -> file.parentFile?.name ?: file.nameWithoutExtension DirectoryBased -> file.parentFile?.parent } @@ -55,10 +60,8 @@ enum class DirectoryStructure(val value: String) { * Returns the path components of [file] until right before the component that contains the * origin identifier according to the current [DirectoryStructure]. * - * At least one of [DirectoryStructure.getIdentifierFor] and - * [DirectoryStructure.getAccountPartFor] will always return a non-null result. - * * Examples: + * - work/example.org.gpg --> work (EncryptedUsername) * - work/example.org/john@doe.org.gpg --> work (FileBased) * - example.org/john@doe.org.gpg --> null (FileBased) * - john@doe.org.gpg --> null (FileBased) @@ -66,6 +69,7 @@ enum class DirectoryStructure(val value: String) { * - example.org/john@doe.org/password.gpg --> null (DirectoryBased) */ fun getPathToIdentifierFor(file: File): String? = when (this) { + EncryptedUsername -> file.parent FileBased -> file.parentFile?.parent DirectoryBased -> file.parentFile?.parentFile?.parent } @@ -74,13 +78,18 @@ enum class DirectoryStructure(val value: String) { * Returns the path component of [file] following the origin identifier according to the current * [DirectoryStructure] (without file extension). * + * At least one of [DirectoryStructure.getIdentifierFor] and + * [DirectoryStructure.getAccountPartFor] will always return a non-null result. + * * Examples: + * - * --> null (EncryptedUsername) * - work/example.org/john@doe.org.gpg --> john@doe.org (FileBased) * - example.org.gpg --> null (FileBased, fallback) * - work/example.org/john@doe.org/password.gpg --> john@doe.org/password (DirectoryBased) * - Temporary PIN.gpg --> Temporary PIN (DirectoryBased, fallback) */ fun getAccountPartFor(file: File): String? = when (this) { + EncryptedUsername -> null FileBased -> file.nameWithoutExtension.takeIf { file.parentFile != null } DirectoryBased -> file.parentFile?.let { parentFile -> "${parentFile.name}/${file.nameWithoutExtension}" @@ -89,11 +98,13 @@ enum class DirectoryStructure(val value: String) { @RequiresApi(Build.VERSION_CODES.O) fun getSaveFolderName(sanitizedIdentifier: String, username: String?) = when (this) { + EncryptedUsername -> "/" FileBased -> sanitizedIdentifier DirectoryBased -> Paths.get(sanitizedIdentifier, username ?: "username").toString() } - fun getSaveFileName(username: String?) = when (this) { + fun getSaveFileName(username: String?, identifier: String) = when (this) { + EncryptedUsername -> identifier FileBased -> username DirectoryBased -> "password" } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt index 9da575fd..384bcad5 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/oreo/ui/AutofillSaveActivity.kt @@ -60,7 +60,7 @@ class AutofillSaveActivity : Activity() { sanitizedIdentifier = sanitizedIdentifier, username = credentials?.username ) - val fileName = directoryStructure.getSaveFileName(username = credentials?.username) + val fileName = directoryStructure.getSaveFileName(username = credentials?.username, identifier = identifier) val intent = Intent(context, AutofillSaveActivity::class.java).apply { putExtras( bundleOf( diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 559a520c..8cfcc7fc 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -52,10 +52,12 @@ xkpasswd - /example.org/john@doe.org(.gpg) - /example.org/john@doe.org/password(.gpg) + work/example.org(.gpg) + work/example.org/john@doe.org(.gpg) + work/example.org/john@doe.org/password(.gpg) + encrypted_username file directory -- cgit v1.2.3