github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/account/accountupdate.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package account 7 8 import ( 9 "bytes" 10 "fmt" 11 12 "github.com/ethereum/go-ethereum/accounts/keystore" 13 "github.com/spf13/cobra" 14 15 "github.com/iotexproject/go-pkgs/crypto" 16 "github.com/iotexproject/go-pkgs/hash" 17 "github.com/iotexproject/iotex-address/address" 18 19 "github.com/iotexproject/iotex-core/ioctl/config" 20 "github.com/iotexproject/iotex-core/ioctl/output" 21 "github.com/iotexproject/iotex-core/ioctl/util" 22 ) 23 24 // Multi-language support 25 var ( 26 _updateCmdShorts = map[config.Language]string{ 27 config.English: "Update password for IoTeX account", 28 config.Chinese: "为IoTeX账户更新密码", 29 } 30 _updateCmdUses = map[config.Language]string{ 31 config.English: "update [ALIAS|ADDRESS]", 32 config.Chinese: "update [别名|地址]", 33 } 34 ) 35 36 // _accountUpdateCmd represents the account update command 37 var _accountUpdateCmd = &cobra.Command{ 38 Use: config.TranslateInLang(_updateCmdUses, config.UILanguage), 39 Short: config.TranslateInLang(_updateCmdShorts, config.UILanguage), 40 Args: cobra.RangeArgs(0, 1), 41 RunE: func(cmd *cobra.Command, args []string) error { 42 cmd.SilenceUsage = true 43 arg := "" 44 if len(args) == 1 { 45 arg = args[0] 46 } 47 err := accountUpdate(arg) 48 return output.PrintError(err) 49 }, 50 } 51 52 func accountUpdate(arg string) error { 53 account, err := util.GetAddress(arg) 54 if err != nil { 55 return output.NewError(output.AddressError, "", err) 56 } 57 addr, err := address.FromString(account) 58 if err != nil { 59 return output.NewError(output.ConvertError, "failed to convert string into addr", err) 60 } 61 62 if CryptoSm2 { 63 // find the pem file and update 64 filePath, err := findSm2PemFile(addr) 65 if err != nil { 66 return output.NewError(output.ReadFileError, fmt.Sprintf("crypto file of account #%s not found", addr), err) 67 } 68 69 output.PrintQuery(fmt.Sprintf("#%s: Enter current password\n", account)) 70 currentPassword, err := util.ReadSecretFromStdin() 71 if err != nil { 72 return output.NewError(output.InputError, "failed to get current password", err) 73 } 74 _, err = crypto.ReadPrivateKeyFromPem(filePath, currentPassword) 75 if err != nil { 76 return output.NewError(output.CryptoError, "error occurs when checking current password", err) 77 } 78 output.PrintQuery(fmt.Sprintf("#%s: Enter new password\n", account)) 79 password, err := util.ReadSecretFromStdin() 80 if err != nil { 81 return output.NewError(output.InputError, "failed to get new password", err) 82 } 83 output.PrintQuery(fmt.Sprintf("#%s: Enter new password again\n", account)) 84 passwordAgain, err := util.ReadSecretFromStdin() 85 if err != nil { 86 return output.NewError(output.InputError, "failed to get new password", err) 87 } 88 if password != passwordAgain { 89 return output.NewError(output.ValidationError, ErrPasswdNotMatch.Error(), nil) 90 } 91 92 if err := crypto.UpdatePrivateKeyPasswordToPem(filePath, currentPassword, password); err != nil { 93 return output.NewError(output.KeystoreError, "failed to update pem file", err) 94 } 95 } else { 96 // find the keystore and update 97 ks := keystore.NewKeyStore(config.ReadConfig.Wallet, 98 keystore.StandardScryptN, keystore.StandardScryptP) 99 for _, v := range ks.Accounts() { 100 if bytes.Equal(addr.Bytes(), v.Address.Bytes()) { 101 output.PrintQuery(fmt.Sprintf("#%s: Enter current password\n", account)) 102 currentPassword, err := util.ReadSecretFromStdin() 103 if err != nil { 104 return output.NewError(output.InputError, "failed to get current password", err) 105 } 106 _, err = ks.SignHashWithPassphrase(v, currentPassword, hash.ZeroHash256[:]) 107 if err != nil { 108 return output.NewError(output.KeystoreError, "error occurs when checking current password", err) 109 } 110 output.PrintQuery(fmt.Sprintf("#%s: Enter new password\n", account)) 111 password, err := util.ReadSecretFromStdin() 112 if err != nil { 113 return output.NewError(output.InputError, "failed to get new password", err) 114 } 115 output.PrintQuery(fmt.Sprintf("#%s: Enter new password again\n", account)) 116 passwordAgain, err := util.ReadSecretFromStdin() 117 if err != nil { 118 return output.NewError(output.InputError, "failed to get new password", err) 119 } 120 if password != passwordAgain { 121 return output.NewError(output.ValidationError, ErrPasswdNotMatch.Error(), nil) 122 } 123 124 if err := ks.Update(v, currentPassword, password); err != nil { 125 return output.NewError(output.KeystoreError, "failed to update keystore", err) 126 } 127 128 output.PrintResult(fmt.Sprintf("Account #%s has been updated.", account)) 129 return nil 130 } 131 } 132 } 133 134 output.PrintResult(fmt.Sprintf("Account #%s has been updated.", account)) 135 return nil 136 }