aboutsummaryrefslogtreecommitdiff
path: root/nexus/src/test/kotlin/CliTest.kt
blob: 7e03053d447c0cf8e813d9f3b17972913e4baa8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
 * 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/>
 */

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.testing.test
import tech.libeufin.common.crypto.CryptoUtil
import tech.libeufin.nexus.*
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import kotlin.io.path.*
import kotlin.test.Test
import kotlin.test.assertEquals

val nexusCmd = LibeufinNexusCommand()

fun CliktCommand.testErr(cmd: String, msg: String) {
    val prevOut = System.err
    val tmpOut = ByteArrayOutputStream()
    System.setErr(PrintStream(tmpOut))
    val result = test(cmd)
    System.setErr(prevOut)
    val tmpStr = tmpOut.toString(Charsets.UTF_8)
    println(tmpStr)
    assertEquals(1, result.statusCode, "'$cmd' should have failed")
    val line = tmpStr.substringAfterLast(" - ").trimEnd('\n')
    println(line)
    assertEquals(msg, line)
}

class CliTest {
    /** Test error format related to the keying process */
    @Test
    fun keys() {
        val cmds = listOf("ebics-submit", "ebics-fetch")
        val allCmds = listOf("ebics-submit", "ebics-fetch", "ebics-setup")
        val conf = "conf/test.conf"
        val cfg = loadConfig(Path(conf))
        val clientKeysPath = cfg.requirePath("nexus-ebics", "client_private_keys_file")
        val bankKeysPath = cfg.requirePath("nexus-ebics", "bank_public_keys_file")
        clientKeysPath.parent!!.createDirectories()
        clientKeysPath.parent!!.toFile().setWritable(true)
        bankKeysPath.parent!!.createDirectories()
        
        // Missing client keys
        clientKeysPath.deleteIfExists()
        for (cmd in cmds) {
            nexusCmd.testErr("$cmd -c $conf", "Missing client private keys file at '$clientKeysPath', run 'libeufin-nexus ebics-setup' first")
        }
        // Bad client json
        clientKeysPath.writeText("CORRUPTION", Charsets.UTF_8)
        for (cmd in allCmds) {
            nexusCmd.testErr("$cmd -c $conf", "Could not decode client private keys at '$clientKeysPath': Expected start of the object '{', but had 'EOF' instead at path: $\nJSON input: CORRUPTION")
        }
        // Missing permission
        clientKeysPath.toFile().setReadable(false)
        if (!clientKeysPath.isReadable()) { // Skip if root
            for (cmd in allCmds) {
                nexusCmd.testErr("$cmd -c $conf", "Could not read client private keys at '$clientKeysPath': permission denied")
            }
        }
        // Unfinished client
        persistClientKeys(generateNewKeys(), clientKeysPath)
        for (cmd in cmds) {
            nexusCmd.testErr("$cmd -c $conf", "Unsubmitted client private keys, run 'libeufin-nexus ebics-setup' first")
        }

        // Missing bank keys
        persistClientKeys(generateNewKeys().apply {
            submitted_hia = true
            submitted_ini = true
        }, clientKeysPath)
        bankKeysPath.deleteIfExists()
        for (cmd in cmds) {
            nexusCmd.testErr("$cmd -c $conf", "Missing bank public keys at '$bankKeysPath', run 'libeufin-nexus ebics-setup' first")
        }
        // Bad bank json
        bankKeysPath.writeText("CORRUPTION", Charsets.UTF_8)
        for (cmd in allCmds) {
            nexusCmd.testErr("$cmd -c $conf", "Could not decode bank public keys at '$bankKeysPath': Expected start of the object '{', but had 'EOF' instead at path: $\nJSON input: CORRUPTION")
        }
        // Missing permission
        bankKeysPath.toFile().setReadable(false)
        if (!bankKeysPath.isReadable()) { // Skip if root
            for (cmd in allCmds) {
                nexusCmd.testErr("$cmd -c $conf", "Could not read bank public keys at '$bankKeysPath': permission denied")
            }
        }
        // Unfinished bank
        persistBankKeys(BankPublicKeysFile(
            bank_authentication_public_key = CryptoUtil.generateRsaKeyPair(2048).public,
            bank_encryption_public_key = CryptoUtil.generateRsaKeyPair(2048).public,
            accepted = false
        ), bankKeysPath)
        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)
        if (!clientKeysPath.parent!!.isWritable()) { // Skip if root
            nexusCmd.testErr("ebics-setup -c $conf", "Could not write client private keys at '$clientKeysPath': permission denied on '${clientKeysPath.parent}'")
        }
    }
}