github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/common/service/destination_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  Copyright Avast Software. All Rights Reserved.
     4  
     5  SPDX-License-Identifier: Apache-2.0
     6  */
     7  
     8  package service
     9  
    10  import (
    11  	"crypto/ed25519"
    12  	"crypto/rand"
    13  	"errors"
    14  	"fmt"
    15  	"strings"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/btcsuite/btcutil/base58"
    20  	"github.com/stretchr/testify/require"
    21  
    22  	"github.com/hyperledger/aries-framework-go/pkg/common/model"
    23  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    24  	mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
    25  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    26  )
    27  
    28  func TestGetDestinationFromDID(t *testing.T) {
    29  	doc := createDIDDoc()
    30  
    31  	t.Run("successfully getting destination from public DID", func(t *testing.T) {
    32  		vdr := mockvdr.MockVDRegistry{ResolveValue: doc}
    33  		destination, err := GetDestination(doc.ID, &vdr)
    34  		require.NoError(t, err)
    35  		require.NotNil(t, destination)
    36  	})
    37  
    38  	t.Run("successfully getting destination from public DID with DIDComm V2 service block", func(t *testing.T) {
    39  		doc2 := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "alicedid")
    40  		vdr := mockvdr.MockVDRegistry{ResolveValue: doc2}
    41  		destination, err := GetDestination(doc.ID, &vdr)
    42  		require.NoError(t, err)
    43  		require.NotNil(t, destination)
    44  	})
    45  
    46  	t.Run("successfully getting destination from public DID with DIDComm V2 service block using relative key "+
    47  		"Agreement ID", func(t *testing.T) {
    48  		doc2 := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "alicedid")
    49  		prefixID := strings.Index(doc2.KeyAgreement[0].VerificationMethod.ID, "#")
    50  		doc2.KeyAgreement[0].VerificationMethod.ID = doc2.KeyAgreement[0].VerificationMethod.ID[prefixID:]
    51  		vdr := mockvdr.MockVDRegistry{ResolveValue: doc2}
    52  		destination, err := GetDestination(doc.ID, &vdr)
    53  		require.NoError(t, err)
    54  		require.NotNil(t, destination)
    55  	})
    56  
    57  	t.Run("error getting destination from public DID with DIDComm V2 service block using empty key "+
    58  		"Agreements", func(t *testing.T) {
    59  		doc2 := mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "alicedid")
    60  		doc2.KeyAgreement = nil
    61  		vdr := mockvdr.MockVDRegistry{ResolveValue: doc2}
    62  		destination, err := GetDestination(doc.ID, &vdr)
    63  		require.EqualError(t, err, fmt.Sprintf("create destination: no keyAgreements in diddoc for didcomm v2 "+
    64  			"service bloc. DIDDoc: %+v", doc2))
    65  		require.Nil(t, destination)
    66  	})
    67  
    68  	t.Run("test service not found", func(t *testing.T) {
    69  		doc2 := createDIDDoc()
    70  		doc2.Service = nil
    71  		vdr := mockvdr.MockVDRegistry{ResolveValue: doc2}
    72  		destination, err := GetDestination(doc2.ID, &vdr)
    73  		require.Error(t, err)
    74  		require.Contains(t, err.Error(), "missing DID doc service")
    75  		require.Nil(t, destination)
    76  	})
    77  
    78  	t.Run("fails if no service of type did-communication is found", func(t *testing.T) {
    79  		diddoc := createDIDDoc()
    80  		for i := range diddoc.Service {
    81  			diddoc.Service[i].Type = "invalid"
    82  		}
    83  		vdr := &mockvdr.MockVDRegistry{ResolveValue: diddoc}
    84  		_, err := GetDestination(diddoc.ID, vdr)
    85  		require.Error(t, err)
    86  	})
    87  
    88  	t.Run("fails if the service endpoint is missing", func(t *testing.T) {
    89  		diddoc := createDIDDoc()
    90  		for i := range diddoc.Service {
    91  			diddoc.Service[i].ServiceEndpoint = model.NewDIDCommV1Endpoint("")
    92  		}
    93  		vdr := &mockvdr.MockVDRegistry{ResolveValue: diddoc}
    94  		_, err := GetDestination(diddoc.ID, vdr)
    95  		require.Error(t, err)
    96  	})
    97  
    98  	t.Run("fails it there are no recipient keys", func(t *testing.T) {
    99  		diddoc := createDIDDoc()
   100  		for i := range diddoc.Service {
   101  			diddoc.Service[i].RecipientKeys = nil
   102  		}
   103  		vdr := &mockvdr.MockVDRegistry{ResolveValue: diddoc}
   104  		_, err := GetDestination(diddoc.ID, vdr)
   105  		require.Error(t, err)
   106  	})
   107  
   108  	t.Run("test did document not found", func(t *testing.T) {
   109  		vdr := mockvdr.MockVDRegistry{ResolveErr: errors.New("resolver error")}
   110  		destination, err := GetDestination(doc.ID, &vdr)
   111  		require.Error(t, err)
   112  		require.Contains(t, err.Error(), "resolver error")
   113  		require.Nil(t, destination)
   114  	})
   115  }
   116  
   117  func TestPrepareDestination(t *testing.T) {
   118  	t.Run("successfully prepared destination", func(t *testing.T) {
   119  		doc := mockdiddoc.GetMockDIDDoc(t, false)
   120  		dest, err := CreateDestination(doc)
   121  		require.NoError(t, err)
   122  		require.NotNil(t, dest)
   123  		uri, err := dest.ServiceEndpoint.URI()
   124  		require.NoError(t, err)
   125  		require.Equal(t, uri, "https://localhost:8090")
   126  		require.EqualValues(t, doc.Service[0].RoutingKeys, dest.RoutingKeys)
   127  	})
   128  
   129  	t.Run("successfully prepared legacy destination", func(t *testing.T) {
   130  		doc := mockdiddoc.GetMockIndyDoc(t)
   131  		dest, err := CreateDestination(doc)
   132  		require.NoError(t, err)
   133  		require.NotNil(t, dest)
   134  		uri, err := dest.ServiceEndpoint.URI()
   135  		require.NoError(t, err)
   136  		require.Equal(t, uri, "https://localhost:8090")
   137  		require.Equal(t, doc.Service[0].RoutingKeys, dest.RoutingKeys)
   138  	})
   139  
   140  	t.Run("error with destination having recipientKeys not did:keys", func(t *testing.T) {
   141  		doc := mockdiddoc.GetMockDIDDoc(t, false)
   142  		doc.Service[0].RecipientKeys = []string{"badKey"}
   143  		dest, err := CreateDestination(doc)
   144  
   145  		require.EqualError(t, err, "create destination: recipient key 1:[badKey] of didComm '' not a did:key")
   146  		require.Nil(t, dest)
   147  	})
   148  
   149  	t.Run("error while getting service", func(t *testing.T) {
   150  		didDoc := mockdiddoc.GetMockDIDDoc(t, false)
   151  		didDoc.Service = nil
   152  
   153  		dest, err := CreateDestination(didDoc)
   154  		require.Error(t, err)
   155  		require.Contains(t, err.Error(), "missing DID doc service")
   156  		require.Nil(t, dest)
   157  	})
   158  
   159  	t.Run("error while getting recipient keys from did doc", func(t *testing.T) {
   160  		didDoc := mockdiddoc.GetMockDIDDoc(t, false)
   161  		didDoc.Service[0].RecipientKeys = []string{}
   162  
   163  		recipientKeys, ok := did.LookupDIDCommRecipientKeys(didDoc)
   164  		require.False(t, ok)
   165  		require.Nil(t, recipientKeys)
   166  	})
   167  }
   168  
   169  func createDIDDoc() *did.Doc {
   170  	pubKey, _ := generateKeyPair()
   171  	return createDIDDocWithKey(pubKey)
   172  }
   173  
   174  func generateKeyPair() (string, []byte) {
   175  	pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)
   176  	if err != nil {
   177  		panic(err)
   178  	}
   179  
   180  	return base58.Encode(pubKey[:]), privKey
   181  }
   182  
   183  func createDIDDocWithKey(pub string) *did.Doc {
   184  	const (
   185  		didFormat    = "did:%s:%s"
   186  		didPKID      = "%s#keys-%d"
   187  		didServiceID = "%s#endpoint-%d"
   188  		method       = "test"
   189  	)
   190  
   191  	id := fmt.Sprintf(didFormat, method, pub[:16])
   192  	pubKeyID := fmt.Sprintf(didPKID, id, 1)
   193  	pubKey := did.VerificationMethod{
   194  		ID:         pubKeyID,
   195  		Type:       "Ed25519VerificationKey2018",
   196  		Controller: id,
   197  		Value:      []byte(pub),
   198  	}
   199  	services := []did.Service{
   200  		{
   201  			ID:              fmt.Sprintf(didServiceID, id, 1),
   202  			Type:            "did-communication",
   203  			ServiceEndpoint: model.NewDIDCommV1Endpoint("http://localhost:58416"),
   204  			Priority:        0,
   205  			RecipientKeys:   []string{pubKeyID},
   206  		},
   207  	}
   208  	createdTime := time.Now()
   209  	didDoc := &did.Doc{
   210  		Context:            []string{did.ContextV1},
   211  		ID:                 id,
   212  		VerificationMethod: []did.VerificationMethod{pubKey},
   213  		Service:            services,
   214  		Created:            &createdTime,
   215  		Updated:            &createdTime,
   216  	}
   217  
   218  	return didDoc
   219  }