code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_revoke_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 TestAdminRevokePermissions(t *testing.T) { 35 t.Run("Documentation matches the code", testAdminRevokePermissionsSchemaCorrect) 36 t.Run("Revoking permissions with invalid params fails", testRevokingPermissionsWithInvalidParamsFails) 37 t.Run("Revoking permissions with valid params succeeds", testRevokingPermissionsWithValidParamsSucceeds) 38 t.Run("Revoking permissions from wallet that does not exists fails", testRevokingPermissionsFromWalletThatDoesNotExistsFails) 39 t.Run("Getting internal error during wallet verification fails", testAdminRevokePermissionsGettingInternalErrorDuringWalletVerificationFails) 40 t.Run("Getting internal error during wallet retrieval fails", testAdminRevokePermissionsGettingInternalErrorDuringWalletRetrievalFails) 41 t.Run("Getting internal error during wallet saving fails", testAdminRevokePermissionsGettingInternalErrorDuringWalletSavingFails) 42 } 43 44 func testAdminRevokePermissionsSchemaCorrect(t *testing.T) { 45 assertEqualSchema(t, "admin.revoke_permissions", api.AdminRevokePermissionsParams{}, nil) 46 } 47 48 func testRevokingPermissionsWithInvalidParamsFails(t *testing.T) { 49 tcs := []struct { 50 name string 51 params interface{} 52 expectedError error 53 }{ 54 { 55 name: "with nil params", 56 params: nil, 57 expectedError: api.ErrParamsRequired, 58 }, { 59 name: "with wrong type of params", 60 params: "test", 61 expectedError: api.ErrParamsDoNotMatch, 62 }, { 63 name: "with empty name", 64 params: api.AdminRevokePermissionsParams{ 65 Wallet: "", 66 Hostname: vgrand.RandomStr(5), 67 }, 68 expectedError: api.ErrWalletIsRequired, 69 }, { 70 name: "with empty hostname", 71 params: api.AdminRevokePermissionsParams{ 72 Wallet: vgrand.RandomStr(5), 73 Hostname: "", 74 }, 75 expectedError: api.ErrHostnameIsRequired, 76 }, 77 } 78 79 for _, tc := range tcs { 80 t.Run(tc.name, func(tt *testing.T) { 81 // given 82 ctx := context.Background() 83 84 // setup 85 handler := newRevokePermissionsHandler(tt) 86 87 // when 88 errorDetails := handler.handle(t, ctx, tc.params) 89 90 // then 91 assertInvalidParams(tt, errorDetails, tc.expectedError) 92 }) 93 } 94 } 95 96 func testRevokingPermissionsWithValidParamsSucceeds(t *testing.T) { 97 // given 98 ctx := context.Background() 99 hostname1 := vgrand.RandomStr(5) 100 expectedWallet, firstKey := walletWithKey(t) 101 if err := expectedWallet.UpdatePermissions(hostname1, 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 hostname2 := vgrand.RandomStr(5) 112 permissions2 := wallet.Permissions{ 113 PublicKeys: wallet.PublicKeysPermission{ 114 Access: "read", 115 AllowedKeys: []string{ 116 firstKey.PublicKey(), 117 }, 118 }, 119 } 120 if err := expectedWallet.UpdatePermissions(hostname2, permissions2); err != nil { 121 t.Fatalf("could not update permissions for test: %v", err) 122 } 123 124 // setup 125 handler := newRevokePermissionsHandler(t) 126 // -- expected calls 127 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 128 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 129 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 130 handler.walletStore.EXPECT().UpdateWallet(ctx, expectedWallet).Times(1).Return(nil) 131 132 // when 133 errorDetails := handler.handle(t, ctx, api.AdminRevokePermissionsParams{ 134 Wallet: expectedWallet.Name(), 135 Hostname: hostname1, 136 }) 137 138 // then 139 require.Nil(t, errorDetails) 140 assert.Equal(t, wallet.DefaultPermissions(), expectedWallet.Permissions(hostname1)) 141 assert.Equal(t, permissions2, expectedWallet.Permissions(hostname2)) 142 } 143 144 func testRevokingPermissionsFromWalletThatDoesNotExistsFails(t *testing.T) { 145 // given 146 ctx := context.Background() 147 name := vgrand.RandomStr(5) 148 149 // setup 150 handler := newRevokePermissionsHandler(t) 151 // -- expected calls 152 handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, nil) 153 154 // when 155 errorDetails := handler.handle(t, ctx, api.AdminRevokePermissionsParams{ 156 Wallet: name, 157 Hostname: vgrand.RandomStr(5), 158 }) 159 160 // then 161 require.NotNil(t, errorDetails) 162 assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist) 163 } 164 165 func testAdminRevokePermissionsGettingInternalErrorDuringWalletVerificationFails(t *testing.T) { 166 // given 167 ctx := context.Background() 168 name := vgrand.RandomStr(5) 169 170 // setup 171 handler := newRevokePermissionsHandler(t) 172 // -- expected calls 173 handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, assert.AnError) 174 175 // when 176 errorDetails := handler.handle(t, ctx, api.AdminRevokePermissionsParams{ 177 Wallet: name, 178 Hostname: vgrand.RandomStr(5), 179 }) 180 181 // then 182 require.NotNil(t, errorDetails) 183 assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError)) 184 } 185 186 func testAdminRevokePermissionsGettingInternalErrorDuringWalletRetrievalFails(t *testing.T) { 187 // given 188 ctx := context.Background() 189 name := vgrand.RandomStr(5) 190 191 // setup 192 handler := newRevokePermissionsHandler(t) 193 // -- expected calls 194 handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(true, nil) 195 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, name).Times(1).Return(true, nil) 196 handler.walletStore.EXPECT().GetWallet(ctx, name).Times(1).Return(nil, assert.AnError) 197 198 // when 199 errorDetails := handler.handle(t, ctx, api.AdminRevokePermissionsParams{ 200 Wallet: name, 201 Hostname: vgrand.RandomStr(5), 202 }) 203 204 // then 205 require.NotNil(t, errorDetails) 206 assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError)) 207 } 208 209 func testAdminRevokePermissionsGettingInternalErrorDuringWalletSavingFails(t *testing.T) { 210 // given 211 ctx := context.Background() 212 expectedWallet, _, err := wallet.NewHDWallet(vgrand.RandomStr(5)) 213 if err != nil { 214 t.Fatal(err) 215 } 216 217 // setup 218 handler := newRevokePermissionsHandler(t) 219 // -- expected calls 220 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 221 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 222 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 223 handler.walletStore.EXPECT().UpdateWallet(ctx, expectedWallet).Times(1).Return(assert.AnError) 224 225 // when 226 errorDetails := handler.handle(t, ctx, api.AdminRevokePermissionsParams{ 227 Wallet: expectedWallet.Name(), 228 Hostname: vgrand.RandomStr(5), 229 }) 230 231 // then 232 require.NotNil(t, errorDetails) 233 assertInternalError(t, errorDetails, fmt.Errorf("could not save the wallet: %w", assert.AnError)) 234 } 235 236 type revokePermissionsHandler struct { 237 *api.AdminRevokePermissions 238 ctrl *gomock.Controller 239 walletStore *mocks.MockWalletStore 240 } 241 242 func (h *revokePermissionsHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) *jsonrpc.ErrorDetails { 243 t.Helper() 244 245 rawResult, err := h.Handle(ctx, params) 246 require.Empty(t, rawResult) 247 return err 248 } 249 250 func newRevokePermissionsHandler(t *testing.T) *revokePermissionsHandler { 251 t.Helper() 252 253 ctrl := gomock.NewController(t) 254 walletStore := mocks.NewMockWalletStore(ctrl) 255 256 return &revokePermissionsHandler{ 257 AdminRevokePermissions: api.NewAdminRevokePermissions(walletStore), 258 ctrl: ctrl, 259 walletStore: walletStore, 260 } 261 }