github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/didexchange/client_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package didexchange 8 9 import ( 10 "crypto/ed25519" 11 "crypto/rand" 12 "encoding/base64" 13 "encoding/json" 14 "errors" 15 "fmt" 16 "strconv" 17 "testing" 18 "time" 19 20 "github.com/google/uuid" 21 "github.com/stretchr/testify/require" 22 23 "github.com/hyperledger/aries-framework-go/component/storageutil/mem" 24 "github.com/hyperledger/aries-framework-go/pkg/common/model" 25 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 26 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator" 27 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange" 28 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator" 29 "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport" 30 "github.com/hyperledger/aries-framework-go/pkg/doc/did" 31 "github.com/hyperledger/aries-framework-go/pkg/framework/aries" 32 "github.com/hyperledger/aries-framework-go/pkg/kms" 33 "github.com/hyperledger/aries-framework-go/pkg/kms/localkms" 34 mockprotocol "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol" 35 mocksvc "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange" 36 mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator" 37 mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms" 38 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 39 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 40 mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr" 41 "github.com/hyperledger/aries-framework-go/pkg/secretlock" 42 "github.com/hyperledger/aries-framework-go/pkg/secretlock/noop" 43 "github.com/hyperledger/aries-framework-go/pkg/store/connection" 44 "github.com/hyperledger/aries-framework-go/pkg/vdr/peer" 45 spi "github.com/hyperledger/aries-framework-go/spi/storage" 46 ) 47 48 func TestNew(t *testing.T) { 49 t.Run("test new client", func(t *testing.T) { 50 svc, err := didexchange.New(&mockprotocol.MockProvider{ 51 ServiceMap: map[string]interface{}{ 52 mediator.Coordination: &mockroute.MockMediatorSvc{}, 53 }, 54 }) 55 require.NoError(t, err) 56 require.NotNil(t, svc) 57 58 _, err = New(&mockprovider.Provider{ 59 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 60 StorageProviderValue: mockstore.NewMockStoreProvider(), 61 ServiceMap: map[string]interface{}{ 62 didexchange.DIDExchange: svc, 63 mediator.Coordination: &mockroute.MockMediatorSvc{}, 64 }, 65 }) 66 require.NoError(t, err) 67 }) 68 69 t.Run("test error from get service from context", func(t *testing.T) { 70 _, err := New(&mockprovider.Provider{ServiceErr: fmt.Errorf("service error")}) 71 require.Error(t, err) 72 require.Contains(t, err.Error(), "service error") 73 }) 74 75 t.Run("test error from cast service", func(t *testing.T) { 76 _, err := New(&mockprovider.Provider{ServiceValue: nil}) 77 require.Error(t, err) 78 require.Contains(t, err.Error(), "cast service to DIDExchange Service failed") 79 }) 80 81 t.Run("test route service cast error", func(t *testing.T) { 82 _, err := New(&mockprovider.Provider{ 83 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 84 StorageProviderValue: mockstore.NewMockStoreProvider(), 85 ServiceMap: map[string]interface{}{ 86 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{}, 87 mediator.Coordination: &mocksvc.MockDIDExchangeSvc{}, 88 }, 89 }) 90 require.Error(t, err) 91 require.Contains(t, err.Error(), "cast service to Route Service failed") 92 }) 93 94 t.Run("test error from open store", func(t *testing.T) { 95 svc, err := didexchange.New(&mockprotocol.MockProvider{ 96 ServiceMap: map[string]interface{}{ 97 mediator.Coordination: &mockroute.MockMediatorSvc{}, 98 }, 99 }) 100 require.NoError(t, err) 101 require.NotNil(t, svc) 102 103 _, err = New(&mockprovider.Provider{ 104 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 105 StorageProviderValue: &mockstore.MockStoreProvider{ 106 ErrOpenStoreHandle: fmt.Errorf("failed to open store"), 107 }, 108 ServiceMap: map[string]interface{}{ 109 didexchange.DIDExchange: svc, 110 mediator.Coordination: &mockroute.MockMediatorSvc{}, 111 }, 112 ServiceEndpointValue: "endpoint", 113 }) 114 require.Error(t, err) 115 require.Contains(t, err.Error(), "failed to open store") 116 }) 117 118 t.Run("test error from open protocol state store", func(t *testing.T) { 119 svc, err := didexchange.New(&mockprotocol.MockProvider{ 120 ServiceMap: map[string]interface{}{ 121 mediator.Coordination: &mockroute.MockMediatorSvc{}, 122 }, 123 }) 124 require.NoError(t, err) 125 require.NotNil(t, svc) 126 127 _, err = New(&mockprovider.Provider{ 128 StorageProviderValue: mockstore.NewMockStoreProvider(), 129 ProtocolStateStorageProviderValue: &mockstore.MockStoreProvider{ 130 ErrOpenStoreHandle: fmt.Errorf("failed to open protocol state store"), 131 }, 132 ServiceMap: map[string]interface{}{ 133 didexchange.DIDExchange: svc, 134 mediator.Coordination: &mockroute.MockMediatorSvc{}, 135 }, 136 ServiceEndpointValue: "endpoint", 137 }) 138 require.Error(t, err) 139 require.Contains(t, err.Error(), "failed to open protocol state store") 140 }) 141 } 142 143 func TestClient_CreateInvitation(t *testing.T) { 144 t.Run("test success", func(t *testing.T) { 145 svc, err := didexchange.New(&mockprotocol.MockProvider{ 146 ServiceMap: map[string]interface{}{ 147 mediator.Coordination: &mockroute.MockMediatorSvc{}, 148 }, 149 }) 150 require.NoError(t, err) 151 require.NotNil(t, svc) 152 153 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 154 require.NoError(t, err) 155 156 c, err := New(&mockprovider.Provider{ 157 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 158 StorageProviderValue: mockstore.NewMockStoreProvider(), 159 ServiceMap: map[string]interface{}{ 160 didexchange.DIDExchange: svc, 161 mediator.Coordination: &mockroute.MockMediatorSvc{}, 162 }, 163 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 164 ServiceEndpointValue: "endpoint", 165 }) 166 167 require.NoError(t, err) 168 inviteReq, err := c.CreateInvitation("agent") 169 require.NoError(t, err) 170 require.NotNil(t, inviteReq) 171 require.NotEmpty(t, inviteReq.Label) 172 require.NotEmpty(t, inviteReq.ID) 173 require.Nil(t, inviteReq.RoutingKeys) 174 require.Equal(t, "endpoint", inviteReq.ServiceEndpoint) 175 }) 176 177 t.Run("test success with DIDCommV2 media profile", func(t *testing.T) { 178 svc, err := didexchange.New(&mockprotocol.MockProvider{ 179 ServiceMap: map[string]interface{}{ 180 mediator.Coordination: &mockroute.MockMediatorSvc{}, 181 }, 182 }) 183 require.NoError(t, err) 184 require.NotNil(t, svc) 185 186 store, err := kms.NewAriesProviderWrapper(mockstore.NewMockStoreProvider()) 187 require.NoError(t, err) 188 189 km := newKMS(t, store) 190 191 c, err := New(&mockprovider.Provider{ 192 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 193 StorageProviderValue: mockstore.NewMockStoreProvider(), 194 ServiceMap: map[string]interface{}{ 195 didexchange.DIDExchange: svc, 196 mediator.Coordination: &mockroute.MockMediatorSvc{}, 197 }, 198 KMSValue: km, 199 ServiceEndpointValue: "endpoint", 200 KeyAgreementTypeValue: kms.NISTP521ECDHKWType, 201 MediaTypeProfilesValue: []string{transport.MediaTypeDIDCommV2Profile}, 202 }) 203 204 require.NoError(t, err) 205 inviteReq, err := c.CreateInvitation("agent") 206 require.NoError(t, err) 207 require.NotNil(t, inviteReq) 208 require.NotEmpty(t, inviteReq.Label) 209 require.NotEmpty(t, inviteReq.ID) 210 require.Nil(t, inviteReq.RoutingKeys) 211 require.Equal(t, "endpoint", inviteReq.ServiceEndpoint) 212 }) 213 214 t.Run("test success with DIDCommV2 media profile and KeyType option", func(t *testing.T) { 215 svc, err := didexchange.New(&mockprotocol.MockProvider{ 216 ServiceMap: map[string]interface{}{ 217 mediator.Coordination: &mockroute.MockMediatorSvc{}, 218 }, 219 }) 220 require.NoError(t, err) 221 require.NotNil(t, svc) 222 223 store, err := kms.NewAriesProviderWrapper(mockstore.NewMockStoreProvider()) 224 require.NoError(t, err) 225 226 km := newKMS(t, store) 227 228 c, err := New(&mockprovider.Provider{ 229 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 230 StorageProviderValue: mockstore.NewMockStoreProvider(), 231 ServiceMap: map[string]interface{}{ 232 didexchange.DIDExchange: svc, 233 mediator.Coordination: &mockroute.MockMediatorSvc{}, 234 }, 235 KMSValue: km, 236 ServiceEndpointValue: "endpoint", 237 KeyAgreementTypeValue: kms.NISTP521ECDHKWType, 238 MediaTypeProfilesValue: []string{transport.MediaTypeDIDCommV2Profile}, 239 }) 240 241 require.NoError(t, err) 242 inviteReq, err := c.CreateInvitation("agent", WithKeyType(kms.X25519ECDHKWType)) 243 require.NoError(t, err) 244 require.NotNil(t, inviteReq) 245 require.NotEmpty(t, inviteReq.Label) 246 require.NotEmpty(t, inviteReq.ID) 247 require.Nil(t, inviteReq.RoutingKeys) 248 x25519DIDKeyPrefix := "did:key:z6L" 249 require.Equal(t, x25519DIDKeyPrefix, inviteReq.RecipientKeys[0][:len(x25519DIDKeyPrefix)]) 250 require.Equal(t, "endpoint", inviteReq.ServiceEndpoint) 251 }) 252 253 t.Run("test failure with DIDCommV2 media profile with empty kms key for calling "+ 254 "kmsdidkey.BuildDIDKeyByKeyType()", func(t *testing.T) { 255 svc, err := didexchange.New(&mockprotocol.MockProvider{ 256 ServiceMap: map[string]interface{}{ 257 mediator.Coordination: &mockroute.MockMediatorSvc{}, 258 }, 259 }) 260 require.NoError(t, err) 261 require.NotNil(t, svc) 262 263 c, err := New(&mockprovider.Provider{ 264 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 265 StorageProviderValue: mockstore.NewMockStoreProvider(), 266 ServiceMap: map[string]interface{}{ 267 didexchange.DIDExchange: svc, 268 mediator.Coordination: &mockroute.MockMediatorSvc{}, 269 }, 270 KMSValue: &mockkms.KeyManager{}, 271 ServiceEndpointValue: "endpoint", 272 KeyAgreementTypeValue: kms.NISTP521ECDHKWType, 273 MediaTypeProfilesValue: []string{transport.MediaTypeDIDCommV2Profile}, 274 }) 275 require.NoError(t, err) 276 277 _, err = c.CreateInvitation("agent") 278 require.EqualError(t, err, "createInvitation: failed to build did:key by key type: buildDIDkeyByKMSKeyType"+ 279 " failed to unmarshal key type NISTP521ECDHKW: unexpected end of JSON input") 280 }) 281 282 t.Run("test error from createSigningKey", func(t *testing.T) { 283 svc, err := didexchange.New(&mockprotocol.MockProvider{ 284 ServiceMap: map[string]interface{}{ 285 mediator.Coordination: &mockroute.MockMediatorSvc{}, 286 }, 287 }) 288 require.NoError(t, err) 289 require.NotNil(t, svc) 290 291 c, err := New(&mockprovider.Provider{ 292 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 293 StorageProviderValue: mockstore.NewMockStoreProvider(), 294 ServiceMap: map[string]interface{}{ 295 didexchange.DIDExchange: svc, 296 mediator.Coordination: &mockroute.MockMediatorSvc{}, 297 }, 298 KMSValue: &mockkms.KeyManager{CrAndExportPubKeyErr: fmt.Errorf("createKeyErr")}, 299 }) 300 require.NoError(t, err) 301 _, err = c.CreateInvitation("agent") 302 require.Error(t, err) 303 require.Contains(t, err.Error(), "createKeyErr") 304 }) 305 306 t.Run("test error from save record", func(t *testing.T) { 307 store := &mockstore.MockStore{ 308 Store: make(map[string]mockstore.DBEntry), 309 ErrPut: fmt.Errorf("store error"), 310 } 311 312 svc, err := didexchange.New(&mockprotocol.MockProvider{ 313 StoreProvider: mockstore.NewCustomMockStoreProvider(store), 314 ServiceMap: map[string]interface{}{ 315 mediator.Coordination: &mockroute.MockMediatorSvc{}, 316 }, 317 }) 318 require.NoError(t, err) 319 require.NotNil(t, svc) 320 321 c, err := New(&mockprovider.Provider{ 322 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 323 StorageProviderValue: mockstore.NewCustomMockStoreProvider(store), 324 ServiceMap: map[string]interface{}{ 325 didexchange.DIDExchange: svc, 326 mediator.Coordination: &mockroute.MockMediatorSvc{}, 327 }, 328 KMSValue: &mockkms.KeyManager{}, 329 }) 330 require.NoError(t, err) 331 _, err = c.CreateInvitation("agent") 332 require.Error(t, err) 333 require.Contains(t, err.Error(), "failed to save invitation") 334 }) 335 336 t.Run("test success with router registered", func(t *testing.T) { 337 endpoint := "http://router.example.com" 338 routingKeys := []string{"abc", "xyz"} 339 340 svc, err := didexchange.New(&mockprotocol.MockProvider{ 341 ServiceMap: map[string]interface{}{ 342 mediator.Coordination: &mockroute.MockMediatorSvc{}, 343 }, 344 }) 345 require.NoError(t, err) 346 require.NotNil(t, svc) 347 348 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 349 require.NoError(t, err) 350 351 c, err := New(&mockprovider.Provider{ 352 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 353 StorageProviderValue: mockstore.NewMockStoreProvider(), 354 ServiceMap: map[string]interface{}{ 355 didexchange.DIDExchange: svc, 356 mediator.Coordination: &mockroute.MockMediatorSvc{ 357 Connections: []string{"xyz"}, 358 RoutingKeys: routingKeys, 359 RouterEndpoint: endpoint, 360 }, 361 }, 362 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 363 ServiceEndpointValue: "endpoint", 364 }) 365 require.NoError(t, err) 366 367 inviteReq, err := c.CreateInvitation("agent", WithRouterConnectionID("xyz")) 368 require.NoError(t, err) 369 require.NotNil(t, inviteReq) 370 require.NotEmpty(t, inviteReq.Label) 371 require.NotEmpty(t, inviteReq.ID) 372 require.Equal(t, endpoint, inviteReq.ServiceEndpoint) 373 require.Equal(t, routingKeys, inviteReq.RoutingKeys) 374 }) 375 376 t.Run("test create invitation with router config error", func(t *testing.T) { 377 svc, err := didexchange.New(&mockprotocol.MockProvider{ 378 ServiceMap: map[string]interface{}{ 379 mediator.Coordination: &mockroute.MockMediatorSvc{}, 380 }, 381 }) 382 require.NoError(t, err) 383 require.NotNil(t, svc) 384 385 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 386 require.NoError(t, err) 387 388 c, err := New(&mockprovider.Provider{ 389 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 390 StorageProviderValue: mockstore.NewMockStoreProvider(), 391 ServiceMap: map[string]interface{}{ 392 didexchange.DIDExchange: svc, 393 mediator.Coordination: &mockroute.MockMediatorSvc{ 394 Connections: []string{"xyz"}, 395 ConfigErr: errors.New("router config error"), 396 }, 397 }, 398 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 399 ServiceEndpointValue: "endpoint", 400 }) 401 require.NoError(t, err) 402 403 inviteReq, err := c.CreateInvitation("agent", WithRouterConnectionID("xyz")) 404 require.EqualError(t, err, "createInvitation: getRouterConfig: fetch router config: router config error") 405 require.Nil(t, inviteReq) 406 }) 407 408 t.Run("test create invitation with adding key to router error", func(t *testing.T) { 409 endpoint := "http://router.example.com" 410 routingKeys := []string{"abc", "xyz"} 411 412 svc, err := didexchange.New(&mockprotocol.MockProvider{ 413 ServiceMap: map[string]interface{}{ 414 mediator.Coordination: &mockroute.MockMediatorSvc{}, 415 }, 416 }) 417 require.NoError(t, err) 418 require.NotNil(t, svc) 419 420 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 421 require.NoError(t, err) 422 423 c, err := New(&mockprovider.Provider{ 424 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 425 StorageProviderValue: mockstore.NewMockStoreProvider(), 426 ServiceMap: map[string]interface{}{ 427 didexchange.DIDExchange: svc, 428 mediator.Coordination: &mockroute.MockMediatorSvc{ 429 Connections: []string{"xyz"}, 430 RoutingKeys: routingKeys, 431 RouterEndpoint: endpoint, 432 AddKeyErr: errors.New("failed to add key to the router"), 433 }, 434 }, 435 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 436 ServiceEndpointValue: "endpoint", 437 }) 438 require.NoError(t, err) 439 440 inviteReq, err := c.CreateInvitation("agent", WithRouterConnectionID("xyz")) 441 require.EqualError(t, err, "createInvitation: AddKeyToRouter: addKey: failed to add key to the router") 442 require.Nil(t, inviteReq) 443 }) 444 } 445 446 func TestClient_CreateInvitationWithDID(t *testing.T) { 447 t.Run("test success", func(t *testing.T) { 448 svc, err := didexchange.New(&mockprotocol.MockProvider{ 449 ServiceMap: map[string]interface{}{ 450 mediator.Coordination: &mockroute.MockMediatorSvc{}, 451 }, 452 }) 453 require.NoError(t, err) 454 require.NotNil(t, svc) 455 456 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 457 require.NoError(t, err) 458 459 c, err := New(&mockprovider.Provider{ 460 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 461 StorageProviderValue: mockstore.NewMockStoreProvider(), 462 ServiceMap: map[string]interface{}{ 463 didexchange.DIDExchange: svc, 464 mediator.Coordination: &mockroute.MockMediatorSvc{}, 465 }, 466 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 467 ServiceEndpointValue: "endpoint", 468 }) 469 require.NoError(t, err) 470 471 const label = "agent" 472 const id = "did:sidetree:123" 473 inviteReq, err := c.CreateInvitationWithDID(label, id) 474 require.NoError(t, err) 475 require.NotNil(t, inviteReq) 476 require.Equal(t, label, inviteReq.Label) 477 require.NotEmpty(t, inviteReq.ID) 478 require.Equal(t, id, inviteReq.DID) 479 }) 480 481 t.Run("test error from save invitation", func(t *testing.T) { 482 store := &mockstore.MockStore{ 483 Store: make(map[string]mockstore.DBEntry), 484 ErrPut: fmt.Errorf("store error"), 485 } 486 487 svc, err := didexchange.New(&mockprotocol.MockProvider{ 488 StoreProvider: mockstore.NewCustomMockStoreProvider(store), 489 ServiceMap: map[string]interface{}{ 490 mediator.Coordination: &mockroute.MockMediatorSvc{}, 491 }, 492 }) 493 require.NoError(t, err) 494 require.NotNil(t, svc) 495 496 c, err := New(&mockprovider.Provider{ 497 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 498 StorageProviderValue: mockstore.NewCustomMockStoreProvider(store), 499 ServiceMap: map[string]interface{}{ 500 didexchange.DIDExchange: svc, 501 mediator.Coordination: &mockroute.MockMediatorSvc{}, 502 }, 503 KMSValue: &mockkms.KeyManager{}, 504 }) 505 require.NoError(t, err) 506 507 _, err = c.CreateInvitationWithDID("agent", "did:sidetree:123") 508 require.Error(t, err) 509 require.Contains(t, err.Error(), "failed to save invitation") 510 }) 511 } 512 513 func TestClient_QueryConnectionByID(t *testing.T) { 514 const ( 515 connID = "id1" 516 threadID = "thid1" 517 ) 518 519 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 520 require.NoError(t, err) 521 522 t.Run("test success", func(t *testing.T) { 523 svc, err := didexchange.New(&mockprotocol.MockProvider{ 524 ServiceMap: map[string]interface{}{ 525 mediator.Coordination: &mockroute.MockMediatorSvc{}, 526 }, 527 }) 528 require.NoError(t, err) 529 require.NotNil(t, svc) 530 531 c, err := New(&mockprovider.Provider{ 532 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 533 StorageProviderValue: mockstore.NewMockStoreProvider(), 534 ServiceMap: map[string]interface{}{ 535 didexchange.DIDExchange: svc, 536 mediator.Coordination: &mockroute.MockMediatorSvc{}, 537 }, 538 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 539 ServiceEndpointValue: "endpoint", 540 }) 541 require.NoError(t, err) 542 543 connRec := &connection.Record{ConnectionID: connID, ThreadID: threadID, State: "complete"} 544 545 require.NoError(t, err) 546 require.NoError(t, c.connectionStore.SaveConnectionRecord(connRec)) 547 result, err := c.GetConnection(connID) 548 require.NoError(t, err) 549 require.Equal(t, "complete", result.State) 550 require.Equal(t, "id1", result.ConnectionID) 551 }) 552 553 t.Run("test error", func(t *testing.T) { 554 const errMsg = "query connection error" 555 svc, err := didexchange.New(&mockprotocol.MockProvider{ 556 ServiceMap: map[string]interface{}{ 557 mediator.Coordination: &mockroute.MockMediatorSvc{}, 558 }, 559 }) 560 require.NoError(t, err) 561 require.NotNil(t, svc) 562 563 store := &mockstore.MockStore{ 564 Store: make(map[string]mockstore.DBEntry), 565 ErrGet: fmt.Errorf(errMsg), 566 } 567 568 c, err := New(&mockprovider.Provider{ 569 ProtocolStateStorageProviderValue: mockstore.NewCustomMockStoreProvider(store), 570 StorageProviderValue: mockstore.NewMockStoreProvider(), 571 ServiceMap: map[string]interface{}{ 572 didexchange.DIDExchange: svc, 573 mediator.Coordination: &mockroute.MockMediatorSvc{}, 574 }, 575 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 576 ServiceEndpointValue: "endpoint", 577 }) 578 require.NoError(t, err) 579 580 connRec := &connection.Record{ConnectionID: connID, ThreadID: threadID, State: "complete"} 581 582 require.NoError(t, err) 583 require.NoError(t, c.connectionStore.SaveConnectionRecord(connRec)) 584 _, err = c.GetConnection(connID) 585 require.Error(t, err) 586 require.Contains(t, err.Error(), errMsg) 587 }) 588 589 t.Run("test data not found", func(t *testing.T) { 590 svc, err := didexchange.New(&mockprotocol.MockProvider{ 591 ServiceMap: map[string]interface{}{ 592 mediator.Coordination: &mockroute.MockMediatorSvc{}, 593 }, 594 }) 595 require.NoError(t, err) 596 require.NotNil(t, svc) 597 598 c, err := New(&mockprovider.Provider{ 599 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 600 StorageProviderValue: mockstore.NewMockStoreProvider(), 601 ServiceMap: map[string]interface{}{ 602 didexchange.DIDExchange: svc, 603 mediator.Coordination: &mockroute.MockMediatorSvc{}, 604 }, 605 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 606 ServiceEndpointValue: "endpoint", 607 }) 608 require.NoError(t, err) 609 610 result, err := c.GetConnection(connID) 611 require.Error(t, err) 612 require.True(t, errors.Is(err, ErrConnectionNotFound)) 613 require.Nil(t, result) 614 }) 615 } 616 617 func TestClient_GetConnection(t *testing.T) { 618 connID := "id1" 619 threadID := "thid1" 620 621 t.Run("test failure", func(t *testing.T) { 622 svc, err := didexchange.New(&mockprotocol.MockProvider{ 623 ServiceMap: map[string]interface{}{ 624 mediator.Coordination: &mockroute.MockMediatorSvc{}, 625 }, 626 }) 627 require.NoError(t, err) 628 require.NotNil(t, svc) 629 s := &mockstore.MockStore{Store: make(map[string]mockstore.DBEntry), ErrGet: ErrConnectionNotFound} 630 c, err := New(&mockprovider.Provider{ 631 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 632 StorageProviderValue: mockstore.NewMockStoreProvider(), 633 ServiceMap: map[string]interface{}{ 634 didexchange.DIDExchange: svc, 635 mediator.Coordination: &mockroute.MockMediatorSvc{}, 636 }, 637 }) 638 require.NoError(t, err) 639 connRec := &connection.Record{ConnectionID: connID, ThreadID: threadID, State: "complete"} 640 connBytes, err := json.Marshal(connRec) 641 require.NoError(t, err) 642 require.NoError(t, s.Put("conn_id1", connBytes)) 643 result, err := c.GetConnection(connID) 644 require.Equal(t, err.Error(), ErrConnectionNotFound.Error()) 645 require.Nil(t, result) 646 }) 647 } 648 649 func TestClientGetConnectionAtState(t *testing.T) { 650 // create service 651 svc, err := didexchange.New(&mockprotocol.MockProvider{ 652 ServiceMap: map[string]interface{}{ 653 mediator.Coordination: &mockroute.MockMediatorSvc{}, 654 }, 655 }) 656 require.NoError(t, err) 657 require.NotNil(t, svc) 658 659 // create client 660 c, err := New(&mockprovider.Provider{ 661 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 662 StorageProviderValue: mockstore.NewMockStoreProvider(), 663 ServiceMap: map[string]interface{}{ 664 didexchange.DIDExchange: svc, 665 mediator.Coordination: &mockroute.MockMediatorSvc{}, 666 }, 667 }) 668 require.NoError(t, err) 669 670 // not found 671 result, err := c.GetConnectionAtState("id1", "complete") 672 require.Equal(t, err.Error(), ErrConnectionNotFound.Error()) 673 require.Nil(t, result) 674 } 675 676 func TestClient_CreateConnection(t *testing.T) { 677 t.Run("test create connection - success", func(t *testing.T) { 678 theirDID := newPeerDID(t) 679 myDID := newPeerDID(t) 680 threadID := uuid.New().String() 681 parentThreadID := uuid.New().String() 682 label := uuid.New().String() 683 invitationID := uuid.New().String() 684 invitationDID := newPeerDID(t).ID 685 implicit := true 686 storageProvider := &mockprovider.Provider{ 687 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 688 StorageProviderValue: mockstore.NewMockStoreProvider(), 689 } 690 c, err := New(&mockprovider.Provider{ 691 ProtocolStateStorageProviderValue: storageProvider.ProtocolStateStorageProvider(), 692 StorageProviderValue: storageProvider.StorageProvider(), 693 ServiceMap: map[string]interface{}{ 694 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{ 695 CreateConnRecordFunc: func(r *connection.Record, td *did.Doc) error { 696 recorder, err := connection.NewRecorder(storageProvider) 697 require.NoError(t, err) 698 err = recorder.SaveConnectionRecord(r) 699 require.NoError(t, err) 700 701 return nil 702 }, 703 }, 704 mediator.Coordination: &mockroute.MockMediatorSvc{}, 705 }, 706 }) 707 require.NoError(t, err) 708 709 id, err := c.CreateConnection(myDID.ID, theirDID, 710 WithTheirLabel(label), WithThreadID(threadID), WithParentThreadID(parentThreadID), 711 WithInvitationID(invitationID), WithInvitationDID(invitationDID), WithImplicit(implicit)) 712 require.NoError(t, err) 713 714 conn, err := c.GetConnection(id) 715 require.NoError(t, err) 716 require.Equal(t, connection.StateNameCompleted, conn.State) 717 require.Equal(t, threadID, conn.ThreadID) 718 require.Equal(t, parentThreadID, conn.ParentThreadID) 719 require.Equal(t, label, conn.TheirLabel) 720 require.Equal(t, theirDID.ID, conn.TheirDID) 721 require.Equal(t, myDID.ID, conn.MyDID) 722 require.Equal(t, invitationID, conn.InvitationID) 723 require.Equal(t, invitationDID, conn.InvitationDID) 724 require.Equal(t, theirDID.Service[0].ServiceEndpoint, conn.ServiceEndPoint) 725 require.Equal(t, implicit, conn.Implicit) 726 }) 727 728 t.Run("test create connection - error", func(t *testing.T) { 729 c, err := New(&mockprovider.Provider{ 730 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 731 StorageProviderValue: mockstore.NewMockStoreProvider(), 732 ServiceMap: map[string]interface{}{ 733 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{ 734 CreateConnRecordFunc: func(*connection.Record, *did.Doc) error { 735 return errors.New("save connection") 736 }, 737 }, 738 mediator.Coordination: &mockroute.MockMediatorSvc{}, 739 }, 740 }) 741 require.NoError(t, err) 742 743 id, err := c.CreateConnection(newPeerDID(t).ID, newPeerDID(t)) 744 require.EqualError(t, err, "createConnection: err: save connection") 745 require.Empty(t, id) 746 }) 747 748 t.Run("test create connection - error from CreateDestination", func(t *testing.T) { 749 theirDID := newPeerDID(t) 750 myDID := newPeerDID(t) 751 threadID := uuid.New().String() 752 parentThreadID := uuid.New().String() 753 label := uuid.New().String() 754 invitationID := uuid.New().String() 755 invitationDID := newPeerDID(t).ID 756 implicit := true 757 storageProvider := &mockprovider.Provider{ 758 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 759 StorageProviderValue: mockstore.NewMockStoreProvider(), 760 } 761 c, err := New(&mockprovider.Provider{ 762 ProtocolStateStorageProviderValue: storageProvider.ProtocolStateStorageProvider(), 763 StorageProviderValue: storageProvider.StorageProvider(), 764 ServiceMap: map[string]interface{}{ 765 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{ 766 CreateConnRecordFunc: func(r *connection.Record, td *did.Doc) error { 767 recorder, err := connection.NewRecorder(storageProvider) 768 require.NoError(t, err) 769 err = recorder.SaveConnectionRecord(r) 770 require.NoError(t, err) 771 772 return nil 773 }, 774 }, 775 mediator.Coordination: &mockroute.MockMediatorSvc{}, 776 }, 777 }) 778 require.NoError(t, err) 779 780 // empty ServiceEndpoint to trigger CreateDestination error 781 theirDID.Service[0].ServiceEndpoint = model.NewDIDCommV1Endpoint("") 782 783 _, err = c.CreateConnection(myDID.ID, theirDID, 784 WithTheirLabel(label), WithThreadID(threadID), WithParentThreadID(parentThreadID), 785 WithInvitationID(invitationID), WithInvitationDID(invitationDID), WithImplicit(implicit)) 786 require.Contains(t, err.Error(), "createConnection: failed to create destination: "+ 787 "create destination: service endpoint URI on didcomm v1 service block in diddoc error:") 788 }) 789 } 790 791 func TestClient_RemoveConnection(t *testing.T) { 792 t.Run("test success", func(t *testing.T) { 793 connID := "id1" 794 threadID := "thid1" 795 796 svc, err := didexchange.New(&mockprotocol.MockProvider{ 797 ServiceMap: map[string]interface{}{ 798 mediator.Coordination: &mockroute.MockMediatorSvc{}, 799 }, 800 }) 801 require.NoError(t, err) 802 require.NotNil(t, svc) 803 804 c, err := New(&mockprovider.Provider{ 805 ProtocolStateStorageProviderValue: mem.NewProvider(), 806 StorageProviderValue: mem.NewProvider(), 807 ServiceMap: map[string]interface{}{ 808 didexchange.DIDExchange: svc, 809 mediator.Coordination: &mockroute.MockMediatorSvc{}, 810 }, 811 }) 812 require.NoError(t, err) 813 814 connRec := &connection.Record{ConnectionID: connID, ThreadID: threadID, State: "complete"} 815 816 require.NoError(t, err) 817 require.NoError(t, c.connectionStore.SaveConnectionRecord(connRec)) 818 819 _, err = c.GetConnection(connID) 820 require.NoError(t, err) 821 822 err = c.RemoveConnection(connID) 823 require.NoError(t, err) 824 825 _, err = c.GetConnection(connID) 826 require.Error(t, err) 827 require.Equal(t, err.Error(), ErrConnectionNotFound.Error()) 828 }) 829 t.Run("test error data not found", func(t *testing.T) { 830 svc, err := didexchange.New(&mockprotocol.MockProvider{ 831 ServiceMap: map[string]interface{}{ 832 mediator.Coordination: &mockroute.MockMediatorSvc{}, 833 }, 834 }) 835 require.NoError(t, err) 836 require.NotNil(t, svc) 837 c, err := New(&mockprovider.Provider{ 838 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 839 StorageProviderValue: mockstore.NewMockStoreProvider(), 840 ServiceMap: map[string]interface{}{ 841 didexchange.DIDExchange: svc, 842 mediator.Coordination: &mockroute.MockMediatorSvc{}, 843 }, 844 }) 845 require.NoError(t, err) 846 847 err = c.RemoveConnection("sample-id") 848 require.Error(t, err) 849 require.Contains(t, err.Error(), "data not found") 850 }) 851 } 852 853 func TestClient_HandleInvitation(t *testing.T) { 854 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 855 require.NoError(t, err) 856 857 t.Run("test success", func(t *testing.T) { 858 c, err := New(&mockprovider.Provider{ 859 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 860 StorageProviderValue: mockstore.NewMockStoreProvider(), 861 ServiceMap: map[string]interface{}{ 862 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{}, 863 mediator.Coordination: &mockroute.MockMediatorSvc{}, 864 }, 865 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 866 ServiceEndpointValue: "endpoint", 867 }) 868 869 require.NoError(t, err) 870 inviteReq, err := c.CreateInvitation("agent") 871 require.NoError(t, err) 872 873 connectionID, err := c.HandleInvitation(inviteReq) 874 require.NoError(t, err) 875 require.NotEmpty(t, connectionID) 876 }) 877 878 t.Run("test error from handle msg", func(t *testing.T) { 879 c, err := New(&mockprovider.Provider{ 880 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 881 StorageProviderValue: mockstore.NewMockStoreProvider(), 882 ServiceMap: map[string]interface{}{ 883 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{HandleFunc: func(msg service.DIDCommMsg) (string, error) { 884 return "", fmt.Errorf("handle error") 885 }}, 886 mediator.Coordination: &mockroute.MockMediatorSvc{}, 887 }, 888 889 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 890 ServiceEndpointValue: "endpoint", 891 }) 892 require.NoError(t, err) 893 inviteReq, err := c.CreateInvitation("agent") 894 require.NoError(t, err) 895 896 _, err = c.HandleInvitation(inviteReq) 897 require.Error(t, err) 898 require.Contains(t, err.Error(), "handle error") 899 }) 900 } 901 902 func TestClient_CreateImplicitInvitation(t *testing.T) { 903 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 904 require.NoError(t, err) 905 906 t.Run("test success", func(t *testing.T) { 907 c, err := New(&mockprovider.Provider{ 908 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 909 StorageProviderValue: mockstore.NewMockStoreProvider(), 910 ServiceMap: map[string]interface{}{ 911 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{}, 912 mediator.Coordination: &mockroute.MockMediatorSvc{}, 913 }, 914 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 915 ServiceEndpointValue: "endpoint", 916 }) 917 require.NoError(t, err) 918 919 connectionID, err := c.CreateImplicitInvitation("alice", "did:example:123") 920 require.NoError(t, err) 921 require.NotEmpty(t, connectionID) 922 }) 923 924 t.Run("test error from service", func(t *testing.T) { 925 c, err := New(&mockprovider.Provider{ 926 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 927 StorageProviderValue: mockstore.NewMockStoreProvider(), 928 ServiceMap: map[string]interface{}{ 929 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{ 930 ImplicitInvitationErr: errors.New("implicit error"), 931 }, 932 mediator.Coordination: &mockroute.MockMediatorSvc{}, 933 }, 934 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 935 ServiceEndpointValue: "endpoint", 936 }) 937 require.NoError(t, err) 938 939 connectionID, err := c.CreateImplicitInvitation("Alice", "did:example:123") 940 require.Error(t, err) 941 require.Contains(t, err.Error(), "implicit error") 942 require.Empty(t, connectionID) 943 }) 944 } 945 946 func TestClient_CreateImplicitInvitationWithDID(t *testing.T) { 947 inviter := &DIDInfo{Label: "alice", DID: "did:example:alice"} 948 invitee := &DIDInfo{Label: "bob", DID: "did:example:bob"} 949 950 ed25519KH, err := mockkms.CreateMockED25519KeyHandle() 951 require.NoError(t, err) 952 953 t.Run("test success", func(t *testing.T) { 954 c, err := New(&mockprovider.Provider{ 955 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 956 StorageProviderValue: mockstore.NewMockStoreProvider(), 957 ServiceMap: map[string]interface{}{ 958 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{}, 959 mediator.Coordination: &mockroute.MockMediatorSvc{}, 960 }, 961 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 962 ServiceEndpointValue: "endpoint", 963 }) 964 require.NoError(t, err) 965 966 connectionID, err := c.CreateImplicitInvitationWithDID(inviter, invitee) 967 require.NoError(t, err) 968 require.NotEmpty(t, connectionID) 969 }) 970 971 t.Run("test error from service", func(t *testing.T) { 972 c, err := New(&mockprovider.Provider{ 973 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 974 StorageProviderValue: mockstore.NewMockStoreProvider(), 975 ServiceMap: map[string]interface{}{ 976 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{ 977 ImplicitInvitationErr: errors.New("implicit with DID error"), 978 }, 979 mediator.Coordination: &mockroute.MockMediatorSvc{}, 980 }, 981 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 982 ServiceEndpointValue: "endpoint", 983 }) 984 require.NoError(t, err) 985 986 connectionID, err := c.CreateImplicitInvitationWithDID(inviter, invitee) 987 require.Error(t, err) 988 require.Contains(t, err.Error(), "implicit with DID error") 989 require.Empty(t, connectionID) 990 }) 991 992 t.Run("test missing required DID info", func(t *testing.T) { 993 c, err := New(&mockprovider.Provider{ 994 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 995 StorageProviderValue: mockstore.NewMockStoreProvider(), 996 ServiceMap: map[string]interface{}{ 997 didexchange.DIDExchange: &mocksvc.MockDIDExchangeSvc{}, 998 mediator.Coordination: &mockroute.MockMediatorSvc{}, 999 }, 1000 KMSValue: &mockkms.KeyManager{CreateKeyValue: ed25519KH}, 1001 ServiceEndpointValue: "endpoint", 1002 }) 1003 require.NoError(t, err) 1004 1005 connectionID, err := c.CreateImplicitInvitationWithDID(inviter, nil) 1006 require.Error(t, err) 1007 require.Contains(t, err.Error(), "missing inviter and/or invitee public DID(s)") 1008 require.Empty(t, connectionID) 1009 1010 connectionID, err = c.CreateImplicitInvitationWithDID(nil, invitee) 1011 require.Error(t, err) 1012 require.Contains(t, err.Error(), "missing inviter and/or invitee public DID(s)") 1013 require.Empty(t, connectionID) 1014 }) 1015 } 1016 1017 func TestClient_QueryConnectionsByParams(t *testing.T) { // nolint: gocyclo 1018 t.Run("test get all connections", func(t *testing.T) { 1019 svc, err := didexchange.New(&mockprotocol.MockProvider{ 1020 ServiceMap: map[string]interface{}{ 1021 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1022 }, 1023 }) 1024 require.NoError(t, err) 1025 require.NotNil(t, svc) 1026 1027 storageProvider := mem.NewProvider() 1028 c, err := New(&mockprovider.Provider{ 1029 ProtocolStateStorageProviderValue: mem.NewProvider(), 1030 StorageProviderValue: storageProvider, 1031 ServiceMap: map[string]interface{}{ 1032 didexchange.DIDExchange: svc, 1033 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1034 }, 1035 }) 1036 require.NoError(t, err) 1037 1038 didExchangeStore, err := storageProvider.OpenStore("didexchange") 1039 require.NoError(t, err) 1040 1041 const count = 10 1042 const keyPrefix = "conn_" 1043 const state = "completed" 1044 for i := 0; i < count; i++ { 1045 val, e := json.Marshal(&connection.Record{ 1046 ConnectionID: fmt.Sprint(i), 1047 State: state, 1048 }) 1049 require.NoError(t, e) 1050 require.NoError(t, 1051 didExchangeStore.Put(fmt.Sprintf("%sabc%d", keyPrefix, i), val, spi.Tag{Name: keyPrefix})) 1052 } 1053 1054 results, err := c.QueryConnections(&QueryConnectionsParams{}) 1055 require.NoError(t, err) 1056 require.Len(t, results, count) 1057 for _, result := range results { 1058 require.NotEmpty(t, result.ConnectionID) 1059 } 1060 }) 1061 1062 t.Run("test get connections with params", func(t *testing.T) { 1063 svc, err := didexchange.New(&mockprotocol.MockProvider{ 1064 ServiceMap: map[string]interface{}{ 1065 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1066 }, 1067 }) 1068 require.NoError(t, err) 1069 require.NotNil(t, svc) 1070 1071 storageProvider := mem.NewProvider() 1072 c, err := New(&mockprovider.Provider{ 1073 ProtocolStateStorageProviderValue: mem.NewProvider(), 1074 StorageProviderValue: storageProvider, 1075 ServiceMap: map[string]interface{}{ 1076 didexchange.DIDExchange: svc, 1077 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1078 }, 1079 }) 1080 require.NoError(t, err) 1081 1082 didExchangeStore, err := storageProvider.OpenStore("didexchange") 1083 require.NoError(t, err) 1084 1085 const count = 10 1086 const countWithState = 5 1087 const keyPrefix = "conn_" 1088 const state = "completed" 1089 const myDID = "my_did" 1090 const theirDID = "their_did" 1091 for i := 0; i < count; i++ { 1092 var queryState string 1093 if i < countWithState { 1094 queryState = state 1095 } 1096 1097 val, e := json.Marshal(&connection.Record{ 1098 ConnectionID: fmt.Sprint(i), 1099 InvitationID: fmt.Sprintf("inv-%d", i), 1100 ParentThreadID: fmt.Sprintf("ptid-%d", i), 1101 State: queryState, 1102 MyDID: myDID + strconv.Itoa(i), 1103 TheirDID: theirDID + strconv.Itoa(i), 1104 }) 1105 require.NoError(t, e) 1106 require.NoError(t, 1107 didExchangeStore.Put(fmt.Sprintf("%sabc%d", keyPrefix, i), val, spi.Tag{Name: keyPrefix})) 1108 } 1109 1110 results, err := c.QueryConnections(&QueryConnectionsParams{}) 1111 require.NoError(t, err) 1112 require.Len(t, results, count) 1113 for _, result := range results { 1114 require.NotEmpty(t, result.ConnectionID) 1115 } 1116 1117 results, err = c.QueryConnections(&QueryConnectionsParams{State: state}) 1118 require.NoError(t, err) 1119 require.Len(t, results, countWithState) 1120 for _, result := range results { 1121 require.NotEmpty(t, result.ConnectionID) 1122 require.Equal(t, result.State, state) 1123 } 1124 1125 params := &QueryConnectionsParams{MyDID: myDID + strconv.Itoa(count-1)} 1126 results, err = c.QueryConnections(params) 1127 require.NoError(t, err) 1128 require.Len(t, results, 1) 1129 for _, result := range results { 1130 require.NotEmpty(t, result.ConnectionID) 1131 require.Equal(t, result.MyDID, params.MyDID) 1132 } 1133 1134 params = &QueryConnectionsParams{TheirDID: theirDID + strconv.Itoa(count-1)} 1135 results, err = c.QueryConnections(params) 1136 require.NoError(t, err) 1137 require.Len(t, results, 1) 1138 for _, result := range results { 1139 require.NotEmpty(t, result.ConnectionID) 1140 require.Equal(t, result.TheirDID, params.TheirDID) 1141 } 1142 1143 params = &QueryConnectionsParams{ 1144 MyDID: myDID + strconv.Itoa(count-1), 1145 TheirDID: theirDID + strconv.Itoa(count-1), 1146 } 1147 results, err = c.QueryConnections(params) 1148 require.NoError(t, err) 1149 require.Len(t, results, 1) 1150 for _, result := range results { 1151 require.NotEmpty(t, result.ConnectionID) 1152 require.Equal(t, result.MyDID, params.MyDID) 1153 require.Equal(t, result.TheirDID, params.TheirDID) 1154 } 1155 1156 params = &QueryConnectionsParams{ 1157 InvitationID: fmt.Sprintf("inv-%d", count-1), 1158 } 1159 results, err = c.QueryConnections(params) 1160 require.NoError(t, err) 1161 require.Len(t, results, 1) 1162 for _, result := range results { 1163 require.NotEmpty(t, result.ConnectionID) 1164 require.Equal(t, result.InvitationID, params.InvitationID) 1165 } 1166 1167 params = &QueryConnectionsParams{ 1168 ParentThreadID: fmt.Sprintf("ptid-%d", count-1), 1169 } 1170 results, err = c.QueryConnections(params) 1171 require.NoError(t, err) 1172 require.Len(t, results, 1) 1173 for _, result := range results { 1174 require.NotEmpty(t, result.ConnectionID) 1175 require.Equal(t, result.ParentThreadID, params.ParentThreadID) 1176 } 1177 }) 1178 1179 t.Run("test get connections error", func(t *testing.T) { 1180 svc, err := didexchange.New(&mockprotocol.MockProvider{ 1181 ServiceMap: map[string]interface{}{ 1182 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1183 }, 1184 }) 1185 require.NoError(t, err) 1186 require.NotNil(t, svc) 1187 const keyPrefix = "conn_" 1188 1189 storageProvider := mem.NewProvider() 1190 c, err := New(&mockprovider.Provider{ 1191 ProtocolStateStorageProviderValue: mem.NewProvider(), 1192 StorageProviderValue: storageProvider, 1193 ServiceMap: map[string]interface{}{ 1194 didexchange.DIDExchange: svc, 1195 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1196 }, 1197 }) 1198 require.NoError(t, err) 1199 1200 didExchangeStore, err := storageProvider.OpenStore("didexchange") 1201 require.NoError(t, err) 1202 1203 require.NoError(t, 1204 didExchangeStore.Put(fmt.Sprintf("%sabc", keyPrefix), []byte("----"), spi.Tag{Name: keyPrefix})) 1205 1206 results, err := c.QueryConnections(&QueryConnectionsParams{}) 1207 require.Error(t, err) 1208 require.Empty(t, results) 1209 }) 1210 } 1211 1212 func TestServiceEvents(t *testing.T) { 1213 protocolStateStore := mockstore.NewMockStoreProvider() 1214 ariesStore := mockstore.NewMockStoreProvider() 1215 kmsStore, err := kms.NewAriesProviderWrapper(ariesStore) 1216 require.NoError(t, err) 1217 1218 km := newKMS(t, kmsStore) 1219 1220 didExSvc, err := didexchange.New(&mockprotocol.MockProvider{ 1221 ProtocolStateStoreProvider: protocolStateStore, 1222 StoreProvider: ariesStore, 1223 KMSStore: kmsStore, 1224 ServiceMap: map[string]interface{}{ 1225 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1226 }, 1227 CustomKMS: km, 1228 KeyTypeValue: kms.ED25519Type, 1229 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1230 }) 1231 require.NoError(t, err) 1232 1233 // create the client 1234 c, err := New(&mockprovider.Provider{ 1235 ProtocolStateStorageProviderValue: protocolStateStore, 1236 StorageProviderValue: ariesStore, 1237 ServiceMap: map[string]interface{}{ 1238 didexchange.DIDExchange: didExSvc, 1239 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1240 }, 1241 KMSValue: km, 1242 KeyTypeValue: kms.ED25519Type, 1243 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1244 }) 1245 require.NoError(t, err) 1246 require.NotNil(t, c) 1247 1248 // register action event channel 1249 aCh := make(chan service.DIDCommAction, 10) 1250 err = c.RegisterActionEvent(aCh) 1251 require.NoError(t, err) 1252 1253 go func() { 1254 service.AutoExecuteActionEvent(aCh) 1255 }() 1256 1257 // register message event channel 1258 mCh := make(chan service.StateMsg, 10) 1259 err = c.RegisterMsgEvent(mCh) 1260 require.NoError(t, err) 1261 1262 stateMsg := make(chan service.StateMsg) 1263 1264 go func() { 1265 for e := range mCh { 1266 if e.Type == service.PostState && e.StateID == "responded" { 1267 stateMsg <- e 1268 } 1269 } 1270 }() 1271 1272 // send connection request message 1273 id := "valid-thread-id" 1274 doc, err := (&mockvdr.MockVDRegistry{}).Create("test", nil) 1275 require.NoError(t, err) 1276 1277 invitation, err := c.CreateInvitation("alice") 1278 require.NoError(t, err) 1279 1280 request, err := json.Marshal( 1281 &didexchange.Request{ 1282 Type: didexchange.RequestMsgType, 1283 ID: id, 1284 Label: "test", 1285 Thread: &decorator.Thread{ 1286 PID: invitation.ID, 1287 }, 1288 DID: doc.DIDDocument.ID, 1289 DocAttach: unsignedDocAttach(t, doc.DIDDocument), 1290 }, 1291 ) 1292 require.NoError(t, err) 1293 1294 msg, err := service.ParseDIDCommMsgMap(request) 1295 require.NoError(t, err) 1296 _, err = didExSvc.HandleInbound(msg, service.EmptyDIDCommContext()) 1297 require.NoError(t, err) 1298 1299 select { 1300 case e := <-stateMsg: 1301 switch v := e.Properties.(type) { 1302 case Event: 1303 props := v 1304 conn, err := c.GetConnectionAtState(props.ConnectionID(), e.StateID) 1305 require.NoError(t, err) 1306 require.Equal(t, e.StateID, conn.State) 1307 default: 1308 require.Fail(t, "unable to cast to did exchange event") 1309 } 1310 case <-time.After(5 * time.Second): 1311 require.Fail(t, "tests are not validated due to timeout") 1312 } 1313 } 1314 1315 func TestAcceptExchangeRequest(t *testing.T) { 1316 ariesStore := mockstore.NewMockStoreProvider() 1317 kmsStore, err := kms.NewAriesProviderWrapper(ariesStore) 1318 require.NoError(t, err) 1319 1320 km := newKMS(t, kmsStore) 1321 didExSvc, err := didexchange.New(&mockprotocol.MockProvider{ 1322 StoreProvider: ariesStore, 1323 KMSStore: kmsStore, 1324 ServiceMap: map[string]interface{}{ 1325 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1326 }, 1327 CustomKMS: km, 1328 KeyTypeValue: kms.ED25519Type, 1329 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1330 }) 1331 require.NoError(t, err) 1332 1333 // create the client 1334 c, err := New(&mockprovider.Provider{ 1335 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 1336 StorageProviderValue: ariesStore, 1337 ServiceMap: map[string]interface{}{ 1338 didexchange.DIDExchange: didExSvc, 1339 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1340 }, 1341 KMSValue: km, 1342 KeyTypeValue: kms.ED25519Type, 1343 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1344 }, 1345 ) 1346 require.NoError(t, err) 1347 require.NotNil(t, c) 1348 1349 // register action event channel 1350 aCh := make(chan service.DIDCommAction, 10) 1351 err = c.RegisterActionEvent(aCh) 1352 require.NoError(t, err) 1353 1354 go func() { 1355 for e := range aCh { 1356 prop, ok := e.Properties.(Event) 1357 if !ok { 1358 require.Fail(t, "Failed to cast the event properties to service.Event") 1359 } 1360 1361 require.NoError(t, c.AcceptExchangeRequest(prop.ConnectionID(), "", "")) 1362 } 1363 }() 1364 1365 // register message event channel 1366 mCh := make(chan service.StateMsg, 10) 1367 err = c.RegisterMsgEvent(mCh) 1368 require.NoError(t, err) 1369 1370 done := make(chan struct{}) 1371 1372 go func() { 1373 for e := range mCh { 1374 if e.Type == service.PostState && e.StateID == "responded" { 1375 close(done) 1376 } 1377 } 1378 }() 1379 1380 invitation, err := c.CreateInvitation("alice") 1381 require.NoError(t, err) 1382 // send connection request message 1383 id := "valid-thread-id" 1384 doc, err := (&mockvdr.MockVDRegistry{}).Create("test", nil) 1385 require.NoError(t, err) 1386 1387 request, err := json.Marshal( 1388 &didexchange.Request{ 1389 Type: didexchange.RequestMsgType, 1390 ID: id, 1391 Label: "test", 1392 Thread: &decorator.Thread{ 1393 PID: invitation.ID, 1394 }, 1395 DocAttach: unsignedDocAttach(t, doc.DIDDocument), 1396 DID: doc.DIDDocument.ID, 1397 }, 1398 ) 1399 require.NoError(t, err) 1400 1401 msg, err := service.ParseDIDCommMsgMap(request) 1402 require.NoError(t, err) 1403 _, err = didExSvc.HandleInbound(msg, service.EmptyDIDCommContext()) 1404 require.NoError(t, err) 1405 1406 select { 1407 case <-done: 1408 case <-time.After(5 * time.Second): 1409 require.Fail(t, "tests are not validated due to timeout") 1410 } 1411 1412 err = c.AcceptExchangeRequest("invalid-id", "", "") 1413 require.Error(t, err) 1414 require.Contains(t, err.Error(), "did exchange client - accept exchange request:") 1415 } 1416 1417 func TestAcceptInvitation(t *testing.T) { 1418 ariesStore := mockstore.NewMockStoreProvider() 1419 kmsStore, err := kms.NewAriesProviderWrapper(ariesStore) 1420 require.NoError(t, err) 1421 1422 km := newKMS(t, kmsStore) 1423 didExSvc, err := didexchange.New(&mockprotocol.MockProvider{ 1424 StoreProvider: ariesStore, 1425 KMSStore: kmsStore, 1426 ServiceMap: map[string]interface{}{ 1427 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1428 }, 1429 CustomKMS: km, 1430 KeyTypeValue: kms.ED25519Type, 1431 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1432 }) 1433 require.NoError(t, err) 1434 1435 // create the client 1436 c, err := New(&mockprovider.Provider{ 1437 ProtocolStateStorageProviderValue: mockstore.NewMockStoreProvider(), 1438 StorageProviderValue: ariesStore, 1439 ServiceMap: map[string]interface{}{ 1440 didexchange.DIDExchange: didExSvc, 1441 mediator.Coordination: &mockroute.MockMediatorSvc{}, 1442 }, 1443 KMSValue: km, 1444 KeyTypeValue: kms.ED25519Type, 1445 KeyAgreementTypeValue: kms.X25519ECDHKWType, 1446 }) 1447 require.NoError(t, err) 1448 require.NotNil(t, c) 1449 1450 t.Run("accept invitation - success", func(t *testing.T) { 1451 // register action event channel 1452 aCh := make(chan service.DIDCommAction, 10) 1453 err = c.RegisterActionEvent(aCh) 1454 require.NoError(t, err) 1455 1456 go func() { 1457 for e := range aCh { 1458 _, ok := e.Properties.(Event) 1459 require.True(t, ok, "Failed to cast the event properties to service.Event") 1460 1461 // ignore action event 1462 } 1463 }() 1464 1465 // register message event channel 1466 mCh := make(chan service.StateMsg, 10) 1467 err = c.RegisterMsgEvent(mCh) 1468 require.NoError(t, err) 1469 1470 done := make(chan struct{}) 1471 1472 go func() { 1473 for e := range mCh { 1474 prop, ok := e.Properties.(Event) 1475 if !ok { 1476 require.Fail(t, "Failed to cast the event properties to service.Event") 1477 } 1478 1479 if e.Type == service.PostState && e.StateID == "invited" { 1480 require.NoError(t, c.AcceptInvitation(prop.ConnectionID(), "", "")) 1481 } 1482 1483 if e.Type == service.PostState && e.StateID == "requested" { 1484 close(done) 1485 } 1486 } 1487 }() 1488 1489 _, pubKey, e := km.CreateAndExportPubKeyBytes(kms.ED25519Type) 1490 require.NoError(t, e) 1491 1492 // send connection invitation message 1493 invitation, jsonErr := json.Marshal( 1494 &didexchange.Invitation{ 1495 Type: InvitationMsgType, 1496 ID: "abc", 1497 Label: "test", 1498 RecipientKeys: []string{string(pubKey)}, 1499 }, 1500 ) 1501 require.NoError(t, jsonErr) 1502 1503 msg, svcErr := service.ParseDIDCommMsgMap(invitation) 1504 require.NoError(t, svcErr) 1505 _, err = didExSvc.HandleInbound(msg, service.EmptyDIDCommContext()) 1506 require.NoError(t, err) 1507 1508 select { 1509 case <-done: 1510 case <-time.After(5 * time.Second): 1511 require.Fail(t, "tests are not validated due to timeout") 1512 } 1513 }) 1514 1515 t.Run("accept invitation - error", func(t *testing.T) { 1516 err = c.AcceptInvitation("invalid-id", "", "") 1517 require.Error(t, err) 1518 require.Contains(t, err.Error(), "did exchange client - accept exchange invitation") 1519 }) 1520 } 1521 1522 func newPeerDID(t *testing.T) *did.Doc { 1523 t.Helper() 1524 1525 a, err := aries.New( 1526 aries.WithStoreProvider(mem.NewProvider()), 1527 aries.WithProtocolStateStoreProvider(mem.NewProvider()), 1528 ) 1529 require.NoError(t, err) 1530 1531 ctx, err := a.Context() 1532 require.NoError(t, err) 1533 1534 d, err := ctx.VDRegistry().Create( 1535 peer.DIDMethod, &did.Doc{Service: []did.Service{{ 1536 Type: "did-communication", 1537 ServiceEndpoint: model.NewDIDCommV1Endpoint("http://agent.example.com/didcomm"), 1538 }}, VerificationMethod: []did.VerificationMethod{getSigningKey()}}) 1539 require.NoError(t, err) 1540 1541 return d.DIDDocument 1542 } 1543 1544 func getSigningKey() did.VerificationMethod { 1545 pub, _, err := ed25519.GenerateKey(rand.Reader) 1546 if err != nil { 1547 panic(err) 1548 } 1549 1550 return did.VerificationMethod{Value: pub[:], Type: "Ed25519VerificationKey2018"} 1551 } 1552 1553 type mockKMSProvider struct { 1554 kmsStore kms.Store 1555 secretLockService secretlock.Service 1556 } 1557 1558 func (m *mockKMSProvider) StorageProvider() kms.Store { 1559 return m.kmsStore 1560 } 1561 1562 func (m *mockKMSProvider) SecretLock() secretlock.Service { 1563 return m.secretLockService 1564 } 1565 1566 func newKMS(t *testing.T, store kms.Store) kms.KeyManager { 1567 t.Helper() 1568 1569 kmsProv := &mockKMSProvider{ 1570 kmsStore: store, 1571 secretLockService: &noop.NoLock{}, 1572 } 1573 1574 customKMS, err := localkms.New("local-lock://primary/test/", kmsProv) 1575 require.NoError(t, err) 1576 1577 return customKMS 1578 } 1579 1580 func unsignedDocAttach(t *testing.T, doc *did.Doc) *decorator.Attachment { 1581 t.Helper() 1582 1583 docBytes, err := doc.JSONBytes() 1584 require.NoError(t, err) 1585 1586 att := &decorator.Attachment{ 1587 Data: decorator.AttachmentData{ 1588 Base64: base64.StdEncoding.EncodeToString(docBytes), 1589 }, 1590 } 1591 1592 return att 1593 }