code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_sign_message_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  )
    31  
    32  func TestAdminSignMessage(t *testing.T) {
    33  	t.Run("Documentation matches the code", testAdminSignMessageSchemaCorrect)
    34  	t.Run("Signing message with invalid params fails", testSigningMessageWithInvalidParamsFails)
    35  	t.Run("Signing message with wallet that doesn't exist fails", testSigningMessageWithWalletThatDoesntExistFails)
    36  	t.Run("Signing message failing to get wallet fails", testSigningMessageFailingToGetWalletFails)
    37  }
    38  
    39  func testAdminSignMessageSchemaCorrect(t *testing.T) {
    40  	assertEqualSchema(t, "admin.sign_message", api.AdminSignMessageParams{}, api.AdminSignMessageResult{})
    41  }
    42  
    43  func testSigningMessageWithInvalidParamsFails(t *testing.T) {
    44  	tcs := []struct {
    45  		name          string
    46  		params        interface{}
    47  		expectedError error
    48  	}{
    49  		{
    50  			name:          "with nil params",
    51  			params:        nil,
    52  			expectedError: api.ErrParamsRequired,
    53  		},
    54  		{
    55  			name:          "with wrong type of params",
    56  			params:        "test",
    57  			expectedError: api.ErrParamsDoNotMatch,
    58  		},
    59  		{
    60  			name: "with empty wallet",
    61  			params: api.AdminSignMessageParams{
    62  				Wallet: "",
    63  			},
    64  			expectedError: api.ErrWalletIsRequired,
    65  		},
    66  		{
    67  			name: "with empty public key",
    68  			params: api.AdminSignMessageParams{
    69  				Wallet:    vgrand.RandomStr(5),
    70  				PublicKey: "",
    71  			},
    72  			expectedError: api.ErrPublicKeyIsRequired,
    73  		},
    74  		{
    75  			name: "with empty message",
    76  			params: api.AdminSignMessageParams{
    77  				Wallet:         vgrand.RandomStr(5),
    78  				PublicKey:      vgrand.RandomStr(5),
    79  				EncodedMessage: "",
    80  			},
    81  			expectedError: api.ErrMessageIsRequired,
    82  		},
    83  		{
    84  			name: "with non-base64 message",
    85  			params: api.AdminSignMessageParams{
    86  				Wallet:         vgrand.RandomStr(5),
    87  				PublicKey:      vgrand.RandomStr(5),
    88  				EncodedMessage: "blahh",
    89  			},
    90  			expectedError: api.ErrEncodedMessageIsNotValidBase64String,
    91  		},
    92  	}
    93  
    94  	for _, tc := range tcs {
    95  		t.Run(tc.name, func(tt *testing.T) {
    96  			// given
    97  			ctx := context.Background()
    98  
    99  			// setup
   100  			handler := newSignMessageHandler(tt)
   101  
   102  			// when
   103  			result, errorDetails := handler.handle(t, ctx, tc.params)
   104  
   105  			// then
   106  			assertInvalidParams(tt, errorDetails, tc.expectedError)
   107  			assert.Empty(tt, result)
   108  		})
   109  	}
   110  }
   111  
   112  func testSigningMessageWithWalletThatDoesntExistFails(t *testing.T) {
   113  	// given
   114  	ctx := context.Background()
   115  	params := paramsWithMessage("bXltZXNzYWdl")
   116  
   117  	// setup
   118  	handler := newSignMessageHandler(t)
   119  	// -- expected calls
   120  	handler.walletStore.EXPECT().WalletExists(ctx, params.Wallet).Times(1).Return(false, nil)
   121  
   122  	// when
   123  	result, errorDetails := handler.handle(t, ctx, params)
   124  
   125  	// then
   126  	assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist)
   127  	assert.Empty(t, result)
   128  }
   129  
   130  func testSigningMessageFailingToGetWalletFails(t *testing.T) {
   131  	// given
   132  	ctx := context.Background()
   133  	params := paramsWithMessage("bXltZXNzYWdl")
   134  
   135  	// setup
   136  	handler := newSignMessageHandler(t)
   137  	// -- expected calls
   138  	handler.walletStore.EXPECT().WalletExists(ctx, params.Wallet).Times(1).Return(true, nil)
   139  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, params.Wallet).Times(1).Return(true, nil)
   140  	handler.walletStore.EXPECT().GetWallet(ctx, params.Wallet).Times(1).Return(nil, assert.AnError)
   141  
   142  	// when
   143  	result, errorDetails := handler.handle(t, ctx, params)
   144  
   145  	// then
   146  	assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError))
   147  	assert.Empty(t, result)
   148  }
   149  
   150  func paramsWithMessage(m string) api.AdminSignMessageParams {
   151  	return api.AdminSignMessageParams{
   152  		Wallet:         vgrand.RandomStr(5),
   153  		PublicKey:      vgrand.RandomStr(5),
   154  		EncodedMessage: m,
   155  	}
   156  }
   157  
   158  type signMessageHandler struct {
   159  	*api.AdminSignMessage
   160  	ctrl        *gomock.Controller
   161  	walletStore *mocks.MockWalletStore
   162  }
   163  
   164  func (h *signMessageHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) (api.AdminSignMessageResult, *jsonrpc.ErrorDetails) {
   165  	t.Helper()
   166  
   167  	rawResult, err := h.Handle(ctx, params)
   168  	if rawResult != nil {
   169  		result, ok := rawResult.(api.AdminSignMessageResult)
   170  		if !ok {
   171  			t.Fatal("AdminUpdatePermissions handler result is not a AdminSignTransactionResult")
   172  		}
   173  		return result, err
   174  	}
   175  	return api.AdminSignMessageResult{}, err
   176  }
   177  
   178  func newSignMessageHandler(t *testing.T) *signMessageHandler {
   179  	t.Helper()
   180  
   181  	ctrl := gomock.NewController(t)
   182  	walletStore := mocks.NewMockWalletStore(ctrl)
   183  
   184  	return &signMessageHandler{
   185  		AdminSignMessage: api.NewAdminSignMessage(walletStore),
   186  		ctrl:             ctrl,
   187  		walletStore:      walletStore,
   188  	}
   189  }