code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_describe_permissions_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  	"code.vegaprotocol.io/vega/wallet/wallet"
    28  
    29  	"github.com/golang/mock/gomock"
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestAdminDescribePermissions(t *testing.T) {
    35  	t.Run("Documentation matches the code", testAdminDescribePermissionsSchemaCorrect)
    36  	t.Run("Describing permissions with invalid params fails", testAdminDescribingPermissionsWithInvalidParamsFails)
    37  	t.Run("Describing permissions with valid params succeeds", testAdminDescribingPermissionsWithValidParamsSucceeds)
    38  	t.Run("Describing permissions from wallet that does not exists fails", testAdminDescribingPermissionsFromWalletThatDoesNotExistsFails)
    39  	t.Run("Getting internal error during wallet verification fails", testAdminDescribePermissionsGettingInternalErrorDuringWalletVerificationFails)
    40  	t.Run("Getting internal error during wallet retrieval fails", testAdminDescribePermissionsGettingInternalErrorDuringWalletRetrievalFails)
    41  }
    42  
    43  func testAdminDescribePermissionsSchemaCorrect(t *testing.T) {
    44  	assertEqualSchema(t, "admin.describe_permissions", api.AdminDescribePermissionsParams{}, api.AdminDescribePermissionsResult{})
    45  }
    46  
    47  func testAdminDescribingPermissionsWithInvalidParamsFails(t *testing.T) {
    48  	tcs := []struct {
    49  		name          string
    50  		params        interface{}
    51  		expectedError error
    52  	}{
    53  		{
    54  			name:          "with nil params",
    55  			params:        nil,
    56  			expectedError: api.ErrParamsRequired,
    57  		}, {
    58  			name:          "with wrong type of params",
    59  			params:        "test",
    60  			expectedError: api.ErrParamsDoNotMatch,
    61  		}, {
    62  			name: "with empty name",
    63  			params: api.AdminDescribePermissionsParams{
    64  				Wallet:   "",
    65  				Hostname: vgrand.RandomStr(5),
    66  			},
    67  			expectedError: api.ErrWalletIsRequired,
    68  		}, {
    69  			name: "with empty hostname key",
    70  			params: api.AdminDescribePermissionsParams{
    71  				Wallet:   vgrand.RandomStr(5),
    72  				Hostname: "",
    73  			},
    74  			expectedError: api.ErrHostnameIsRequired,
    75  		},
    76  	}
    77  
    78  	for _, tc := range tcs {
    79  		t.Run(tc.name, func(tt *testing.T) {
    80  			// given
    81  			ctx := context.Background()
    82  
    83  			// setup
    84  			handler := newDescribePermissionsHandler(tt)
    85  
    86  			// when
    87  			result, errorDetails := handler.handle(t, ctx, tc.params)
    88  
    89  			// then
    90  			require.Empty(tt, result)
    91  			assertInvalidParams(tt, errorDetails, tc.expectedError)
    92  		})
    93  	}
    94  }
    95  
    96  func testAdminDescribingPermissionsWithValidParamsSucceeds(t *testing.T) {
    97  	// given
    98  	ctx := context.Background()
    99  	hostname := vgrand.RandomStr(5)
   100  	expectedWallet, firstKey := walletWithKey(t)
   101  	if err := expectedWallet.UpdatePermissions(hostname, wallet.Permissions{
   102  		PublicKeys: wallet.PublicKeysPermission{
   103  			Access: "read",
   104  			AllowedKeys: []string{
   105  				firstKey.PublicKey(),
   106  			},
   107  		},
   108  	}); err != nil {
   109  		t.Fatalf("could not update permissions for test: %v", err)
   110  	}
   111  
   112  	// setup
   113  	handler := newDescribePermissionsHandler(t)
   114  	// -- expected calls
   115  	handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   116  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   117  	handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil)
   118  
   119  	// when
   120  	result, errorDetails := handler.handle(t, ctx, api.AdminDescribePermissionsParams{
   121  		Wallet:   expectedWallet.Name(),
   122  		Hostname: hostname,
   123  	})
   124  
   125  	// then
   126  	require.Nil(t, errorDetails)
   127  	assert.Equal(t, api.AdminDescribePermissionsResult{
   128  		Permissions: wallet.Permissions{
   129  			PublicKeys: wallet.PublicKeysPermission{
   130  				Access: "read",
   131  				AllowedKeys: []string{
   132  					firstKey.PublicKey(),
   133  				},
   134  			},
   135  		},
   136  	}, result)
   137  }
   138  
   139  func testAdminDescribingPermissionsFromWalletThatDoesNotExistsFails(t *testing.T) {
   140  	// given
   141  	ctx := context.Background()
   142  	name := vgrand.RandomStr(5)
   143  
   144  	// setup
   145  	handler := newDescribePermissionsHandler(t)
   146  	// -- expected calls
   147  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, nil)
   148  
   149  	// when
   150  	result, errorDetails := handler.handle(t, ctx, api.AdminDescribePermissionsParams{
   151  		Wallet:   name,
   152  		Hostname: vgrand.RandomStr(5),
   153  	})
   154  
   155  	// then
   156  	require.NotNil(t, errorDetails)
   157  	assert.Empty(t, result)
   158  	assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist)
   159  }
   160  
   161  func testAdminDescribePermissionsGettingInternalErrorDuringWalletVerificationFails(t *testing.T) {
   162  	// given
   163  	ctx := context.Background()
   164  	name := vgrand.RandomStr(5)
   165  
   166  	// setup
   167  	handler := newDescribePermissionsHandler(t)
   168  	// -- expected calls
   169  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, assert.AnError)
   170  
   171  	// when
   172  	result, errorDetails := handler.handle(t, ctx, api.AdminDescribePermissionsParams{
   173  		Wallet:   name,
   174  		Hostname: vgrand.RandomStr(5),
   175  	})
   176  
   177  	// then
   178  	require.NotNil(t, errorDetails)
   179  	assert.Empty(t, result)
   180  	assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError))
   181  }
   182  
   183  func testAdminDescribePermissionsGettingInternalErrorDuringWalletRetrievalFails(t *testing.T) {
   184  	// given
   185  	ctx := context.Background()
   186  	name := vgrand.RandomStr(5)
   187  
   188  	// setup
   189  	handler := newDescribePermissionsHandler(t)
   190  	// -- expected calls
   191  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(true, nil)
   192  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, name).Times(1).Return(true, nil)
   193  	handler.walletStore.EXPECT().GetWallet(ctx, name).Times(1).Return(nil, assert.AnError)
   194  
   195  	// when
   196  	result, errorDetails := handler.handle(t, ctx, api.AdminDescribePermissionsParams{
   197  		Wallet:   name,
   198  		Hostname: vgrand.RandomStr(5),
   199  	})
   200  
   201  	// then
   202  	require.NotNil(t, errorDetails)
   203  	assert.Empty(t, result)
   204  	assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError))
   205  }
   206  
   207  type describePermissionsHandler struct {
   208  	*api.AdminDescribePermissions
   209  	ctrl        *gomock.Controller
   210  	walletStore *mocks.MockWalletStore
   211  }
   212  
   213  func (h *describePermissionsHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) (api.AdminDescribePermissionsResult, *jsonrpc.ErrorDetails) {
   214  	t.Helper()
   215  
   216  	rawResult, err := h.Handle(ctx, params)
   217  	if rawResult != nil {
   218  		result, ok := rawResult.(api.AdminDescribePermissionsResult)
   219  		if !ok {
   220  			t.Fatal("AdminDescribePermissions handler result is not a AdminDescribePermissionsResult")
   221  		}
   222  		return result, err
   223  	}
   224  	return api.AdminDescribePermissionsResult{}, err
   225  }
   226  
   227  func newDescribePermissionsHandler(t *testing.T) *describePermissionsHandler {
   228  	t.Helper()
   229  
   230  	ctrl := gomock.NewController(t)
   231  	walletStore := mocks.NewMockWalletStore(ctrl)
   232  
   233  	return &describePermissionsHandler{
   234  		AdminDescribePermissions: api.NewAdminDescribePermissions(walletStore),
   235  		ctrl:                     ctrl,
   236  		walletStore:              walletStore,
   237  	}
   238  }