summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2022-10-07 19:41:14 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2022-10-07 19:41:14 +0530
commitb313c4216ea86d6202e2730b26e4fc3924d731eb (patch)
tree2affaf10d8c8216cc04e9d05b192dbb0251ed432
parentf778eab94e90c6f40f2aa4689d6e123d74aa9de4 (diff)
fix(app): ensure decryption errors are captured by UI
-rw-r--r--app/src/main/java/app/passwordstore/data/crypto/CryptoRepository.kt20
-rw-r--r--app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt51
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()