code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_taint_key_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 TestAdminTaintKey(t *testing.T) { 34 t.Run("Documentation matches the code", testAdminTaintKeySchemaCorrect) 35 t.Run("Tainting a key with invalid params fails", testTaintingKeyWithInvalidParamsFails) 36 t.Run("Tainting a key with valid params succeeds", testTaintingKeyWithValidParamsSucceeds) 37 t.Run("Tainting a key on unknown wallet fails", testTaintingKeyOnUnknownWalletFails) 38 t.Run("Tainting a key on unknown key fails", testTaintingKeyOnUnknownKeyFails) 39 t.Run("Getting internal error during wallet verification doesn't taint the key", testGettingInternalErrorDuringWalletVerificationDoesNotTaintKey) 40 t.Run("Getting internal error during wallet retrieval doesn't taint the key", testGettingInternalErrorDuringWalletRetrievalDoesNotTaintKey) 41 t.Run("Getting internal error during wallet saving doesn't taint the key", testGettingInternalErrorDuringWalletSavingDoesNotTaintKey) 42 } 43 44 func testAdminTaintKeySchemaCorrect(t *testing.T) { 45 assertEqualSchema(t, "admin.taint_key", api.AdminTaintKeyParams{}, nil) 46 } 47 48 func testTaintingKeyWithInvalidParamsFails(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.AdminTaintKeyParams{ 65 Wallet: "", 66 PublicKey: "b5fd9d3c4ad553cb3196303b6e6df7f484cf7f5331a572a45031239fd71ad8a0", 67 }, 68 expectedError: api.ErrWalletIsRequired, 69 }, { 70 name: "with empty public key", 71 params: api.AdminTaintKeyParams{ 72 PublicKey: "", 73 Wallet: vgrand.RandomStr(5), 74 }, 75 expectedError: api.ErrPublicKeyIsRequired, 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 := newTaintKeyHandler(tt) 86 87 // when 88 errorDetails := handler.handle(t, ctx, tc.params) 89 90 // the 91 assertInvalidParams(tt, errorDetails, tc.expectedError) 92 }) 93 } 94 } 95 96 func testTaintingKeyWithValidParamsSucceeds(t *testing.T) { 97 // given 98 ctx := context.Background() 99 expectedWallet, kp := walletWithKey(t) 100 101 // setup 102 handler := newTaintKeyHandler(t) 103 // -- expected calls 104 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 105 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 106 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 107 handler.walletStore.EXPECT().UpdateWallet(ctx, expectedWallet).Times(1).Return(nil) 108 109 // when 110 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 111 Wallet: expectedWallet.Name(), 112 PublicKey: kp.PublicKey(), 113 }) 114 115 // then 116 require.Nil(t, errorDetails) 117 require.True(t, expectedWallet.ListKeyPairs()[0].IsTainted()) 118 } 119 120 func testTaintingKeyOnUnknownWalletFails(t *testing.T) { 121 // given 122 ctx := context.Background() 123 name := vgrand.RandomStr(5) 124 125 // setup 126 handler := newTaintKeyHandler(t) 127 // -- expected calls 128 handler.walletStore.EXPECT().WalletExists(ctx, name).Times(1).Return(false, nil) 129 130 // when 131 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 132 Wallet: name, 133 PublicKey: vgrand.RandomStr(5), 134 }) 135 136 // then 137 require.NotNil(t, errorDetails) 138 assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist) 139 } 140 141 func testTaintingKeyOnUnknownKeyFails(t *testing.T) { 142 // given 143 ctx := context.Background() 144 expectedWallet, _ := walletWithKey(t) 145 146 // setup 147 handler := newTaintKeyHandler(t) 148 // -- expected calls 149 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 150 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 151 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 152 153 // when 154 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 155 Wallet: expectedWallet.Name(), 156 PublicKey: vgrand.RandomStr(5), 157 }) 158 159 // then 160 require.NotNil(t, errorDetails) 161 assertInvalidParams(t, errorDetails, api.ErrPublicKeyDoesNotExist) 162 } 163 164 func testGettingInternalErrorDuringWalletVerificationDoesNotTaintKey(t *testing.T) { 165 // given 166 ctx := context.Background() 167 expectedWallet, kp := walletWithKey(t) 168 169 // setup 170 handler := newTaintKeyHandler(t) 171 // -- expected calls 172 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(false, assert.AnError) 173 174 // when 175 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 176 Wallet: expectedWallet.Name(), 177 PublicKey: kp.PublicKey(), 178 }) 179 180 // then 181 require.NotNil(t, errorDetails) 182 assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError)) 183 } 184 185 func testGettingInternalErrorDuringWalletRetrievalDoesNotTaintKey(t *testing.T) { 186 // given 187 ctx := context.Background() 188 expectedWallet, kp := walletWithKey(t) 189 190 // setup 191 handler := newTaintKeyHandler(t) 192 // -- expected calls 193 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 194 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 195 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(nil, assert.AnError) 196 197 // when 198 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 199 Wallet: expectedWallet.Name(), 200 PublicKey: kp.PublicKey(), 201 }) 202 203 // then 204 require.NotNil(t, errorDetails) 205 assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError)) 206 } 207 208 func testGettingInternalErrorDuringWalletSavingDoesNotTaintKey(t *testing.T) { 209 // given 210 ctx := context.Background() 211 expectedWallet, kp := walletWithKey(t) 212 213 // setup 214 handler := newTaintKeyHandler(t) 215 // -- expected calls 216 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 217 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 218 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 219 handler.walletStore.EXPECT().UpdateWallet(ctx, gomock.Any()).Times(1).Return(assert.AnError) 220 221 // when 222 errorDetails := handler.handle(t, ctx, api.AdminTaintKeyParams{ 223 Wallet: expectedWallet.Name(), 224 PublicKey: kp.PublicKey(), 225 }) 226 227 // then 228 require.NotNil(t, errorDetails) 229 assertInternalError(t, errorDetails, fmt.Errorf("could not save the wallet: %w", assert.AnError)) 230 } 231 232 type taintKeyHandler struct { 233 *api.AdminTaintKey 234 ctrl *gomock.Controller 235 walletStore *mocks.MockWalletStore 236 } 237 238 func (h *taintKeyHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) *jsonrpc.ErrorDetails { 239 t.Helper() 240 241 result, err := h.Handle(ctx, params) 242 assert.Nil(t, result) 243 return err 244 } 245 246 func newTaintKeyHandler(t *testing.T) *taintKeyHandler { 247 t.Helper() 248 249 ctrl := gomock.NewController(t) 250 walletStore := mocks.NewMockWalletStore(ctrl) 251 252 return &taintKeyHandler{ 253 AdminTaintKey: api.NewAdminTaintKey(walletStore), 254 ctrl: ctrl, 255 walletStore: walletStore, 256 } 257 }