refactor: consistently adopt PGP over GPG for naming

PGP is the standard, GPG is an implementation of it. We're adhering to PGP, and not using GPG.
This commit is contained in:
Harsh Shandilya 2023-06-15 15:49:32 +05:30
parent c168ce2e86
commit 5dac84c3c8
No known key found for this signature in database
19 changed files with 94 additions and 95 deletions

View file

@ -6,9 +6,9 @@
package app.passwordstore.data.crypto
import android.content.SharedPreferences
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.crypto.PGPDecryptOptions
import app.passwordstore.crypto.PGPEncryptOptions
import app.passwordstore.crypto.PGPIdentifier
import app.passwordstore.crypto.PGPKeyManager
import app.passwordstore.crypto.PGPainlessCryptoHandler
import app.passwordstore.crypto.errors.CryptoHandlerException
@ -40,20 +40,20 @@ constructor(
suspend fun decrypt(
password: String,
identities: List<GpgIdentifier>,
identities: List<PGPIdentifier>,
message: ByteArrayInputStream,
out: ByteArrayOutputStream,
) = withContext(dispatcherProvider.io()) { decryptPgp(password, identities, message, out) }
suspend fun encrypt(
identities: List<GpgIdentifier>,
identities: List<PGPIdentifier>,
content: ByteArrayInputStream,
out: ByteArrayOutputStream,
) = withContext(dispatcherProvider.io()) { encryptPgp(identities, content, out) }
private suspend fun decryptPgp(
password: String,
identities: List<GpgIdentifier>,
identities: List<PGPIdentifier>,
message: ByteArrayInputStream,
out: ByteArrayOutputStream,
): Result<Unit, CryptoHandlerException> {
@ -63,7 +63,7 @@ constructor(
}
private suspend fun encryptPgp(
identities: List<GpgIdentifier>,
identities: List<PGPIdentifier>,
content: ByteArrayInputStream,
out: ByteArrayOutputStream,
): Result<Unit, CryptoHandlerException> {

View file

@ -4,15 +4,14 @@ import android.content.Context
import androidx.core.content.edit
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.crypto.PGPIdentifier
import app.passwordstore.util.coroutines.DispatcherProvider
import app.passwordstore.util.extensions.getString
import javax.inject.Inject
import kotlinx.coroutines.withContext
/** Implements a rudimentary [EncryptedSharedPreferences]-backed cache for GPG passphrases. */
@Suppress("Unused") // Soon
class GPGPassphraseCache
class PGPPassphraseCache
@Inject
constructor(
private val dispatcherProvider: DispatcherProvider,
@ -20,7 +19,7 @@ constructor(
suspend fun cachePassphrase(
context: Context,
identifier: GpgIdentifier,
identifier: PGPIdentifier,
passphrase: String,
) {
withContext(dispatcherProvider.io()) {
@ -30,7 +29,7 @@ constructor(
suspend fun retrieveCachedPassphrase(
context: Context,
identifier: GpgIdentifier,
identifier: PGPIdentifier,
): String? {
return withContext(dispatcherProvider.io()) {
getPreferences(context).getString(identifier.toString())
@ -39,7 +38,7 @@ constructor(
suspend fun clearCachedPassphrase(
context: Context,
identifier: GpgIdentifier,
identifier: PGPIdentifier,
) {
withContext(dispatcherProvider.io()) {
getPreferences(context).edit { remove(identifier.toString()) }

View file

@ -7,7 +7,7 @@ package app.passwordstore.data.password
import android.content.Context
import android.content.Intent
import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.ui.crypto.BasePgpActivity
import app.passwordstore.ui.crypto.BasePGPActivity
import app.passwordstore.ui.main.LaunchActivity
import java.io.File
@ -21,7 +21,7 @@ data class PasswordItem(
val fullPathToParent = file.absolutePath.replace(rootDir.absolutePath, "").replace(file.name, "")
val longName = BasePgpActivity.getLongName(fullPathToParent, rootDir.absolutePath, toString())
val longName = BasePGPActivity.getLongName(fullPathToParent, rootDir.absolutePath, toString())
override fun equals(other: Any?): Boolean {
return (other is PasswordItem) && (other.file == file)

View file

@ -13,16 +13,16 @@ import android.os.Bundle
import android.view.autofill.AutofillManager
import androidx.lifecycle.lifecycleScope
import app.passwordstore.R
import app.passwordstore.data.crypto.GPGPassphraseCache
import app.passwordstore.data.crypto.PGPPassphraseCache
import app.passwordstore.data.passfile.PasswordEntry
import app.passwordstore.ui.crypto.BasePgpActivity
import app.passwordstore.ui.crypto.BasePGPActivity
import app.passwordstore.ui.crypto.PasswordDialog
import app.passwordstore.util.auth.BiometricAuthenticator
import app.passwordstore.util.autofill.AutofillPreferences
import app.passwordstore.util.autofill.AutofillResponseBuilder
import app.passwordstore.util.autofill.DirectoryStructure
import app.passwordstore.util.extensions.asLog
import app.passwordstore.util.features.Feature.EnableGPGPassphraseCache
import app.passwordstore.util.features.Feature.EnablePGPPassphraseCache
import app.passwordstore.util.features.Features
import com.github.androidpasswordstore.autofillparser.AutofillAction
import com.github.androidpasswordstore.autofillparser.Credentials
@ -41,11 +41,11 @@ import logcat.LogPriority.ERROR
import logcat.logcat
@AndroidEntryPoint
class AutofillDecryptActivity : BasePgpActivity() {
class AutofillDecryptActivity : BasePGPActivity() {
@Inject lateinit var passwordEntryFactory: PasswordEntry.Factory
@Inject lateinit var features: Features
@Inject lateinit var passphraseCache: GPGPassphraseCache
@Inject lateinit var passphraseCache: PGPPassphraseCache
private lateinit var directoryStructure: DirectoryStructure
@ -70,9 +70,9 @@ class AutofillDecryptActivity : BasePgpActivity() {
directoryStructure = AutofillPreferences.directoryStructure(this)
logcat { action.toString() }
requireKeysExist {
val gpgIdentifiers = getGpgIdentifiers("") ?: return@requireKeysExist
val gpgIdentifiers = getPGPIdentifiers("") ?: return@requireKeysExist
if (
features.isEnabled(EnableGPGPassphraseCache) && BiometricAuthenticator.canAuthenticate(this)
features.isEnabled(EnablePGPPassphraseCache) && BiometricAuthenticator.canAuthenticate(this)
) {
BiometricAuthenticator.authenticate(
this,
@ -143,7 +143,7 @@ class AutofillDecryptActivity : BasePgpActivity() {
}
private suspend fun decryptCredential(file: File, password: String): Credentials? {
val gpgIdentifiers = getGpgIdentifiers("") ?: return null
val gpgIdentifiers = getPGPIdentifiers("") ?: return null
runCatching { file.readBytes().inputStream() }
.onFailure { e ->
logcat(ERROR) { e.asLog("File to decrypt not found") }

View file

@ -18,7 +18,7 @@ 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.crypto.PGPIdentifier
import app.passwordstore.data.crypto.CryptoRepository
import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.injection.prefs.SettingsPreferences
@ -41,7 +41,7 @@ import kotlinx.coroutines.withContext
@Suppress("Registered")
@AndroidEntryPoint
open class BasePgpActivity : AppCompatActivity() {
open class BasePGPActivity : AppCompatActivity() {
/** Full path to the repository */
val repoPath by unsafeLazy { intent.getStringExtra("REPO_PATH")!! }
@ -110,12 +110,12 @@ open class BasePgpActivity : AppCompatActivity() {
val hasKeys = repository.hasKeys()
if (!hasKeys) {
withContext(dispatcherProvider.main()) {
MaterialAlertDialogBuilder(this@BasePgpActivity)
MaterialAlertDialogBuilder(this@BasePGPActivity)
.setTitle(resources.getString(R.string.no_keys_imported_dialog_title))
.setMessage(resources.getString(R.string.no_keys_imported_dialog_message))
.setPositiveButton(resources.getString(R.string.button_label_import)) { _, _ ->
onKeyImport = onKeysExist
keyImportAction.launch(Intent(this@BasePgpActivity, PGPKeyImportActivity::class.java))
keyImportAction.launch(Intent(this@BasePGPActivity, PGPKeyImportActivity::class.java))
}
.show()
}
@ -147,12 +147,12 @@ open class BasePgpActivity : AppCompatActivity() {
}
/**
* Get a list of available [GpgIdentifier]s for the current password repository. This method
* Get a list of available [PGPIdentifier]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<GpgIdentifier>? {
fun getPGPIdentifiers(subDir: String): List<PGPIdentifier>? {
val repoRoot = PasswordRepository.getRepositoryDirectory()
val gpgIdentifierFile =
File(repoRoot, subDir).findTillRoot(".gpg-id", repoRoot)
@ -162,7 +162,7 @@ open class BasePgpActivity : AppCompatActivity() {
.readLines()
.filter { it.isNotBlank() }
.map { line ->
GpgIdentifier.fromString(line)
PGPIdentifier.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
@ -176,7 +176,7 @@ open class BasePgpActivity : AppCompatActivity() {
return null
}
}
.filterIsInstance<GpgIdentifier>()
.filterIsInstance<PGPIdentifier>()
if (gpgIdentifiers.isEmpty()) {
error("Failed to parse identifiers from .gpg-id: ${gpgIdentifierFile.readText()}")
}

View file

@ -11,8 +11,8 @@ import android.view.Menu
import android.view.MenuItem
import androidx.lifecycle.lifecycleScope
import app.passwordstore.R
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.data.crypto.GPGPassphraseCache
import app.passwordstore.crypto.PGPIdentifier
import app.passwordstore.data.crypto.PGPPassphraseCache
import app.passwordstore.data.passfile.PasswordEntry
import app.passwordstore.data.password.FieldItem
import app.passwordstore.databinding.DecryptLayoutBinding
@ -21,7 +21,7 @@ import app.passwordstore.util.auth.BiometricAuthenticator
import app.passwordstore.util.extensions.getString
import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.extensions.viewBinding
import app.passwordstore.util.features.Feature.EnableGPGPassphraseCache
import app.passwordstore.util.features.Feature.EnablePGPPassphraseCache
import app.passwordstore.util.features.Features
import app.passwordstore.util.settings.Constants
import app.passwordstore.util.settings.PreferenceKeys
@ -42,10 +42,10 @@ import logcat.LogPriority.ERROR
import logcat.logcat
@AndroidEntryPoint
class DecryptActivity : BasePgpActivity() {
class DecryptActivity : BasePGPActivity() {
@Inject lateinit var passwordEntryFactory: PasswordEntry.Factory
@Inject lateinit var passphraseCache: GPGPassphraseCache
@Inject lateinit var passphraseCache: PGPPassphraseCache
@Inject lateinit var features: Features
private val binding by viewBinding(DecryptLayoutBinding::inflate)
@ -67,7 +67,7 @@ class DecryptActivity : BasePgpActivity() {
}
}
if (
features.isEnabled(EnableGPGPassphraseCache) &&
features.isEnabled(EnablePGPPassphraseCache) &&
BiometricAuthenticator.canAuthenticate(this@DecryptActivity)
) {
BiometricAuthenticator.authenticate(
@ -150,7 +150,7 @@ class DecryptActivity : BasePgpActivity() {
}
private fun decrypt(isError: Boolean, authResult: BiometricAuthenticator.Result) {
val gpgIdentifiers = getGpgIdentifiers("") ?: return
val gpgIdentifiers = getPGPIdentifiers("") ?: return
lifecycleScope.launch(dispatcherProvider.main()) {
if (authResult is BiometricAuthenticator.Result.Success) {
val cachedPassphrase =
@ -168,7 +168,7 @@ class DecryptActivity : BasePgpActivity() {
private fun askPassphrase(
isError: Boolean,
gpgIdentifiers: List<GpgIdentifier>,
gpgIdentifiers: List<PGPIdentifier>,
authResult: BiometricAuthenticator.Result,
) {
if (retries < MAX_RETRIES) {
@ -206,7 +206,7 @@ class DecryptActivity : BasePgpActivity() {
private suspend fun decryptWithCachedPassphrase(
passphrase: String,
identifiers: List<GpgIdentifier>,
identifiers: List<PGPIdentifier>,
authResult: BiometricAuthenticator.Result,
) {
when (val result = decryptWithPassphrase(passphrase, identifiers)) {
@ -225,7 +225,7 @@ class DecryptActivity : BasePgpActivity() {
private suspend fun decryptWithPassphrase(
password: String,
gpgIdentifiers: List<GpgIdentifier>,
gpgIdentifiers: List<PGPIdentifier>,
) = runCatching {
val message = withContext(dispatcherProvider.io()) { File(fullPath).readBytes().inputStream() }
val outputStream = ByteArrayOutputStream()

View file

@ -63,7 +63,7 @@ import logcat.asLog
import logcat.logcat
@AndroidEntryPoint
class PasswordCreationActivity : BasePgpActivity() {
class PasswordCreationActivity : BasePGPActivity() {
private val binding by viewBinding(PasswordCreationActivityBinding::inflate)
@Inject lateinit var passwordEntryFactory: PasswordEntry.Factory
@ -330,7 +330,7 @@ class PasswordCreationActivity : BasePgpActivity() {
}
// pass enters the key ID into `.gpg-id`.
val gpgIdentifiers = getGpgIdentifiers(directory.text.toString()) ?: return@with
val gpgIdentifiers = getPGPIdentifiers(directory.text.toString()) ?: return@with
val content = "$editPass\n$editExtra"
val path =
when {

View file

@ -11,7 +11,7 @@ import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.edit
import app.passwordstore.ui.crypto.BasePgpActivity
import app.passwordstore.ui.crypto.BasePGPActivity
import app.passwordstore.ui.crypto.DecryptActivity
import app.passwordstore.ui.passwords.PasswordStore
import app.passwordstore.util.auth.BiometricAuthenticator
@ -56,12 +56,12 @@ class LaunchActivity : AppCompatActivity() {
if (intent.action == ACTION_DECRYPT_PASS)
getDecryptIntent().apply {
putExtra(
BasePgpActivity.EXTRA_FILE_PATH,
intent.getStringExtra(BasePgpActivity.EXTRA_FILE_PATH)
BasePGPActivity.EXTRA_FILE_PATH,
intent.getStringExtra(BasePGPActivity.EXTRA_FILE_PATH)
)
putExtra(
BasePgpActivity.EXTRA_REPO_PATH,
intent.getStringExtra(BasePgpActivity.EXTRA_REPO_PATH)
BasePGPActivity.EXTRA_REPO_PATH,
intent.getStringExtra(BasePGPActivity.EXTRA_REPO_PATH)
)
}
else Intent(this, PasswordStore::class.java)

View file

@ -25,8 +25,8 @@ import androidx.lifecycle.lifecycleScope
import app.passwordstore.R
import app.passwordstore.data.password.PasswordItem
import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.ui.crypto.BasePgpActivity
import app.passwordstore.ui.crypto.BasePgpActivity.Companion.getLongName
import app.passwordstore.ui.crypto.BasePGPActivity
import app.passwordstore.ui.crypto.BasePGPActivity.Companion.getLongName
import app.passwordstore.ui.crypto.DecryptActivity
import app.passwordstore.ui.crypto.PasswordCreationActivity
import app.passwordstore.ui.dialogs.FolderCreationDialogFragment
@ -393,9 +393,9 @@ class PasswordStore : BaseGitActivity() {
val currentDir = currentDir
logcat(INFO) { "Adding file to : ${currentDir.absolutePath}" }
val intent = Intent(this, PasswordCreationActivity::class.java)
intent.putExtra(BasePgpActivity.EXTRA_FILE_PATH, currentDir.absolutePath)
intent.putExtra(BasePGPActivity.EXTRA_FILE_PATH, currentDir.absolutePath)
intent.putExtra(
BasePgpActivity.EXTRA_REPO_PATH,
BasePGPActivity.EXTRA_REPO_PATH,
PasswordRepository.getRepositoryDirectory().absolutePath
)
listRefreshAction.launch(intent)

View file

@ -32,7 +32,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import app.passwordstore.R
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.crypto.PGPIdentifier
import app.passwordstore.ui.compose.theme.APSThemePreview
import app.passwordstore.util.extensions.conditional
import kotlinx.collections.immutable.ImmutableList
@ -41,10 +41,10 @@ import kotlinx.collections.immutable.toPersistentList
@Composable
fun KeyList(
identifiers: ImmutableList<GpgIdentifier>,
onItemClick: (identifier: GpgIdentifier) -> Unit,
identifiers: ImmutableList<PGPIdentifier>,
onItemClick: (identifier: PGPIdentifier) -> Unit,
modifier: Modifier = Modifier,
onKeySelected: ((identifier: GpgIdentifier) -> Unit)? = null,
onKeySelected: ((identifier: PGPIdentifier) -> Unit)? = null,
) {
if (identifiers.isEmpty()) {
Column(
@ -69,10 +69,10 @@ fun KeyList(
@Composable
private fun KeyItem(
identifier: GpgIdentifier,
onItemClick: (identifier: GpgIdentifier) -> Unit,
identifier: PGPIdentifier,
onItemClick: (identifier: PGPIdentifier) -> Unit,
modifier: Modifier = Modifier,
onKeySelected: ((identifier: GpgIdentifier) -> Unit)? = null,
onKeySelected: ((identifier: PGPIdentifier) -> Unit)? = null,
) {
var isDeleting by remember { mutableStateOf(false) }
DeleteConfirmationDialog(
@ -85,8 +85,8 @@ private fun KeyItem(
)
val label =
when (identifier) {
is GpgIdentifier.KeyId -> identifier.id.toString()
is GpgIdentifier.UserId -> identifier.email
is PGPIdentifier.KeyId -> identifier.id.toString()
is PGPIdentifier.UserId -> identifier.email
}
Row(
modifier =
@ -144,8 +144,8 @@ private fun KeyListPreview() {
KeyList(
identifiers =
listOfNotNull(
GpgIdentifier.fromString("ultramicroscopicsilicovolcanoconiosis@example.com"),
GpgIdentifier.fromString("0xB950AE2813841585"),
PGPIdentifier.fromString("ultramicroscopicsilicovolcanoconiosis@example.com"),
PGPIdentifier.fromString("0xB950AE2813841585"),
)
.toPersistentList(),
onItemClick = {}

View file

@ -32,7 +32,7 @@ class PGPSettings(private val activity: FragmentActivity) : SettingsProvider {
titleRes = R.string.pref_pgp_ascii_armor_title
persistent = true
}
switch(Feature.EnableGPGPassphraseCache.configKey) {
switch(Feature.EnablePGPPassphraseCache.configKey) {
titleRes = R.string.pref_passphrase_cache_title
summaryRes = R.string.pref_passphrase_cache_summary
defaultValue = false

View file

@ -23,8 +23,8 @@ enum class Feature(
/** Opt into the new SSH layer implemented as a freestanding module. */
EnableNewSSHLayer(false, "enable_new_ssh"),
/** Opt into a cache layer for GPG passphrases. */
EnableGPGPassphraseCache(false, "enable_gpg_passphrase_cache"),
/** Opt into a cache layer for PGP passphrases. */
EnablePGPPassphraseCache(false, "enable_gpg_passphrase_cache"),
;
companion object {

View file

@ -5,8 +5,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.passwordstore.crypto.GpgIdentifier
import app.passwordstore.crypto.KeyUtils
import app.passwordstore.crypto.PGPIdentifier
import app.passwordstore.crypto.PGPKeyManager
import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok
@ -20,7 +20,7 @@ import kotlinx.coroutines.launch
@HiltViewModel
class PGPKeyListViewModel @Inject constructor(private val keyManager: PGPKeyManager) : ViewModel() {
var keys: ImmutableList<GpgIdentifier> by mutableStateOf(persistentListOf())
var keys: ImmutableList<PGPIdentifier> by mutableStateOf(persistentListOf())
init {
updateKeySet()
@ -40,7 +40,7 @@ class PGPKeyListViewModel @Inject constructor(private val keyManager: PGPKeyMana
}
}
fun deleteKey(identifier: GpgIdentifier) {
fun deleteKey(identifier: PGPIdentifier) {
viewModelScope.launch {
keyManager.removeKey(identifier)
updateKeySet()

View file

@ -5,8 +5,8 @@
package app.passwordstore.crypto
import app.passwordstore.crypto.GpgIdentifier.KeyId
import app.passwordstore.crypto.GpgIdentifier.UserId
import app.passwordstore.crypto.PGPIdentifier.KeyId
import app.passwordstore.crypto.PGPIdentifier.UserId
import com.github.michaelbull.result.get
import com.github.michaelbull.result.runCatching
import org.bouncycastle.openpgp.PGPKeyRing

View file

@ -8,11 +8,11 @@ package app.passwordstore.crypto
import java.util.Locale
import java.util.regex.Pattern
/** Supertype for valid identifiers of GPG keys. */
public sealed class GpgIdentifier {
/** Supertype for valid identifiers of PGP keys. */
public sealed class PGPIdentifier {
/** A [GpgIdentifier] that represents either a long key ID or a fingerprint. */
public data class KeyId(val id: Long) : GpgIdentifier() {
/** A [PGPIdentifier] that represents either a long key ID or a fingerprint. */
public data class KeyId(val id: Long) : PGPIdentifier() {
override fun toString(): String {
return convertKeyIdToHex(id)
}
@ -36,10 +36,10 @@ public sealed class GpgIdentifier {
}
/**
* A [GpgIdentifier] that represents the textual name/email combination corresponding to a key.
* A [PGPIdentifier] that represents the textual name/email combination corresponding to a key.
* Despite the [email] property in this class, the value is not guaranteed to be a valid email.
*/
public data class UserId(val email: String) : GpgIdentifier() {
public data class UserId(val email: String) : PGPIdentifier() {
override fun toString(): String {
return email
}
@ -53,10 +53,10 @@ public sealed class GpgIdentifier {
private const val TRUNCATED_FINGERPRINT_LENGTH = 16
/**
* Attempts to parse an untyped String identifier into a concrete subtype of [GpgIdentifier].
* Attempts to parse an untyped String identifier into a concrete subtype of [PGPIdentifier].
*/
@Suppress("ReturnCount")
public fun fromString(identifier: String): GpgIdentifier? {
public fun fromString(identifier: String): PGPIdentifier? {
if (identifier.isEmpty()) return null
// Match long key IDs:
// FF22334455667788 or 0xFF22334455667788

View file

@ -32,7 +32,7 @@ public class PGPKeyManager
constructor(
filesDir: String,
private val dispatcher: CoroutineDispatcher,
) : KeyManager<PGPKey, GpgIdentifier> {
) : KeyManager<PGPKey, PGPIdentifier> {
private val keyDir = File(filesDir, KEY_DIR_NAME)
@ -74,7 +74,7 @@ constructor(
}
/** @see KeyManager.removeKey */
override suspend fun removeKey(identifier: GpgIdentifier): Result<Unit, Throwable> =
override suspend fun removeKey(identifier: PGPIdentifier): Result<Unit, Throwable> =
withContext(dispatcher) {
runSuspendCatching {
if (!keyDirExists()) throw KeyDirectoryUnavailableException
@ -87,7 +87,7 @@ constructor(
}
/** @see KeyManager.getKeyById */
override suspend fun getKeyById(id: GpgIdentifier): Result<PGPKey, Throwable> =
override suspend fun getKeyById(id: PGPIdentifier): Result<PGPKey, Throwable> =
withContext(dispatcher) {
runSuspendCatching {
if (!keyDirExists()) throw KeyDirectoryUnavailableException
@ -97,14 +97,14 @@ constructor(
val matchResult =
when (id) {
is GpgIdentifier.KeyId -> {
is PGPIdentifier.KeyId -> {
val keyIdMatch =
keys
.map { key -> key to tryGetId(key) }
.firstOrNull { (_, keyId) -> keyId?.id == id.id }
keyIdMatch?.first
}
is GpgIdentifier.UserId -> {
is PGPIdentifier.UserId -> {
val selector = SelectUserId.byEmail(id.email)
val userIdMatch =
keys
@ -134,7 +134,7 @@ constructor(
}
/** @see KeyManager.getKeyById */
override suspend fun getKeyId(key: PGPKey): GpgIdentifier? = tryGetId(key)
override suspend fun getKeyId(key: PGPKey): PGPIdentifier? = tryGetId(key)
/** Checks if [keyDir] exists and attempts to create it if not. */
private fun keyDirExists(): Boolean {

View file

@ -18,7 +18,7 @@ class KeyUtilsTest {
assertIs<PGPSecretKeyRing>(keyring)
val keyId = tryGetId(key)
assertNotNull(keyId)
assertIs<GpgIdentifier.KeyId>(keyId)
assertIs<PGPIdentifier.KeyId>(keyId)
assertEquals("b950ae2813841585", keyId.toString())
}
}

View file

@ -9,33 +9,33 @@ import kotlin.test.Test
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
class GpgIdentifierTest {
class PGPIdentifierTest {
@Test
fun parseHexKeyIdWithout0xPrefix() {
val identifier = GpgIdentifier.fromString("79E8208280490C77")
val identifier = PGPIdentifier.fromString("79E8208280490C77")
assertNotNull(identifier)
assertTrue { identifier is GpgIdentifier.KeyId }
assertTrue { identifier is PGPIdentifier.KeyId }
}
@Test
fun parseHexKeyId() {
val identifier = GpgIdentifier.fromString("0x79E8208280490C77")
val identifier = PGPIdentifier.fromString("0x79E8208280490C77")
assertNotNull(identifier)
assertTrue { identifier is GpgIdentifier.KeyId }
assertTrue { identifier is PGPIdentifier.KeyId }
}
@Test
fun parseValidEmail() {
val identifier = GpgIdentifier.fromString("john.doe@example.org")
val identifier = PGPIdentifier.fromString("john.doe@example.org")
assertNotNull(identifier)
assertTrue { identifier is GpgIdentifier.UserId }
assertTrue { identifier is PGPIdentifier.UserId }
}
@Test
fun parseEmailWithoutTLD() {
val identifier = GpgIdentifier.fromString("john.doe@example")
val identifier = PGPIdentifier.fromString("john.doe@example")
assertNotNull(identifier)
assertTrue { identifier is GpgIdentifier.UserId }
assertTrue { identifier is PGPIdentifier.UserId }
}
}

View file

@ -1,8 +1,8 @@
package app.passwordstore.crypto
import app.passwordstore.crypto.GpgIdentifier.KeyId
import app.passwordstore.crypto.GpgIdentifier.UserId
import app.passwordstore.crypto.KeyUtils.tryGetId
import app.passwordstore.crypto.PGPIdentifier.KeyId
import app.passwordstore.crypto.PGPIdentifier.UserId
import app.passwordstore.crypto.errors.KeyAlreadyExistsException
import app.passwordstore.crypto.errors.KeyNotFoundException
import app.passwordstore.crypto.errors.NoKeysAvailableException