commit 0f45089ada0c1eac60120c6b4b0914ce10d788bc
parent c7471702ab241ab16b0ad6c13a22201c4077c1e0
Author: Antoine A <>
Date: Wed, 28 Aug 2024 19:13:11 +0200
common: improve and fix CLI
Diffstat:
7 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
@@ -124,6 +124,16 @@ sealed class Option<out T> {
return Some(valueSerializer.deserialize(decoder))
}
}
+
+ companion object {
+ fun <T> invert(optional: Option<T>?): Option<T?> {
+ return when (optional) {
+ null -> Option.None
+ is Option.None -> Option.Some(null)
+ is Option.Some -> Option.Some(optional.value)
+ }
+ }
+ }
}
@Serializable
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt
@@ -273,6 +273,12 @@ suspend fun patchAccount(
"'admin' account cannot be public",
TalerErrorCode.END
)
+
+ if (login == "exchange" && req.is_taler_exchange == false)
+ throw conflict(
+ "'exchange' account must be a taler exchange account",
+ TalerErrorCode.END
+ )
if (req.tan_channel is Option.Some && req.tan_channel.value != null && !cfg.tanChannels.contains(req.tan_channel.value)) {
throw unsupportedTanChannel(req.tan_channel.value)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/cli/EditAccount.kt b/bank/src/main/kotlin/tech/libeufin/bank/cli/EditAccount.kt
@@ -43,25 +43,39 @@ class EditAccount : CliktCommand(
private val name: String? by option(
help = "Legal name of the account owner"
)
- private val exchange: Boolean? by option(
- hidden = true
- ).boolean()
private val is_public: Boolean? by option(
"--public",
help = "Make this account visible to anyone"
).boolean()
+ private val exchange: Boolean? by option(
+ help = "Make this account a taler exchange"
+ ).boolean()
private val email: String? by option(help = "E-Mail address used for TAN transmission")
private val phone: String? by option(help = "Phone number used for TAN transmission")
- private val tan_channel: String? by option(help = "which channel TAN challenges should be sent to")
- private val cashout_payto_uri: IbanPayto? by option(help = "Payto URI of a fiant account who receive cashout amount").convert { Payto.parse(it).expectIban() }
- private val debit_threshold: TalerAmount? by option(help = "Max debit allowed for this account").convert { TalerAmount(it) }
- private val min_cashout: Option<TalerAmount>? by option(help = "Custom minimum cashout amount for this account").convert {
+ private val cashout_payto_uri: IbanPayto? by option(
+ help = "Payto URI of a fiant account who receive cashout amount"
+ ).convert { Payto.parse(it).expectIban() }
+ private val debit_threshold: TalerAmount? by option(
+ help = "Max debit allowed for this account"
+ ).convert { TalerAmount(it) }
+ private val min_cashout: Option<TalerAmount>? by option(
+ help = "Custom minimum cashout amount for this account"
+ ).convert {
if (it == "") {
Option.None
} else {
Option.Some(TalerAmount(it))
}
}
+ private val tan_channel: Option<TanChannel>? by option(
+ help = "Enables 2FA and set the TAN channel used for challenges"
+ ).convert {
+ if (it == "") {
+ Option.None
+ } else {
+ Option.Some(TanChannel.valueOf(it))
+ }
+ }
override fun run() = cliCmd(logger, common.log) {
bankConfig(common.config).withDb { db, cfg ->
@@ -76,11 +90,8 @@ class EditAccount : CliktCommand(
),
cashout_payto_uri = Option.Some(cashout_payto_uri),
debit_threshold = debit_threshold,
- min_cashout = when (val tmp = min_cashout) {
- null -> Option.None
- is Option.None -> Option.Some(null)
- is Option.Some -> Option.Some(tmp.value)
- }
+ min_cashout = Option.invert(min_cashout),
+ tan_channel = Option.invert(tan_channel)
)
when (patchAccount(db, cfg, req, username, true, true)) {
AccountPatchResult.Success ->
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/cli/LibeufinBank.kt b/bank/src/main/kotlin/tech/libeufin/bank/cli/LibeufinBank.kt
@@ -29,7 +29,7 @@ import tech.libeufin.common.getVersion
class LibeufinBank : CliktCommand() {
init {
versionOption(getVersion())
- subcommands(Serve(), DbInit(), CreateAccount(), EditAccount(), ChangePw(), BenchPwh(), GC(), CliConfigCmd(BANK_CONFIG_SOURCE))
+ subcommands(DbInit(), ChangePw(), Serve(), CreateAccount(), EditAccount(), GC(), BenchPwh(), CliConfigCmd(BANK_CONFIG_SOURCE))
}
override fun run() = Unit
diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt b/bank/src/test/kotlin/CoreBankApiTest.kt
@@ -769,6 +769,13 @@ class CoreBankAccountsApiTest {
}
}.assertConflict(TalerErrorCode.END)
+ // Exchange must be exchange
+ client.patchA("/accounts/exchange") {
+ json {
+ "is_taler_exchange" to false
+ }
+ }.assertConflict(TalerErrorCode.END)
+
// Check cashout payto receiver name logic
client.post("/accounts") {
json {
diff --git a/common/src/main/kotlin/Cli.kt b/common/src/main/kotlin/Cli.kt
@@ -77,7 +77,7 @@ class CommonOption: OptionGroup() {
class CliConfigCmd(configSource: ConfigSource) : CliktCommand("Inspect or change the configuration", name = "config") {
init {
- subcommands(CliConfigDump(configSource), CliConfigPathsub(configSource), CliConfigGet(configSource))
+ subcommands(CliConfigGet(configSource), CliConfigDump(configSource), CliConfigPathsub(configSource))
}
override fun run() = Unit
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/cli/LibeufinNexus.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/cli/LibeufinNexus.kt
@@ -44,7 +44,7 @@ fun CliktCommand.transientOption() = option(
class LibeufinNexus : CliktCommand() {
init {
versionOption(getVersion())
- subcommands(EbicsSetup(), DbInit(), Serve(), EbicsSubmit(), EbicsFetch(), InitiatePayment(), CliConfigCmd(NEXUS_CONFIG_SOURCE), TestingCmd())
+ subcommands(DbInit(), EbicsSetup(), EbicsSubmit(), EbicsFetch(), Serve(), InitiatePayment(), CliConfigCmd(NEXUS_CONFIG_SOURCE), TestingCmd())
}
override fun run() = Unit
}
\ No newline at end of file