diff options
author | Antoine A <> | 2024-01-24 11:59:25 +0100 |
---|---|---|
committer | Antoine A <> | 2024-01-24 11:59:25 +0100 |
commit | 7edfaa739f019e89e38e078cee08f33bfab0272b (patch) | |
tree | 23dc41ec1c0028dedec5987ec08f66cad33b47aa | |
parent | 5cc79b332d9595500290523e4c60cc877b0a237f (diff) | |
download | libeufin-7edfaa739f019e89e38e078cee08f33bfab0272b.tar.gz libeufin-7edfaa739f019e89e38e078cee08f33bfab0272b.tar.bz2 libeufin-7edfaa739f019e89e38e078cee08f33bfab0272b.zip |
Improve nexus keys files error logs
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt | 76 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/KeyFiles.kt | 219 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 144 | ||||
-rw-r--r-- | nexus/src/test/kotlin/CliTest.kt | 16 | ||||
-rw-r--r-- | nexus/src/test/kotlin/Keys.kt | 19 |
5 files changed, 247 insertions, 227 deletions
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt index 11fe512c..dc742111 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt @@ -32,51 +32,10 @@ import tech.libeufin.common.* import tech.libeufin.ebics.* import tech.libeufin.ebics.ebics_h004.HTDResponseOrderData import java.time.Instant -import kotlin.reflect.typeOf -import java.nio.file.Files -import java.nio.file.StandardCopyOption +import java.nio.file.* import kotlin.io.path.* /** - * Writes the JSON content to disk. Used when we create or update - * keys and other metadata JSON content to disk. WARNING: this overrides - * silently what's found under the given location! - * - * @param obj the class representing the JSON content to store to disk. - * @param path where to store `obj` - */ -inline fun <reified T> syncJsonToDisk(obj: T, path: String) { - val content = try { - myJson.encodeToString(obj) - } catch (e: Exception) { - throw Exception("Could not encode the input '${typeOf<T>()}' to JSON", e) - } - try { - // Write to temp file then rename to enable atomicity when possible - val path = Path(path).absolute() - val tmp = Files.createTempFile(path.parent, "tmp_", "_${path.fileName}") - tmp.writeText(content) - tmp.moveTo(path, StandardCopyOption.REPLACE_EXISTING); - } catch (e: Exception) { - throw Exception("Could not write JSON content at $path", e) - } -} - -/** - * Generates new client private keys. - * - * @return [ClientPrivateKeysFile] - */ -fun generateNewKeys(): ClientPrivateKeysFile = - ClientPrivateKeysFile( - authentication_private_key = CryptoUtil.generateRsaKeyPair(2048).private, - encryption_private_key = CryptoUtil.generateRsaKeyPair(2048).private, - signature_private_key = CryptoUtil.generateRsaKeyPair(2048).private, - submitted_hia = false, - submitted_ini = false - ) - -/** * Obtains the client private keys, regardless of them being * created for the first time, or read from an existing file * on disk. @@ -84,20 +43,15 @@ fun generateNewKeys(): ClientPrivateKeysFile = * @param path path to the file that contains the keys. * @return current or new client keys */ -private fun preparePrivateKeys(path: String): ClientPrivateKeysFile { +private fun loadOrGenerateClientKeys(path: String): ClientPrivateKeysFile { // If exists load from disk - val current = loadPrivateKeysFromDisk(path) + val current = loadClientKeys(path) if (current != null) return current // Else create new keys - try { - val newKeys = generateNewKeys() - syncJsonToDisk(newKeys, path) - logger.info("New client keys created at: $path") - return newKeys - } catch (e: Exception) { - throw Exception("Could not create client keys at $path", e) - // TODO Better log - } + val newKeys = generateNewKeys() + persistClientKeys(newKeys, path) + logger.info("New client private keys created at '$path'") + return newKeys } /** @@ -159,7 +113,7 @@ private fun handleHpbResponse( val hpbObj = try { parseEbicsHpbOrder(hpbBytes) } catch (e: Exception) { - throw Exception("HPB response content seems invalid: e") + throw Exception("HPB response content seems invalid", e) } val encPub = try { CryptoUtil.loadRsaPublicKey(hpbObj.encryptionPubKey.encoded) @@ -176,11 +130,7 @@ private fun handleHpbResponse( bank_encryption_public_key = encPub, accepted = false ) - try { - syncJsonToDisk(json, cfg.bankPublicKeysFilename) - } catch (e: Exception) { - throw Exception("Failed to persist the bank keys to disk", e) - } + persistBankKeys(json, cfg.bankPublicKeysFilename) } /** @@ -201,7 +151,7 @@ suspend fun doKeysRequestAndUpdateState( client: HttpClient, orderType: KeysOrderType ) { - logger.debug("Doing key request ${orderType.name}") + logger.info("Doing key request ${orderType.name}") val req = when(orderType) { KeysOrderType.INI -> generateIniMessage(cfg, privs) KeysOrderType.HIA -> generateHiaMessage(cfg, privs) @@ -228,7 +178,7 @@ suspend fun doKeysRequestAndUpdateState( KeysOrderType.HPB -> return handleHpbResponse(cfg, ebics) } try { - syncJsonToDisk(privs, cfg.clientPrivateKeysFilename) + persistClientKeys(privs, cfg.clientPrivateKeysFilename) } catch (e: Exception) { throw Exception("Could not update the ${orderType.name} state on disk", e) } @@ -286,7 +236,7 @@ class EbicsSetup: CliktCommand("Set up the EBICS subscriber") { override fun run() = cliCmd(logger, common.log) { val cfg = extractEbicsConfig(common.config) // Config is sane. Go (maybe) making the private keys. - val clientKeys = preparePrivateKeys(cfg.clientPrivateKeysFilename) + val clientKeys = loadOrGenerateClientKeys(cfg.clientPrivateKeysFilename) val httpClient = HttpClient() // Privs exist. Upload their pubs val keysNotSub = !clientKeys.submitted_ini || !clientKeys.submitted_hia @@ -330,7 +280,7 @@ class EbicsSetup: CliktCommand("Set up the EBICS subscriber") { throw Exception("Cannot successfully finish the setup without accepting the bank keys.") } try { - syncJsonToDisk(bankKeysMaybe, cfg.bankPublicKeysFilename) + persistBankKeys(bankKeysMaybe, cfg.bankPublicKeysFilename) } catch (e: Exception) { throw Exception("Could not set bank keys as accepted on disk.", e) } diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/KeyFiles.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/KeyFiles.kt new file mode 100644 index 00000000..14b88b42 --- /dev/null +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/KeyFiles.kt @@ -0,0 +1,219 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2023 Stanisci and Dold. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ + +package tech.libeufin.nexus + +import kotlinx.serialization.* +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.SerializersModule +import java.security.interfaces.RSAPrivateCrtKey +import java.security.interfaces.RSAPublicKey +import tech.libeufin.common.* +import java.nio.file.* +import kotlin.io.path.* +import java.io.File +import kotlin.reflect.typeOf + +val JSON = Json { + this.serializersModule = SerializersModule { + contextual(RSAPrivateCrtKey::class) { RSAPrivateCrtKeySerializer } + contextual(RSAPublicKey::class) { RSAPublicKeySerializer } + } +} + +/** + * Converts base 32 representation of RSA public keys and vice versa. + */ +object RSAPublicKeySerializer : KSerializer<RSAPublicKey> { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("RSAPublicKey", PrimitiveKind.STRING) + override fun serialize(encoder: Encoder, value: RSAPublicKey) { + encoder.encodeString(Base32Crockford.encode(value.encoded)) + } + + // Caller must handle exceptions here. + override fun deserialize(decoder: Decoder): RSAPublicKey { + val fieldValue = decoder.decodeString() + val bytes = Base32Crockford.decode(fieldValue) + return CryptoUtil.loadRsaPublicKey(bytes) + } +} + +/** + * Converts base 32 representation of RSA private keys and vice versa. + */ +object RSAPrivateCrtKeySerializer : KSerializer<RSAPrivateCrtKey> { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("RSAPrivateCrtKey", PrimitiveKind.STRING) + override fun serialize(encoder: Encoder, value: RSAPrivateCrtKey) { + encoder.encodeString(Base32Crockford.encode(value.encoded)) + } + + // Caller must handle exceptions here. + override fun deserialize(decoder: Decoder): RSAPrivateCrtKey { + val fieldValue = decoder.decodeString() + val bytes = Base32Crockford.decode(fieldValue) + return CryptoUtil.loadRsaPrivateKey(bytes) + } +} + +/** + * Structure of the JSON file that contains the client + * private keys on disk. + */ +@Serializable +data class ClientPrivateKeysFile( + @Contextual val signature_private_key: RSAPrivateCrtKey, + @Contextual val encryption_private_key: RSAPrivateCrtKey, + @Contextual val authentication_private_key: RSAPrivateCrtKey, + var submitted_ini: Boolean, + var submitted_hia: Boolean +) + +/** + * Structure of the JSON file that contains the bank + * public keys on disk. + */ +@Serializable +data class BankPublicKeysFile( + @Contextual val bank_encryption_public_key: RSAPublicKey, + @Contextual val bank_authentication_public_key: RSAPublicKey, + var accepted: Boolean +) + +/** + * Generates new client private keys. + * + * @return [ClientPrivateKeysFile] + */ +fun generateNewKeys(): ClientPrivateKeysFile = + ClientPrivateKeysFile( + authentication_private_key = CryptoUtil.generateRsaKeyPair(2048).private, + encryption_private_key = CryptoUtil.generateRsaKeyPair(2048).private, + signature_private_key = CryptoUtil.generateRsaKeyPair(2048).private, + submitted_hia = false, + submitted_ini = false + ) + +private inline fun <reified T> persistJsonFile(obj: T, path: String, name: String) { + val content = try { + JSON.encodeToString(obj) + } catch (e: Exception) { + throw Exception("Could not encode '${typeOf<T>()}' to JSON", e) + } + val (path, parent) = try { + val path = Path(path) + Pair(path, path.parent ?: path.absolute().parent) + } catch (e: Exception) { + throw Exception("Could not write $name at '$path'", e) + } + try { + // Write to temp file then rename to enable atomicity when possible + val tmp = Files.createTempFile(parent, "tmp_", "_${path.fileName}") + tmp.writeText(content) + tmp.moveTo(path, StandardCopyOption.REPLACE_EXISTING); + } catch (e: Exception) { + when { + !parent.toFile().canWrite() -> throw Exception("Could not write $name at '$path': permission denied on '$parent'") + !path.toFile().canWrite() -> throw Exception("Could not write $name at '$path': permission denied") + else -> throw Exception("Could not write $name at '$path'", e) + } + throw Exception("Could not write $name at '$path'", e) + } +} + +/** + * Persist the bank keys file to disk + * + * @param location the keys file location + */ +fun persistBankKeys(keys: BankPublicKeysFile, location: String) = persistJsonFile(keys, location, "bank public keys") + +/** + * Persist the client keys file to disk + * + * @param location the keys file location + */ +fun persistClientKeys(keys: ClientPrivateKeysFile, location: String) = persistJsonFile(keys, location, "client private keys") + + +private inline fun <reified T> loadJsonFile(path: String, name: String): T? { + val content = try { + val path = Path(path) + path.readText() + } catch (e: Exception) { + when { + e is NoSuchFileException -> return null + e is AccessDeniedException -> throw Exception("Could not read $name at '$path': permission denied") + else -> throw Exception("Could not read $name at '$path'", e) + } + } + return try { + JSON.decodeFromString(content) + } catch (e: Exception) { + throw Exception("Could not decode $name at '$path'", e) + } +} + +/** + * Load the bank keys file from disk. + * + * @param location the keys file location. + * @return the internal JSON representation of the keys file, + * or null if the file does not exist + */ +fun loadBankKeys(location: String): BankPublicKeysFile? = loadJsonFile(location, "bank public keys") + +/** + * Load the client keys file from disk. + * + * @param location the keys file location. + * @return the internal JSON representation of the keys file, + * or null if the file does not exist + */ +fun loadClientKeys(location: String): ClientPrivateKeysFile? = loadJsonFile(location, "client private keys") + +/** + * Load client and bank keys from disk. + * Checks that the keying process has been fully completed. + * + * Helps to fail before starting to talk EBICS to the bank. + * + * @param cfg configuration handle. + * @return both client and bank keys + */ +fun expectFullKeys( + cfg: EbicsSetupConfig +): Pair<ClientPrivateKeysFile, BankPublicKeysFile> { + val clientKeys = loadClientKeys(cfg.clientPrivateKeysFilename) + if (clientKeys == null) { + throw Exception("Missing client private keys file at '${cfg.clientPrivateKeysFilename}', run 'libeufin-nexus ebics-setup' first") + } else if (!clientKeys.submitted_ini || !clientKeys.submitted_hia) { + throw Exception("Unsubmitted client private keys, run 'libeufin-nexus ebics-setup' first") + } + val bankKeys = loadBankKeys(cfg.bankPublicKeysFilename) + if (bankKeys == null) { + throw Exception("Missing bank public keys at '${cfg.bankPublicKeysFilename}', run 'libeufin-nexus ebics-setup' first") + } else if (!bankKeys.accepted) { + throw Exception("Unaccepted bank public keys, run 'libeufin-nexus ebics-setup' until accepting the bank keys") + } + return Pair(clientKeys, bankKeys) +}
\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt index 607e39c1..4d27910a 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -29,33 +29,13 @@ import com.github.ajalt.clikt.core.subcommands import com.github.ajalt.clikt.parameters.options.versionOption import io.ktor.client.* import io.ktor.util.* -import kotlinx.serialization.Contextual -import kotlinx.serialization.KSerializer import org.slf4j.Logger import org.slf4j.LoggerFactory -import java.io.File -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.json.Json -import kotlinx.serialization.modules.SerializersModule import tech.libeufin.nexus.ebics.* import tech.libeufin.common.* -import java.security.interfaces.RSAPrivateCrtKey -import java.security.interfaces.RSAPublicKey -import java.io.FileNotFoundException val NEXUS_CONFIG_SOURCE = ConfigSource("libeufin", "libeufin-nexus", "libeufin-nexus") val logger: Logger = LoggerFactory.getLogger("libeufin-nexus") -val myJson = Json { - this.serializersModule = SerializersModule { - contextual(RSAPrivateCrtKey::class) { RSAPrivateCrtKeySerializer } - contextual(RSAPublicKey::class) { RSAPublicKeySerializer } - } -} /** * Triple identifying one IBAN bank account. @@ -210,130 +190,6 @@ class EbicsSetupConfig(val config: TalerConfig) { } /** - * Converts base 32 representation of RSA public keys and vice versa. - */ -object RSAPublicKeySerializer : KSerializer<RSAPublicKey> { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("RSAPublicKey", PrimitiveKind.STRING) - override fun serialize(encoder: Encoder, value: RSAPublicKey) { - encoder.encodeString(Base32Crockford.encode(value.encoded)) - } - - // Caller must handle exceptions here. - override fun deserialize(decoder: Decoder): RSAPublicKey { - val fieldValue = decoder.decodeString() - val bytes = Base32Crockford.decode(fieldValue) - return CryptoUtil.loadRsaPublicKey(bytes) - } -} - -/** - * Converts base 32 representation of RSA private keys and vice versa. - */ -object RSAPrivateCrtKeySerializer : KSerializer<RSAPrivateCrtKey> { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("RSAPrivateCrtKey", PrimitiveKind.STRING) - override fun serialize(encoder: Encoder, value: RSAPrivateCrtKey) { - encoder.encodeString(Base32Crockford.encode(value.encoded)) - } - - // Caller must handle exceptions here. - override fun deserialize(decoder: Decoder): RSAPrivateCrtKey { - val fieldValue = decoder.decodeString() - val bytes = Base32Crockford.decode(fieldValue) - return CryptoUtil.loadRsaPrivateKey(bytes) - } -} - -/** - * Structure of the JSON file that contains the client - * private keys on disk. - */ -@Serializable -data class ClientPrivateKeysFile( - @Contextual val signature_private_key: RSAPrivateCrtKey, - @Contextual val encryption_private_key: RSAPrivateCrtKey, - @Contextual val authentication_private_key: RSAPrivateCrtKey, - var submitted_ini: Boolean, - var submitted_hia: Boolean -) - -/** - * Structure of the JSON file that contains the bank - * public keys on disk. - */ -@Serializable -data class BankPublicKeysFile( - @Contextual val bank_encryption_public_key: RSAPublicKey, - @Contextual val bank_authentication_public_key: RSAPublicKey, - var accepted: Boolean -) - -/** - * Load client and bank keys from disk. - * Checks that the keying process has been fully completed. - * - * Helps to fail before starting to talk EBICS to the bank. - * - * @param cfg configuration handle. - * @return both client and bank keys - */ -fun expectFullKeys( - cfg: EbicsSetupConfig -): Pair<ClientPrivateKeysFile, BankPublicKeysFile> { - val clientKeys = loadPrivateKeysFromDisk(cfg.clientPrivateKeysFilename) - if (clientKeys == null) { - throw Exception("Missing client private keys file at '${cfg.clientPrivateKeysFilename}', run 'libeufin-nexus ebics-setup' first") - } else if (!clientKeys.submitted_ini || !clientKeys.submitted_hia) { - throw Exception("Unsubmitted client private keys, run 'libeufin-nexus ebics-setup' first") - } - val bankKeys = loadBankKeys(cfg.bankPublicKeysFilename) - if (bankKeys == null) { - throw Exception("Missing bank public keys at '${cfg.bankPublicKeysFilename}', run 'libeufin-nexus ebics-setup' first") - } else if (!bankKeys.accepted) { - throw Exception("Unaccepted bank public keys, run 'libeufin-nexus ebics-setup' until accepting the bank keys") - } - return Pair(clientKeys, bankKeys) -} - -private inline fun <reified T> loadJsonFile(path: String, name: String): T? { - val file = File(path) - val content = try { - file.readText() - } catch (e: Exception) { - // FileNotFoundException can be thrown if the file exists, but is not accessible... - when { - !file.exists() -> return null - !file.canRead() -> throw Exception("Could not read $name at '$path': permission denied") - else -> throw Exception("Could not read $name at '$path'", e) - } - } - return try { - myJson.decodeFromString(content) - } catch (e: Exception) { - throw Exception("Could not decode $name at '$path'", e) - } -} - -/** - * Load the bank keys file from disk. - * - * @param location the keys file location. - * @return the internal JSON representation of the keys file, - * or null if the file does not exist - */ -fun loadBankKeys(location: String): BankPublicKeysFile? = loadJsonFile(location, "bank public keys") - -/** - * Load the client keys file from disk. - * - * @param location the keys file location. - * @return the internal JSON representation of the keys file, - * or null if the file does not exist - */ -fun loadPrivateKeysFromDisk(location: String): ClientPrivateKeysFile? = loadJsonFile(location, "client private keys") - -/** * Abstracts the config loading * * @param configFile potentially NULL configuration file location. diff --git a/nexus/src/test/kotlin/CliTest.kt b/nexus/src/test/kotlin/CliTest.kt index a57088c7..e53db43e 100644 --- a/nexus/src/test/kotlin/CliTest.kt +++ b/nexus/src/test/kotlin/CliTest.kt @@ -52,8 +52,9 @@ class CliTest { val cfg = loadConfig(conf) val clientKeysPath = Path(cfg.requireString("nexus-ebics", "client_private_keys_file")) val bankKeysPath = Path(cfg.requireString("nexus-ebics", "bank_public_keys_file")) - clientKeysPath.parent?.createDirectories() - bankKeysPath.parent?.createDirectories() + clientKeysPath.parent!!.createDirectories() + clientKeysPath.parent!!.toFile().setWritable(true) + bankKeysPath.parent!!.createDirectories() // Missing client keys clientKeysPath.deleteIfExists() @@ -71,13 +72,13 @@ class CliTest { nexusCmd.testErr("$cmd -c $conf", "Could not read client private keys at '$clientKeysPath': permission denied") } // Unfinished client - syncJsonToDisk(generateNewKeys(), clientKeysPath.toString()) + persistClientKeys(generateNewKeys(), clientKeysPath.toString()) for (cmd in cmds) { nexusCmd.testErr("$cmd -c $conf", "Unsubmitted client private keys, run 'libeufin-nexus ebics-setup' first") } // Missing bank keys - syncJsonToDisk(generateNewKeys().apply { + persistClientKeys(generateNewKeys().apply { submitted_hia = true submitted_ini = true }, clientKeysPath.toString()) @@ -96,7 +97,7 @@ class CliTest { nexusCmd.testErr("$cmd -c $conf", "Could not read bank public keys at '$bankKeysPath': permission denied") } // Unfinished bank - syncJsonToDisk(BankPublicKeysFile( + persistBankKeys(BankPublicKeysFile( bank_authentication_public_key = CryptoUtil.generateRsaKeyPair(2048).public, bank_encryption_public_key = CryptoUtil.generateRsaKeyPair(2048).public, accepted = false @@ -104,5 +105,10 @@ class CliTest { for (cmd in cmds) { nexusCmd.testErr("$cmd -c $conf", "Unaccepted bank public keys, run 'libeufin-nexus ebics-setup' until accepting the bank keys") } + + // Missing permission + clientKeysPath.deleteIfExists() + clientKeysPath.parent!!.toFile().setWritable(false) + nexusCmd.testErr("ebics-setup -c $conf", "Could not write client private keys at '$clientKeysPath': permission denied on '${clientKeysPath.parent}'") } }
\ No newline at end of file diff --git a/nexus/src/test/kotlin/Keys.kt b/nexus/src/test/kotlin/Keys.kt index 41b6b11f..ededc7a5 100644 --- a/nexus/src/test/kotlin/Keys.kt +++ b/nexus/src/test/kotlin/Keys.kt @@ -42,7 +42,7 @@ class PublicKeys { bank_encryption_public_key = CryptoUtil.generateRsaKeyPair(2028).public ) // storing them on disk. - syncJsonToDisk(fileContent, "/tmp/nexus-tests-bank-keys.json") + persistBankKeys(fileContent, "/tmp/nexus-tests-bank-keys.json") // loading them and check that values are the same. val fromDisk = loadBankKeys("/tmp/nexus-tests-bank-keys.json") assertNotNull(fromDisk) @@ -64,17 +64,6 @@ class PrivateKeys { f.delete() } - // Testing write failure due to insufficient permissions. - @Test - fun createWrongPermissions() { - f.writeText("won't be overridden") - f.setReadOnly() - try { - syncJsonToDisk(clientKeys, f.path) - throw Exception("Should have failed") - } catch (e: Exception) { } - } - /** * Tests whether loading keys from disk yields the same * values that were stored to the file. @@ -82,8 +71,8 @@ class PrivateKeys { @Test fun load() { assertFalse(f.exists()) - syncJsonToDisk(clientKeys, f.path) // Artificially storing this to the file. - val fromDisk = loadPrivateKeysFromDisk(f.path) // loading it via the tested routine. + persistClientKeys(clientKeys, f.path) // Artificially storing this to the file. + val fromDisk = loadClientKeys(f.path) // loading it via the tested routine. assertNotNull(fromDisk) // Checking the values from disk match the initial object. assertTrue { @@ -98,6 +87,6 @@ class PrivateKeys { // Testing failure on file not found. @Test fun loadNotFound() { - assertNull(loadPrivateKeysFromDisk("/tmp/highly-unlikely-to-be-found.json")) + assertNull(loadClientKeys("/tmp/highly-unlikely-to-be-found.json")) } }
\ No newline at end of file |