From 36b45f90f90e76ca2611e9cfcca9a6ee440683b3 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Fri, 31 May 2024 17:30:59 +0530 Subject: refactor: migrate to NIO --- .../app/passwordstore/crypto/PGPKeyManager.kt | 32 +++++++++++++--------- .../app/passwordstore/crypto/PGPKeyManagerTest.kt | 16 ++++++----- 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'crypto/pgpainless') diff --git a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt index cbaa110d..8efa2a97 100644 --- a/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt +++ b/crypto/pgpainless/src/main/kotlin/app/passwordstore/crypto/PGPKeyManager.kt @@ -19,9 +19,17 @@ import app.passwordstore.crypto.errors.NoKeysAvailableException import app.passwordstore.crypto.errors.UnusableKeyException import com.github.michaelbull.result.Result import com.github.michaelbull.result.coroutines.runSuspendCatching +import com.github.michaelbull.result.runCatching import com.github.michaelbull.result.unwrap -import java.io.File +import java.nio.file.Paths import javax.inject.Inject +import kotlin.io.path.createDirectories +import kotlin.io.path.deleteIfExists +import kotlin.io.path.exists +import kotlin.io.path.isRegularFile +import kotlin.io.path.listDirectoryEntries +import kotlin.io.path.readBytes +import kotlin.io.path.writeBytes import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext import org.bouncycastle.openpgp.PGPPublicKeyRing @@ -34,7 +42,7 @@ public class PGPKeyManager constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : KeyManager { - private val keyDir = File(filesDir, KEY_DIR_NAME) + private val keyDir = Paths.get(filesDir, KEY_DIR_NAME) /** @see KeyManager.addKey */ override suspend fun addKey(key: PGPKey, replace: Boolean): Result = @@ -43,7 +51,7 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : if (!keyDirExists()) throw KeyDirectoryUnavailableException val incomingKeyRing = tryParseKeyring(key) ?: throw InvalidKeyException if (!isKeyUsable(key)) throw UnusableKeyException - val keyFile = File(keyDir, "${tryGetId(key)}.$KEY_EXTENSION") + val keyFile = keyDir.resolve("${tryGetId(key)}.$KEY_EXTENSION") if (keyFile.exists()) { val existingKeyBytes = keyFile.readBytes() val existingKeyRing = @@ -65,7 +73,7 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : throw KeyAlreadyExistsException( tryGetId(key)?.toString() ?: "Failed to retrieve key ID" ) - if (!keyFile.delete()) throw KeyDeletionFailedException + if (!keyFile.deleteIfExists()) throw KeyDeletionFailedException } keyFile.writeBytes(key.contents) @@ -80,10 +88,8 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : runSuspendCatching { if (!keyDirExists()) throw KeyDirectoryUnavailableException val key = getKeyById(identifier).unwrap() - val keyFile = File(keyDir, "${tryGetId(key)}.$KEY_EXTENSION") - if (keyFile.exists()) { - if (!keyFile.delete()) throw KeyDeletionFailedException - } + val keyFile = keyDir.resolve("${tryGetId(key)}.$KEY_EXTENSION") + if (!keyFile.deleteIfExists()) throw KeyDeletionFailedException } } @@ -92,8 +98,8 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : withContext(dispatcher) { runSuspendCatching { if (!keyDirExists()) throw KeyDirectoryUnavailableException - val keyFiles = keyDir.listFiles() - if (keyFiles.isNullOrEmpty()) throw NoKeysAvailableException + val keyFiles = keyDir.listDirectoryEntries().filter { it.isRegularFile() } + if (keyFiles.isEmpty()) throw NoKeysAvailableException val keys = keyFiles.map { file -> PGPKey(file.readBytes()) } val matchResult = @@ -128,8 +134,8 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : withContext(dispatcher) { runSuspendCatching { if (!keyDirExists()) throw KeyDirectoryUnavailableException - val keyFiles = keyDir.listFiles() - if (keyFiles.isNullOrEmpty()) return@runSuspendCatching emptyList() + val keyFiles = keyDir.listDirectoryEntries().filter { it.isRegularFile() } + if (keyFiles.isEmpty()) return@runSuspendCatching emptyList() keyFiles.map { keyFile -> PGPKey(keyFile.readBytes()) }.toList() } } @@ -139,7 +145,7 @@ constructor(filesDir: String, private val dispatcher: CoroutineDispatcher) : /** Checks if [keyDir] exists and attempts to create it if not. */ private fun keyDirExists(): Boolean { - return keyDir.exists() || keyDir.mkdirs() + return keyDir.exists() || runCatching { keyDir.createDirectories() }.isOk } public companion object { diff --git a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt index 8893d0eb..8f4452c8 100644 --- a/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt +++ b/crypto/pgpainless/src/test/kotlin/app/passwordstore/crypto/PGPKeyManagerTest.kt @@ -9,7 +9,9 @@ import app.passwordstore.crypto.errors.NoKeysAvailableException import app.passwordstore.crypto.errors.UnusableKeyException import com.github.michaelbull.result.unwrap import com.github.michaelbull.result.unwrapError -import java.io.File +import kotlin.io.path.absolutePathString +import kotlin.io.path.listDirectoryEntries +import kotlin.io.path.name import kotlin.test.Test import kotlin.test.assertContentEquals import kotlin.test.assertEquals @@ -26,9 +28,9 @@ class PGPKeyManagerTest { @get:Rule val temporaryFolder: TemporaryFolder = TemporaryFolder() private val dispatcher = StandardTestDispatcher() - private val filesDir by unsafeLazy { temporaryFolder.root } - private val keysDir by unsafeLazy { File(filesDir, PGPKeyManager.KEY_DIR_NAME) } - private val keyManager by unsafeLazy { PGPKeyManager(filesDir.absolutePath, dispatcher) } + private val filesDir by unsafeLazy { temporaryFolder.root.toPath() } + private val keysDir by unsafeLazy { filesDir.resolve(PGPKeyManager.KEY_DIR_NAME) } + private val keyManager by unsafeLazy { PGPKeyManager(filesDir.absolutePathString(), dispatcher) } private val secretKey = PGPKey(TestUtils.getArmoredSecretKey()) private val publicKey = PGPKey(TestUtils.getArmoredPublicKey()) @@ -42,10 +44,10 @@ class PGPKeyManagerTest { val keyId = keyManager.getKeyId(keyManager.addKey(secretKey).unwrap()) assertEquals(KeyId(CryptoConstants.KEY_ID), keyId) // Check if the keys directory have one file - assertEquals(1, filesDir.list()?.size) + assertEquals(1, filesDir.listDirectoryEntries().size) // Check if the file name is correct - val keyFile = keysDir.listFiles()?.first() - assertEquals(keyFile?.name, "$keyId.${PGPKeyManager.KEY_EXTENSION}") + val keyFile = keysDir.listDirectoryEntries().first() + assertEquals(keyFile.name, "$keyId.${PGPKeyManager.KEY_EXTENSION}") } @Test -- cgit v1.2.3