code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_update_passphrase_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package api_test
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"testing"
    22  
    23  	"code.vegaprotocol.io/vega/libs/jsonrpc"
    24  	vgrand "code.vegaprotocol.io/vega/libs/rand"
    25  	"code.vegaprotocol.io/vega/wallet/api"
    26  	"code.vegaprotocol.io/vega/wallet/api/mocks"
    27  
    28  	"github.com/golang/mock/gomock"
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestAdminUpdatePassphrase(t *testing.T) {
    34  	t.Run("Documentation matches the code", testAdminUpdatePassphraseSchemaCorrect)
    35  	t.Run("Updating a passphrase with invalid params fails", testUpdatingPassphraseWithInvalidParamsFails)
    36  	t.Run("Updating a passphrase with valid params succeeds", testUpdatingPassphraseWithValidParamsSucceeds)
    37  	t.Run("Getting internal error during wallet verification fails", testUpdatingPassphraseGettingInternalErrorDuringWalletVerificationFails)
    38  	t.Run("Updating a passphrase from wallet that does not exists fails", testUpdatingPassphraseFromWalletThatDoesNotExistsFails)
    39  	t.Run("Getting internal error during isolated wallet saving fails", testUpdatingPassphraseGettingInternalErrorDuringPassphraseUpdateFails)
    40  }
    41  
    42  func testAdminUpdatePassphraseSchemaCorrect(t *testing.T) {
    43  	assertEqualSchema(t, "admin.update_passphrase", api.AdminUpdatePassphraseParams{}, nil)
    44  }
    45  
    46  func testUpdatingPassphraseWithInvalidParamsFails(t *testing.T) {
    47  	tcs := []struct {
    48  		name          string
    49  		params        interface{}
    50  		expectedError error
    51  	}{
    52  		{
    53  			name:          "with nil params",
    54  			params:        nil,
    55  			expectedError: api.ErrParamsRequired,
    56  		}, {
    57  			name:          "with wrong type of params",
    58  			params:        "test",
    59  			expectedError: api.ErrParamsDoNotMatch,
    60  		}, {
    61  			name: "with empty name",
    62  			params: api.AdminUpdatePassphraseParams{
    63  				Wallet:        "",
    64  				NewPassphrase: vgrand.RandomStr(5),
    65  			},
    66  			expectedError: api.ErrWalletIsRequired,
    67  		}, {
    68  			name: "with empty new passphrase",
    69  			params: api.AdminUpdatePassphraseParams{
    70  				Wallet:        vgrand.RandomStr(5),
    71  				NewPassphrase: "",
    72  			},
    73  			expectedError: api.ErrNewPassphraseIsRequired,
    74  		},
    75  	}
    76  
    77  	for _, tc := range tcs {
    78  		t.Run(tc.name, func(tt *testing.T) {
    79  			// given
    80  			ctx := context.Background()
    81  
    82  			// setup
    83  			handler := newUpdatePassphraseHandler(tt)
    84  
    85  			// when
    86  			errorDetails := handler.handle(t, ctx, tc.params)
    87  
    88  			// then
    89  			assertInvalidParams(tt, errorDetails, tc.expectedError)
    90  		})
    91  	}
    92  }
    93  
    94  func testUpdatingPassphraseWithValidParamsSucceeds(t *testing.T) {
    95  	// given
    96  	ctx := context.Background()
    97  	newPassphrase := vgrand.RandomStr(5)
    98  	expectedWallet, _ := walletWithKey(t)
    99  
   100  	// setup
   101  	handler := newUpdatePassphraseHandler(t)
   102  	// -- expected calls
   103  	handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   104  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   105  	handler.walletStore.EXPECT().UpdatePassphrase(ctx, expectedWallet.Name(), newPassphrase).Times(1).Return(nil)
   106  
   107  	// when
   108  	errorDetails := handler.handle(t, ctx, api.AdminUpdatePassphraseParams{
   109  		Wallet:        expectedWallet.Name(),
   110  		NewPassphrase: newPassphrase,
   111  	})
   112  
   113  	// then
   114  	require.Nil(t, errorDetails)
   115  }
   116  
   117  func testUpdatingPassphraseFromWalletThatDoesNotExistsFails(t *testing.T) {
   118  	// given
   119  	ctx := context.Background()
   120  	newPassphrase := vgrand.RandomStr(5)
   121  	name := vgrand.RandomStr(5)
   122  
   123  	// setup
   124  	handler := newUpdatePassphraseHandler(t)
   125  	// -- expected calls
   126  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, nil)
   127  
   128  	// when
   129  	errorDetails := handler.handle(t, ctx, api.AdminUpdatePassphraseParams{
   130  		Wallet:        name,
   131  		NewPassphrase: newPassphrase,
   132  	})
   133  
   134  	// then
   135  	require.NotNil(t, errorDetails)
   136  	assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist)
   137  }
   138  
   139  func testUpdatingPassphraseGettingInternalErrorDuringWalletVerificationFails(t *testing.T) {
   140  	// given
   141  	ctx := context.Background()
   142  	newPassphrase := vgrand.RandomStr(5)
   143  	name := vgrand.RandomStr(5)
   144  
   145  	// setup
   146  	handler := newUpdatePassphraseHandler(t)
   147  	// -- expected calls
   148  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, assert.AnError)
   149  
   150  	// when
   151  	errorDetails := handler.handle(t, ctx, api.AdminUpdatePassphraseParams{
   152  		Wallet:        name,
   153  		NewPassphrase: newPassphrase,
   154  	})
   155  
   156  	// then
   157  	require.NotNil(t, errorDetails)
   158  	assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError))
   159  }
   160  
   161  func testUpdatingPassphraseGettingInternalErrorDuringPassphraseUpdateFails(t *testing.T) {
   162  	// given
   163  	ctx := context.Background()
   164  	newPassphrase := vgrand.RandomStr(5)
   165  	expectedWallet, _ := walletWithKey(t)
   166  
   167  	// setup
   168  	handler := newUpdatePassphraseHandler(t)
   169  	// -- expected calls
   170  	handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   171  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   172  	handler.walletStore.EXPECT().UpdatePassphrase(ctx, gomock.Any(), newPassphrase).Times(1).Return(assert.AnError)
   173  
   174  	// when
   175  	errorDetails := handler.handle(t, ctx, api.AdminUpdatePassphraseParams{
   176  		Wallet:        expectedWallet.Name(),
   177  		NewPassphrase: newPassphrase,
   178  	})
   179  
   180  	// then
   181  	require.NotNil(t, errorDetails)
   182  	assertInternalError(t, errorDetails, fmt.Errorf("could not save the wallet with the new passphrase: %w", assert.AnError))
   183  }
   184  
   185  type updatePassphraseHandler struct {
   186  	*api.AdminUpdatePassphrase
   187  	ctrl        *gomock.Controller
   188  	walletStore *mocks.MockWalletStore
   189  }
   190  
   191  func (h *updatePassphraseHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) *jsonrpc.ErrorDetails {
   192  	t.Helper()
   193  
   194  	rawResult, err := h.Handle(ctx, params)
   195  	require.Nil(t, rawResult)
   196  	return err
   197  }
   198  
   199  func newUpdatePassphraseHandler(t *testing.T) *updatePassphraseHandler {
   200  	t.Helper()
   201  
   202  	ctrl := gomock.NewController(t)
   203  	walletStore := mocks.NewMockWalletStore(ctrl)
   204  
   205  	return &updatePassphraseHandler{
   206  		AdminUpdatePassphrase: api.NewAdminUpdatePassphrase(walletStore),
   207  		ctrl:                  ctrl,
   208  		walletStore:           walletStore,
   209  	}
   210  }