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