diff --git a/cmd/neofs-adm/internal/modules/morph/generate.go b/cmd/neofs-adm/internal/modules/morph/generate.go index c9a139ce3..5b17afaac 100644 --- a/cmd/neofs-adm/internal/modules/morph/generate.go +++ b/cmd/neofs-adm/internal/modules/morph/generate.go @@ -42,6 +42,12 @@ func generateAlphabetCreds(cmd *cobra.Command, args []string) error { return err } + w, err := initializeContractWallet(walletDir) + if err != nil { + return err + } + w.Close() + cmd.Println("size:", size) cmd.Println("alphabet-wallets:", walletDir) for i := range pwds { diff --git a/cmd/neofs-adm/internal/modules/morph/generate_test.go b/cmd/neofs-adm/internal/modules/morph/generate_test.go index d54d538cc..8299a3588 100644 --- a/cmd/neofs-adm/internal/modules/morph/generate_test.go +++ b/cmd/neofs-adm/internal/modules/morph/generate_test.go @@ -48,6 +48,15 @@ func TestGenerateAlphabet(t *testing.T) { buf.WriteString("pass\r") require.Error(t, generateAlphabetCreds(cmd, nil)) }) + t.Run("no password for contract group wallet", func(t *testing.T) { + buf.Reset() + v.Set(alphabetWalletsFlag, walletDir) + require.NoError(t, cmd.Flags().Set(alphabetSizeFlag, strconv.FormatUint(size, 10))) + for i := uint64(0); i < size; i++ { + buf.WriteString(strconv.FormatUint(i, 10) + "\r") + } + require.Error(t, generateAlphabetCreds(cmd, nil)) + }) buf.Reset() v.Set(alphabetWalletsFlag, walletDir) @@ -56,6 +65,8 @@ func TestGenerateAlphabet(t *testing.T) { buf.WriteString(strconv.FormatUint(i, 10) + "\r") } + const groupPassword = "grouppass" + buf.WriteString(groupPassword + "\r") require.NoError(t, generateAlphabetCreds(cmd, nil)) for i := uint64(0); i < size; i++ { @@ -76,6 +87,14 @@ func TestGenerateAlphabet(t *testing.T) { } } } + + t.Run("check contract group wallet", func(t *testing.T) { + p := filepath.Join(walletDir, contractWalletName) + w, err := wallet.NewWalletFromFile(p) + require.NoError(t, err, "contract wallet doesn't exist") + require.Equal(t, 1, len(w.Accounts), "contract wallet must have 1 accout") + require.NoError(t, w.Accounts[0].Decrypt(groupPassword, keys.NEP2ScryptParams())) + }) } func setupTestTerminal(t *testing.T) *bytes.Buffer { diff --git a/cmd/neofs-adm/internal/modules/morph/group.go b/cmd/neofs-adm/internal/modules/morph/group.go index 854aa61e7..c86883c49 100644 --- a/cmd/neofs-adm/internal/modules/morph/group.go +++ b/cmd/neofs-adm/internal/modules/morph/group.go @@ -3,23 +3,74 @@ package morph import ( "encoding/json" "fmt" + "os" "path" + "path/filepath" "github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/wallet" + "github.com/spf13/cobra" "github.com/spf13/viper" ) const contractWalletName = "contract.json" -func openContractWallet(walletDir string) (*wallet.Wallet, error) { +func initializeContractWallet(walletDir string) (*wallet.Wallet, error) { + var ( + password string + err error + ) + + if key := "credentials.contract"; viper.IsSet(key) { + password = viper.GetString(key) + } else { + prompt := "Password for contract wallet > " + password, err = input.ReadPassword(prompt) + if err != nil { + return nil, err + } + } + + w, err := wallet.NewWallet(path.Join(walletDir, contractWalletName)) + if err != nil { + return nil, err + } + + acc, err := wallet.NewAccount() + if err != nil { + return nil, err + } + + err = acc.Encrypt(password, keys.NEP2ScryptParams()) + if err != nil { + return nil, err + } + + w.AddAccount(acc) + if err := w.Save(); err != nil { + return nil, err + } + + return w, nil +} + +func openContractWallet(cmd *cobra.Command, walletDir string) (*wallet.Wallet, error) { p := path.Join(walletDir, contractWalletName) w, err := wallet.NewWalletFromFile(p) if err != nil { - return nil, fmt.Errorf("can't open wallet: %w", err) + if !os.IsNotExist(err) { + return nil, fmt.Errorf("can't open wallet: %w", err) + } + + cmd.Printf("Contract group wallet is missing, initialize at %s\n", + filepath.Join(walletDir, contractWalletName)) + w, err = initializeContractWallet(walletDir) + if err != nil { + return nil, err + } } var password string diff --git a/cmd/neofs-adm/internal/modules/morph/initialize.go b/cmd/neofs-adm/internal/modules/morph/initialize.go index 472322038..26fedb795 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize.go @@ -97,7 +97,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex return nil, err } - w, err := openContractWallet(walletDir) + w, err := openContractWallet(cmd, walletDir) if err != nil { return nil, err }