diff options
author | Harsh Shandilya <me@msfjarvis.dev> | 2022-10-07 19:41:14 +0530 |
---|---|---|
committer | Harsh Shandilya <me@msfjarvis.dev> | 2022-10-07 19:41:14 +0530 |
commit | b313c4216ea86d6202e2730b26e4fc3924d731eb (patch) | |
tree | 2affaf10d8c8216cc04e9d05b192dbb0251ed432 | |
parent | f778eab94e90c6f40f2aa4689d6e123d74aa9de4 (diff) |
fix(app): ensure decryption errors are captured by UI
-rw-r--r-- | app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt | 20 | ||||
-rw-r--r-- | app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt | 51 |
2 files changed, 36 insertions, 35 deletions
diff --git a/app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt b/app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt index d52574c9..b673e94c 100644 --- a/app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt +++ b/app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt @@ -8,6 +8,8 @@ package app.passwordstore.data.crypto import app.passwordstore.crypto.GpgIdentifier import app.passwordstore.crypto.PGPKeyManager import app.passwordstore.crypto.PGPainlessCryptoHandler +import app.passwordstore.crypto.errors.CryptoHandlerException +import com.github.michaelbull.result.Result import com.github.michaelbull.result.getAll import com.github.michaelbull.result.unwrap import java.io.ByteArrayInputStream @@ -27,34 +29,30 @@ constructor( password: String, message: ByteArrayInputStream, out: ByteArrayOutputStream, - ) { - withContext(Dispatchers.IO) { decryptPgp(password, message, out) } - } + ) = withContext(Dispatchers.IO) { decryptPgp(password, message, out) } suspend fun encrypt( identities: List<GpgIdentifier>, content: ByteArrayInputStream, out: ByteArrayOutputStream, - ) { - withContext(Dispatchers.IO) { encryptPgp(identities, content, out) } - } + ) = withContext(Dispatchers.IO) { encryptPgp(identities, content, out) } private suspend fun decryptPgp( password: String, message: ByteArrayInputStream, out: ByteArrayOutputStream, - ) { + ): Result<Unit, CryptoHandlerException> { val keys = pgpKeyManager.getAllKeys().unwrap() - pgpCryptoHandler.decrypt(keys, password, message, out) + return pgpCryptoHandler.decrypt(keys, password, message, out) } private suspend fun encryptPgp( identities: List<GpgIdentifier>, content: ByteArrayInputStream, out: ByteArrayOutputStream, - ) { - val keys = identities.map { ident -> pgpKeyManager.getKeyById(ident) }.getAll() - pgpCryptoHandler.encrypt( + ): Result<Unit, CryptoHandlerException> { + val keys = identities.map { id -> pgpKeyManager.getKeyById(id) }.getAll() + return pgpCryptoHandler.encrypt( keys, content, out, diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt index dfe9f8bc..bb3d2fdf 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt @@ -17,13 +17,13 @@ import app.passwordstore.data.password.FieldItem import app.passwordstore.databinding.DecryptLayoutBinding import app.passwordstore.ui.adapters.FieldItemAdapter import app.passwordstore.util.extensions.getString -import app.passwordstore.util.extensions.isErr import app.passwordstore.util.extensions.unsafeLazy import app.passwordstore.util.extensions.viewBinding import app.passwordstore.util.settings.Constants import app.passwordstore.util.settings.PreferenceKeys +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok import com.github.michaelbull.result.runCatching -import com.github.michaelbull.result.unwrapError import dagger.hilt.android.AndroidEntryPoint import java.io.ByteArrayOutputStream import java.io.File @@ -66,7 +66,7 @@ class DecryptActivity : BasePgpActivity() { true } } - decrypt(isError = false) + askPassphrase(isError = false) } override fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -137,7 +137,7 @@ class DecryptActivity : BasePgpActivity() { ) } - private fun decrypt(isError: Boolean) { + private fun askPassphrase(isError: Boolean) { if (retries < MAX_RETRIES) { retries += 1 } else { @@ -150,10 +150,17 @@ class DecryptActivity : BasePgpActivity() { lifecycleScope.launch(Dispatchers.Main) { dialog.password.collectLatest { value -> if (value != null) { - val res = runCatching { decrypt(value) } - if (res.isErr()) { - logcat(ERROR) { res.unwrapError().stackTraceToString() } - decrypt(isError = true) + when (val result = decryptWithPassphrase(value)) { + is Ok -> { + val entry = passwordEntryFactory.create(result.value.toByteArray()) + passwordEntry = entry + createPasswordUI(entry) + startAutoDismissTimer() + } + is Err -> { + logcat(ERROR) { result.error.stackTraceToString() } + askPassphrase(isError = true) + } } } } @@ -161,26 +168,22 @@ class DecryptActivity : BasePgpActivity() { dialog.show(supportFragmentManager, "PASSWORD_DIALOG") } - private suspend fun decrypt(password: String) { + private suspend fun decryptWithPassphrase(password: String) = runCatching { val message = withContext(Dispatchers.IO) { File(fullPath).readBytes().inputStream() } + val outputStream = ByteArrayOutputStream() val result = - withContext(Dispatchers.IO) { - val outputStream = ByteArrayOutputStream() - repository.decrypt( - password, - message, - outputStream, - ) - outputStream - } - startAutoDismissTimer() - - val entry = passwordEntryFactory.create(result.toByteArray()) - passwordEntry = entry - createPasswordUi(entry) + repository.decrypt( + password, + message, + outputStream, + ) + when (result) { + is Ok -> outputStream + is Err -> throw result.error + } } - private suspend fun createPasswordUi(entry: PasswordEntry) = + private suspend fun createPasswordUI(entry: PasswordEntry) = withContext(Dispatchers.Main) { val showPassword = settings.getBoolean(PreferenceKeys.SHOW_PASSWORD, true) invalidateOptionsMenu() |