github.com/core-coin/go-core/v2@v2.1.9/cmd/gocore/accountcmd_test.go (about) 1 // Copyright 2023 by the Authors 2 // This file is part of go-core. 3 // 4 // go-core is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-core is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-core. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "path/filepath" 23 "runtime" 24 "strings" 25 "testing" 26 27 "github.com/cespare/cp" 28 ) 29 30 // These tests are 'smoke tests' for the account related 31 // subcommands and flags. 32 // 33 // For most tests, the test files from package accounts 34 // are copied into a temporary keystore directory. 35 36 func tmpDatadirWithKeystore(t *testing.T) string { 37 datadir := tmpdir(t) 38 keystore := filepath.Join(datadir, "keystore") 39 source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore") 40 if err := cp.CopyAll(keystore, source); err != nil { 41 t.Fatal(err) 42 } 43 fmt.Println(keystore) 44 return datadir 45 } 46 47 func TestAccountListEmpty(t *testing.T) { 48 gocore := runGocore(t, "account", "list") 49 gocore.ExpectExit() 50 } 51 52 func TestAccountList(t *testing.T) { 53 datadir := tmpDatadirWithKeystore(t) 54 gocore := runGocore(t, "account", "list", "--datadir", datadir) 55 defer gocore.ExpectExit() 56 if runtime.GOOS == "windows" { 57 gocore.Expect(` 58 Account #0: {cb27de521e43741cf785cbad450d5649187b9612018f} keystore://{{.Datadir}}\keystore\UTC--2020-07-20T17-37-08.515483762Z--cb27de521e43741cf785cbad450d5649187b9612018f 59 Account #1: {cb74db416ff2f9c53dabaf34f81142db30350ea7b144} keystore://{{.Datadir}}\keystore\aaa 60 Account #2: {cb65e49851f010cd7d81b5b4969f3b0e8325c415359d} keystore://{{.Datadir}}\keystore\zzz 61 `) 62 } else { 63 gocore.Expect(` 64 Account #0: {cb27de521e43741cf785cbad450d5649187b9612018f} keystore://{{.Datadir}}/keystore/UTC--2020-07-20T17-37-08.515483762Z--cb27de521e43741cf785cbad450d5649187b9612018f 65 Account #1: {cb74db416ff2f9c53dabaf34f81142db30350ea7b144} keystore://{{.Datadir}}/keystore/aaa 66 Account #2: {cb65e49851f010cd7d81b5b4969f3b0e8325c415359d} keystore://{{.Datadir}}/keystore/zzz 67 `) 68 } 69 } 70 71 func TestAccountNew(t *testing.T) { 72 gocore := runGocore(t, "account", "new", "--lightkdf") 73 defer gocore.ExpectExit() 74 gocore.Expect(` 75 Your new account is locked with a password. Please give a password. Do not forget this password. 76 !! Unsupported terminal, password will be echoed. 77 Password: {{.InputLine "foobar"}} 78 Repeat password: {{.InputLine "foobar"}} 79 80 Your new key was generated 81 `) 82 gocore.ExpectRegexp(` 83 Public address of the key: [0-9a-fA-F]{44} 84 Path of the secret key file: .*UTC--.+--[0-9a-f]{44} 85 86 - You can share your public address with anyone. Others need it to interact with you. 87 - You must NEVER share the secret key with anyone! The key controls access to your funds! 88 - You must BACKUP your key file! Without the key, it's impossible to access account funds! 89 - You must REMEMBER your password! Without the password, it's impossible to decrypt the key! 90 `) 91 } 92 93 func TestAccountImport(t *testing.T) { 94 tests := []struct{ name, key, output string }{ 95 { 96 name: "correct account", 97 key: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e", 98 output: "Address: {fcad0b19bb29d4674531d6f115237e16afce377c}\n", 99 }, 100 { 101 name: "invalid character", 102 key: "69bb68c3a00a0cd9cbf2cab316476228c758329bbfe0b1759e8634694a9497afea05bcbf24e2aa0627eac4240484bb71de646a9296872a3c0e1", 103 output: "Fatal: Failed to load the private key: invalid character '1' at end of key file\n", 104 }, 105 } 106 for _, test := range tests { 107 t.Run(test.name, func(t *testing.T) { 108 t.Parallel() 109 importAccountWithExpect(t, test.key, test.output) 110 }) 111 } 112 } 113 114 func importAccountWithExpect(t *testing.T, key string, expected string) { 115 dir := tmpdir(t) 116 keyfile := filepath.Join(dir, "key.prv") 117 if err := ioutil.WriteFile(keyfile, []byte(key), 0600); err != nil { 118 t.Error(err) 119 } 120 passwordFile := filepath.Join(dir, "password.txt") 121 if err := ioutil.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil { 122 t.Error(err) 123 } 124 gocore := runGocore(t, "account", "import", keyfile, "-password", passwordFile) 125 defer gocore.ExpectExit() 126 gocore.Expect(expected) 127 } 128 129 func TestAccountNewBadRepeat(t *testing.T) { 130 gocore := runGocore(t, "account", "new", "--lightkdf") 131 defer gocore.ExpectExit() 132 gocore.Expect(` 133 Your new account is locked with a password. Please give a password. Do not forget this password. 134 !! Unsupported terminal, password will be echoed. 135 Password: {{.InputLine "something"}} 136 Repeat password: {{.InputLine "something else"}} 137 Fatal: Passwords do not match 138 `) 139 } 140 141 func TestAccountUpdate(t *testing.T) { 142 datadir := tmpDatadirWithKeystore(t) 143 gocore := runGocore(t, "account", "update", 144 "--datadir", datadir, "--lightkdf", 145 "cb74db416ff2f9c53dabaf34f81142db30350ea7b144") 146 defer gocore.ExpectExit() 147 gocore.Expect(` 148 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 1/3 149 !! Unsupported terminal, password will be echoed. 150 Password: {{.InputLine "foobar"}} 151 Please give a new password. Do not forget this password. 152 Password: {{.InputLine "foobar"}} 153 Repeat password: {{.InputLine "foobar"}} 154 `) 155 } 156 157 func TestUnlockFlag(t *testing.T) { 158 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 159 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "js", "testdata/empty.js") 160 gocore.Expect(` 161 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 1/3 162 !! Unsupported terminal, password will be echoed. 163 Password: {{.InputLine "foobar"}} 164 `) 165 gocore.ExpectExit() 166 167 wantMessages := []string{ 168 "Unlocked account", 169 "=cb74db416ff2f9c53dabaf34f81142db30350ea7b144", 170 } 171 for _, m := range wantMessages { 172 if !strings.Contains(gocore.StderrText(), m) { 173 t.Errorf("stderr text does not contain %q", m) 174 } 175 } 176 } 177 178 func TestUnlockFlagWrongPassword(t *testing.T) { 179 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 180 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "js", "testdata/empty.js") 181 182 defer gocore.ExpectExit() 183 gocore.Expect(` 184 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 1/3 185 !! Unsupported terminal, password will be echoed. 186 Password: {{.InputLine "wrong1"}} 187 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 2/3 188 Password: {{.InputLine "wrong2"}} 189 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 3/3 190 Password: {{.InputLine "wrong3"}} 191 Fatal: Failed to unlock account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 (could not decrypt key with given password) 192 `) 193 } 194 195 // https://github.com/core-coin/go-core/v2/issues/1785 196 func TestUnlockFlagMultiIndex(t *testing.T) { 197 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 198 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "--unlock", "0,2", "js", "testdata/empty.js") 199 200 gocore.Expect(` 201 Unlocking account 0 | Attempt 1/3 202 !! Unsupported terminal, password will be echoed. 203 Password: {{.InputLine "foobar"}} 204 Unlocking account 2 | Attempt 1/3 205 Password: {{.InputLine "foobar"}} 206 `) 207 gocore.ExpectExit() 208 209 wantMessages := []string{ 210 "Unlocked account", 211 "=cb27de521e43741cf785cbad450d5649187b9612018f", 212 "=cb65e49851f010cd7d81b5b4969f3b0e8325c415359d", 213 } 214 for _, m := range wantMessages { 215 if !strings.Contains(gocore.StderrText(), m) { 216 t.Errorf("stderr text does not contain %q", m) 217 } 218 } 219 } 220 221 func TestUnlockFlagPasswordFile(t *testing.T) { 222 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 223 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "--password", "testdata/passwords.txt", "--unlock", "0,2", "js", "testdata/empty.js") 224 225 gocore.ExpectExit() 226 227 wantMessages := []string{ 228 "Unlocked account", 229 "=cb27de521e43741cf785cbad450d5649187b9612018f", 230 "=cb65e49851f010cd7d81b5b4969f3b0e8325c415359d", 231 } 232 for _, m := range wantMessages { 233 if !strings.Contains(gocore.StderrText(), m) { 234 t.Errorf("stderr text does not contain %q", m) 235 } 236 } 237 } 238 239 func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { 240 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 241 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "--password", 242 "testdata/wrong-passwords.txt", "--unlock", "0,2") 243 defer gocore.ExpectExit() 244 gocore.Expect(` 245 Fatal: Failed to unlock account 0 (could not decrypt key with given password) 246 `) 247 } 248 249 func TestUnlockFlagAmbiguous(t *testing.T) { 250 store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") 251 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 252 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "--keystore", 253 store, "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", 254 "js", "testdata/empty.js") 255 defer gocore.ExpectExit() 256 257 // Helper for the expect template, returns absolute keystore path. 258 gocore.SetTemplateFunc("keypath", func(file string) string { 259 abs, _ := filepath.Abs(filepath.Join(store, file)) 260 return abs 261 }) 262 gocore.Expect(` 263 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 1/3 264 !! Unsupported terminal, password will be echoed. 265 Password: {{.InputLine "foobar"}} 266 Multiple key files exist for address cb74db416ff2f9c53dabaf34f81142db30350ea7b144: 267 keystore://{{keypath "1"}} 268 keystore://{{keypath "2"}} 269 Testing your password against all of them... 270 Your password unlocked keystore://{{keypath "1"}} 271 In order to avoid this warning, you need to remove the following duplicate key files: 272 keystore://{{keypath "2"}} 273 `) 274 gocore.ExpectExit() 275 276 wantMessages := []string{ 277 "Unlocked account", 278 "=cb74db416ff2f9c53dabaf34f81142db30350ea7b144", 279 } 280 for _, m := range wantMessages { 281 if !strings.Contains(gocore.StderrText(), m) { 282 t.Errorf("stderr text does not contain %q", m) 283 } 284 } 285 } 286 287 func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) { 288 store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes") 289 gocore := runMinimalGocore(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t), 290 "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144", "--keystore", 291 store, "--unlock", "cb74db416ff2f9c53dabaf34f81142db30350ea7b144") 292 293 defer gocore.ExpectExit() 294 295 // Helper for the expect template, returns absolute keystore path. 296 gocore.SetTemplateFunc("keypath", func(file string) string { 297 abs, _ := filepath.Abs(filepath.Join(store, file)) 298 return abs 299 }) 300 gocore.Expect(` 301 Unlocking account cb74db416ff2f9c53dabaf34f81142db30350ea7b144 | Attempt 1/3 302 !! Unsupported terminal, password will be echoed. 303 Password: {{.InputLine "wrong"}} 304 Multiple key files exist for address cb74db416ff2f9c53dabaf34f81142db30350ea7b144: 305 keystore://{{keypath "1"}} 306 keystore://{{keypath "2"}} 307 Testing your password against all of them... 308 Fatal: None of the listed files could be unlocked. 309 `) 310 gocore.ExpectExit() 311 }