code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_list_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 TestAdminListPermissions(t *testing.T) {
    35  	t.Run("Documentation matches the code", testAdminListPermissionsSchemaCorrect)
    36  	t.Run("Listing permissions with invalid params fails", testListingPermissionsWithInvalidParamsFails)
    37  	t.Run("Listing permissions with valid params succeeds", testListingPermissionsWithValidParamsSucceeds)
    38  	t.Run("Listing permissions from wallet that does not exists fails", testListingPermissionsFromWalletThatDoesNotExistsFails)
    39  	t.Run("Getting internal error during wallet verification fails", testAdminListPermissionsGettingInternalErrorDuringWalletVerificationFails)
    40  	t.Run("Getting internal error during wallet retrieval fails", testAdminListPermissionsGettingInternalErrorDuringWalletRetrievalFails)
    41  }
    42  
    43  func testAdminListPermissionsSchemaCorrect(t *testing.T) {
    44  	assertEqualSchema(t, "admin.list_permissions", api.AdminListPermissionsParams{}, api.AdminListPermissionsResult{})
    45  }
    46  
    47  func testListingPermissionsWithInvalidParamsFails(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.AdminListPermissionsParams{
    64  				Wallet: "",
    65  			},
    66  			expectedError: api.ErrWalletIsRequired,
    67  		},
    68  	}
    69  
    70  	for _, tc := range tcs {
    71  		t.Run(tc.name, func(tt *testing.T) {
    72  			// given
    73  			ctx := context.Background()
    74  
    75  			// setup
    76  			handler := newListPermissionsHandler(tt)
    77  
    78  			// when
    79  			result, errorDetails := handler.handle(t, ctx, tc.params)
    80  
    81  			// then
    82  			require.Empty(tt, result)
    83  			assertInvalidParams(tt, errorDetails, tc.expectedError)
    84  		})
    85  	}
    86  }
    87  
    88  func testListingPermissionsWithValidParamsSucceeds(t *testing.T) {
    89  	// given
    90  	ctx := context.Background()
    91  	hostname := vgrand.RandomStr(5)
    92  	expectedWallet, firstKey := walletWithKey(t)
    93  	if err := expectedWallet.UpdatePermissions(hostname, wallet.Permissions{
    94  		PublicKeys: wallet.PublicKeysPermission{
    95  			Access: "read",
    96  			AllowedKeys: []string{
    97  				firstKey.PublicKey(),
    98  			},
    99  		},
   100  	}); err != nil {
   101  		t.Fatalf("could not update permissions for test: %v", err)
   102  	}
   103  
   104  	// setup
   105  	handler := newListPermissionsHandler(t)
   106  	// -- expected calls
   107  	handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   108  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil)
   109  	handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil)
   110  
   111  	// when
   112  	result, errorDetails := handler.handle(t, ctx, api.AdminListPermissionsParams{
   113  		Wallet: expectedWallet.Name(),
   114  	})
   115  
   116  	// then
   117  	require.Nil(t, errorDetails)
   118  	assert.Equal(t, api.AdminListPermissionsResult{
   119  		Permissions: map[string]wallet.PermissionsSummary{
   120  			hostname: {
   121  				"public_keys": "read",
   122  			},
   123  		},
   124  	}, result)
   125  }
   126  
   127  func testListingPermissionsFromWalletThatDoesNotExistsFails(t *testing.T) {
   128  	// given
   129  	ctx := context.Background()
   130  	name := vgrand.RandomStr(5)
   131  
   132  	// setup
   133  	handler := newListPermissionsHandler(t)
   134  	// -- expected calls
   135  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, nil)
   136  
   137  	// when
   138  	result, errorDetails := handler.handle(t, ctx, api.AdminListPermissionsParams{
   139  		Wallet: name,
   140  	})
   141  
   142  	// then
   143  	require.NotNil(t, errorDetails)
   144  	assert.Empty(t, result)
   145  	assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist)
   146  }
   147  
   148  func testAdminListPermissionsGettingInternalErrorDuringWalletVerificationFails(t *testing.T) {
   149  	// given
   150  	ctx := context.Background()
   151  	name := vgrand.RandomStr(5)
   152  
   153  	// setup
   154  	handler := newListPermissionsHandler(t)
   155  	// -- expected calls
   156  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, assert.AnError)
   157  
   158  	// when
   159  	result, errorDetails := handler.handle(t, ctx, api.AdminListPermissionsParams{
   160  		Wallet: name,
   161  	})
   162  
   163  	// then
   164  	require.NotNil(t, errorDetails)
   165  	assert.Empty(t, result)
   166  	assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError))
   167  }
   168  
   169  func testAdminListPermissionsGettingInternalErrorDuringWalletRetrievalFails(t *testing.T) {
   170  	// given
   171  	ctx := context.Background()
   172  	name := vgrand.RandomStr(5)
   173  
   174  	// setup
   175  	handler := newListPermissionsHandler(t)
   176  	// -- expected calls
   177  	handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(true, nil)
   178  	handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, name).Times(1).Return(true, nil)
   179  	handler.walletStore.EXPECT().GetWallet(ctx, name).Times(1).Return(nil, assert.AnError)
   180  
   181  	// when
   182  	result, errorDetails := handler.handle(t, ctx, api.AdminListPermissionsParams{
   183  		Wallet: name,
   184  	})
   185  
   186  	// then
   187  	require.NotNil(t, errorDetails)
   188  	assert.Empty(t, result)
   189  	assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError))
   190  }
   191  
   192  type listPermissionsHandler struct {
   193  	*api.AdminListPermissions
   194  	ctrl        *gomock.Controller
   195  	walletStore *mocks.MockWalletStore
   196  }
   197  
   198  func (h *listPermissionsHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) (api.AdminListPermissionsResult, *jsonrpc.ErrorDetails) {
   199  	t.Helper()
   200  
   201  	rawResult, err := h.Handle(ctx, params)
   202  	if rawResult != nil {
   203  		result, ok := rawResult.(api.AdminListPermissionsResult)
   204  		if !ok {
   205  			t.Fatal("AdminListPermissions handler result is not a AdminListPermissionsResult")
   206  		}
   207  		return result, err
   208  	}
   209  	return api.AdminListPermissionsResult{}, err
   210  }
   211  
   212  func newListPermissionsHandler(t *testing.T) *listPermissionsHandler {
   213  	t.Helper()
   214  
   215  	ctrl := gomock.NewController(t)
   216  	walletStore := mocks.NewMockWalletStore(ctrl)
   217  
   218  	return &listPermissionsHandler{
   219  		AdminListPermissions: api.NewAdminListPermissions(walletStore),
   220  		ctrl:                 ctrl,
   221  		walletStore:          walletStore,
   222  	}
   223  }