From df58f484acffe8f77aa7cf9c38e240c2858a1c54 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 8 May 2023 01:49:23 +0530 Subject: refactor: move out GPG identifier parser to `BasePgpActivity` --- .../app/passwordstore/ui/crypto/BasePgpActivity.kt | 53 ++++++++++++++++++++++ .../ui/crypto/PasswordCreationActivity.kt | 45 +----------------- 2 files changed, 54 insertions(+), 44 deletions(-) (limited to 'app/src/main') diff --git a/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt index ede3839a..f171d3c5 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/BasePgpActivity.kt @@ -18,7 +18,9 @@ import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import app.passwordstore.R +import app.passwordstore.crypto.GpgIdentifier import app.passwordstore.data.crypto.CryptoRepository +import app.passwordstore.data.repo.PasswordRepository import app.passwordstore.injection.prefs.SettingsPreferences import app.passwordstore.ui.pgp.PGPKeyImportActivity import app.passwordstore.util.coroutines.DispatcherProvider @@ -150,6 +152,57 @@ open class BasePgpActivity : AppCompatActivity() { } } + /** + * Get a list of available [GpgIdentifier]s for the current password repository. This method + * throws when no identifiers were able to be parsed. If this method returns null, it means that + * an invalid identifier was encountered and further execution must stop to let the user correct + * the problem. + */ + fun getGpgIdentifiers(subDir: String): List? { + val repoRoot = PasswordRepository.getRepositoryDirectory() + val gpgIdentifierFile = + File(repoRoot, subDir).findTillRoot(".gpg-id", repoRoot) + ?: File(repoRoot, ".gpg-id").apply { createNewFile() } + val gpgIdentifiers = + gpgIdentifierFile + .readLines() + .filter { it.isNotBlank() } + .map { line -> + GpgIdentifier.fromString(line) + ?: run { + // The line being empty means this is most likely an empty `.gpg-id` + // file we created. Skip the validation so we can make the user add a + // real ID. + if (line.isEmpty()) return@run + if (line.removePrefix("0x").matches("[a-fA-F0-9]{8}".toRegex()).not()) { + snackbar(message = resources.getString(R.string.invalid_gpg_id)) + } + return null + } + } + .filterIsInstance() + if (gpgIdentifiers.isEmpty()) { + error("Failed to parse identifiers from .gpg-id: ${gpgIdentifierFile.readText()}") + } + return gpgIdentifiers + } + + @Suppress("ReturnCount") + private fun File.findTillRoot(fileName: String, rootPath: File): File? { + val gpgFile = File(this, fileName) + if (gpgFile.exists()) return gpgFile + + if (this.absolutePath == rootPath.absolutePath) { + return null + } + val parent = parentFile + return if (parent != null && parent.exists()) { + parent.findTillRoot(fileName, rootPath) + } else { + null + } + } + companion object { const val EXTRA_FILE_PATH = "FILE_PATH" diff --git a/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt index e7b04ade..8d5cdb11 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/PasswordCreationActivity.kt @@ -24,9 +24,7 @@ import androidx.core.view.isVisible import androidx.core.widget.doAfterTextChanged import androidx.lifecycle.lifecycleScope import app.passwordstore.R -import app.passwordstore.crypto.GpgIdentifier import app.passwordstore.data.passfile.PasswordEntry -import app.passwordstore.data.repo.PasswordRepository import app.passwordstore.databinding.PasswordCreationActivityBinding import app.passwordstore.ui.dialogs.DicewarePasswordGeneratorDialogFragment import app.passwordstore.ui.dialogs.OtpImportDialogFragment @@ -333,31 +331,7 @@ class PasswordCreationActivity : BasePgpActivity() { } // pass enters the key ID into `.gpg-id`. - val repoRoot = PasswordRepository.getRepositoryDirectory() - val gpgIdentifierFile = - File(repoRoot, directory.text.toString()).findTillRoot(".gpg-id", repoRoot) - ?: File(repoRoot, ".gpg-id").apply { createNewFile() } - val gpgIdentifiers = - gpgIdentifierFile - .readLines() - .filter { it.isNotBlank() } - .map { line -> - GpgIdentifier.fromString(line) - ?: run { - // The line being empty means this is most likely an empty `.gpg-id` - // file we created. Skip the validation so we can make the user add a - // real ID. - if (line.isEmpty()) return@run - if (line.removePrefix("0x").matches("[a-fA-F0-9]{8}".toRegex()).not()) { - snackbar(message = resources.getString(R.string.invalid_gpg_id)) - } - return@with - } - } - .filterIsInstance() - if (gpgIdentifiers.isEmpty()) { - error("Failed to parse identifiers from .gpg-id: ${gpgIdentifierFile.readText()}") - } + val gpgIdentifiers = getGpgIdentifiers(directory.text.toString()) ?: return@with val content = "$editPass\n$editExtra" val path = when { @@ -483,23 +457,6 @@ class PasswordCreationActivity : BasePgpActivity() { } } - @Suppress("ReturnCount") - private fun File.findTillRoot(fileName: String, rootPath: File): File? { - val gpgFile = File(this, fileName) - if (gpgFile.exists()) return gpgFile - - if (this.absolutePath == rootPath.absolutePath) { - return null - } - - val parent = parentFile - return if (parent != null && parent.exists()) { - parent.findTillRoot(fileName, rootPath) - } else { - null - } - } - companion object { private const val KEY_PWGEN_TYPE_CLASSIC = "classic" -- cgit v1.2.3