code.vegaprotocol.io/vega@v0.79.0/wallet/api/admin_annotate_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 "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 TestAdminAnnotateKey(t *testing.T) { 35 t.Run("Documentation matches the code", testAdminAnnotateKeySchemaCorrect) 36 t.Run("Annotating a key with invalid params fails", testAnnotatingKeyWithInvalidParamsFails) 37 t.Run("Annotating a key with valid params succeeds", testAnnotatingKeyWithValidParamsSucceeds) 38 t.Run("Annotating a key on unknown wallet fails", testAnnotatingKeyOnUnknownWalletFails) 39 t.Run("Annotating a key on unknown key fails", testAnnotatingKeyOnUnknownKeyFails) 40 t.Run("Getting internal error during wallet verification doesn't annotate the key", testGettingInternalErrorDuringWalletVerificationDoesNotAnnotateKey) 41 t.Run("Getting internal error during wallet retrieval doesn't annotate the key", testGettingInternalErrorDuringWalletRetrievalDoesNotAnnotateKey) 42 t.Run("Getting internal error during wallet saving doesn't annotate the key", testGettingInternalErrorDuringWalletSavingDoesNotAnnotateKey) 43 } 44 45 func testAdminAnnotateKeySchemaCorrect(t *testing.T) { 46 assertEqualSchema(t, "admin.annotate_key", api.AdminAnnotateKeyParams{}, api.AdminAnnotateKeyResult{}) 47 } 48 49 func testAnnotatingKeyWithInvalidParamsFails(t *testing.T) { 50 tcs := []struct { 51 name string 52 params interface{} 53 expectedError error 54 }{ 55 { 56 name: "with nil params", 57 params: nil, 58 expectedError: api.ErrParamsRequired, 59 }, { 60 name: "with wrong type of params", 61 params: "test", 62 expectedError: api.ErrParamsDoNotMatch, 63 }, { 64 name: "with empty name", 65 params: api.AdminAnnotateKeyParams{ 66 Wallet: "", 67 PublicKey: "b5fd9d3c4ad553cb3196303b6e6df7f484cf7f5331a572a45031239fd71ad8a0", 68 Metadata: []wallet.Metadata{{Key: vgrand.RandomStr(5), Value: vgrand.RandomStr(5)}}, 69 }, 70 expectedError: api.ErrWalletIsRequired, 71 }, { 72 name: "with empty public key", 73 params: api.AdminAnnotateKeyParams{ 74 PublicKey: "", 75 Metadata: []wallet.Metadata{{Key: vgrand.RandomStr(5), Value: vgrand.RandomStr(5)}}, 76 Wallet: vgrand.RandomStr(5), 77 }, 78 expectedError: api.ErrPublicKeyIsRequired, 79 }, 80 } 81 82 for _, tc := range tcs { 83 t.Run(tc.name, func(tt *testing.T) { 84 // given 85 ctx := context.Background() 86 87 // setup 88 handler := newAnnotateKeyHandler(tt) 89 90 // when 91 result, errorDetails := handler.handle(t, ctx, tc.params) 92 93 // then 94 require.Empty(tt, result) 95 assertInvalidParams(tt, errorDetails, tc.expectedError) 96 }) 97 } 98 } 99 100 func testAnnotatingKeyWithValidParamsSucceeds(t *testing.T) { 101 // given 102 ctx := context.Background() 103 expectedWallet, kp := walletWithKey(t) 104 105 // setup 106 handler := newAnnotateKeyHandler(t) 107 // -- expected calls 108 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 109 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 110 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 111 handler.walletStore.EXPECT().UpdateWallet(ctx, expectedWallet).Times(1).Return(nil) 112 113 // when 114 result, errorDetails := handler.handle(t, ctx, api.AdminAnnotateKeyParams{ 115 Wallet: expectedWallet.Name(), 116 PublicKey: kp.PublicKey(), 117 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 118 }) 119 120 // then 121 require.Nil(t, errorDetails) 122 expectedMeta := []wallet.Metadata{{Key: "mode", Value: "test"}, {Key: "name", Value: "Key 1"}} 123 assert.Equal(t, expectedMeta, result.Metadata) 124 assert.Equal(t, expectedMeta, expectedWallet.ListKeyPairs()[0].Metadata()) 125 } 126 127 func testAnnotatingKeyOnUnknownWalletFails(t *testing.T) { 128 // given 129 ctx := context.Background() 130 name := vgrand.RandomStr(5) 131 132 // setup 133 handler := newAnnotateKeyHandler(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.AdminAnnotateKeyParams{ 139 Wallet: name, 140 PublicKey: vgrand.RandomStr(5), 141 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 142 }) 143 144 // then 145 require.NotNil(t, errorDetails) 146 assert.Empty(t, result) 147 assertInvalidParams(t, errorDetails, api.ErrWalletDoesNotExist) 148 } 149 150 func testAnnotatingKeyOnUnknownKeyFails(t *testing.T) { 151 // given 152 ctx := context.Background() 153 expectedWallet, _ := walletWithKey(t) 154 155 // setup 156 handler := newAnnotateKeyHandler(t) 157 // -- expected calls 158 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 159 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 160 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 161 162 // when 163 result, errorDetails := handler.handle(t, ctx, api.AdminAnnotateKeyParams{ 164 Wallet: expectedWallet.Name(), 165 PublicKey: vgrand.RandomStr(5), 166 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 167 }) 168 169 // then 170 require.NotNil(t, errorDetails) 171 assert.Empty(t, result) 172 assertInvalidParams(t, errorDetails, api.ErrPublicKeyDoesNotExist) 173 } 174 175 func testGettingInternalErrorDuringWalletVerificationDoesNotAnnotateKey(t *testing.T) { 176 // given 177 ctx := context.Background() 178 expectedWallet, kp := walletWithKey(t) 179 180 // setup 181 handler := newAnnotateKeyHandler(t) 182 // -- expected calls 183 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(false, assert.AnError) 184 185 // when 186 result, errorDetails := handler.handle(t, ctx, api.AdminAnnotateKeyParams{ 187 Wallet: expectedWallet.Name(), 188 PublicKey: kp.PublicKey(), 189 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 190 }) 191 192 // then 193 require.NotNil(t, errorDetails) 194 assert.Empty(t, result) 195 assertInternalError(t, errorDetails, fmt.Errorf("could not verify the wallet exists: %w", assert.AnError)) 196 } 197 198 func testGettingInternalErrorDuringWalletRetrievalDoesNotAnnotateKey(t *testing.T) { 199 // given 200 ctx := context.Background() 201 expectedWallet, kp := walletWithKey(t) 202 203 // setup 204 handler := newAnnotateKeyHandler(t) 205 // -- expected calls 206 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 207 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 208 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(nil, assert.AnError) 209 210 // when 211 result, errorDetails := handler.handle(t, ctx, api.AdminAnnotateKeyParams{ 212 Wallet: expectedWallet.Name(), 213 PublicKey: kp.PublicKey(), 214 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 215 }) 216 217 // then 218 require.NotNil(t, errorDetails) 219 assert.Empty(t, result) 220 assertInternalError(t, errorDetails, fmt.Errorf("could not retrieve the wallet: %w", assert.AnError)) 221 } 222 223 func testGettingInternalErrorDuringWalletSavingDoesNotAnnotateKey(t *testing.T) { 224 // given 225 ctx := context.Background() 226 expectedWallet, kp := walletWithKey(t) 227 228 // setup 229 handler := newAnnotateKeyHandler(t) 230 // -- expected calls 231 handler.walletStore.EXPECT().WalletExists(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 232 handler.walletStore.EXPECT().IsWalletAlreadyUnlocked(ctx, expectedWallet.Name()).Times(1).Return(true, nil) 233 handler.walletStore.EXPECT().GetWallet(ctx, expectedWallet.Name()).Times(1).Return(expectedWallet, nil) 234 handler.walletStore.EXPECT().UpdateWallet(ctx, gomock.Any()).Times(1).Return(assert.AnError) 235 236 // when 237 result, errorDetails := handler.handle(t, ctx, api.AdminAnnotateKeyParams{ 238 Wallet: expectedWallet.Name(), 239 PublicKey: kp.PublicKey(), 240 Metadata: []wallet.Metadata{{Key: "mode", Value: "test"}}, 241 }) 242 243 // then 244 require.NotNil(t, errorDetails) 245 assert.Empty(t, result) 246 assertInternalError(t, errorDetails, fmt.Errorf("could not save the wallet: %w", assert.AnError)) 247 } 248 249 type annotateKeyHandler struct { 250 *api.AdminAnnotateKey 251 ctrl *gomock.Controller 252 walletStore *mocks.MockWalletStore 253 } 254 255 func (h *annotateKeyHandler) handle(t *testing.T, ctx context.Context, params jsonrpc.Params) (api.AdminAnnotateKeyResult, *jsonrpc.ErrorDetails) { 256 t.Helper() 257 258 rawResult, err := h.Handle(ctx, params) 259 if rawResult != nil { 260 result, ok := rawResult.(api.AdminAnnotateKeyResult) 261 if !ok { 262 t.Fatal("AdminAnnotateKey handler result is not a AdminAnnotateKeyResult") 263 } 264 return result, err 265 } 266 return api.AdminAnnotateKeyResult{}, err 267 } 268 269 func newAnnotateKeyHandler(t *testing.T) *annotateKeyHandler { 270 t.Helper() 271 272 ctrl := gomock.NewController(t) 273 walletStore := mocks.NewMockWalletStore(ctrl) 274 275 return &annotateKeyHandler{ 276 AdminAnnotateKey: api.NewAdminAnnotateKey(walletStore), 277 ctrl: ctrl, 278 walletStore: walletStore, 279 } 280 }